diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1402,7 +1402,10 @@ return; } - if (Style.isVerilog()) { + if (Style.isCpp()) { + while (FormatTok->is(tok::l_square) && handleCppAttributes()) { + } + } else if (Style.isVerilog()) { if (Keywords.isVerilogStructuredProcedure(*FormatTok)) { parseForOrWhileLoop(/*HasParens=*/false); return; @@ -1638,6 +1641,17 @@ parseNamespace(); return; } + // In Verilog labels can be any expression, so we don't do them here. + if (!Style.isVerilog() && Tokens->peekNextToken()->is(tok::colon) && + !Line->MustBeDeclaration) { + nextToken(); + Line->Tokens.begin()->Tok->MustBreakBefore = true; + FormatTok->setFinalizedType(TT_GotoLabelColon); + parseLabel(!Style.IndentGotoLabels); + if (HasLabel) + *HasLabel = true; + return; + } // In all other cases, parse the declaration. break; default: @@ -1942,16 +1956,6 @@ return I != E && (++I == E); }; if (OneTokenSoFar()) { - // In Verilog labels can be any expression, so we don't do them here. - if (!Style.isVerilog() && FormatTok->is(tok::colon) && - !Line->MustBeDeclaration) { - Line->Tokens.begin()->Tok->MustBreakBefore = true; - FormatTok->setFinalizedType(TT_GotoLabelColon); - parseLabel(!Style.IndentGotoLabels); - if (HasLabel) - *HasLabel = true; - return; - } // Recognize function-like macro usages without trailing semicolon as // well as free-standing macros like Q_OBJECT. bool FunctionLike = FormatTok->is(tok::l_paren); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -3023,6 +3023,26 @@ " some_other_code();\n" "}\n" "}"); + verifyFormat("{\n" + "L0:\n" + "[[foo]] L1:\n" + "[[bar]] [[baz]] L2:\n" + " g();\n" + "}"); + verifyFormat("{\n" + "[[foo]] L1: {\n" + "[[bar]] [[baz]] L2:\n" + " g();\n" + "}\n" + "}"); + verifyFormat("{\n" + "[[foo]] L1:\n" + " f();\n" + " {\n" + " [[bar]] [[baz]] L2:\n" + " g();\n" + " }\n" + "}"); FormatStyle Style = getLLVMStyle(); Style.IndentGotoLabels = false; verifyFormat("void f() {\n" @@ -3046,12 +3066,22 @@ " some_code();\n" "test_label:;\n" " int i = 0;\n" - "}"); + "}", + Style); verifyFormat("{\n" " some_code();\n" "test_label: { some_other_code(); }\n" "}", Style); + verifyFormat("{\n" + "[[foo]] L1:\n" + " f();\n" + " {\n" + "[[bar]] [[baz]] L2:\n" + " g();\n" + " }\n" + "}", + Style); // The opening brace may either be on the same unwrapped line as the colon or // on a separate one. The formatter should recognize both. Style = getLLVMStyle(); @@ -3064,6 +3094,14 @@ "}\n" "}", Style); + verifyFormat("{\n" + "[[foo]] L1:\n" + "{\n" + "[[bar]] [[baz]] L2:\n" + " g();\n" + "}\n" + "}", + Style); } TEST_F(FormatTest, MultiLineControlStatements) {