diff options
author | Owen Pan <owenpiano@gmail.com> | 2025-07-13 14:29:51 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-13 14:29:51 -0700 |
commit | c384ec431dd7f771c9dd7c462cec5301ac0f32bb (patch) | |
tree | a2a0cbab11398735e199b7aaa482e7c52ee29bd9 /clang/lib/Format | |
parent | 1fbfa333f64bf714efa84db6b1075fc864d53bf8 (diff) | |
download | llvm-c384ec431dd7f771c9dd7c462cec5301ac0f32bb.zip llvm-c384ec431dd7f771c9dd7c462cec5301ac0f32bb.tar.gz llvm-c384ec431dd7f771c9dd7c462cec5301ac0f32bb.tar.bz2 |
[clang-format] Add MacrosSkippedByRemoveParentheses option (#148345)
This allows RemoveParentheses to skip the invocations of function-like
macros.
Fixes #68354.
Fixes #147780.
Diffstat (limited to 'clang/lib/Format')
-rw-r--r-- | clang/lib/Format/Format.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Format/FormatToken.h | 1 | ||||
-rw-r--r-- | clang/lib/Format/FormatTokenLexer.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Format/FormatTokenLexer.h | 4 | ||||
-rw-r--r-- | clang/lib/Format/TokenAnnotator.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Format/UnwrappedLineParser.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Format/UnwrappedLineParser.h | 3 |
7 files changed, 22 insertions, 9 deletions
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 4956607..78c09be 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1099,6 +1099,8 @@ template <> struct MappingTraits<FormatStyle> { IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin); IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd); IO.mapOptional("Macros", Style.Macros); + IO.mapOptional("MacrosSkippedByRemoveParentheses", + Style.MacrosSkippedByRemoveParentheses); IO.mapOptional("MainIncludeChar", Style.IncludeStyle.MainIncludeChar); IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep); IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation); diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 94014ae..9252a79 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -83,6 +83,7 @@ namespace format { TYPE(FunctionDeclarationName) \ TYPE(FunctionDeclarationLParen) \ TYPE(FunctionLBrace) \ + TYPE(FunctionLikeMacro) \ TYPE(FunctionLikeOrFreestandingMacro) \ TYPE(FunctionTypeLParen) \ /* The colons as part of a C11 _Generic selection */ \ diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp index d8ee5cb..49da316 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -74,6 +74,8 @@ FormatTokenLexer::FormatTokenLexer( Macros.insert({Identifier, TT_StatementAttributeLikeMacro}); } + for (const auto &Macro : Style.MacrosSkippedByRemoveParentheses) + MacrosSkippedByRemoveParentheses.insert(&IdentTable.get(Macro)); for (const auto &TemplateName : Style.TemplateNames) TemplateNames.insert(&IdentTable.get(TemplateName)); for (const auto &TypeName : Style.TypeNames) @@ -1473,6 +1475,8 @@ FormatToken *FormatTokenLexer::getNextToken() { FormatTok->setType(TT_MacroBlockBegin); else if (MacroBlockEndRegex.match(Text)) FormatTok->setType(TT_MacroBlockEnd); + else if (MacrosSkippedByRemoveParentheses.contains(Identifier)) + FormatTok->setFinalizedType(TT_FunctionLikeMacro); else if (TemplateNames.contains(Identifier)) FormatTok->setFinalizedType(TT_TemplateName); else if (TypeNames.contains(Identifier)) diff --git a/clang/lib/Format/FormatTokenLexer.h b/clang/lib/Format/FormatTokenLexer.h index 026383d..57c572a 100644 --- a/clang/lib/Format/FormatTokenLexer.h +++ b/clang/lib/Format/FormatTokenLexer.h @@ -132,8 +132,8 @@ private: llvm::SmallMapVector<IdentifierInfo *, TokenType, 8> Macros; - llvm::SmallPtrSet<IdentifierInfo *, 8> TemplateNames, TypeNames, - VariableTemplates; + llvm::SmallPtrSet<IdentifierInfo *, 8> MacrosSkippedByRemoveParentheses, + TemplateNames, TypeNames, VariableTemplates; bool FormattingDisabled; llvm::Regex FormatOffRegex; // For one line. diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index aab8f05..739209a 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2090,7 +2090,8 @@ private: TT_RecordLBrace, TT_StructLBrace, TT_UnionLBrace, TT_RequiresClause, TT_RequiresClauseInARequiresExpression, TT_RequiresExpression, TT_RequiresExpressionLParen, TT_RequiresExpressionLBrace, - TT_CompoundRequirementLBrace, TT_BracedListLBrace)) { + TT_CompoundRequirementLBrace, TT_BracedListLBrace, + TT_FunctionLikeMacro)) { CurrentToken->setType(TT_Unknown); } CurrentToken->Role.reset(); diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 7e8634a..91b8fdc 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -2579,30 +2579,34 @@ bool UnwrappedLineParser::parseBracedList(bool IsAngleBracket, bool IsEnum) { /// double ampersands. This applies for all nested scopes as well. /// /// Returns whether there is a `=` token between the parentheses. -bool UnwrappedLineParser::parseParens(TokenType AmpAmpTokenType) { +bool UnwrappedLineParser::parseParens(TokenType AmpAmpTokenType, + bool InMacroCall) { assert(FormatTok->is(tok::l_paren) && "'(' expected."); auto *LParen = FormatTok; + auto *Prev = FormatTok->Previous; bool SeenComma = false; bool SeenEqual = false; bool MightBeFoldExpr = false; nextToken(); const bool MightBeStmtExpr = FormatTok->is(tok::l_brace); + if (!InMacroCall && Prev && Prev->is(TT_FunctionLikeMacro)) + InMacroCall = true; do { switch (FormatTok->Tok.getKind()) { case tok::l_paren: - if (parseParens(AmpAmpTokenType)) + if (parseParens(AmpAmpTokenType, InMacroCall)) SeenEqual = true; if (Style.isJava() && FormatTok->is(tok::l_brace)) parseChildBlock(); break; case tok::r_paren: { - auto *Prev = LParen->Previous; auto *RParen = FormatTok; nextToken(); if (Prev) { auto OptionalParens = [&] { - if (MightBeStmtExpr || MightBeFoldExpr || Line->InMacroBody || - SeenComma || Style.RemoveParentheses == FormatStyle::RPS_Leave || + if (MightBeStmtExpr || MightBeFoldExpr || SeenComma || InMacroCall || + Line->InMacroBody || + Style.RemoveParentheses == FormatStyle::RPS_Leave || RParen->getPreviousNonComment() == LParen) { return false; } diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h index 2d1492c..8e29680 100644 --- a/clang/lib/Format/UnwrappedLineParser.h +++ b/clang/lib/Format/UnwrappedLineParser.h @@ -145,7 +145,8 @@ private: bool *HasLabel = nullptr); bool tryToParseBracedList(); bool parseBracedList(bool IsAngleBracket = false, bool IsEnum = false); - bool parseParens(TokenType AmpAmpTokenType = TT_Unknown); + bool parseParens(TokenType AmpAmpTokenType = TT_Unknown, + bool InMacroCall = false); void parseSquare(bool LambdaIntroducer = false); void keepAncestorBraces(); void parseUnbracedBody(bool CheckEOF = false); |