From: John McCall Date: Wed, 14 Jul 2010 06:43:17 +0000 (+0000) Subject: Fix the mangling of template template arguments, which do not always X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b6f532e2b03dbbfd97a37a7bb845fe23f8136889;p=clang Fix the mangling of template template arguments, which do not always follow ; instead they follow , which has as a subset. Fixes PR7446. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108326 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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 . Required for +/// template template arguments. +/// ::= +/// ::= +/// ::= +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(TD)) + mangleTemplateParameter(cast(TD)->getIndex()); + else + mangleName(TD); + break; + + case TemplateName::OverloadedTemplate: + llvm_unreachable("can't mangle an overloaded template name as a "); + break; + + case TemplateName::DependentTemplate: { + const DependentTemplateName *Dependent = TN.getAsDependentTemplateName(); + assert(Dependent->isIdentifier()); + + // ::= + // ::= + 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 . + 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 struct A { }; void f(A<33000>) { } -} \ No newline at end of file +} + +// PR7446 +namespace test13 { + template