[clang] d4d28f2 - [clang-format] Fix QualifierAlignment with global namespace qualified types.

Marek Kurdej via cfe-commits cfe-commits at lists.llvm.org
Thu May 26 06:02:23 PDT 2022


Author: Marek Kurdej
Date: 2022-05-26T15:02:33+02:00
New Revision: d4d28f2ace764a0420a33462628b43a1c71fc3dc

URL: https://github.com/llvm/llvm-project/commit/d4d28f2ace764a0420a33462628b43a1c71fc3dc
DIFF: https://github.com/llvm/llvm-project/commit/d4d28f2ace764a0420a33462628b43a1c71fc3dc.diff

LOG: [clang-format] Fix QualifierAlignment with global namespace qualified types.

Fixes https://github.com/llvm/llvm-project/issues/55610.

Reviewed By: MyDeveloperDay

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

Added: 
    

Modified: 
    clang/lib/Format/QualifierAlignmentFixer.cpp
    clang/unittests/Format/QualifierFixerTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Format/QualifierAlignmentFixer.cpp b/clang/lib/Format/QualifierAlignmentFixer.cpp
index dd12298a57ff..61f17cae383e 100644
--- a/clang/lib/Format/QualifierAlignmentFixer.cpp
+++ b/clang/lib/Format/QualifierAlignmentFixer.cpp
@@ -216,6 +216,29 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight(
   if (LeftRightQualifierAlignmentFixer::isPossibleMacro(Tok->Next))
     return Tok;
 
+  auto AnalyzeTemplate =
+      [&](const FormatToken *Tok,
+          const FormatToken *StartTemplate) -> const FormatToken * {
+    // Read from the TemplateOpener to TemplateCloser.
+    FormatToken *EndTemplate = StartTemplate->MatchingParen;
+    if (EndTemplate) {
+      // Move to the end of any template class members e.g.
+      // `Foo<int>::iterator`.
+      if (EndTemplate->startsSequence(TT_TemplateCloser, tok::coloncolon,
+                                      tok::identifier)) {
+        EndTemplate = EndTemplate->Next->Next;
+      }
+    }
+    if (EndTemplate && EndTemplate->Next &&
+        !EndTemplate->Next->isOneOf(tok::equal, tok::l_paren)) {
+      insertQualifierAfter(SourceMgr, Fixes, EndTemplate, Qualifier);
+      // Remove the qualifier.
+      removeToken(SourceMgr, Fixes, Tok);
+      return Tok;
+    }
+    return nullptr;
+  };
+
   FormatToken *Qual = Tok->Next;
   FormatToken *LastQual = Qual;
   while (Qual && isQualifierOrType(Qual, ConfiguredQualifierTokens)) {
@@ -233,27 +256,24 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight(
     return Tok;
   } else if (Tok->startsSequence(QualifierType, tok::identifier,
                                  TT_TemplateOpener)) {
-    // Read from the TemplateOpener to
-    // TemplateCloser as in const ArrayRef<int> a; const ArrayRef<int> &a;
-    FormatToken *EndTemplate = Tok->Next->Next->MatchingParen;
-    if (EndTemplate) {
-      // Move to the end of any template class members e.g.
-      // `Foo<int>::iterator`.
-      if (EndTemplate->startsSequence(TT_TemplateCloser, tok::coloncolon,
-                                      tok::identifier)) {
-        EndTemplate = EndTemplate->Next->Next;
-      }
-    }
-    if (EndTemplate && EndTemplate->Next &&
-        !EndTemplate->Next->isOneOf(tok::equal, tok::l_paren)) {
-      insertQualifierAfter(SourceMgr, Fixes, EndTemplate, Qualifier);
-      // Remove the qualifier.
-      removeToken(SourceMgr, Fixes, Tok);
-      return Tok;
-    }
-  } else if (Tok->startsSequence(QualifierType, tok::identifier)) {
+    // `const ArrayRef<int> a;`
+    // `const ArrayRef<int> &a;`
+    const FormatToken *NewTok = AnalyzeTemplate(Tok, Tok->Next->Next);
+    if (NewTok)
+      return NewTok;
+  } else if (Tok->startsSequence(QualifierType, tok::coloncolon,
+                                 tok::identifier, TT_TemplateOpener)) {
+    // `const ::ArrayRef<int> a;`
+    // `const ::ArrayRef<int> &a;`
+    const FormatToken *NewTok = AnalyzeTemplate(Tok, Tok->Next->Next->Next);
+    if (NewTok)
+      return NewTok;
+  } else if (Tok->startsSequence(QualifierType, tok::identifier) ||
+             Tok->startsSequence(QualifierType, tok::coloncolon,
+                                 tok::identifier)) {
     FormatToken *Next = Tok->Next;
     // The case  `const Foo` -> `Foo const`
+    // The case  `const ::Foo` -> `::Foo const`
     // The case  `const Foo *` -> `Foo const *`
     // The case  `const Foo &` -> `Foo const &`
     // The case  `const Foo &&` -> `Foo const &&`
@@ -331,7 +351,9 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeLeft(
       Tok->Next->Next && Tok->Next->Next->is(QualifierType)) {
     rotateTokens(SourceMgr, Fixes, Tok->Next, Tok->Next->Next, /*Left=*/true);
   }
-  if (Tok->startsSequence(tok::identifier) && Tok->Next) {
+  if ((Tok->startsSequence(tok::coloncolon, tok::identifier) ||
+       Tok->is(tok::identifier)) &&
+      Tok->Next) {
     if (Tok->Previous &&
         Tok->Previous->isOneOf(tok::star, tok::ampamp, tok::amp)) {
       return Tok;

diff  --git a/clang/unittests/Format/QualifierFixerTest.cpp b/clang/unittests/Format/QualifierFixerTest.cpp
index fc7e932af440..b01aff53150d 100755
--- a/clang/unittests/Format/QualifierFixerTest.cpp
+++ b/clang/unittests/Format/QualifierFixerTest.cpp
@@ -318,6 +318,8 @@ TEST_F(QualifierFixerTest, RightQualifier) {
   verifyFormat("Foo<int> const &a", "const Foo<int> &a", Style);
   verifyFormat("Foo<int>::iterator const &a", "const Foo<int>::iterator &a",
                Style);
+  verifyFormat("::Foo<int>::iterator const &a", "const ::Foo<int>::iterator &a",
+               Style);
 
   verifyFormat("Foo(int a, "
                "unsigned b, // c-style args\n"
@@ -355,6 +357,8 @@ TEST_F(QualifierFixerTest, RightQualifier) {
 
   verifyFormat("void fn(Foo<T> const &i);", "void fn(const Foo<T> &i);", Style);
   verifyFormat("void fns(ns::S const &s);", "void fns(const ns::S &s);", Style);
+  verifyFormat("void fns(::ns::S const &s);", "void fns(const ::ns::S &s);",
+               Style);
   verifyFormat("void fn(ns::Foo<T> const &i);", "void fn(const ns::Foo<T> &i);",
                Style);
   verifyFormat("void fns(ns::ns2::S const &s);",
@@ -445,6 +449,8 @@ TEST_F(QualifierFixerTest, LeftQualifier) {
   verifyFormat("const Foo<int> &a", "Foo<int> const &a", Style);
   verifyFormat("const Foo<int>::iterator &a", "Foo<int>::iterator const &a",
                Style);
+  verifyFormat("const ::Foo<int>::iterator &a", "::Foo<int>::iterator const &a",
+               Style);
 
   verifyFormat("const int a;", "int const a;", Style);
   verifyFormat("const int *a;", "int const *a;", Style);
@@ -508,6 +514,8 @@ TEST_F(QualifierFixerTest, LeftQualifier) {
 
   verifyFormat("void fn(const Foo<T> &i);", "void fn(Foo<T> const &i);", Style);
   verifyFormat("void fns(const ns::S &s);", "void fns(ns::S const &s);", Style);
+  verifyFormat("void fns(const ::ns::S &s);", "void fns(::ns::S const &s);",
+               Style);
   verifyFormat("void fn(const ns::Foo<T> &i);", "void fn(ns::Foo<T> const &i);",
                Style);
   verifyFormat("void fns(const ns::ns2::S &s);",


        


More information about the cfe-commits mailing list