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 @@ -3419,11 +3419,18 @@ while (FormatTok->Tok.getIdentifierInfo() || FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less, - tok::greater, tok::comma, tok::question)) { + tok::greater, tok::comma, tok::question, + tok::l_square, tok::r_square)) { nextToken(); // We can have macros or attributes in between 'enum' and the enum name. if (FormatTok->is(tok::l_paren)) parseParens(); + if (FormatTok->is(TT_AttributeSquare)) { + parseSquare(); + // Consume the closing TT_AttributeSquare. + if (FormatTok->Next && FormatTok->is(TT_AttributeSquare)) + nextToken(); + } if (FormatTok->is(tok::identifier)) { nextToken(); // If there are two identifiers in a row, this is likely an elaborate 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 @@ -3573,6 +3573,7 @@ verifyFormat("enum X E {} d;"); verifyFormat("enum __attribute__((...)) E {} d;"); verifyFormat("enum __declspec__((...)) E {} d;"); + verifyFormat("enum [[nodiscard]] E {} d;"); verifyFormat("enum {\n" " Bar = Foo::value\n" "};", @@ -3619,6 +3620,17 @@ "};", EightIndent); + verifyFormat("enum [[nodiscard]] E {\n" + " ONE,\n" + " TWO,\n" + "};"); + verifyFormat("enum [[nodiscard]] E {\n" + " // Comment 1\n" + " ONE,\n" + " // Comment 2\n" + " TWO,\n" + "};"); + // Not enums. verifyFormat("enum X f() {\n" " a();\n" @@ -3666,7 +3678,19 @@ verifyFormat("enum struct X E {} d;"); verifyFormat("enum struct __attribute__((...)) E {} d;"); verifyFormat("enum struct __declspec__((...)) E {} d;"); + verifyFormat("enum struct [[nodiscard]] E {} d;"); verifyFormat("enum struct X f() {\n a();\n return 42;\n}"); + + verifyFormat("enum struct [[nodiscard]] E {\n" + " ONE,\n" + " TWO,\n" + "};"); + verifyFormat("enum struct [[nodiscard]] E {\n" + " // Comment 1\n" + " ONE,\n" + " // Comment 2\n" + " TWO,\n" + "};"); } TEST_F(FormatTest, FormatsEnumClass) { @@ -3683,7 +3707,19 @@ verifyFormat("enum class X E {} d;"); verifyFormat("enum class __attribute__((...)) E {} d;"); verifyFormat("enum class __declspec__((...)) E {} d;"); + verifyFormat("enum class [[nodiscard]] E {} d;"); verifyFormat("enum class X f() {\n a();\n return 42;\n}"); + + verifyFormat("enum class [[nodiscard]] E {\n" + " ONE,\n" + " TWO,\n" + "};"); + verifyFormat("enum class [[nodiscard]] E {\n" + " // Comment 1\n" + " ONE,\n" + " // Comment 2\n" + " TWO,\n" + "};"); } TEST_F(FormatTest, FormatsEnumTypes) {