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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits