Author: Owen Pan Date: 2023-03-27T14:07:15-07:00 New Revision: 767aee1de9e98256a62ae8b4c2f84381203613c3
URL: https://github.com/llvm/llvm-project/commit/767aee1de9e98256a62ae8b4c2f84381203613c3 DIFF: https://github.com/llvm/llvm-project/commit/767aee1de9e98256a62ae8b4c2f84381203613c3.diff LOG: [clang-format] Don't annotate left brace of struct as FunctionLBrace Related to a02c3af9f19d. Fixes #61700. Differential Revision: https://reviews.llvm.org/D146895 Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTest.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Removed: ################################################################################ diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 9b17c28280f19..3a661292b2d72 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -2602,16 +2602,17 @@ void UnwrappedLineParser::handleAttributes() { // Handle AttributeMacro, e.g. `if (x) UNLIKELY`. if (FormatTok->is(TT_AttributeMacro)) nextToken(); - handleCppAttributes(); + if (FormatTok->is(tok::l_square)) + handleCppAttributes(); } bool UnwrappedLineParser::handleCppAttributes() { // Handle [[likely]] / [[unlikely]] attributes. - if (FormatTok->is(tok::l_square) && tryToParseSimpleAttribute()) { - parseSquare(); - return true; - } - return false; + assert(FormatTok->is(tok::l_square)); + if (!tryToParseSimpleAttribute()) + return false; + parseSquare(); + return true; } /// Returns whether \c Tok begins a block. @@ -3728,13 +3729,13 @@ void UnwrappedLineParser::parseJavaEnumBody() { 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::kw_alignas, tok::l_square) || ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) && FormatTok->isOneOf(tok::period, tok::comma))) { if (Style.isJavaScript() && @@ -3748,16 +3749,15 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { continue; } } + if (FormatTok->is(tok::l_square) && handleCppAttributes()) + continue; bool IsNonMacroIdentifier = FormatTok->is(tok::identifier) && FormatTok->TokenText != FormatTok->TokenText.upper(); nextToken(); // We can have macros in between 'class' and the class name. - if (!IsNonMacroIdentifier) { - if (FormatTok->is(tok::l_paren)) { - parseParens(); - } - } + if (!IsNonMacroIdentifier && FormatTok->is(tok::l_paren)) + parseParens(); } // Note that parsing away template declarations here leads to incorrectly diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 80efa8c4babfc..1c960eb28ef94 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -25308,6 +25308,11 @@ TEST_F(FormatTest, RemoveSemicolon) { "};", Style); + verifyFormat("struct EXPORT_MACRO [[nodiscard]] 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 index 94b3a77ed5a00..b058e62654551 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -374,6 +374,14 @@ TEST_F(TokenAnnotatorTest, UnderstandsStructs) { auto Tokens = annotate("struct S {};"); EXPECT_EQ(Tokens.size(), 6u) << Tokens; EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_StructLBrace); + + Tokens = annotate("struct EXPORT_MACRO [[nodiscard]] C { int i; };"); + EXPECT_EQ(Tokens.size(), 15u) << Tokens; + EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_StructLBrace); + + Tokens = annotate("struct [[deprecated]] [[nodiscard]] C { int i; };"); + EXPECT_EQ(Tokens.size(), 19u) << Tokens; + EXPECT_TOKEN(Tokens[12], tok::l_brace, TT_StructLBrace); } TEST_F(TokenAnnotatorTest, UnderstandsUnions) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits