[clang] [clang-format] Add support for absl nullability macros (PR #130346)
Jan Voung via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 13 08:26:36 PDT 2025
https://github.com/jvoung updated https://github.com/llvm/llvm-project/pull/130346
>From 10df1857532a6a27b0e5286e10c9f0724d6d7e1d Mon Sep 17 00:00:00 2001
From: Jan Voung <jvoung at gmail.com>
Date: Fri, 7 Mar 2025 21:02:16 +0000
Subject: [PATCH 1/8] [clang-format] Add support for absl nullability macros
---
clang/lib/Format/Format.cpp | 4 ++++
clang/unittests/Format/ConfigParseTest.cpp | 4 +++-
clang/unittests/Format/FormatTest.cpp | 19 +++++++++++++++++--
3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index b5f1241321891..1401b51586d03 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -1508,6 +1508,10 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
LLVMStyle.AttributeMacros.push_back("__capability");
+ // Abseil aliases to clang's `_Nonnull`, `_Nullable` and `_Null_unspecified`.
+ LLVMStyle.AttributeMacros.push_back("absl_nonnull");
+ LLVMStyle.AttributeMacros.push_back("absl_nullable");
+ LLVMStyle.AttributeMacros.push_back("absl_nullability_unknown");
LLVMStyle.BinPackArguments = true;
LLVMStyle.BinPackLongBracedList = true;
LLVMStyle.BinPackParameters = FormatStyle::BPPS_BinPack;
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 273bab87b1ee1..2cc2a45a7a590 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -908,7 +908,9 @@ TEST(ConfigParseTest, ParsesConfiguration) {
Style.AttributeMacros.clear();
CHECK_PARSE("BasedOnStyle: LLVM", AttributeMacros,
- std::vector<std::string>{"__capability"});
+ std::vector<std::string>({"__capability", "absl_nonnull", "absl_nullable",
+ "absl_nullability_unknown"}));
+ Style.AttributeMacros.clear();
CHECK_PARSE("AttributeMacros: [attr1, attr2]", AttributeMacros,
std::vector<std::string>({"attr1", "attr2"}));
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index bd335f4b6a21b..a17cad0b67b08 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -12375,6 +12375,9 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyFormat("vector<a *_Nonnull> v;");
verifyFormat("vector<a *_Nullable> v;");
verifyFormat("vector<a *_Null_unspecified> v;");
+ verifyFormat("vector<a *absl_nonnull> v;");
+ verifyFormat("vector<a *absl_nullable> v;");
+ verifyFormat("vector<a *absl_nullability_unknown> v;");
verifyFormat("vector<a *__ptr32> v;");
verifyFormat("vector<a *__ptr64> v;");
verifyFormat("vector<a *__capability> v;");
@@ -12518,6 +12521,9 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyIndependentOfContext("MACRO(A *_Nonnull a);");
verifyIndependentOfContext("MACRO(A *_Nullable a);");
verifyIndependentOfContext("MACRO(A *_Null_unspecified a);");
+ verifyIndependentOfContext("MACRO(A *absl_nonnull a);");
+ verifyIndependentOfContext("MACRO(A *absl_nullable a);");
+ verifyIndependentOfContext("MACRO(A *absl_nullability_unknown a);");
verifyIndependentOfContext("MACRO(A *__attribute__((foo)) a);");
verifyIndependentOfContext("MACRO(A *__attribute((foo)) a);");
verifyIndependentOfContext("MACRO(A *[[clang::attr]] a);");
@@ -12674,6 +12680,12 @@ TEST_F(FormatTest, UnderstandsAttributes) {
verifyFormat("SomeType *__unused s{InitValue};", CustomAttrs);
verifyFormat("SomeType s __unused(InitValue);", CustomAttrs);
verifyFormat("SomeType s __unused{InitValue};", CustomAttrs);
+ verifyFormat("SomeType *absl_nonnull s(InitValue);", CustomAttrs);
+ verifyFormat("SomeType *absl_nonnull s{InitValue};", CustomAttrs);
+ verifyFormat("SomeType *absl_nullable s(InitValue);", CustomAttrs);
+ verifyFormat("SomeType *absl_nullable s{InitValue};", CustomAttrs);
+ verifyFormat("SomeType *absl_nullability_unknown s(InitValue);", CustomAttrs);
+ verifyFormat("SomeType *absl_nullability_unknown s{InitValue};", CustomAttrs);
verifyFormat("SomeType *__capability s(InitValue);", CustomAttrs);
verifyFormat("SomeType *__capability s{InitValue};", CustomAttrs);
}
@@ -12687,7 +12699,9 @@ TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) {
verifyFormat("x = (foo *_Nonnull)*v;");
verifyFormat("x = (foo *_Nullable)*v;");
verifyFormat("x = (foo *_Null_unspecified)*v;");
- verifyFormat("x = (foo *_Nonnull)*v;");
+ verifyFormat("x = (foo *absl_nonnull)*v;");
+ verifyFormat("x = (foo *absl_nullable)*v;");
+ verifyFormat("x = (foo *absl_nullability_unknown)*v;");
verifyFormat("x = (foo *[[clang::attr]])*v;");
verifyFormat("x = (foo *[[clang::attr(\"foo\")]])*v;");
verifyFormat("x = (foo *__ptr32)*v;");
@@ -12701,7 +12715,8 @@ TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) {
LongPointerLeft.PointerAlignment = FormatStyle::PAS_Left;
StringRef AllQualifiers =
"const volatile restrict __attribute__((foo)) _Nonnull _Null_unspecified "
- "_Nonnull [[clang::attr]] __ptr32 __ptr64 __capability";
+ "_Nullable absl_nonnull absl_nullable absl_nullability_unknown "
+ "[[clang::attr]] __ptr32 __ptr64 __capability";
verifyFormat(("x = (foo *" + AllQualifiers + ")*v;").str(), LongPointerRight);
verifyFormat(("x = (foo* " + AllQualifiers + ")*v;").str(), LongPointerLeft);
>From 05dd2f2392c36befc16716e495e0deec7bfae0d7 Mon Sep 17 00:00:00 2001
From: Jan Voung <jvoung at gmail.com>
Date: Fri, 7 Mar 2025 21:03:07 +0000
Subject: [PATCH 2/8] format
---
clang/unittests/Format/ConfigParseTest.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 2cc2a45a7a590..5c789b21c306f 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -907,7 +907,8 @@ TEST(ConfigParseTest, ParsesConfiguration) {
CHECK_PARSE("IfMacros: [MYIF]", IfMacros, CustomIfs);
Style.AttributeMacros.clear();
- CHECK_PARSE("BasedOnStyle: LLVM", AttributeMacros,
+ CHECK_PARSE(
+ "BasedOnStyle: LLVM", AttributeMacros,
std::vector<std::string>({"__capability", "absl_nonnull", "absl_nullable",
"absl_nullability_unknown"}));
Style.AttributeMacros.clear();
>From f3654a24e3aa5f4281fc2a7082d2d4dc267416dc Mon Sep 17 00:00:00 2001
From: Jan Voung <jvoung at gmail.com>
Date: Mon, 10 Mar 2025 14:35:49 +0000
Subject: [PATCH 3/8] Switch to only in Google style
---
clang/lib/Format/Format.cpp | 8 ++--
clang/unittests/Format/ConfigParseTest.cpp | 4 ++
clang/unittests/Format/FormatTest.cpp | 49 ++++++++++++++--------
3 files changed, 40 insertions(+), 21 deletions(-)
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 1401b51586d03..c67db4752e87b 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -1508,10 +1508,6 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
LLVMStyle.AttributeMacros.push_back("__capability");
- // Abseil aliases to clang's `_Nonnull`, `_Nullable` and `_Null_unspecified`.
- LLVMStyle.AttributeMacros.push_back("absl_nonnull");
- LLVMStyle.AttributeMacros.push_back("absl_nullable");
- LLVMStyle.AttributeMacros.push_back("absl_nullability_unknown");
LLVMStyle.BinPackArguments = true;
LLVMStyle.BinPackLongBracedList = true;
LLVMStyle.BinPackParameters = FormatStyle::BPPS_BinPack;
@@ -1717,6 +1713,10 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
FormatStyle::SIS_WithoutElse;
GoogleStyle.AllowShortLoopsOnASingleLine = true;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
+ // Abseil aliases to clang's `_Nonnull`, `_Nullable` and `_Null_unspecified`.
+ GoogleStyle.AttributeMacros.push_back("absl_nonnull");
+ GoogleStyle.AttributeMacros.push_back("absl_nullable");
+ GoogleStyle.AttributeMacros.push_back("absl_nullability_unknown");
GoogleStyle.BreakTemplateDeclarations = FormatStyle::BTDS_Yes;
GoogleStyle.DerivePointerAlignment = true;
GoogleStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 5c789b21c306f..a74032f8a6f16 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -909,6 +909,10 @@ TEST(ConfigParseTest, ParsesConfiguration) {
Style.AttributeMacros.clear();
CHECK_PARSE(
"BasedOnStyle: LLVM", AttributeMacros,
+ std::vector<std::string>({"__capability"}));
+ Style.AttributeMacros.clear();
+ CHECK_PARSE(
+ "BasedOnStyle: Google", AttributeMacros,
std::vector<std::string>({"__capability", "absl_nonnull", "absl_nullable",
"absl_nullability_unknown"}));
Style.AttributeMacros.clear();
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index a17cad0b67b08..85122f1ae6008 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -12375,9 +12375,9 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyFormat("vector<a *_Nonnull> v;");
verifyFormat("vector<a *_Nullable> v;");
verifyFormat("vector<a *_Null_unspecified> v;");
- verifyFormat("vector<a *absl_nonnull> v;");
- verifyFormat("vector<a *absl_nullable> v;");
- verifyFormat("vector<a *absl_nullability_unknown> v;");
+ verifyGoogleFormat("vector<a *absl_nonnull> v;");
+ verifyGoogleFormat("vector<a *absl_nullable> v;");
+ verifyGoogleFormat("vector<a *absl_nullability_unknown> v;");
verifyFormat("vector<a *__ptr32> v;");
verifyFormat("vector<a *__ptr64> v;");
verifyFormat("vector<a *__capability> v;");
@@ -12521,9 +12521,10 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyIndependentOfContext("MACRO(A *_Nonnull a);");
verifyIndependentOfContext("MACRO(A *_Nullable a);");
verifyIndependentOfContext("MACRO(A *_Null_unspecified a);");
- verifyIndependentOfContext("MACRO(A *absl_nonnull a);");
- verifyIndependentOfContext("MACRO(A *absl_nullable a);");
- verifyIndependentOfContext("MACRO(A *absl_nullability_unknown a);");
+ verifyIndependentOfContext("MACRO(A *absl_nonnull a);", getGoogleStyle());
+ verifyIndependentOfContext("MACRO(A *absl_nullable a);", getGoogleStyle());
+ verifyIndependentOfContext("MACRO(A *absl_nullability_unknown a);",
+ getGoogleStyle());
verifyIndependentOfContext("MACRO(A *__attribute__((foo)) a);");
verifyIndependentOfContext("MACRO(A *__attribute((foo)) a);");
verifyIndependentOfContext("MACRO(A *[[clang::attr]] a);");
@@ -12680,14 +12681,14 @@ TEST_F(FormatTest, UnderstandsAttributes) {
verifyFormat("SomeType *__unused s{InitValue};", CustomAttrs);
verifyFormat("SomeType s __unused(InitValue);", CustomAttrs);
verifyFormat("SomeType s __unused{InitValue};", CustomAttrs);
- verifyFormat("SomeType *absl_nonnull s(InitValue);", CustomAttrs);
- verifyFormat("SomeType *absl_nonnull s{InitValue};", CustomAttrs);
- verifyFormat("SomeType *absl_nullable s(InitValue);", CustomAttrs);
- verifyFormat("SomeType *absl_nullable s{InitValue};", CustomAttrs);
- verifyFormat("SomeType *absl_nullability_unknown s(InitValue);", CustomAttrs);
- verifyFormat("SomeType *absl_nullability_unknown s{InitValue};", CustomAttrs);
verifyFormat("SomeType *__capability s(InitValue);", CustomAttrs);
verifyFormat("SomeType *__capability s{InitValue};", CustomAttrs);
+ verifyGoogleFormat("SomeType *absl_nonnull s(InitValue);");
+ verifyGoogleFormat("SomeType *absl_nonnull s{InitValue};");
+ verifyGoogleFormat("SomeType *absl_nullable s(InitValue);");
+ verifyGoogleFormat("SomeType *absl_nullable s{InitValue};");
+ verifyGoogleFormat("SomeType *absl_nullability_unknown s(InitValue);");
+ verifyGoogleFormat("SomeType *absl_nullability_unknown s{InitValue};");
}
TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) {
@@ -12699,9 +12700,9 @@ TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) {
verifyFormat("x = (foo *_Nonnull)*v;");
verifyFormat("x = (foo *_Nullable)*v;");
verifyFormat("x = (foo *_Null_unspecified)*v;");
- verifyFormat("x = (foo *absl_nonnull)*v;");
- verifyFormat("x = (foo *absl_nullable)*v;");
- verifyFormat("x = (foo *absl_nullability_unknown)*v;");
+ verifyGoogleFormat("x = (foo *absl_nonnull)*v;");
+ verifyGoogleFormat("x = (foo *absl_nullable)*v;");
+ verifyGoogleFormat("x = (foo *absl_nullability_unknown)*v;");
verifyFormat("x = (foo *[[clang::attr]])*v;");
verifyFormat("x = (foo *[[clang::attr(\"foo\")]])*v;");
verifyFormat("x = (foo *__ptr32)*v;");
@@ -12715,8 +12716,7 @@ TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) {
LongPointerLeft.PointerAlignment = FormatStyle::PAS_Left;
StringRef AllQualifiers =
"const volatile restrict __attribute__((foo)) _Nonnull _Null_unspecified "
- "_Nullable absl_nonnull absl_nullable absl_nullability_unknown "
- "[[clang::attr]] __ptr32 __ptr64 __capability";
+ "_Nullable [[clang::attr]] __ptr32 __ptr64 __capability";
verifyFormat(("x = (foo *" + AllQualifiers + ")*v;").str(), LongPointerRight);
verifyFormat(("x = (foo* " + AllQualifiers + ")*v;").str(), LongPointerLeft);
@@ -12735,6 +12735,21 @@ TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) {
verifyFormat(("x = (foo *" + AllQualifiers + " __my_qualifier)&v;").str(),
CustomQualifier);
+ // Check additional attribute macros in Google style:
+ FormatStyle LongPointerRightGoogle = getGoogleStyleWithColumns(999);
+ FormatStyle LongPointerLeftGoogle = getGoogleStyleWithColumns(999);
+ LongPointerLeftGoogle.PointerAlignment = FormatStyle::PAS_Left;
+ Twine AllQualifiersPlusGoogle = AllQualifiers +
+ " absl_nonnull absl_nullable absl_nullability_unknown";
+ verifyFormat(("x = (foo *" + AllQualifiersPlusGoogle + ")*v;").str(),
+ LongPointerRightGoogle);
+ verifyFormat(("x = (foo* " + AllQualifiersPlusGoogle + ")*v;").str(),
+ LongPointerLeftGoogle);
+ verifyFormat(("x = (foo *" + AllQualifiersPlusGoogle + ")&v;").str(),
+ LongPointerRightGoogle);
+ verifyFormat(("x = (foo* " + AllQualifiersPlusGoogle + ")&v;").str(),
+ LongPointerLeftGoogle);
+
// Check that unknown identifiers result in binary operator parsing:
verifyFormat("x = (foo * __unknown_qualifier) * v;");
verifyFormat("x = (foo * __unknown_qualifier) & v;");
>From f7ecc7e8bc6ebd3da346dd4c87427564099c353c Mon Sep 17 00:00:00 2001
From: Jan Voung <jvoung at gmail.com>
Date: Mon, 10 Mar 2025 14:37:47 +0000
Subject: [PATCH 4/8] reformat
---
clang/unittests/Format/ConfigParseTest.cpp | 5 ++---
clang/unittests/Format/FormatTest.cpp | 4 ++--
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index a74032f8a6f16..4169b62731ed7 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -907,9 +907,8 @@ TEST(ConfigParseTest, ParsesConfiguration) {
CHECK_PARSE("IfMacros: [MYIF]", IfMacros, CustomIfs);
Style.AttributeMacros.clear();
- CHECK_PARSE(
- "BasedOnStyle: LLVM", AttributeMacros,
- std::vector<std::string>({"__capability"}));
+ CHECK_PARSE("BasedOnStyle: LLVM", AttributeMacros,
+ std::vector<std::string>{"__capability"});
Style.AttributeMacros.clear();
CHECK_PARSE(
"BasedOnStyle: Google", AttributeMacros,
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 85122f1ae6008..8b6453d881956 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -12739,8 +12739,8 @@ TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) {
FormatStyle LongPointerRightGoogle = getGoogleStyleWithColumns(999);
FormatStyle LongPointerLeftGoogle = getGoogleStyleWithColumns(999);
LongPointerLeftGoogle.PointerAlignment = FormatStyle::PAS_Left;
- Twine AllQualifiersPlusGoogle = AllQualifiers +
- " absl_nonnull absl_nullable absl_nullability_unknown";
+ Twine AllQualifiersPlusGoogle =
+ AllQualifiers + " absl_nonnull absl_nullable absl_nullability_unknown";
verifyFormat(("x = (foo *" + AllQualifiersPlusGoogle + ")*v;").str(),
LongPointerRightGoogle);
verifyFormat(("x = (foo* " + AllQualifiersPlusGoogle + ")*v;").str(),
>From 1fb4e5c7b200f2d771235648bab2a93e264cd28b Mon Sep 17 00:00:00 2001
From: Jan Voung <jvoung at gmail.com>
Date: Wed, 12 Mar 2025 18:46:54 +0000
Subject: [PATCH 5/8] Address comments
---
clang/unittests/Format/ConfigParseTest.cpp | 1 -
clang/unittests/Format/FormatTest.cpp | 24 +++-------
clang/unittests/Format/TokenAnnotatorTest.cpp | 47 +++++++++++++++++++
3 files changed, 53 insertions(+), 19 deletions(-)
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 4169b62731ed7..cc42642f99252 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -909,7 +909,6 @@ TEST(ConfigParseTest, ParsesConfiguration) {
Style.AttributeMacros.clear();
CHECK_PARSE("BasedOnStyle: LLVM", AttributeMacros,
std::vector<std::string>{"__capability"});
- Style.AttributeMacros.clear();
CHECK_PARSE(
"BasedOnStyle: Google", AttributeMacros,
std::vector<std::string>({"__capability", "absl_nonnull", "absl_nullable",
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 8b6453d881956..da2361fe5aa24 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -12521,10 +12521,13 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyIndependentOfContext("MACRO(A *_Nonnull a);");
verifyIndependentOfContext("MACRO(A *_Nullable a);");
verifyIndependentOfContext("MACRO(A *_Null_unspecified a);");
- verifyIndependentOfContext("MACRO(A *absl_nonnull a);", getGoogleStyle());
- verifyIndependentOfContext("MACRO(A *absl_nullable a);", getGoogleStyle());
+
+ Style = getGoogleStyle();
+ verifyIndependentOfContext("MACRO(A *absl_nonnull a);", Style);
+ verifyIndependentOfContext("MACRO(A *absl_nullable a);", Style);
verifyIndependentOfContext("MACRO(A *absl_nullability_unknown a);",
- getGoogleStyle());
+ Style);
+
verifyIndependentOfContext("MACRO(A *__attribute__((foo)) a);");
verifyIndependentOfContext("MACRO(A *__attribute((foo)) a);");
verifyIndependentOfContext("MACRO(A *[[clang::attr]] a);");
@@ -12735,21 +12738,6 @@ TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) {
verifyFormat(("x = (foo *" + AllQualifiers + " __my_qualifier)&v;").str(),
CustomQualifier);
- // Check additional attribute macros in Google style:
- FormatStyle LongPointerRightGoogle = getGoogleStyleWithColumns(999);
- FormatStyle LongPointerLeftGoogle = getGoogleStyleWithColumns(999);
- LongPointerLeftGoogle.PointerAlignment = FormatStyle::PAS_Left;
- Twine AllQualifiersPlusGoogle =
- AllQualifiers + " absl_nonnull absl_nullable absl_nullability_unknown";
- verifyFormat(("x = (foo *" + AllQualifiersPlusGoogle + ")*v;").str(),
- LongPointerRightGoogle);
- verifyFormat(("x = (foo* " + AllQualifiersPlusGoogle + ")*v;").str(),
- LongPointerLeftGoogle);
- verifyFormat(("x = (foo *" + AllQualifiersPlusGoogle + ")&v;").str(),
- LongPointerRightGoogle);
- verifyFormat(("x = (foo* " + AllQualifiersPlusGoogle + ")&v;").str(),
- LongPointerLeftGoogle);
-
// Check that unknown identifiers result in binary operator parsing:
verifyFormat("x = (foo * __unknown_qualifier) * v;");
verifyFormat("x = (foo * __unknown_qualifier) & v;");
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index b44a369f77d92..28418729ddd46 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -3185,6 +3185,53 @@ TEST_F(TokenAnnotatorTest, UnderstandsAttributes) {
EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_AttributeRParen);
}
+TEST_F(TokenAnnotatorTest, UnderstandsNullabilityAttributes) {
+ auto Tokens = annotate("x = (foo *_Nullable)*v;");
+ ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown);
+ EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
+ EXPECT_TOKEN(Tokens[5], tok::kw__Nullable, TT_Unknown);
+ EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
+
+ Tokens = annotate("x = (foo *_Nonnull)*v;");
+ ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown);
+ EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
+ EXPECT_TOKEN(Tokens[5], tok::kw__Nonnull, TT_Unknown);
+ EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
+
+ Tokens = annotate("x = (foo *_Null_unspecified)*v;");
+ ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown);
+ EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
+ EXPECT_TOKEN(Tokens[5], tok::kw__Null_unspecified, TT_Unknown);
+ EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
+
+ // Under Google style, also handles the Abseil macro aliases for the
+ // nullability annotations.
+ FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+ Tokens = annotate("x = (foo *absl_nullable)*v;", Style);
+ ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown);
+ EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
+ EXPECT_TOKEN(Tokens[5], tok::identifier, TT_AttributeMacro);
+ EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
+
+ Tokens = annotate("x = (foo *absl_nonnull)*v;", Style);
+ ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown);
+ EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
+ EXPECT_TOKEN(Tokens[5], tok::identifier, TT_AttributeMacro);
+ EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
+
+ Tokens = annotate("x = (foo *absl_nullability_unknown)*v;", Style);
+ ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown);
+ EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
+ EXPECT_TOKEN(Tokens[5], tok::identifier, TT_AttributeMacro);
+ EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
+}
+
TEST_F(TokenAnnotatorTest, UnderstandsControlStatements) {
auto Tokens = annotate("while (true) {}");
ASSERT_EQ(Tokens.size(), 7u) << Tokens;
>From eb2a542b8325129e8a64bb137a8810703ec2f129 Mon Sep 17 00:00:00 2001
From: Jan Voung <jvoung at gmail.com>
Date: Wed, 12 Mar 2025 18:47:47 +0000
Subject: [PATCH 6/8] format
---
clang/unittests/Format/FormatTest.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index da2361fe5aa24..aaefb3b1922b0 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -12525,8 +12525,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
Style = getGoogleStyle();
verifyIndependentOfContext("MACRO(A *absl_nonnull a);", Style);
verifyIndependentOfContext("MACRO(A *absl_nullable a);", Style);
- verifyIndependentOfContext("MACRO(A *absl_nullability_unknown a);",
- Style);
+ verifyIndependentOfContext("MACRO(A *absl_nullability_unknown a);", Style);
verifyIndependentOfContext("MACRO(A *__attribute__((foo)) a);");
verifyIndependentOfContext("MACRO(A *__attribute((foo)) a);");
>From f50660c67b7b245e50631b47297cf86c736d5b00 Mon Sep 17 00:00:00 2001
From: Jan Voung <jvoung at gmail.com>
Date: Thu, 13 Mar 2025 15:19:43 +0000
Subject: [PATCH 7/8] Address comments
---
clang/unittests/Format/FormatTest.cpp | 24 ++++++------
clang/unittests/Format/TokenAnnotatorTest.cpp | 38 ++++---------------
2 files changed, 19 insertions(+), 43 deletions(-)
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index aaefb3b1922b0..978d4d7513771 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -12375,9 +12375,9 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyFormat("vector<a *_Nonnull> v;");
verifyFormat("vector<a *_Nullable> v;");
verifyFormat("vector<a *_Null_unspecified> v;");
- verifyGoogleFormat("vector<a *absl_nonnull> v;");
- verifyGoogleFormat("vector<a *absl_nullable> v;");
- verifyGoogleFormat("vector<a *absl_nullability_unknown> v;");
+ verifyGoogleFormat("vector<a* absl_nonnull> v;");
+ verifyGoogleFormat("vector<a* absl_nullable> v;");
+ verifyGoogleFormat("vector<a* absl_nullability_unknown> v;");
verifyFormat("vector<a *__ptr32> v;");
verifyFormat("vector<a *__ptr64> v;");
verifyFormat("vector<a *__capability> v;");
@@ -12523,9 +12523,9 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyIndependentOfContext("MACRO(A *_Null_unspecified a);");
Style = getGoogleStyle();
- verifyIndependentOfContext("MACRO(A *absl_nonnull a);", Style);
- verifyIndependentOfContext("MACRO(A *absl_nullable a);", Style);
- verifyIndependentOfContext("MACRO(A *absl_nullability_unknown a);", Style);
+ verifyIndependentOfContext("MACRO(A* absl_nonnull a);", Style);
+ verifyIndependentOfContext("MACRO(A* absl_nullable a);", Style);
+ verifyIndependentOfContext("MACRO(A* absl_nullability_unknown a);", Style);
verifyIndependentOfContext("MACRO(A *__attribute__((foo)) a);");
verifyIndependentOfContext("MACRO(A *__attribute((foo)) a);");
@@ -12685,12 +12685,12 @@ TEST_F(FormatTest, UnderstandsAttributes) {
verifyFormat("SomeType s __unused{InitValue};", CustomAttrs);
verifyFormat("SomeType *__capability s(InitValue);", CustomAttrs);
verifyFormat("SomeType *__capability s{InitValue};", CustomAttrs);
- verifyGoogleFormat("SomeType *absl_nonnull s(InitValue);");
- verifyGoogleFormat("SomeType *absl_nonnull s{InitValue};");
- verifyGoogleFormat("SomeType *absl_nullable s(InitValue);");
- verifyGoogleFormat("SomeType *absl_nullable s{InitValue};");
- verifyGoogleFormat("SomeType *absl_nullability_unknown s(InitValue);");
- verifyGoogleFormat("SomeType *absl_nullability_unknown s{InitValue};");
+ verifyGoogleFormat("SomeType* absl_nonnull s(InitValue);");
+ verifyGoogleFormat("SomeType* absl_nonnull s{InitValue};");
+ verifyGoogleFormat("SomeType* absl_nullable s(InitValue);");
+ verifyGoogleFormat("SomeType* absl_nullable s{InitValue};");
+ verifyGoogleFormat("SomeType* absl_nullability_unknown s(InitValue);");
+ verifyGoogleFormat("SomeType* absl_nullability_unknown s{InitValue};");
}
TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) {
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 28418729ddd46..52dcb6da482b4 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -3185,48 +3185,24 @@ TEST_F(TokenAnnotatorTest, UnderstandsAttributes) {
EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_AttributeRParen);
}
-TEST_F(TokenAnnotatorTest, UnderstandsNullabilityAttributes) {
- auto Tokens = annotate("x = (foo *_Nullable)*v;");
+TEST_F(TokenAnnotatorTest, UnderstandsNullabilityAttributeMacros) {
+ // Under Google style, handles the Abseil macro aliases for the
+ // Clang nullability annotations.
+ auto Style = getGoogleStyle(FormatStyle::LK_Cpp);
+ auto Tokens = annotate("x = (foo* absl_nullable)*v;", Style);
ASSERT_EQ(Tokens.size(), 11u) << Tokens;
- EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown);
- EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
- EXPECT_TOKEN(Tokens[5], tok::kw__Nullable, TT_Unknown);
- EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
-
- Tokens = annotate("x = (foo *_Nonnull)*v;");
- ASSERT_EQ(Tokens.size(), 11u) << Tokens;
- EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown);
- EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
- EXPECT_TOKEN(Tokens[5], tok::kw__Nonnull, TT_Unknown);
- EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
-
- Tokens = annotate("x = (foo *_Null_unspecified)*v;");
- ASSERT_EQ(Tokens.size(), 11u) << Tokens;
- EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown);
- EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
- EXPECT_TOKEN(Tokens[5], tok::kw__Null_unspecified, TT_Unknown);
- EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
-
- // Under Google style, also handles the Abseil macro aliases for the
- // nullability annotations.
- FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
- Tokens = annotate("x = (foo *absl_nullable)*v;", Style);
- ASSERT_EQ(Tokens.size(), 11u) << Tokens;
- EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown);
EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
EXPECT_TOKEN(Tokens[5], tok::identifier, TT_AttributeMacro);
EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
- Tokens = annotate("x = (foo *absl_nonnull)*v;", Style);
+ Tokens = annotate("x = (foo* absl_nonnull)*v;", Style);
ASSERT_EQ(Tokens.size(), 11u) << Tokens;
- EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown);
EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
EXPECT_TOKEN(Tokens[5], tok::identifier, TT_AttributeMacro);
EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
- Tokens = annotate("x = (foo *absl_nullability_unknown)*v;", Style);
+ Tokens = annotate("x = (foo* absl_nullability_unknown)*v;", Style);
ASSERT_EQ(Tokens.size(), 11u) << Tokens;
- EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown);
EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
EXPECT_TOKEN(Tokens[5], tok::identifier, TT_AttributeMacro);
EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
>From 1efd20d9f0ac6d6384af5353d9eaf5ca64544533 Mon Sep 17 00:00:00 2001
From: Jan Voung <jvoung at gmail.com>
Date: Thu, 13 Mar 2025 15:26:14 +0000
Subject: [PATCH 8/8] one more
---
clang/unittests/Format/FormatTest.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 978d4d7513771..1085958eaeb3a 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -12702,9 +12702,9 @@ TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) {
verifyFormat("x = (foo *_Nonnull)*v;");
verifyFormat("x = (foo *_Nullable)*v;");
verifyFormat("x = (foo *_Null_unspecified)*v;");
- verifyGoogleFormat("x = (foo *absl_nonnull)*v;");
- verifyGoogleFormat("x = (foo *absl_nullable)*v;");
- verifyGoogleFormat("x = (foo *absl_nullability_unknown)*v;");
+ verifyGoogleFormat("x = (foo* absl_nonnull)*v;");
+ verifyGoogleFormat("x = (foo* absl_nullable)*v;");
+ verifyGoogleFormat("x = (foo* absl_nullability_unknown)*v;");
verifyFormat("x = (foo *[[clang::attr]])*v;");
verifyFormat("x = (foo *[[clang::attr(\"foo\")]])*v;");
verifyFormat("x = (foo *__ptr32)*v;");
More information about the cfe-commits
mailing list