Skip to content

Commit 596fa2d

Browse files
committed
[clang-format] Handle attributes before case label.
Fixes llvm#53110. Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D121450
1 parent 3e4950d commit 596fa2d

File tree

3 files changed

+81
-12
lines changed

3 files changed

+81
-12
lines changed

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,10 @@ bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace,
480480
unsigned StatementCount = 0;
481481
bool SwitchLabelEncountered = false;
482482
do {
483+
if (FormatTok->getType() == TT_AttributeMacro) {
484+
nextToken();
485+
continue;
486+
}
483487
tok::TokenKind kind = FormatTok->Tok.getKind();
484488
if (FormatTok->getType() == TT_MacroBlockBegin)
485489
kind = tok::l_brace;
@@ -569,6 +573,8 @@ bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace,
569573
parseCSharpAttribute();
570574
break;
571575
}
576+
if (handleCppAttributes())
577+
break;
572578
LLVM_FALLTHROUGH;
573579
default:
574580
ParseDefault();
@@ -1390,9 +1396,11 @@ void UnwrappedLineParser::parseStructuralElement(IfStmtKind *IfKind,
13901396
// e.g. "default void f() {}" in a Java interface.
13911397
break;
13921398
case tok::kw_case:
1393-
if (Style.isJavaScript() && Line->MustBeDeclaration)
1399+
if (Style.isJavaScript() && Line->MustBeDeclaration) {
13941400
// 'case: string' field declaration.
1401+
nextToken();
13951402
break;
1403+
}
13961404
parseCaseLabel();
13971405
return;
13981406
case tok::kw_try:
@@ -1813,6 +1821,12 @@ void UnwrappedLineParser::parseStructuralElement(IfStmtKind *IfKind,
18131821
case tok::kw_new:
18141822
parseNew();
18151823
break;
1824+
case tok::kw_case:
1825+
if (Style.isJavaScript() && Line->MustBeDeclaration)
1826+
// 'case: string' field declaration.
1827+
break;
1828+
parseCaseLabel();
1829+
break;
18161830
default:
18171831
nextToken();
18181832
break;
@@ -2376,17 +2390,24 @@ static void markOptionalBraces(FormatToken *LeftBrace) {
23762390
RightBrace->Optional = true;
23772391
}
23782392

2393+
void UnwrappedLineParser::handleAttributes() {
2394+
// Handle AttributeMacro, e.g. `if (x) UNLIKELY`.
2395+
if (FormatTok->is(TT_AttributeMacro))
2396+
nextToken();
2397+
handleCppAttributes();
2398+
}
2399+
2400+
bool UnwrappedLineParser::handleCppAttributes() {
2401+
// Handle [[likely]] / [[unlikely]] attributes.
2402+
if (FormatTok->is(tok::l_square) && tryToParseSimpleAttribute()) {
2403+
parseSquare();
2404+
return true;
2405+
}
2406+
return false;
2407+
}
2408+
23792409
FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
23802410
bool KeepBraces) {
2381-
auto HandleAttributes = [this]() {
2382-
// Handle AttributeMacro, e.g. `if (x) UNLIKELY`.
2383-
if (FormatTok->is(TT_AttributeMacro))
2384-
nextToken();
2385-
// Handle [[likely]] / [[unlikely]] attributes.
2386-
if (FormatTok->is(tok::l_square) && tryToParseSimpleAttribute())
2387-
parseSquare();
2388-
};
2389-
23902411
assert(FormatTok->is(tok::kw_if) && "'if' expected");
23912412
nextToken();
23922413
if (FormatTok->is(tok::exclaim))
@@ -2399,7 +2420,7 @@ FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
23992420
if (FormatTok->is(tok::l_paren))
24002421
parseParens();
24012422
}
2402-
HandleAttributes();
2423+
handleAttributes();
24032424

24042425
bool NeedsUnwrappedLine = false;
24052426
keepAncestorBraces();
@@ -2436,7 +2457,7 @@ FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
24362457
Kind = IfStmtKind::IfElse;
24372458
}
24382459
nextToken();
2439-
HandleAttributes();
2460+
handleAttributes();
24402461
if (FormatTok->is(tok::l_brace)) {
24412462
ElseLeftBrace = FormatTok;
24422463
CompoundStatementIndenter Indenter(this, Style, Line->Level);

clang/lib/Format/UnwrappedLineParser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ class UnwrappedLineParser {
121121
void parseSquare(bool LambdaIntroducer = false);
122122
void keepAncestorBraces();
123123
void parseUnbracedBody(bool CheckEOF = false);
124+
void handleAttributes();
125+
bool handleCppAttributes();
124126
FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false);
125127
void parseTryCatch();
126128
void parseForOrWhileLoop();

clang/unittests/Format/FormatTest.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2602,6 +2602,52 @@ TEST_F(FormatTest, FormatsSwitchStatement) {
26022602
"}",
26032603
getLLVMStyleWithColumns(34));
26042604

2605+
verifyFormat("switch (a) {\n"
2606+
"[[likely]] case 1:\n"
2607+
" return;\n"
2608+
"}");
2609+
verifyFormat("switch (a) {\n"
2610+
"[[likely]] [[other::likely]] case 1:\n"
2611+
" return;\n"
2612+
"}");
2613+
verifyFormat("switch (x) {\n"
2614+
"case 1:\n"
2615+
" return;\n"
2616+
"[[likely]] case 2:\n"
2617+
" return;\n"
2618+
"}");
2619+
verifyFormat("switch (a) {\n"
2620+
"case 1:\n"
2621+
"[[likely]] case 2:\n"
2622+
" return;\n"
2623+
"}");
2624+
FormatStyle Attributes = getLLVMStyle();
2625+
Attributes.AttributeMacros.push_back("LIKELY");
2626+
Attributes.AttributeMacros.push_back("OTHER_LIKELY");
2627+
verifyFormat("switch (a) {\n"
2628+
"LIKELY case b:\n"
2629+
" return;\n"
2630+
"}",
2631+
Attributes);
2632+
verifyFormat("switch (a) {\n"
2633+
"LIKELY OTHER_LIKELY() case b:\n"
2634+
" return;\n"
2635+
"}",
2636+
Attributes);
2637+
verifyFormat("switch (a) {\n"
2638+
"case 1:\n"
2639+
" return;\n"
2640+
"LIKELY case 2:\n"
2641+
" return;\n"
2642+
"}",
2643+
Attributes);
2644+
verifyFormat("switch (a) {\n"
2645+
"case 1:\n"
2646+
"LIKELY case 2:\n"
2647+
" return;\n"
2648+
"}",
2649+
Attributes);
2650+
26052651
FormatStyle Style = getLLVMStyle();
26062652
Style.IndentCaseLabels = true;
26072653
Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;

0 commit comments

Comments
 (0)