Skip to content

Commit 84b5178

Browse files
authored
[clang-format] Correctly parse C++11 attributes in enum specifiers (#85498)
Fixes #85476.
1 parent 2867095 commit 84b5178

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,7 +1224,6 @@ void UnwrappedLineParser::parsePPUnknown() {
12241224
static bool tokenCanStartNewLine(const FormatToken &Tok) {
12251225
// Semicolon can be a null-statement, l_square can be a start of a macro or
12261226
// a C++11 attribute, but this doesn't seem to be common.
1227-
assert(Tok.isNot(TT_AttributeSquare));
12281227
return !Tok.isOneOf(tok::semi, tok::l_brace,
12291228
// Tokens that can only be used as binary operators and a
12301229
// part of overloaded operator names.
@@ -3712,14 +3711,19 @@ bool UnwrappedLineParser::parseEnum() {
37123711
if (Style.Language == FormatStyle::LK_Proto && FormatTok->is(tok::equal))
37133712
return false;
37143713

3715-
// Eat up enum class ...
3716-
if (FormatTok->isOneOf(tok::kw_class, tok::kw_struct))
3717-
nextToken();
3714+
if (IsCpp) {
3715+
// Eat up enum class ...
3716+
if (FormatTok->isOneOf(tok::kw_class, tok::kw_struct))
3717+
nextToken();
3718+
while (FormatTok->is(tok::l_square))
3719+
if (!handleCppAttributes())
3720+
return false;
3721+
}
37183722

37193723
while (FormatTok->Tok.getIdentifierInfo() ||
37203724
FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less,
37213725
tok::greater, tok::comma, tok::question,
3722-
tok::l_square, tok::r_square)) {
3726+
tok::l_square)) {
37233727
if (Style.isVerilog()) {
37243728
FormatTok->setFinalizedType(TT_VerilogDimensionedTypeName);
37253729
nextToken();
@@ -3732,7 +3736,6 @@ bool UnwrappedLineParser::parseEnum() {
37323736
// We can have macros or attributes in between 'enum' and the enum name.
37333737
if (FormatTok->is(tok::l_paren))
37343738
parseParens();
3735-
assert(FormatTok->isNot(TT_AttributeSquare));
37363739
if (FormatTok->is(tok::identifier)) {
37373740
nextToken();
37383741
// If there are two identifiers in a row, this is likely an elaborate

clang/unittests/Format/FormatTest.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3802,6 +3802,27 @@ TEST_F(FormatTest, FormatsEnum) {
38023802
" // Comment 2\n"
38033803
" TWO,\n"
38043804
"};");
3805+
verifyFormat("enum [[clang::enum_extensibility(open)]] E {\n"
3806+
" // Comment 1\n"
3807+
" ONE,\n"
3808+
" // Comment 2\n"
3809+
" TWO\n"
3810+
"};");
3811+
verifyFormat("enum [[nodiscard]] [[clang::enum_extensibility(open)]] E {\n"
3812+
" // Comment 1\n"
3813+
" ONE,\n"
3814+
" // Comment 2\n"
3815+
" TWO\n"
3816+
"};");
3817+
verifyFormat("enum [[clang::enum_extensibility(open)]] E { // foo\n"
3818+
" A,\n"
3819+
" // bar\n"
3820+
" B\n"
3821+
"};",
3822+
"enum [[clang::enum_extensibility(open)]] E{// foo\n"
3823+
" A,\n"
3824+
" // bar\n"
3825+
" B};");
38053826

38063827
// Not enums.
38073828
verifyFormat("enum X f() {\n"

0 commit comments

Comments
 (0)