diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -442,6 +442,7 @@ private: bool mangleSubstitution(const NamedDecl *ND); + bool mangleSubstitution(NestedNameSpecifier *NNS); bool mangleSubstitution(QualType T); bool mangleSubstitution(TemplateName Template); bool mangleSubstitution(uintptr_t Ptr); @@ -455,6 +456,11 @@ addSubstitution(reinterpret_cast(ND)); } + void addSubstitution(NestedNameSpecifier *NNS) { + NNS = Context.getASTContext().getCanonicalNestedNameSpecifier(NNS); + + addSubstitution(reinterpret_cast(NNS)); + } void addSubstitution(QualType T); void addSubstitution(TemplateName Template); void addSubstitution(uintptr_t Ptr); @@ -2041,12 +2047,16 @@ return; case NestedNameSpecifier::Identifier: + if (mangleSubstitution(qualifier)) + return; + // Member expressions can have these without prefixes, but that // should end up in mangleUnresolvedPrefix instead. assert(qualifier->getPrefix()); manglePrefix(qualifier->getPrefix()); mangleSourceName(qualifier->getAsIdentifier()); + addSubstitution(qualifier); return; } @@ -5962,6 +5972,11 @@ return mangleSubstitution(reinterpret_cast(ND)); } +bool CXXNameMangler::mangleSubstitution(NestedNameSpecifier *NNS) { + NNS = Context.getASTContext().getCanonicalNestedNameSpecifier(NNS); + return mangleSubstitution(reinterpret_cast(NNS)); +} + /// Determine whether the given type has any qualifiers that are relevant for /// substitutions. static bool hasMangledSubstitutionQualifiers(QualType T) { diff --git a/clang/test/CodeGenCXX/mangle.cpp b/clang/test/CodeGenCXX/mangle.cpp --- a/clang/test/CodeGenCXX/mangle.cpp +++ b/clang/test/CodeGenCXX/mangle.cpp @@ -1155,3 +1155,15 @@ // CHECK-LABEL: @_ZN6test601fIiEEvDTplL_ZNS_1aEEcvT__EE template void f(int); } + +namespace test61 { + struct X { + struct Y { + using a = int; + using b = int; + }; + }; + template void f(typename T::Y::a, typename T::Y::b) {} + // CHECK-LABEL: @_ZN6test611fINS_1XEEEvNT_1Y1aENS3_1bE + template void f(int, int); +}