hvdijk created this revision. hvdijk added a reviewer: rsmith. hvdijk added a project: clang. Herald added a project: All. hvdijk requested review of this revision. Herald added a subscriber: cfe-commits.
The Itanium C++ ABI says prefixes are substitutable. For most prefixes we already handle this: the manglePrefix(const DeclContext *, bool) and manglePrefix(QualType) overloads explicitly handles substitutions or defer to functions that handle substitutions on their behalf. The manglePrefix(NestedNameSpecifier *) overload, however, is different and handles some cases implicitly, but not all. The Identifier case was not handled; this change adds handling for it, as well as a test case. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D122663 Files: clang/lib/AST/ItaniumMangle.cpp clang/test/CodeGenCXX/mangle.cpp Index: clang/test/CodeGenCXX/mangle.cpp =================================================================== --- clang/test/CodeGenCXX/mangle.cpp +++ clang/test/CodeGenCXX/mangle.cpp @@ -1155,3 +1155,15 @@ // CHECK-LABEL: @_ZN6test601fIiEEvDTplL_ZNS_1aEEcvT__EE template void f<int>(int); } + +namespace test61 { + struct X { + struct Y { + using a = int; + using b = int; + }; + }; + template <typename T> void f(typename T::Y::a, typename T::Y::b) {} + // CHECK-LABEL: @_ZN6test611fINS_1XEEEvNT_1Y1aENS3_1bE + template void f<X>(int, int); +} Index: clang/lib/AST/ItaniumMangle.cpp =================================================================== --- clang/lib/AST/ItaniumMangle.cpp +++ 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<uintptr_t>(ND)); } + void addSubstitution(NestedNameSpecifier *NNS) { + NNS = Context.getASTContext().getCanonicalNestedNameSpecifier(NNS); + + addSubstitution(reinterpret_cast<uintptr_t>(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<uintptr_t>(ND)); } +bool CXXNameMangler::mangleSubstitution(NestedNameSpecifier *NNS) { + NNS = Context.getASTContext().getCanonicalNestedNameSpecifier(NNS); + return mangleSubstitution(reinterpret_cast<uintptr_t>(NNS)); +} + /// Determine whether the given type has any qualifiers that are relevant for /// substitutions. static bool hasMangledSubstitutionQualifiers(QualType T) {
Index: clang/test/CodeGenCXX/mangle.cpp =================================================================== --- clang/test/CodeGenCXX/mangle.cpp +++ clang/test/CodeGenCXX/mangle.cpp @@ -1155,3 +1155,15 @@ // CHECK-LABEL: @_ZN6test601fIiEEvDTplL_ZNS_1aEEcvT__EE template void f<int>(int); } + +namespace test61 { + struct X { + struct Y { + using a = int; + using b = int; + }; + }; + template <typename T> void f(typename T::Y::a, typename T::Y::b) {} + // CHECK-LABEL: @_ZN6test611fINS_1XEEEvNT_1Y1aENS3_1bE + template void f<X>(int, int); +} Index: clang/lib/AST/ItaniumMangle.cpp =================================================================== --- clang/lib/AST/ItaniumMangle.cpp +++ 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<uintptr_t>(ND)); } + void addSubstitution(NestedNameSpecifier *NNS) { + NNS = Context.getASTContext().getCanonicalNestedNameSpecifier(NNS); + + addSubstitution(reinterpret_cast<uintptr_t>(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<uintptr_t>(ND)); } +bool CXXNameMangler::mangleSubstitution(NestedNameSpecifier *NNS) { + NNS = Context.getASTContext().getCanonicalNestedNameSpecifier(NNS); + return mangleSubstitution(reinterpret_cast<uintptr_t>(NNS)); +} + /// Determine whether the given type has any qualifiers that are relevant for /// substitutions. static bool hasMangledSubstitutionQualifiers(QualType T) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits