[clang-format] Fix AlignConsecutiveDeclarations handling of pointers
authorDarwin Xu <darwin.xu@icloud.com>
Sat, 27 Feb 2021 21:40:57 +0000 (22:40 +0100)
committerBjörn Schäpers <bjoern@hazardy.de>
Sat, 27 Feb 2021 21:56:36 +0000 (22:56 +0100)
This is a bug fix of https://bugs.llvm.org/show_bug.cgi?id=49175

The expected code format:

unsigned int*       a;
int*                b;
unsigned int Const* c;

The actual code after formatting (without this patch):

unsigned int* a;
int*          b;
unsigned int Const* c;

Differential Revision: https://reviews.llvm.org/D97137

clang/lib/Format/WhitespaceManager.cpp
clang/unittests/Format/FormatTest.cpp

index 7d6964b..ac68fe0 100644 (file)
@@ -709,6 +709,8 @@ void WhitespaceManager::alignConsecutiveDeclarations() {
         for (FormatToken *Next = C.Tok->Next; Next; Next = Next->Next) {
           if (Next->is(tok::comment))
             continue;
+          if (Next->is(TT_PointerOrReference))
+            return false;
           if (!Next->Tok.getIdentifierInfo())
             break;
           if (Next->isOneOf(TT_StartOfName, TT_FunctionDeclarationName,
index b4b31fa..8bb90e0 100644 (file)
@@ -13945,6 +13945,20 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) {
   verifyFormat("int      oneTwoThree{0}; // comment\n"
                "unsigned oneTwo;         // comment",
                Alignment);
+  verifyFormat("unsigned int *      a;\n"
+               "int *               b;\n"
+               "unsigned int Const *c;\n"
+               "unsigned int const *d;\n"
+               "unsigned int Const &e;\n"
+               "unsigned int const &f;",
+               Alignment);
+  verifyFormat("Const unsigned int *c;\n"
+               "const unsigned int *d;\n"
+               "Const unsigned int &e;\n"
+               "const unsigned int &f;\n"
+               "const unsigned      g;\n"
+               "Const unsigned      h;",
+               Alignment);
   EXPECT_EQ("float const a = 5;\n"
             "\n"
             "int oneTwoThree = 123;",
@@ -14249,6 +14263,38 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) {
   EXPECT_EQ("DECOR1 /**/ int8_t /**/ DECOR2 /**/\n"
             "foo(int a);",
             format("DECOR1 /**/ int8_t /**/ DECOR2 /**/ foo (int a);", Style));
+
+  Alignment.PointerAlignment = FormatStyle::PAS_Left;
+  verifyFormat("unsigned int*       a;\n"
+               "int*                b;\n"
+               "unsigned int Const* c;\n"
+               "unsigned int const* d;\n"
+               "unsigned int Const& e;\n"
+               "unsigned int const& f;",
+               Alignment);
+  verifyFormat("Const unsigned int* c;\n"
+               "const unsigned int* d;\n"
+               "Const unsigned int& e;\n"
+               "const unsigned int& f;\n"
+               "const unsigned      g;\n"
+               "Const unsigned      h;",
+               Alignment);
+
+  Alignment.PointerAlignment = FormatStyle::PAS_Middle;
+  verifyFormat("unsigned int *       a;\n"
+               "int *                b;\n"
+               "unsigned int Const * c;\n"
+               "unsigned int const * d;\n"
+               "unsigned int Const & e;\n"
+               "unsigned int const & f;",
+               Alignment);
+  verifyFormat("Const unsigned int * c;\n"
+               "const unsigned int * d;\n"
+               "Const unsigned int & e;\n"
+               "const unsigned int & f;\n"
+               "const unsigned       g;\n"
+               "Const unsigned       h;",
+               Alignment);
 }
 
 TEST_F(FormatTest, LinuxBraceBreaking) {