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