Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clang/lib/Format/Format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions clang/unittests/Format/ConfigParseTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"}));

Expand Down
21 changes: 19 additions & 2 deletions clang/unittests/Format/FormatTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;");
Expand Down Expand Up @@ -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);");
Expand Down Expand Up @@ -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) {
Expand All @@ -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;");
Expand All @@ -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);

Expand Down
47 changes: 47 additions & 0 deletions clang/unittests/Format/TokenAnnotatorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading