[clang] [clang-format] Correctly parse C++11 attributes in enum specifiers (PR #85498)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 15 22:26:43 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-format
Author: Owen Pan (owenca)
<details>
<summary>Changes</summary>
Fixes #<!-- -->85476.
---
Full diff: https://github.com/llvm/llvm-project/pull/85498.diff
2 Files Affected:
- (modified) clang/lib/Format/UnwrappedLineParser.cpp (+9-6)
- (modified) clang/unittests/Format/FormatTest.cpp (+21)
``````````diff
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index a1f6ce05e45ebc..2b893f7abe4023 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 fc367a7a5a8981..add92d3e111089 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"
``````````
</details>
https://github.com/llvm/llvm-project/pull/85498
More information about the cfe-commits
mailing list