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 @@ -3701,13 +3701,13 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { const FormatToken &InitialToken = *FormatTok; nextToken(); + handleAttributes(); // The actual identifier can be a nested name specifier, and in macros // it is often token-pasted. - // An [[attribute]] can be before the identifier. while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::hashhash, tok::kw___attribute, tok::kw___declspec, - tok::kw_alignas, tok::l_square, tok::r_square) || + tok::kw_alignas) || ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) && FormatTok->isOneOf(tok::period, tok::comma))) { if (Style.isJavaScript() && @@ -3725,15 +3725,10 @@ FormatTok->is(tok::identifier) && FormatTok->TokenText != FormatTok->TokenText.upper(); nextToken(); - // We can have macros or attributes in between 'class' and the class name. + // We can have macros in between 'class' and the class name. if (!IsNonMacroIdentifier) { if (FormatTok->is(tok::l_paren)) { parseParens(); - } else if (FormatTok->is(TT_AttributeSquare)) { - parseSquare(); - // Consume the closing TT_AttributeSquare. - if (FormatTok->Next && FormatTok->is(TT_AttributeSquare)) - nextToken(); } } } 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 @@ -25233,6 +25233,11 @@ "}", Style); + verifyFormat("class [[deprecated(\"\")]] C {\n" + " int i;\n" + "};", + Style); + verifyIncompleteFormat("class C final [[deprecated(l]] {});", Style); // These tests are here to show a problem that may not be easily 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 @@ -345,6 +345,10 @@ Tokens = annotate("const class {} c;"); EXPECT_EQ(Tokens.size(), 7u) << Tokens; EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_ClassLBrace); + + Tokens = annotate("class [[deprecated(\"\")]] C { int i; };"); + EXPECT_EQ(Tokens.size(), 17u) << Tokens; + EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_ClassLBrace); } TEST_F(TokenAnnotatorTest, UnderstandsStructs) {