[clang] [clang-format] Fix annotating attrs in class/struct (PR #124634)

Gedare Bloom via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 28 15:06:37 PST 2025


https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/124634

>From 5292f110ce4c7f5b060165e3c3f817b6716c2c1e Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Mon, 27 Jan 2025 14:49:54 -0700
Subject: [PATCH 1/2] [clang-format] Fix annotating attrs in class/struct

An attribute in a class/struct declaration confuses the annotater to treat
the identifier following the attribute as a function or variable name.

Fixes #124574
---
 clang/lib/Format/TokenAnnotator.cpp   | 14 +++++++++++---
 clang/unittests/Format/FormatTest.cpp | 12 ++++++++++++
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 08fda7a2ffa51a..3b4b0b78e8bf16 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -2633,12 +2633,20 @@ class AnnotatingParser {
              PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template);
     }
 
-    if ((PreviousNotConst->is(tok::r_paren) &&
-         PreviousNotConst->is(TT_TypeDeclarationParen)) ||
-        PreviousNotConst->is(TT_AttributeRParen)) {
+    if (PreviousNotConst->is(tok::r_paren) &&
+        PreviousNotConst->is(TT_TypeDeclarationParen)) {
       return true;
     }
 
+    auto InTypeDecl = [&]() {
+      for (auto Next = Tok.Next; Next; Next = Next->Next)
+        if (Next->isOneOf(TT_ClassLBrace, TT_StructLBrace))
+          return true;
+      return false;
+    };
+    if (PreviousNotConst->is(TT_AttributeRParen) && (!IsCpp || !InTypeDecl()))
+      return true;
+
     // If is a preprocess keyword like #define.
     if (IsPPKeyword)
       return false;
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 265461561d2012..6145500a56582a 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -12415,6 +12415,18 @@ TEST_F(FormatTest, UnderstandsAttributes) {
   verifyFormat("SomeType s __unused{InitValue};", CustomAttrs);
   verifyFormat("SomeType *__capability s(InitValue);", CustomAttrs);
   verifyFormat("SomeType *__capability s{InitValue};", CustomAttrs);
+
+  FormatStyle Style = getLLVMStyle(FormatStyle::LK_Cpp);
+  verifyFormat(
+      "template <>\n"
+      "struct __declspec(uuid(\"3895C200-8F26-4F5A-B29D-2B5D72E68F99\"))\n"
+      "IAsyncOperation<IUnknown *> : IAsyncOperation_impl<IUnknown *> {};",
+      Style);
+  verifyFormat(
+      "template <>\n"
+      "class __declspec(uuid(\"3895C200-8F26-4F5A-B29D-2B5D72E68F99\"))\n"
+      "IAsyncOperation<IUnknown *> : IAsyncOperation_impl<IUnknown *> {};",
+      Style);
 }
 
 TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) {

>From be986097927022a402cd5ed786804e7065e05c57 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Tue, 28 Jan 2025 16:02:01 -0700
Subject: [PATCH 2/2] Replace format test with annotator test

---
 clang/unittests/Format/FormatTest.cpp         | 12 ------------
 clang/unittests/Format/TokenAnnotatorTest.cpp |  9 +++++++++
 2 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 6145500a56582a..265461561d2012 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -12415,18 +12415,6 @@ TEST_F(FormatTest, UnderstandsAttributes) {
   verifyFormat("SomeType s __unused{InitValue};", CustomAttrs);
   verifyFormat("SomeType *__capability s(InitValue);", CustomAttrs);
   verifyFormat("SomeType *__capability s{InitValue};", CustomAttrs);
-
-  FormatStyle Style = getLLVMStyle(FormatStyle::LK_Cpp);
-  verifyFormat(
-      "template <>\n"
-      "struct __declspec(uuid(\"3895C200-8F26-4F5A-B29D-2B5D72E68F99\"))\n"
-      "IAsyncOperation<IUnknown *> : IAsyncOperation_impl<IUnknown *> {};",
-      Style);
-  verifyFormat(
-      "template <>\n"
-      "class __declspec(uuid(\"3895C200-8F26-4F5A-B29D-2B5D72E68F99\"))\n"
-      "IAsyncOperation<IUnknown *> : IAsyncOperation_impl<IUnknown *> {};",
-      Style);
 }
 
 TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) {
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index fc77e277947c56..1b4a1eccdb9b66 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -3123,6 +3123,15 @@ TEST_F(TokenAnnotatorTest, UnderstandsAttributes) {
   EXPECT_TOKEN(Tokens[7], tok::identifier, TT_FunctionDeclarationName);
   EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_FunctionDeclarationLParen);
 
+  Tokens = annotate("struct __attribute__((x)) foo {};");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_AttributeLParen);
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_Unknown);
+  EXPECT_TOKEN(Tokens[6], tok::r_paren, TT_AttributeRParen);
+  EXPECT_TOKEN(Tokens[7], tok::identifier, TT_Unknown);
+  EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_StructLBrace);
+
   FormatStyle Style = getLLVMStyle();
   Style.AttributeMacros.push_back("FOO");
   Tokens = annotate("bool foo FOO(unused);", Style);



More information about the cfe-commits mailing list