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 @@ -3360,11 +3360,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 @@ -3565,6 +3565,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" "};", @@ -3658,6 +3659,7 @@ 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}"); } @@ -3675,6 +3677,7 @@ 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}"); }