Skip to content

Commit 467ad6a

Browse files
authored
[clang-format] Add support for absl nullability macros (#130346)
Add support for formatting w/ absl nullability macros (https://github.com/abseil/abseil-cpp/blob/c52afac4f87ef76e6293b84874e5126a62be1f15/absl/base/nullability.h#L237). Example at https://godbolt.org/z/PYv19M1Gj input: ``` std::vector<int* _Nonnull> x; std::vector<int* absl_nonnull> y; ``` orig output: ``` std::vector<int* _Nonnull> x; std::vector<int * absl_nonnull> y; ``` new output: ``` std::vector<int* _Nonnull> x; std::vector<int* absl_nonnull> y; ``` credit to @ymand for the original patch
1 parent 6b7daf2 commit 467ad6a

File tree

4 files changed

+51
-2
lines changed

4 files changed

+51
-2
lines changed

clang/lib/Format/Format.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1713,6 +1713,10 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
17131713
FormatStyle::SIS_WithoutElse;
17141714
GoogleStyle.AllowShortLoopsOnASingleLine = true;
17151715
GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
1716+
// Abseil aliases to clang's `_Nonnull`, `_Nullable` and `_Null_unspecified`.
1717+
GoogleStyle.AttributeMacros.push_back("absl_nonnull");
1718+
GoogleStyle.AttributeMacros.push_back("absl_nullable");
1719+
GoogleStyle.AttributeMacros.push_back("absl_nullability_unknown");
17161720
GoogleStyle.BreakTemplateDeclarations = FormatStyle::BTDS_Yes;
17171721
GoogleStyle.DerivePointerAlignment = true;
17181722
GoogleStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;

clang/unittests/Format/ConfigParseTest.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,11 @@ TEST(ConfigParseTest, ParsesConfiguration) {
909909
Style.AttributeMacros.clear();
910910
CHECK_PARSE("BasedOnStyle: LLVM", AttributeMacros,
911911
std::vector<std::string>{"__capability"});
912+
CHECK_PARSE(
913+
"BasedOnStyle: Google", AttributeMacros,
914+
std::vector<std::string>({"__capability", "absl_nonnull", "absl_nullable",
915+
"absl_nullability_unknown"}));
916+
Style.AttributeMacros.clear();
912917
CHECK_PARSE("AttributeMacros: [attr1, attr2]", AttributeMacros,
913918
std::vector<std::string>({"attr1", "attr2"}));
914919

clang/unittests/Format/FormatTest.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12375,6 +12375,9 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
1237512375
verifyFormat("vector<a *_Nonnull> v;");
1237612376
verifyFormat("vector<a *_Nullable> v;");
1237712377
verifyFormat("vector<a *_Null_unspecified> v;");
12378+
verifyGoogleFormat("vector<a* absl_nonnull> v;");
12379+
verifyGoogleFormat("vector<a* absl_nullable> v;");
12380+
verifyGoogleFormat("vector<a* absl_nullability_unknown> v;");
1237812381
verifyFormat("vector<a *__ptr32> v;");
1237912382
verifyFormat("vector<a *__ptr64> v;");
1238012383
verifyFormat("vector<a *__capability> v;");
@@ -12518,6 +12521,12 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
1251812521
verifyIndependentOfContext("MACRO(A *_Nonnull a);");
1251912522
verifyIndependentOfContext("MACRO(A *_Nullable a);");
1252012523
verifyIndependentOfContext("MACRO(A *_Null_unspecified a);");
12524+
12525+
Style = getGoogleStyle();
12526+
verifyIndependentOfContext("MACRO(A* absl_nonnull a);", Style);
12527+
verifyIndependentOfContext("MACRO(A* absl_nullable a);", Style);
12528+
verifyIndependentOfContext("MACRO(A* absl_nullability_unknown a);", Style);
12529+
1252112530
verifyIndependentOfContext("MACRO(A *__attribute__((foo)) a);");
1252212531
verifyIndependentOfContext("MACRO(A *__attribute((foo)) a);");
1252312532
verifyIndependentOfContext("MACRO(A *[[clang::attr]] a);");
@@ -12676,6 +12685,12 @@ TEST_F(FormatTest, UnderstandsAttributes) {
1267612685
verifyFormat("SomeType s __unused{InitValue};", CustomAttrs);
1267712686
verifyFormat("SomeType *__capability s(InitValue);", CustomAttrs);
1267812687
verifyFormat("SomeType *__capability s{InitValue};", CustomAttrs);
12688+
verifyGoogleFormat("SomeType* absl_nonnull s(InitValue);");
12689+
verifyGoogleFormat("SomeType* absl_nonnull s{InitValue};");
12690+
verifyGoogleFormat("SomeType* absl_nullable s(InitValue);");
12691+
verifyGoogleFormat("SomeType* absl_nullable s{InitValue};");
12692+
verifyGoogleFormat("SomeType* absl_nullability_unknown s(InitValue);");
12693+
verifyGoogleFormat("SomeType* absl_nullability_unknown s{InitValue};");
1267912694
}
1268012695

1268112696
TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) {
@@ -12687,7 +12702,9 @@ TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) {
1268712702
verifyFormat("x = (foo *_Nonnull)*v;");
1268812703
verifyFormat("x = (foo *_Nullable)*v;");
1268912704
verifyFormat("x = (foo *_Null_unspecified)*v;");
12690-
verifyFormat("x = (foo *_Nonnull)*v;");
12705+
verifyGoogleFormat("x = (foo* absl_nonnull)*v;");
12706+
verifyGoogleFormat("x = (foo* absl_nullable)*v;");
12707+
verifyGoogleFormat("x = (foo* absl_nullability_unknown)*v;");
1269112708
verifyFormat("x = (foo *[[clang::attr]])*v;");
1269212709
verifyFormat("x = (foo *[[clang::attr(\"foo\")]])*v;");
1269312710
verifyFormat("x = (foo *__ptr32)*v;");
@@ -12701,7 +12718,7 @@ TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) {
1270112718
LongPointerLeft.PointerAlignment = FormatStyle::PAS_Left;
1270212719
StringRef AllQualifiers =
1270312720
"const volatile restrict __attribute__((foo)) _Nonnull _Null_unspecified "
12704-
"_Nonnull [[clang::attr]] __ptr32 __ptr64 __capability";
12721+
"_Nullable [[clang::attr]] __ptr32 __ptr64 __capability";
1270512722
verifyFormat(("x = (foo *" + AllQualifiers + ")*v;").str(), LongPointerRight);
1270612723
verifyFormat(("x = (foo* " + AllQualifiers + ")*v;").str(), LongPointerLeft);
1270712724

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3185,6 +3185,29 @@ TEST_F(TokenAnnotatorTest, UnderstandsAttributes) {
31853185
EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_AttributeRParen);
31863186
}
31873187

3188+
TEST_F(TokenAnnotatorTest, UnderstandsNullabilityAttributeMacros) {
3189+
// Under Google style, handles the Abseil macro aliases for the Clang
3190+
// nullability annotations.
3191+
auto Style = getGoogleStyle(FormatStyle::LK_Cpp);
3192+
auto Tokens = annotate("x = (foo* absl_nullable)*v;", Style);
3193+
ASSERT_EQ(Tokens.size(), 11u) << Tokens;
3194+
EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
3195+
EXPECT_TOKEN(Tokens[5], tok::identifier, TT_AttributeMacro);
3196+
EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
3197+
3198+
Tokens = annotate("x = (foo* absl_nonnull)*v;", Style);
3199+
ASSERT_EQ(Tokens.size(), 11u) << Tokens;
3200+
EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
3201+
EXPECT_TOKEN(Tokens[5], tok::identifier, TT_AttributeMacro);
3202+
EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
3203+
3204+
Tokens = annotate("x = (foo* absl_nullability_unknown)*v;", Style);
3205+
ASSERT_EQ(Tokens.size(), 11u) << Tokens;
3206+
EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
3207+
EXPECT_TOKEN(Tokens[5], tok::identifier, TT_AttributeMacro);
3208+
EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
3209+
}
3210+
31883211
TEST_F(TokenAnnotatorTest, UnderstandsControlStatements) {
31893212
auto Tokens = annotate("while (true) {}");
31903213
ASSERT_EQ(Tokens.size(), 7u) << Tokens;

0 commit comments

Comments
 (0)