[clang] b646f09 - [clang-format] Fix misplacement of `*` in declaration of pointer to struct
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 29 00:21:16 PDT 2022
Author: Huang Zhen-Hong
Date: 2022-06-29T15:21:02+08:00
New Revision: b646f0955574c6ad4c156c9db522e46f597cfda9
URL: https://github.com/llvm/llvm-project/commit/b646f0955574c6ad4c156c9db522e46f597cfda9
DIFF: https://github.com/llvm/llvm-project/commit/b646f0955574c6ad4c156c9db522e46f597cfda9.diff
LOG: [clang-format] Fix misplacement of `*` in declaration of pointer to struct
Fixes #55810
Differential Revision: https://reviews.llvm.org/D127873
Added:
Modified:
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/FormatTest.cpp
clang/unittests/Format/TokenAnnotatorTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 1ee95f26d1fc7..029cb9097871c 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -2314,6 +2314,31 @@ class AnnotatingParser {
if (NextToken->isOneOf(tok::comma, tok::semi))
return TT_PointerOrReference;
+ // After right braces, star tokens are likely to be pointers to struct,
+ // union, or class.
+ // struct {} *ptr;
+ if (PrevToken->is(tok::r_brace) && Tok.is(tok::star))
+ return TT_PointerOrReference;
+
+ // For "} &&"
+ if (PrevToken->is(tok::r_brace) && Tok.is(tok::ampamp)) {
+ const FormatToken *MatchingLBrace = PrevToken->MatchingParen;
+
+ // We check whether there is a TemplateCloser(">") to indicate it's a
+ // template or not. If it's not a template, "&&" is likely a reference
+ // operator.
+ // struct {} &&ref = {};
+ if (!MatchingLBrace)
+ return TT_PointerOrReference;
+ FormatToken *BeforeLBrace = MatchingLBrace->getPreviousNonComment();
+ if (!BeforeLBrace || BeforeLBrace->isNot(TT_TemplateCloser))
+ return TT_PointerOrReference;
+
+ // If it is a template, "&&" is a binary operator.
+ // enable_if<>{} && ...
+ return TT_BinaryOperator;
+ }
+
if (PrevToken->Tok.isLiteral() ||
PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
tok::kw_false, tok::r_brace)) {
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 972f3f195d856..d6deafe1093c8 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -10431,6 +10431,67 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
"void F();",
getGoogleStyleWithColumns(68));
+ FormatStyle Style = getLLVMStyle();
+ Style.PointerAlignment = FormatStyle::PAS_Left;
+ verifyFormat("struct {\n"
+ "}* ptr;",
+ Style);
+ verifyFormat("union {\n"
+ "}* ptr;",
+ Style);
+ verifyFormat("class {\n"
+ "}* ptr;",
+ Style);
+ verifyFormat("struct {\n"
+ "}&& ptr = {};",
+ Style);
+ verifyFormat("union {\n"
+ "}&& ptr = {};",
+ Style);
+ verifyFormat("class {\n"
+ "}&& ptr = {};",
+ Style);
+
+ Style.PointerAlignment = FormatStyle::PAS_Middle;
+ verifyFormat("struct {\n"
+ "} * ptr;",
+ Style);
+ verifyFormat("union {\n"
+ "} * ptr;",
+ Style);
+ verifyFormat("class {\n"
+ "} * ptr;",
+ Style);
+ verifyFormat("struct {\n"
+ "} && ptr = {};",
+ Style);
+ verifyFormat("union {\n"
+ "} && ptr = {};",
+ Style);
+ verifyFormat("class {\n"
+ "} && ptr = {};",
+ Style);
+
+ Style.PointerAlignment = FormatStyle::PAS_Right;
+ verifyFormat("struct {\n"
+ "} *ptr;",
+ Style);
+ verifyFormat("union {\n"
+ "} *ptr;",
+ Style);
+ verifyFormat("class {\n"
+ "} *ptr;",
+ Style);
+ verifyFormat("struct {\n"
+ "} &&ptr = {};",
+ Style);
+ verifyFormat("union {\n"
+ "} &&ptr = {};",
+ Style);
+ verifyFormat("class {\n"
+ "} &&ptr = {};",
+ Style);
+
verifyIndependentOfContext("MACRO(int *i);");
verifyIndependentOfContext("MACRO(auto *a);");
verifyIndependentOfContext("MACRO(const A *a);");
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 2dbc5da07d4db..df1b052267478 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -85,6 +85,32 @@ TEST_F(TokenAnnotatorTest, UnderstandsUsesOfStarAndAmp) {
Tokens = annotate("case &x:");
EXPECT_EQ(Tokens.size(), 5u) << Tokens;
EXPECT_TOKEN(Tokens[1], tok::amp, TT_UnaryOperator);
+
+ Tokens = annotate("struct {\n"
+ "} *ptr;");
+ EXPECT_EQ(Tokens.size(), 7u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference);
+ Tokens = annotate("union {\n"
+ "} *ptr;");
+ EXPECT_EQ(Tokens.size(), 7u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference);
+ Tokens = annotate("class {\n"
+ "} *ptr;");
+ EXPECT_EQ(Tokens.size(), 7u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference);
+
+ Tokens = annotate("struct {\n"
+ "} &&ptr = {};");
+ EXPECT_EQ(Tokens.size(), 10u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_PointerOrReference);
+ Tokens = annotate("union {\n"
+ "} &&ptr = {};");
+ EXPECT_EQ(Tokens.size(), 10u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_PointerOrReference);
+ Tokens = annotate("class {\n"
+ "} &&ptr = {};");
+ EXPECT_EQ(Tokens.size(), 10u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_PointerOrReference);
}
TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {
More information about the cfe-commits
mailing list