[clang] [clang-format] BreakAfterAttributes did not take into account gnu attributes (PR #78102)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Jan 14 08:35:31 PST 2024
https://github.com/mydeveloperday created https://github.com/llvm/llvm-project/pull/78102
Not completely sure if we should handle this with a separate option or just treat [[attribute]] the same as __attribute((attribute))
This was raised by #77310
>From f95a9a43eff1a2c4cc01cc701e12a306a6d80d6d Mon Sep 17 00:00:00 2001
From: mydeveloperday <mydeveloperday at gmail.com>
Date: Sun, 14 Jan 2024 16:31:42 +0000
Subject: [PATCH] [clang-format] BreakAfterAttributes did not take into account
gnu based attributes
---
clang/lib/Format/TokenAnnotator.cpp | 5 ++++
clang/unittests/Format/FormatTest.cpp | 25 +++++++++++++++++++
clang/unittests/Format/TokenAnnotatorTest.cpp | 18 +++++++++++++
3 files changed, 48 insertions(+)
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 24ce18a64348c1..ffe8428005b41d 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -489,6 +489,10 @@ class AnnotatingParser {
if (OpeningParen.is(TT_AttributeLParen))
CurrentToken->setType(TT_AttributeRParen);
+ if (CurrentToken->is(TT_AttributeRParen) && CurrentToken->Next &&
+ !CurrentToken->Next->is(tok::kw___attribute)) {
+ CurrentToken->EndsCppAttributeGroup = true;
+ }
if (OpeningParen.is(TT_TypeDeclarationParen))
CurrentToken->setType(TT_TypeDeclarationParen);
if (OpeningParen.Previous &&
@@ -983,6 +987,7 @@ class AnnotatingParser {
CurrentToken->MustBreakBefore = true;
}
}
+
FormatToken *Tok = CurrentToken;
next();
// In Verilog primitives' state tables, `:`, `?`, and `-` aren't normal
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 8f115fb8cbf0fb..2d85395d3c540f 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -26827,6 +26827,31 @@ TEST_F(FormatTest, BreakAdjacentStringLiterals) {
Style.BreakAdjacentStringLiterals = false;
verifyFormat(Code, Style);
}
+
+TEST_F(FormatTest, BreakAfterGNUAttributes) {
+ FormatStyle Style = getLLVMStyle();
+ Style.BreakAfterAttributes = FormatStyle::ABS_Never;
+
+ verifyFormat("__attribute__((__warn_unused_result__)) const int i;", Style);
+
+ verifyFormat(
+ "__attribute__((other)) __attribute__((__warn_unused_result__)) int j;",
+ Style);
+
+ verifyFormat("__attribute__((__warn_unused_result__)) inline int f(int &i);",
+ Style);
+
+ Style.BreakAfterAttributes = FormatStyle::ABS_Always;
+ verifyFormat("__attribute__((__warn_unused_result__))\nconst int i;", Style);
+
+ verifyFormat(
+ "__attribute__((other)) __attribute__((__warn_unused_result__))\nint j;",
+ Style);
+
+ verifyFormat("__attribute__((__warn_unused_result__))\ninline int f(int &i);",
+ Style);
+}
+
} // namespace
} // namespace test
} // namespace format
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 92f57a77cdaf01..2b255e89307f23 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -2381,11 +2381,14 @@ TEST_F(TokenAnnotatorTest, UnderstandsAttributes) {
EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_Unknown);
EXPECT_TOKEN(Tokens[6], tok::r_paren, TT_Unknown);
EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_AttributeRParen);
+ EXPECT_FALSE(Tokens[6]->EndsCppAttributeGroup);
+ EXPECT_TRUE(Tokens[7]->EndsCppAttributeGroup);
Tokens = annotate("bool foo __declspec(dllimport);");
ASSERT_EQ(Tokens.size(), 8u) << Tokens;
EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_AttributeLParen);
EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_AttributeRParen);
+ EXPECT_TRUE(Tokens[5]->EndsCppAttributeGroup);
Tokens = annotate("bool __attribute__((unused)) foo;");
ASSERT_EQ(Tokens.size(), 10u) << Tokens;
@@ -2394,6 +2397,21 @@ TEST_F(TokenAnnotatorTest, UnderstandsAttributes) {
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_StartOfName);
+ EXPECT_TRUE(Tokens[6]->EndsCppAttributeGroup);
+
+ Tokens = annotate("bool __attribute__((unused)) __attribute__((const)) foo;");
+ ASSERT_EQ(Tokens.size(), 16u) << 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[8], tok::l_paren, TT_AttributeLParen);
+ EXPECT_TOKEN(Tokens[9], tok::l_paren, TT_Unknown);
+ EXPECT_TOKEN(Tokens[11], tok::r_paren, TT_Unknown);
+ EXPECT_TOKEN(Tokens[12], tok::r_paren, TT_AttributeRParen);
+ EXPECT_TOKEN(Tokens[13], tok::identifier, TT_StartOfName);
+ EXPECT_FALSE(Tokens[8]->EndsCppAttributeGroup);
+ EXPECT_TRUE(Tokens[12]->EndsCppAttributeGroup);
Tokens = annotate("void __attribute__((x)) Foo();");
ASSERT_EQ(Tokens.size(), 12u) << Tokens;
More information about the cfe-commits
mailing list