[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
This commit is contained in:
parent
3e4950d7fa
commit
596fa2d900
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue