[clang] [clang-format] Correctly parse C++11 attributes in enum specifiers (PR #85498)
Owen Pan via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 15 22:26:16 PDT 2024
https://github.com/owenca created https://github.com/llvm/llvm-project/pull/85498
Fixes #85476.
>From 89c06a9acfebffa4f9e65c6d683c3c46774edc88 Mon Sep 17 00:00:00 2001
From: Owen Pan <owenpiano at gmail.com>
Date: Fri, 15 Mar 2024 22:14:01 -0700
Subject: [PATCH] [clang-format] Correctly parse C++11 attributes in enum
specifiers
Fixes #85476.
---
clang/lib/Format/UnwrappedLineParser.cpp | 15 +++++++++------
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 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"
More information about the cfe-commits
mailing list