Author: Jan Voung Date: 2025-03-14T00:01:35-07:00 New Revision: 467ad6a03583ba0566ec4f7c8ca4e2dabc60c8f6
URL: https://github.com/llvm/llvm-project/commit/467ad6a03583ba0566ec4f7c8ca4e2dabc60c8f6 DIFF: https://github.com/llvm/llvm-project/commit/467ad6a03583ba0566ec4f7c8ca4e2dabc60c8f6.diff LOG: [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 Added: Modified: clang/lib/Format/Format.cpp clang/unittests/Format/ConfigParseTest.cpp clang/unittests/Format/FormatTest.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Removed: ################################################################################ diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index b5f1241321891..c67db4752e87b 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1713,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 273bab87b1ee1..cc42642f99252 100644 --- a/clang/unittests/Format/ConfigParseTest.cpp +++ b/clang/unittests/Format/ConfigParseTest.cpp @@ -909,6 +909,11 @@ TEST(ConfigParseTest, ParsesConfiguration) { Style.AttributeMacros.clear(); CHECK_PARSE("BasedOnStyle: LLVM", AttributeMacros, std::vector<std::string>{"__capability"}); + CHECK_PARSE( + "BasedOnStyle: Google", AttributeMacros, + 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 6cd424c20720d..9864e7ec1b2ec 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;"); + 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;"); @@ -12518,6 +12521,12 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { verifyIndependentOfContext("MACRO(A *_Nonnull a);"); verifyIndependentOfContext("MACRO(A *_Nullable a);"); 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 *__attribute__((foo)) a);"); verifyIndependentOfContext("MACRO(A *__attribute((foo)) a);"); verifyIndependentOfContext("MACRO(A *[[clang::attr]] a);"); @@ -12676,6 +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};"); } TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) { @@ -12687,7 +12702,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;"); + 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;"); @@ -12701,7 +12718,7 @@ 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 [[clang::attr]] __ptr32 __ptr64 __capability"; verifyFormat(("x = (foo *" + AllQualifiers + ")*v;").str(), LongPointerRight); verifyFormat(("x = (foo* " + AllQualifiers + ")*v;").str(), LongPointerLeft); diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index b44a369f77d92..5e2d301c5d1f3 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -3185,6 +3185,29 @@ TEST_F(TokenAnnotatorTest, UnderstandsAttributes) { EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_AttributeRParen); } +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[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[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[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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits