diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2246,8 +2246,9 @@ PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template); } - if (PreviousNotConst->is(tok::r_paren) && - PreviousNotConst->is(TT_TypeDeclarationParen)) { + if ((PreviousNotConst->is(tok::r_paren) && + PreviousNotConst->is(TT_TypeDeclarationParen)) || + PreviousNotConst->is(TT_AttributeRParen)) { return true; } 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 @@ -16394,8 +16394,10 @@ verifyFormat("int f ();", SpaceFuncDecl); verifyFormat("void f(int a, T b) {}", SpaceFuncDecl); + verifyFormat("void __attribute__((asdf)) f(int a, T b) {}", SpaceFuncDecl); verifyFormat("A::A() : a(1) {}", SpaceFuncDecl); verifyFormat("void f () __attribute__((asdf));", SpaceFuncDecl); + verifyFormat("void __attribute__((asdf)) f ();", SpaceFuncDecl); verifyFormat("#define A(x) x", SpaceFuncDecl); verifyFormat("#define A (x) x", SpaceFuncDecl); verifyFormat("#if defined(x)\n" @@ -16429,8 +16431,10 @@ verifyFormat("int f();", SpaceFuncDef); verifyFormat("void f (int a, T b) {}", SpaceFuncDef); + verifyFormat("void __attribute__((asdf)) f (int a, T b) {}", SpaceFuncDef); verifyFormat("A::A() : a(1) {}", SpaceFuncDef); verifyFormat("void f() __attribute__((asdf));", SpaceFuncDef); + verifyFormat("void __attribute__((asdf)) f();", SpaceFuncDef); verifyFormat("#define A(x) x", SpaceFuncDef); verifyFormat("#define A (x) x", SpaceFuncDef); verifyFormat("#if defined(x)\n" diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -2313,6 +2313,7 @@ TEST_F(TokenAnnotatorTest, UnderstandsAttributes) { auto Tokens = annotate("bool foo __attribute__((unused));"); ASSERT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::identifier, TT_StartOfName); EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_AttributeLParen); EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_Unknown); EXPECT_TOKEN(Tokens[6], tok::r_paren, TT_Unknown); @@ -2323,6 +2324,22 @@ EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_AttributeLParen); EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_AttributeRParen); + Tokens = annotate("bool __attribute__((unused)) foo;"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_AttributeLParen); + EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_Unknown); + EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_Unknown); + EXPECT_TOKEN(Tokens[6], tok::r_paren, TT_AttributeRParen); + EXPECT_TOKEN(Tokens[7], tok::identifier, TT_StartOfName); + + Tokens = annotate("void __attribute__((x)) Foo();"); + ASSERT_EQ(Tokens.size(), 12u) << Tokens; + EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_AttributeLParen); + EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_Unknown); + EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_Unknown); + EXPECT_TOKEN(Tokens[6], tok::r_paren, TT_AttributeRParen); + EXPECT_TOKEN(Tokens[7], tok::identifier, TT_FunctionDeclarationName); + FormatStyle Style = getLLVMStyle(); Style.AttributeMacros.push_back("FOO"); Tokens = annotate("bool foo FOO(unused);", Style);