summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Pan <owenpiano@gmail.com>2023-03-25 19:31:57 -0700
committerTom Stellard <tstellar@redhat.com>2023-04-04 11:49:22 -0700
commitdae44c8ccc84ef557b646164c185fcda6c15eb5f (patch)
tree44772897ee70d0d31831264a60c65318aec310de
parent86b0c6e4050261823f07a3fbfd272bea0cda778e (diff)
downloadllvm-dae44c8ccc84ef557b646164c185fcda6c15eb5f.tar.gz
[clang-format] Don't annotate left brace of struct as FunctionLBrace
Related to a02c3af9f19d. Fixes #61700. Differential Revision: https://reviews.llvm.org/D146895 (cherry picked from commit 767aee1de9e98256a62ae8b4c2f84381203613c3)
-rw-r--r--clang/lib/Format/UnwrappedLineParser.cpp26
-rw-r--r--clang/unittests/Format/FormatTest.cpp5
-rw-r--r--clang/unittests/Format/TokenAnnotatorTest.cpp8
3 files changed, 26 insertions, 13 deletions
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 7e3957e62d3a..7a49b189b481 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -2739,16 +2739,17 @@ void UnwrappedLineParser::handleAttributes() {
// Handle AttributeMacro, e.g. `if (x) UNLIKELY`.
if (FormatTok->is(TT_AttributeMacro))
nextToken();
- handleCppAttributes();
+ if (FormatTok->is(tok::l_square))
+ handleCppAttributes();
}
bool UnwrappedLineParser::handleCppAttributes() {
// Handle [[likely]] / [[unlikely]] attributes.
- if (FormatTok->is(tok::l_square) && tryToParseSimpleAttribute()) {
- parseSquare();
- return true;
- }
- return false;
+ assert(FormatTok->is(tok::l_square));
+ if (!tryToParseSimpleAttribute())
+ return false;
+ parseSquare();
+ return true;
}
/// Returns whether \c Tok begins a block.
@@ -3849,13 +3850,13 @@ void UnwrappedLineParser::parseJavaEnumBody() {
void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
const FormatToken &InitialToken = *FormatTok;
nextToken();
- handleAttributes();
// The actual identifier can be a nested name specifier, and in macros
// it is often token-pasted.
+ // An [[attribute]] can be before the identifier.
while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
tok::kw___attribute, tok::kw___declspec,
- tok::kw_alignas) ||
+ tok::kw_alignas, tok::l_square) ||
((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) &&
FormatTok->isOneOf(tok::period, tok::comma))) {
if (Style.isJavaScript() &&
@@ -3869,16 +3870,15 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
continue;
}
}
+ if (FormatTok->is(tok::l_square) && handleCppAttributes())
+ continue;
bool IsNonMacroIdentifier =
FormatTok->is(tok::identifier) &&
FormatTok->TokenText != FormatTok->TokenText.upper();
nextToken();
// We can have macros in between 'class' and the class name.
- if (!IsNonMacroIdentifier) {
- if (FormatTok->is(tok::l_paren)) {
- parseParens();
- }
- }
+ if (!IsNonMacroIdentifier && FormatTok->is(tok::l_paren))
+ parseParens();
}
// Note that parsing away template declarations here leads to incorrectly
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 189c8ee9e9da..c1280cc9ce58 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -25212,6 +25212,11 @@ TEST_F(FormatTest, RemoveSemicolon) {
"};",
Style);
+ verifyFormat("struct EXPORT_MACRO [[nodiscard]] C {\n"
+ " int i;\n"
+ "};",
+ Style);
+
verifyIncompleteFormat("class C final [[deprecated(l]] {});", Style);
// These tests are here to show a problem that may not be easily
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index a74a2992823e..e44d666206b4 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -288,6 +288,14 @@ TEST_F(TokenAnnotatorTest, UnderstandsStructs) {
auto Tokens = annotate("struct S {};");
EXPECT_EQ(Tokens.size(), 6u) << Tokens;
EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_StructLBrace);
+
+ Tokens = annotate("struct EXPORT_MACRO [[nodiscard]] C { int i; };");
+ EXPECT_EQ(Tokens.size(), 15u) << Tokens;
+ EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_StructLBrace);
+
+ Tokens = annotate("struct [[deprecated]] [[nodiscard]] C { int i; };");
+ EXPECT_EQ(Tokens.size(), 19u) << Tokens;
+ EXPECT_TOKEN(Tokens[12], tok::l_brace, TT_StructLBrace);
}
TEST_F(TokenAnnotatorTest, UnderstandsUnions) {