diff options
-rw-r--r-- | lib/CodeGen/Mangle.cpp | 53 | ||||
-rw-r--r-- | test/CodeGenCXX/mangle.cpp | 13 |
2 files changed, 62 insertions, 4 deletions
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index 41178c2a24..30ee541c00 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -232,6 +232,7 @@ private: #include "clang/AST/TypeNodes.def" void mangleType(const TagType*); + void mangleType(TemplateName); void mangleBareFunctionType(const FunctionType *T, bool MangleReturnType); @@ -956,6 +957,53 @@ void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND) { addSubstitution(ND); } +/// Mangles a template name under the production <type>. Required for +/// template template arguments. +/// <type> ::= <class-enum-type> +/// ::= <template-param> +/// ::= <substitution> +void CXXNameMangler::mangleType(TemplateName TN) { + if (mangleSubstitution(TN)) + return; + + TemplateDecl *TD = 0; + + switch (TN.getKind()) { + case TemplateName::QualifiedTemplate: + TD = TN.getAsQualifiedTemplateName()->getTemplateDecl(); + goto HaveDecl; + + case TemplateName::Template: + TD = TN.getAsTemplateDecl(); + goto HaveDecl; + + HaveDecl: + if (isa<TemplateTemplateParmDecl>(TD)) + mangleTemplateParameter(cast<TemplateTemplateParmDecl>(TD)->getIndex()); + else + mangleName(TD); + break; + + case TemplateName::OverloadedTemplate: + llvm_unreachable("can't mangle an overloaded template name as a <type>"); + break; + + case TemplateName::DependentTemplate: { + const DependentTemplateName *Dependent = TN.getAsDependentTemplateName(); + assert(Dependent->isIdentifier()); + + // <class-enum-type> ::= <name> + // <name> ::= <nested-name> + mangleUnresolvedScope(Dependent->getQualifier()); + mangleSourceName(Dependent->getIdentifier()); + break; + } + + } + + addSubstitution(TN); +} + void CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) { switch (OO) { @@ -2034,9 +2082,8 @@ void CXXNameMangler::mangleTemplateArg(const NamedDecl *P, mangleType(A.getAsType()); break; case TemplateArgument::Template: - assert(A.getAsTemplate().getAsTemplateDecl() && - "Can't get dependent template names here"); - mangleName(A.getAsTemplate().getAsTemplateDecl()); + // This is mangled as <type>. + mangleType(A.getAsTemplate()); break; case TemplateArgument::Expression: Out << 'X'; diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index 54a4060352..814a7592fa 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/test/CodeGenCXX/mangle.cpp @@ -495,4 +495,15 @@ namespace test12 { // CHECK: _ZN6test121fENS_1AILt33000EEE template <unsigned short> struct A { }; void f(A<33000>) { } -}
\ No newline at end of file +} + +// PR7446 +namespace test13 { + template <template <class> class T> class A {}; + template <class U> class B {}; + + template <template<class> class T> void foo(const A<T> &a) {} + + // CHECK: define weak_odr void @_ZN6test133fooINS_1BEEEvRKNS_1AIT_EE( + template void foo(const A<B> &a); +} |