diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 06775b6df9458..cfca7c00312aa 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3477,6 +3477,19 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const { } } + if (IsCpp && LineIsFunctionDeclaration && + Line.endsWith(tok::semi, tok::r_brace)) { + auto *Tok = Line.Last->Previous; + while (Tok->isNot(tok::r_brace)) + Tok = Tok->Previous; + if (auto *LBrace = Tok->MatchingParen; LBrace) { + assert(LBrace->is(tok::l_brace)); + Tok->setBlockKind(BK_Block); + LBrace->setBlockKind(BK_Block); + LBrace->setFinalizedType(TT_FunctionLBrace); + } + } + if (IsCpp && SeenName && AfterLastAttribute && mustBreakAfterAttributes(*AfterLastAttribute, Style)) { AfterLastAttribute->MustBreakBefore = true; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 45f12d158089a..67423f9b06fbc 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -3415,7 +3415,7 @@ TEST_F(FormatTest, UnderstandsAccessSpecifiers) { verifyFormat("myFunc(public);"); verifyFormat("std::vector testVec = {private};"); verifyFormat("private.p = 1;"); - verifyFormat("void function(private...){};"); + verifyFormat("void function(private...) {};"); verifyFormat("if (private && public)"); verifyFormat("private &= true;"); verifyFormat("int x = private * public;"); @@ -16093,16 +16093,16 @@ TEST_F(FormatTest, ZeroTabWidth) { Tab.IndentWidth = 8; Tab.UseTab = FormatStyle::UT_Never; Tab.TabWidth = 0; - verifyFormat("void a(){\n" - " // line starts with '\t'\n" + verifyFormat("void a() {\n" + " // line starts with '\t'\n" "};", "void a(){\n" "\t// line starts with '\t'\n" "};", Tab); - verifyFormat("void a(){\n" - " // line starts with '\t'\n" + verifyFormat("void a() {\n" + " // line starts with '\t'\n" "};", "void a(){\n" "\t\t// line starts with '\t'\n" @@ -16110,16 +16110,16 @@ TEST_F(FormatTest, ZeroTabWidth) { Tab); Tab.UseTab = FormatStyle::UT_ForIndentation; - verifyFormat("void a(){\n" - " // line starts with '\t'\n" + verifyFormat("void a() {\n" + " // line starts with '\t'\n" "};", "void a(){\n" "\t// line starts with '\t'\n" "};", Tab); - verifyFormat("void a(){\n" - " // line starts with '\t'\n" + verifyFormat("void a() {\n" + " // line starts with '\t'\n" "};", "void a(){\n" "\t\t// line starts with '\t'\n" @@ -16127,16 +16127,16 @@ TEST_F(FormatTest, ZeroTabWidth) { Tab); Tab.UseTab = FormatStyle::UT_ForContinuationAndIndentation; - verifyFormat("void a(){\n" - " // line starts with '\t'\n" + verifyFormat("void a() {\n" + " // line starts with '\t'\n" "};", "void a(){\n" "\t// line starts with '\t'\n" "};", Tab); - verifyFormat("void a(){\n" - " // line starts with '\t'\n" + verifyFormat("void a() {\n" + " // line starts with '\t'\n" "};", "void a(){\n" "\t\t// line starts with '\t'\n" @@ -16144,16 +16144,16 @@ TEST_F(FormatTest, ZeroTabWidth) { Tab); Tab.UseTab = FormatStyle::UT_AlignWithSpaces; - verifyFormat("void a(){\n" - " // line starts with '\t'\n" + verifyFormat("void a() {\n" + " // line starts with '\t'\n" "};", "void a(){\n" "\t// line starts with '\t'\n" "};", Tab); - verifyFormat("void a(){\n" - " // line starts with '\t'\n" + verifyFormat("void a() {\n" + " // line starts with '\t'\n" "};", "void a(){\n" "\t\t// line starts with '\t'\n" @@ -16161,7 +16161,7 @@ TEST_F(FormatTest, ZeroTabWidth) { Tab); Tab.UseTab = FormatStyle::UT_Always; - verifyFormat("void a(){\n" + verifyFormat("void a() {\n" "// line starts with '\t'\n" "};", "void a(){\n" @@ -16169,7 +16169,7 @@ TEST_F(FormatTest, ZeroTabWidth) { "};", Tab); - verifyFormat("void a(){\n" + verifyFormat("void a() {\n" "// line starts with '\t'\n" "};", "void a(){\n" diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index b6abf34c589b1..7b3b619899698 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -2410,6 +2410,60 @@ TEST_F(TokenAnnotatorTest, StartOfName) { EXPECT_TOKEN(Tokens[4], tok::identifier, TT_StartOfName); } +TEST_F(TokenAnnotatorTest, BraceKind) { + auto Tokens = annotate("void f() {};"); + ASSERT_EQ(Tokens.size(), 8u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_FunctionLBrace); + EXPECT_BRACE_KIND(Tokens[4], BK_Block); + EXPECT_BRACE_KIND(Tokens[5], BK_Block); + + Tokens = annotate("void f() override {};"); + ASSERT_EQ(Tokens.size(), 9u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_FunctionLBrace); + EXPECT_BRACE_KIND(Tokens[5], BK_Block); + EXPECT_BRACE_KIND(Tokens[6], BK_Block); + + Tokens = annotate("void f() noexcept(false) {};"); + ASSERT_EQ(Tokens.size(), 12u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_FunctionLBrace); + EXPECT_BRACE_KIND(Tokens[8], BK_Block); + EXPECT_BRACE_KIND(Tokens[9], BK_Block); + + Tokens = annotate("auto f() -> void {};"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_FunctionLBrace); + EXPECT_BRACE_KIND(Tokens[6], BK_Block); + EXPECT_BRACE_KIND(Tokens[7], BK_Block); + + Tokens = annotate("void f() { /**/ };"); + ASSERT_EQ(Tokens.size(), 9u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_FunctionLBrace); + EXPECT_BRACE_KIND(Tokens[4], BK_Block); + EXPECT_BRACE_KIND(Tokens[6], BK_Block); + + Tokens = annotate("void f() { //\n" + "};"); + ASSERT_EQ(Tokens.size(), 9u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_FunctionLBrace); + EXPECT_BRACE_KIND(Tokens[4], BK_Block); + EXPECT_BRACE_KIND(Tokens[6], BK_Block); + + Tokens = annotate("void f() {\n" + " //\n" + "};"); + ASSERT_EQ(Tokens.size(), 9u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_FunctionLBrace); + EXPECT_BRACE_KIND(Tokens[4], BK_Block); + EXPECT_BRACE_KIND(Tokens[6], BK_Block); +} + } // namespace } // namespace format } // namespace clang