Fix the mangling of template template arguments, which do not always

follow <name>;  instead they follow <type>, which has <name> as a subset.

Fixes PR7446.

llvm-svn: 108326
This commit is contained in:
John McCall 2010-07-14 06:43:17 +00:00
parent cb3b5a483f
commit 4f3b5f302c
2 changed files with 62 additions and 4 deletions

View File

@ -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';

View File

@ -495,4 +495,15 @@ namespace test12 {
// CHECK: _ZN6test121fENS_1AILt33000EEE
template <unsigned short> struct A { };
void f(A<33000>) { }
}
}
// 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);
}