[clang] [clang-format] add option to control bin-packing keyworded parameters (PR #131605)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Sep 14 15:12:21 PDT 2025
owenca wrote:
> As to the implementation, it can be simplified and probably made less brittle. I would do something like the following instead:
>
> * Name the option as `AllowBreakBeforeQtProperty`.
> * Use `Q_PROPERTY` for a new context `Context::QtProperty`. (See `_Generic` and `Context::C11GenericSelection`.)
> * Either use all-uppercase identifiers as the criterion or binary-search in a sorted table of all Qt property keywords (`READ`, `WRITE`, etc.) similar to `CppNonKeywordTypes` in FormatToken.cpp.
> * Set the token type of those keywords to `TT_QtProperty`.
When I said the above in https://github.com/llvm/llvm-project/pull/131605#issuecomment-2774441914, I had the following in mind:
```diff
diff --git a/clang/lib/Format/FormatToken.cpp b/clang/lib/Format/FormatToken.cpp
@@ -34,6 +34,17 @@ const char *getTokenTypeName(TokenType Type) {
return nullptr;
}
+static SmallVector<StringRef> QtPropertyKeywords = {
+ "BINDABLE", "CONSTANT", "DESIGNABLE", "FINAL", "MEMBER",
+ "NOTIFY", "READ", "REQUIRED", "RESET", "REVISION",
+ "SCRIPTABLE", "STORED", "USER", "WRITE",
+};
+
+bool FormatToken::isQtProperty() const {
+ return std::binary_search(QtPropertyKeywords.begin(),
+ QtPropertyKeywords.end(), TokenText);
+}
+
// Sorted common C++ non-keyword types.
static SmallVector<StringRef> CppNonKeywordTypes = {
"clock_t", "int16_t", "int32_t", "int64_t", "int8_t",
@@ -331,6 +342,8 @@ bool startsNextParameter(const FormatToken &Current, const FormatStyle &Style) {
}
if (Style.Language == FormatStyle::LK_Proto && Current.is(TT_SelectorName))
return true;
+ if (Current.is(TT_QtProperty))
+ return true;
return Previous.is(tok::comma) && !Current.isTrailingComment() &&
((Previous.isNot(TT_CtorInitializerComma) ||
Style.BreakConstructorInitializers !=
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
@@ -135,6 +135,7 @@ namespace format {
TYPE(PointerOrReference) \
TYPE(ProtoExtensionLSquare) \
TYPE(PureVirtualSpecifier) \
+ TYPE(QtProperty) \
TYPE(RangeBasedForLoopColon) \
TYPE(RecordLBrace) \
TYPE(RecordRBrace) \
@@ -703,6 +704,7 @@ public:
isAttribute();
}
+ [[nodiscard]] bool isQtProperty() const;
[[nodiscard]] bool isTypeName(const LangOptions &LangOpts) const;
[[nodiscard]] bool isTypeOrIdentifier(const LangOptions &LangOpts) const;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
@@ -390,6 +390,10 @@ private:
OpeningParen.Previous->is(tok::kw__Generic)) {
Contexts.back().ContextType = Context::C11GenericSelection;
Contexts.back().IsExpression = true;
+ } else if (OpeningParen.Previous &&
+ OpeningParen.Previous->TokenText == "Q_PROPERTY") {
+ Contexts.back().ContextType = Context::QtProperty;
+ Contexts.back().IsExpression = false;
} else if (Line.InPPDirective &&
(!OpeningParen.Previous ||
OpeningParen.Previous->isNot(tok::identifier))) {
@@ -1811,6 +1815,11 @@ private:
return false;
}
}
+ if (Style.AllowBreakBeforeQtProperty &&
+ Contexts.back().ContextType == Context::QtProperty &&
+ Tok->isQtProperty()) {
+ Tok->setFinalizedType(TT_QtProperty);
+ }
break;
case tok::arrow:
if (Tok->isNot(TT_LambdaArrow) && Tok->Previous &&
@@ -2179,6 +2188,7 @@ private:
TemplateArgument,
// C11 _Generic selection.
C11GenericSelection,
+ QtProperty,
// Like in the outer parentheses in `ffnand ff1(.q());`.
VerilogInstancePortList,
} ContextType = Unknown;
@@ -6235,7 +6245,7 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
Right.Next->isOneOf(TT_FunctionDeclarationName, tok::kw_const)));
}
if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName,
- TT_ClassHeadName, tok::kw_operator)) {
+ TT_ClassHeadName, TT_QtProperty, tok::kw_operator)) {
return true;
}
if (Right.isAttribute())
```
https://github.com/llvm/llvm-project/pull/131605
More information about the cfe-commits
mailing list