Preserve qualifiers when getting fully qualified type
authorWeverything <rtrieu@google.com>
Sat, 30 Jul 2022 02:17:20 +0000 (19:17 -0700)
committerWeverything <rtrieu@google.com>
Sat, 30 Jul 2022 02:42:54 +0000 (19:42 -0700)
15f3cd6bfc670ba6106184a903eb04be059e5977 moved the handling of UsingType
to a later point in the function getFullyQualifiedType.  This moved it
after the removal of an ElaboratedType and its qualifiers.  However,
the qualifiers were not added back, causing the fully qualified type to
have a qualifier mismatch with the original type.  Make sure the
qualifers are added before continuing to fully qualify the type.

clang/lib/AST/QualTypeNames.cpp
clang/unittests/Tooling/QualTypeNamesTest.cpp

index 8c736a7..1bfe999 100644 (file)
@@ -452,8 +452,8 @@ QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
   // We don't consider the alias introduced by `using a::X` as a new type.
   // The qualified name is still a::X.
   if (const auto *UT = QT->getAs<UsingType>()) {
-    return getFullyQualifiedType(UT->getUnderlyingType(), Ctx,
-                                 WithGlobalNsPrefix);
+    QT = Ctx.getQualifiedType(UT->getUnderlyingType(), PrefixQualifiers);
+    return getFullyQualifiedType(QT, Ctx, WithGlobalNsPrefix);
   }
 
   // Create a nested name specifier if needed.
index 4e51560..686d189 100644 (file)
@@ -287,4 +287,14 @@ TEST(QualTypeNameTest, AnonStrucs) {
                         } anon_st;)");
 }
 
+TEST(QualTypeNameTest, ConstUsing) {
+  TypeNameVisitor ConstUsing;
+  ConstUsing.ExpectedQualTypeNames["param1"] = "const A::S &";
+  ConstUsing.ExpectedQualTypeNames["param2"] = "const A::S";
+  ConstUsing.runOver(R"(namespace A {
+                          class S {};
+                        }
+                        using ::A::S;
+                        void foo(const S& param1, const S param2);)");
+}
 }  // end anonymous namespace