[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