Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
authorMarek Kurdej <marek.kurdej+llvm.org@gmail.com>2022-03-09 13:05:34 +0300
committerMarek Kurdej <marek.kurdej+llvm.org@gmail.com>2022-03-13 23:53:40 +0300
commit596fa2d90044841c33b9a0e6b17406c2a45077a2 (patch)
tree8c901d0d8aaa5ae92156b7bb7212f895b5426c54 /clang
parent3e4950d7fa78ac83f33bbf1658e2f49a73719236 (diff)
[clang-format] Handle attributes before case label.
Fixes https://github.com/llvm/llvm-project/issues/53110. Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D121450
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Format/UnwrappedLineParser.cpp45
-rw-r--r--clang/lib/Format/UnwrappedLineParser.h2
-rw-r--r--clang/unittests/Format/FormatTest.cpp46
3 files changed, 81 insertions, 12 deletions
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 3a245b8b5fa0..47e794c7b1ca 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -480,6 +480,10 @@ bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace,
unsigned StatementCount = 0;
bool SwitchLabelEncountered = false;
do {
+ if (FormatTok->getType() == TT_AttributeMacro) {
+ nextToken();
+ continue;
+ }
tok::TokenKind kind = FormatTok->Tok.getKind();
if (FormatTok->getType() == TT_MacroBlockBegin)
kind = tok::l_brace;
@@ -569,6 +573,8 @@ bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace,
parseCSharpAttribute();
break;
}
+ if (handleCppAttributes())
+ break;
LLVM_FALLTHROUGH;
default:
ParseDefault();
@@ -1390,9 +1396,11 @@ void UnwrappedLineParser::parseStructuralElement(IfStmtKind *IfKind,
// e.g. "default void f() {}" in a Java interface.
break;
case tok::kw_case:
- if (Style.isJavaScript() && Line->MustBeDeclaration)
+ if (Style.isJavaScript() && Line->MustBeDeclaration) {
// 'case: string' field declaration.
+ nextToken();
break;
+ }
parseCaseLabel();
return;
case tok::kw_try:
@@ -1813,6 +1821,12 @@ void UnwrappedLineParser::parseStructuralElement(IfStmtKind *IfKind,
case tok::kw_new:
parseNew();
break;
+ case tok::kw_case:
+ if (Style.isJavaScript() && Line->MustBeDeclaration)
+ // 'case: string' field declaration.
+ break;
+ parseCaseLabel();
+ break;
default:
nextToken();
break;
@@ -2376,17 +2390,24 @@ static void markOptionalBraces(FormatToken *LeftBrace) {
RightBrace->Optional = true;
}
+void UnwrappedLineParser::handleAttributes() {
+ // Handle AttributeMacro, e.g. `if (x) UNLIKELY`.
+ if (FormatTok->is(TT_AttributeMacro))
+ nextToken();
+ handleCppAttributes();
+}
+
+bool UnwrappedLineParser::handleCppAttributes() {
+ // Handle [[likely]] / [[unlikely]] attributes.
+ if (FormatTok->is(tok::l_square) && tryToParseSimpleAttribute()) {
+ parseSquare();
+ return true;
+ }
+ return false;
+}
+
FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
bool KeepBraces) {
- auto HandleAttributes = [this]() {
- // Handle AttributeMacro, e.g. `if (x) UNLIKELY`.
- if (FormatTok->is(TT_AttributeMacro))
- nextToken();
- // Handle [[likely]] / [[unlikely]] attributes.
- if (FormatTok->is(tok::l_square) && tryToParseSimpleAttribute())
- parseSquare();
- };
-
assert(FormatTok->is(tok::kw_if) && "'if' expected");
nextToken();
if (FormatTok->is(tok::exclaim))
@@ -2399,7 +2420,7 @@ FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
if (FormatTok->is(tok::l_paren))
parseParens();
}
- HandleAttributes();
+ handleAttributes();
bool NeedsUnwrappedLine = false;
keepAncestorBraces();
@@ -2436,7 +2457,7 @@ FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
Kind = IfStmtKind::IfElse;
}
nextToken();
- HandleAttributes();
+ handleAttributes();
if (FormatTok->is(tok::l_brace)) {
ElseLeftBrace = FormatTok;
CompoundStatementIndenter Indenter(this, Style, Line->Level);
diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h
index 5cc01398a545..798bae24ad07 100644
--- a/clang/lib/Format/UnwrappedLineParser.h
+++ b/clang/lib/Format/UnwrappedLineParser.h
@@ -121,6 +121,8 @@ private:
void parseSquare(bool LambdaIntroducer = false);
void keepAncestorBraces();
void parseUnbracedBody(bool CheckEOF = false);
+ void handleAttributes();
+ bool handleCppAttributes();
FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false);
void parseTryCatch();
void parseForOrWhileLoop();
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 37a42382e8f8..430a195f6025 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -2602,6 +2602,52 @@ TEST_F(FormatTest, FormatsSwitchStatement) {
"}",
getLLVMStyleWithColumns(34));
+ verifyFormat("switch (a) {\n"
+ "[[likely]] case 1:\n"
+ " return;\n"
+ "}");
+ verifyFormat("switch (a) {\n"
+ "[[likely]] [[other::likely]] case 1:\n"
+ " return;\n"
+ "}");
+ verifyFormat("switch (x) {\n"
+ "case 1:\n"
+ " return;\n"
+ "[[likely]] case 2:\n"
+ " return;\n"
+ "}");
+ verifyFormat("switch (a) {\n"
+ "case 1:\n"
+ "[[likely]] case 2:\n"
+ " return;\n"
+ "}");
+ FormatStyle Attributes = getLLVMStyle();
+ Attributes.AttributeMacros.push_back("LIKELY");
+ Attributes.AttributeMacros.push_back("OTHER_LIKELY");
+ verifyFormat("switch (a) {\n"
+ "LIKELY case b:\n"
+ " return;\n"
+ "}",
+ Attributes);
+ verifyFormat("switch (a) {\n"
+ "LIKELY OTHER_LIKELY() case b:\n"
+ " return;\n"
+ "}",
+ Attributes);
+ verifyFormat("switch (a) {\n"
+ "case 1:\n"
+ " return;\n"
+ "LIKELY case 2:\n"
+ " return;\n"
+ "}",
+ Attributes);
+ verifyFormat("switch (a) {\n"
+ "case 1:\n"
+ "LIKELY case 2:\n"
+ " return;\n"
+ "}",
+ Attributes);
+
FormatStyle Style = getLLVMStyle();
Style.IndentCaseLabels = true;
Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;