aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Format
diff options
context:
space:
mode:
authorOwen Pan <owenpiano@gmail.com>2025-07-13 14:29:51 -0700
committerGitHub <noreply@github.com>2025-07-13 14:29:51 -0700
commitc384ec431dd7f771c9dd7c462cec5301ac0f32bb (patch)
treea2a0cbab11398735e199b7aaa482e7c52ee29bd9 /clang/lib/Format
parent1fbfa333f64bf714efa84db6b1075fc864d53bf8 (diff)
downloadllvm-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.cpp2
-rw-r--r--clang/lib/Format/FormatToken.h1
-rw-r--r--clang/lib/Format/FormatTokenLexer.cpp4
-rw-r--r--clang/lib/Format/FormatTokenLexer.h4
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp3
-rw-r--r--clang/lib/Format/UnwrappedLineParser.cpp14
-rw-r--r--clang/lib/Format/UnwrappedLineParser.h3
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);