Skip to content

Commit c384ec4

Browse files
authored
[clang-format] Add MacrosSkippedByRemoveParentheses option (#148345)
This allows RemoveParentheses to skip the invocations of function-like macros. Fixes #68354. Fixes #147780.
1 parent 1fbfa33 commit c384ec4

File tree

12 files changed

+42
-9
lines changed

12 files changed

+42
-9
lines changed

clang/docs/ClangFormatStyleOptions.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4975,6 +4975,12 @@ the configuration (without a prefix: ``Auto``).
49754975
A(z); -> z;
49764976
A(a, b); // will not be expanded.
49774977

4978+
.. _MacrosSkippedByRemoveParentheses:
4979+
4980+
**MacrosSkippedByRemoveParentheses** (``List of Strings``) :versionbadge:`clang-format 21` :ref:`<MacrosSkippedByRemoveParentheses>`
4981+
A vector of function-like macros whose invocations should be skipped by
4982+
``RemoveParentheses``.
4983+
49784984
.. _MainIncludeChar:
49794985

49804986
**MainIncludeChar** (``MainIncludeCharDiscriminator``) :versionbadge:`clang-format 19` :ref:`<MainIncludeChar>`

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,8 @@ clang-format
11361136
``enum`` enumerator lists.
11371137
- Add ``OneLineFormatOffRegex`` option for turning formatting off for one line.
11381138
- Add ``SpaceAfterOperatorKeyword`` option.
1139+
- Add ``MacrosSkippedByRemoveParentheses`` option so that their invocations are
1140+
skipped by ``RemoveParentheses``.
11391141

11401142
clang-refactor
11411143
--------------

clang/include/clang/Format/Format.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3488,6 +3488,11 @@ struct FormatStyle {
34883488
/// \version 17
34893489
std::vector<std::string> Macros;
34903490

3491+
/// A vector of function-like macros whose invocations should be skipped by
3492+
/// ``RemoveParentheses``.
3493+
/// \version 21
3494+
std::vector<std::string> MacrosSkippedByRemoveParentheses;
3495+
34913496
/// The maximum number of consecutive empty lines to keep.
34923497
/// \code
34933498
/// MaxEmptyLinesToKeep: 1 vs. MaxEmptyLinesToKeep: 0
@@ -5410,6 +5415,8 @@ struct FormatStyle {
54105415
LambdaBodyIndentation == R.LambdaBodyIndentation &&
54115416
LineEnding == R.LineEnding && MacroBlockBegin == R.MacroBlockBegin &&
54125417
MacroBlockEnd == R.MacroBlockEnd && Macros == R.Macros &&
5418+
MacrosSkippedByRemoveParentheses ==
5419+
R.MacrosSkippedByRemoveParentheses &&
54135420
MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep &&
54145421
NamespaceIndentation == R.NamespaceIndentation &&
54155422
NamespaceMacros == R.NamespaceMacros &&

clang/lib/Format/Format.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,8 @@ template <> struct MappingTraits<FormatStyle> {
10991099
IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin);
11001100
IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd);
11011101
IO.mapOptional("Macros", Style.Macros);
1102+
IO.mapOptional("MacrosSkippedByRemoveParentheses",
1103+
Style.MacrosSkippedByRemoveParentheses);
11021104
IO.mapOptional("MainIncludeChar", Style.IncludeStyle.MainIncludeChar);
11031105
IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
11041106
IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation);

clang/lib/Format/FormatToken.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ namespace format {
8383
TYPE(FunctionDeclarationName) \
8484
TYPE(FunctionDeclarationLParen) \
8585
TYPE(FunctionLBrace) \
86+
TYPE(FunctionLikeMacro) \
8687
TYPE(FunctionLikeOrFreestandingMacro) \
8788
TYPE(FunctionTypeLParen) \
8889
/* The colons as part of a C11 _Generic selection */ \

clang/lib/Format/FormatTokenLexer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ FormatTokenLexer::FormatTokenLexer(
7474
Macros.insert({Identifier, TT_StatementAttributeLikeMacro});
7575
}
7676

77+
for (const auto &Macro : Style.MacrosSkippedByRemoveParentheses)
78+
MacrosSkippedByRemoveParentheses.insert(&IdentTable.get(Macro));
7779
for (const auto &TemplateName : Style.TemplateNames)
7880
TemplateNames.insert(&IdentTable.get(TemplateName));
7981
for (const auto &TypeName : Style.TypeNames)
@@ -1473,6 +1475,8 @@ FormatToken *FormatTokenLexer::getNextToken() {
14731475
FormatTok->setType(TT_MacroBlockBegin);
14741476
else if (MacroBlockEndRegex.match(Text))
14751477
FormatTok->setType(TT_MacroBlockEnd);
1478+
else if (MacrosSkippedByRemoveParentheses.contains(Identifier))
1479+
FormatTok->setFinalizedType(TT_FunctionLikeMacro);
14761480
else if (TemplateNames.contains(Identifier))
14771481
FormatTok->setFinalizedType(TT_TemplateName);
14781482
else if (TypeNames.contains(Identifier))

clang/lib/Format/FormatTokenLexer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ class FormatTokenLexer {
132132

133133
llvm::SmallMapVector<IdentifierInfo *, TokenType, 8> Macros;
134134

135-
llvm::SmallPtrSet<IdentifierInfo *, 8> TemplateNames, TypeNames,
136-
VariableTemplates;
135+
llvm::SmallPtrSet<IdentifierInfo *, 8> MacrosSkippedByRemoveParentheses,
136+
TemplateNames, TypeNames, VariableTemplates;
137137

138138
bool FormattingDisabled;
139139
llvm::Regex FormatOffRegex; // For one line.

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2090,7 +2090,8 @@ class AnnotatingParser {
20902090
TT_RecordLBrace, TT_StructLBrace, TT_UnionLBrace, TT_RequiresClause,
20912091
TT_RequiresClauseInARequiresExpression, TT_RequiresExpression,
20922092
TT_RequiresExpressionLParen, TT_RequiresExpressionLBrace,
2093-
TT_CompoundRequirementLBrace, TT_BracedListLBrace)) {
2093+
TT_CompoundRequirementLBrace, TT_BracedListLBrace,
2094+
TT_FunctionLikeMacro)) {
20942095
CurrentToken->setType(TT_Unknown);
20952096
}
20962097
CurrentToken->Role.reset();

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2579,30 +2579,34 @@ bool UnwrappedLineParser::parseBracedList(bool IsAngleBracket, bool IsEnum) {
25792579
/// double ampersands. This applies for all nested scopes as well.
25802580
///
25812581
/// Returns whether there is a `=` token between the parentheses.
2582-
bool UnwrappedLineParser::parseParens(TokenType AmpAmpTokenType) {
2582+
bool UnwrappedLineParser::parseParens(TokenType AmpAmpTokenType,
2583+
bool InMacroCall) {
25832584
assert(FormatTok->is(tok::l_paren) && "'(' expected.");
25842585
auto *LParen = FormatTok;
2586+
auto *Prev = FormatTok->Previous;
25852587
bool SeenComma = false;
25862588
bool SeenEqual = false;
25872589
bool MightBeFoldExpr = false;
25882590
nextToken();
25892591
const bool MightBeStmtExpr = FormatTok->is(tok::l_brace);
2592+
if (!InMacroCall && Prev && Prev->is(TT_FunctionLikeMacro))
2593+
InMacroCall = true;
25902594
do {
25912595
switch (FormatTok->Tok.getKind()) {
25922596
case tok::l_paren:
2593-
if (parseParens(AmpAmpTokenType))
2597+
if (parseParens(AmpAmpTokenType, InMacroCall))
25942598
SeenEqual = true;
25952599
if (Style.isJava() && FormatTok->is(tok::l_brace))
25962600
parseChildBlock();
25972601
break;
25982602
case tok::r_paren: {
2599-
auto *Prev = LParen->Previous;
26002603
auto *RParen = FormatTok;
26012604
nextToken();
26022605
if (Prev) {
26032606
auto OptionalParens = [&] {
2604-
if (MightBeStmtExpr || MightBeFoldExpr || Line->InMacroBody ||
2605-
SeenComma || Style.RemoveParentheses == FormatStyle::RPS_Leave ||
2607+
if (MightBeStmtExpr || MightBeFoldExpr || SeenComma || InMacroCall ||
2608+
Line->InMacroBody ||
2609+
Style.RemoveParentheses == FormatStyle::RPS_Leave ||
26062610
RParen->getPreviousNonComment() == LParen) {
26072611
return false;
26082612
}

clang/lib/Format/UnwrappedLineParser.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ class UnwrappedLineParser {
145145
bool *HasLabel = nullptr);
146146
bool tryToParseBracedList();
147147
bool parseBracedList(bool IsAngleBracket = false, bool IsEnum = false);
148-
bool parseParens(TokenType AmpAmpTokenType = TT_Unknown);
148+
bool parseParens(TokenType AmpAmpTokenType = TT_Unknown,
149+
bool InMacroCall = false);
149150
void parseSquare(bool LambdaIntroducer = false);
150151
void keepAncestorBraces();
151152
void parseUnbracedBody(bool CheckEOF = false);

0 commit comments

Comments
 (0)