diff options
author | Owen Pan <owenpiano@gmail.com> | 2024-03-16 13:51:36 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-16 13:51:36 -0700 |
commit | 84b5178124e47f6019b56c04abcfb978a94b1c3c (patch) | |
tree | c7f15ee2aeeb8e648bf0dd23418e11f274ca4eb0 | |
parent | 2867095917cef0d01a68b112bcb01e2f85de4308 (diff) | |
download | llvm-84b5178124e47f6019b56c04abcfb978a94b1c3c.zip llvm-84b5178124e47f6019b56c04abcfb978a94b1c3c.tar.gz llvm-84b5178124e47f6019b56c04abcfb978a94b1c3c.tar.bz2 |
[clang-format] Correctly parse C++11 attributes in enum specifiers (#85498)
Fixes #85476.
-rw-r--r-- | clang/lib/Format/UnwrappedLineParser.cpp | 15 | ||||
-rw-r--r-- | clang/unittests/Format/FormatTest.cpp | 21 |
2 files changed, 30 insertions, 6 deletions
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index a1f6ce0..2b893f7 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1224,7 +1224,6 @@ void UnwrappedLineParser::parsePPUnknown() { static bool tokenCanStartNewLine(const FormatToken &Tok) { // Semicolon can be a null-statement, l_square can be a start of a macro or // a C++11 attribute, but this doesn't seem to be common. - assert(Tok.isNot(TT_AttributeSquare)); return !Tok.isOneOf(tok::semi, tok::l_brace, // Tokens that can only be used as binary operators and a // part of overloaded operator names. @@ -3712,14 +3711,19 @@ bool UnwrappedLineParser::parseEnum() { if (Style.Language == FormatStyle::LK_Proto && FormatTok->is(tok::equal)) return false; - // Eat up enum class ... - if (FormatTok->isOneOf(tok::kw_class, tok::kw_struct)) - nextToken(); + if (IsCpp) { + // Eat up enum class ... + if (FormatTok->isOneOf(tok::kw_class, tok::kw_struct)) + nextToken(); + while (FormatTok->is(tok::l_square)) + if (!handleCppAttributes()) + return false; + } while (FormatTok->Tok.getIdentifierInfo() || FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less, tok::greater, tok::comma, tok::question, - tok::l_square, tok::r_square)) { + tok::l_square)) { if (Style.isVerilog()) { FormatTok->setFinalizedType(TT_VerilogDimensionedTypeName); nextToken(); @@ -3732,7 +3736,6 @@ bool UnwrappedLineParser::parseEnum() { // We can have macros or attributes in between 'enum' and the enum name. if (FormatTok->is(tok::l_paren)) parseParens(); - assert(FormatTok->isNot(TT_AttributeSquare)); 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 index fc367a7..add92d3 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -3802,6 +3802,27 @@ TEST_F(FormatTest, FormatsEnum) { " // Comment 2\n" " TWO,\n" "};"); + verifyFormat("enum [[clang::enum_extensibility(open)]] E {\n" + " // Comment 1\n" + " ONE,\n" + " // Comment 2\n" + " TWO\n" + "};"); + verifyFormat("enum [[nodiscard]] [[clang::enum_extensibility(open)]] E {\n" + " // Comment 1\n" + " ONE,\n" + " // Comment 2\n" + " TWO\n" + "};"); + verifyFormat("enum [[clang::enum_extensibility(open)]] E { // foo\n" + " A,\n" + " // bar\n" + " B\n" + "};", + "enum [[clang::enum_extensibility(open)]] E{// foo\n" + " A,\n" + " // bar\n" + " B};"); // Not enums. verifyFormat("enum X f() {\n" |