victordk created this revision.
victordk added reviewers: ilya-biryukov, saugustine.
victordk requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Template args of outer types were not fully-qualified when calling 
getFullyQualifiedType() for inner types.

For simplicity the patch is a copy-paste of the same call from 
getFullyQualifiedType().


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D103039

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


Index: clang/unittests/Tooling/QualTypeNamesTest.cpp
===================================================================
--- clang/unittests/Tooling/QualTypeNamesTest.cpp
+++ clang/unittests/Tooling/QualTypeNamesTest.cpp
@@ -93,12 +93,14 @@
       "Foo<X>::non_dependent_type";
   Visitor.ExpectedQualTypeNames["AnEnumVar"] = "EnumScopeClass::AnEnum";
   Visitor.ExpectedQualTypeNames["AliasTypeVal"] = "A::B::C::InnerAlias<int>";
+  Visitor.ExpectedQualTypeNames["AliasInnerTypeVal"] =
+      "OuterTemplateClass<A::B::Class0>::Inner";
   Visitor.ExpectedQualTypeNames["CheckM"] = "const A::B::Class0 *";
   Visitor.ExpectedQualTypeNames["CheckN"] = "const X *";
   Visitor.runOver(
       "int CheckInt;\n"
       "template <typename T>\n"
-      "class OuterTemplateClass { };\n"
+      "class OuterTemplateClass { public: struct Inner {}; };\n"
       "namespace A {\n"
       " namespace B {\n"
       "   class Class0 { };\n"
@@ -107,6 +109,7 @@
       "     template <typename T>\n"
       "     using InnerAlias = OuterTemplateClass<T>;\n"
       "     InnerAlias<int> AliasTypeVal;\n"
+      "     InnerAlias<Class0>::Inner AliasInnerTypeVal;\n"
       "   }\n"
       "   template<class X, class Y> class Template0;"
       "   template<class X, class Y> class Template1;"
@@ -165,8 +168,7 @@
       "  enum AnEnum { ZERO, ONE };\n"
       "};\n"
       "EnumScopeClass::AnEnum AnEnumVar;\n",
-      TypeNameVisitor::Lang_CXX11
-);
+      TypeNameVisitor::Lang_CXX11);
 
   TypeNameVisitor Complex;
   Complex.ExpectedQualTypeNames["CheckTX"] = "B::TX";
Index: clang/lib/AST/QualTypeNames.cpp
===================================================================
--- clang/lib/AST/QualTypeNames.cpp
+++ clang/lib/AST/QualTypeNames.cpp
@@ -356,11 +356,19 @@
                                                const TypeDecl *TD,
                                                bool FullyQualify,
                                                bool WithGlobalNsPrefix) {
+  const Type *TypePtr = TD->getTypeForDecl();
+  if (isa<const TemplateSpecializationType>(TypePtr) ||
+      isa<const RecordType>(TypePtr)) {
+    // We are asked to fully qualify and we have a Record Type (which
+    // may point to a template specialization) or Template
+    // Specialization Type. We need to fully qualify their arguments.
+
+    TypePtr = getFullyQualifiedTemplateType(Ctx, TypePtr, WithGlobalNsPrefix);
+  }
+
   return NestedNameSpecifier::Create(
-      Ctx,
-      createOuterNNS(Ctx, TD, FullyQualify, WithGlobalNsPrefix),
-      false /*No TemplateKeyword*/,
-      TD->getTypeForDecl());
+      Ctx, createOuterNNS(Ctx, TD, FullyQualify, WithGlobalNsPrefix),
+      false /*No TemplateKeyword*/, TypePtr);
 }
 
 /// Return the fully qualified type, including fully-qualified


Index: clang/unittests/Tooling/QualTypeNamesTest.cpp
===================================================================
--- clang/unittests/Tooling/QualTypeNamesTest.cpp
+++ clang/unittests/Tooling/QualTypeNamesTest.cpp
@@ -93,12 +93,14 @@
       "Foo<X>::non_dependent_type";
   Visitor.ExpectedQualTypeNames["AnEnumVar"] = "EnumScopeClass::AnEnum";
   Visitor.ExpectedQualTypeNames["AliasTypeVal"] = "A::B::C::InnerAlias<int>";
+  Visitor.ExpectedQualTypeNames["AliasInnerTypeVal"] =
+      "OuterTemplateClass<A::B::Class0>::Inner";
   Visitor.ExpectedQualTypeNames["CheckM"] = "const A::B::Class0 *";
   Visitor.ExpectedQualTypeNames["CheckN"] = "const X *";
   Visitor.runOver(
       "int CheckInt;\n"
       "template <typename T>\n"
-      "class OuterTemplateClass { };\n"
+      "class OuterTemplateClass { public: struct Inner {}; };\n"
       "namespace A {\n"
       " namespace B {\n"
       "   class Class0 { };\n"
@@ -107,6 +109,7 @@
       "     template <typename T>\n"
       "     using InnerAlias = OuterTemplateClass<T>;\n"
       "     InnerAlias<int> AliasTypeVal;\n"
+      "     InnerAlias<Class0>::Inner AliasInnerTypeVal;\n"
       "   }\n"
       "   template<class X, class Y> class Template0;"
       "   template<class X, class Y> class Template1;"
@@ -165,8 +168,7 @@
       "  enum AnEnum { ZERO, ONE };\n"
       "};\n"
       "EnumScopeClass::AnEnum AnEnumVar;\n",
-      TypeNameVisitor::Lang_CXX11
-);
+      TypeNameVisitor::Lang_CXX11);
 
   TypeNameVisitor Complex;
   Complex.ExpectedQualTypeNames["CheckTX"] = "B::TX";
Index: clang/lib/AST/QualTypeNames.cpp
===================================================================
--- clang/lib/AST/QualTypeNames.cpp
+++ clang/lib/AST/QualTypeNames.cpp
@@ -356,11 +356,19 @@
                                                const TypeDecl *TD,
                                                bool FullyQualify,
                                                bool WithGlobalNsPrefix) {
+  const Type *TypePtr = TD->getTypeForDecl();
+  if (isa<const TemplateSpecializationType>(TypePtr) ||
+      isa<const RecordType>(TypePtr)) {
+    // We are asked to fully qualify and we have a Record Type (which
+    // may point to a template specialization) or Template
+    // Specialization Type. We need to fully qualify their arguments.
+
+    TypePtr = getFullyQualifiedTemplateType(Ctx, TypePtr, WithGlobalNsPrefix);
+  }
+
   return NestedNameSpecifier::Create(
-      Ctx,
-      createOuterNNS(Ctx, TD, FullyQualify, WithGlobalNsPrefix),
-      false /*No TemplateKeyword*/,
-      TD->getTypeForDecl());
+      Ctx, createOuterNNS(Ctx, TD, FullyQualify, WithGlobalNsPrefix),
+      false /*No TemplateKeyword*/, TypePtr);
 }
 
 /// Return the fully qualified type, including fully-qualified
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to