forked from OSchip/llvm-project
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:
parent
cb3b5a483f
commit
4f3b5f302c
|
@ -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';
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue