Change the mangling of enclosing template template parameters

that serve as the base template name of an unresolved-name to
be mangled as a substitution.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134213 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
John McCall 2011-07-01 00:04:39 +00:00
Родитель b44e0cf937
Коммит 68a51a7f9c
2 изменённых файлов: 74 добавлений и 22 удалений

Просмотреть файл

@ -237,6 +237,9 @@ private:
bool mangleSubstitution(TemplateName Template);
bool mangleSubstitution(uintptr_t Ptr);
void mangleExistingSubstitution(QualType type);
void mangleExistingSubstitution(TemplateName name);
bool mangleStandardSubstitution(const NamedDecl *ND);
void addSubstitution(const NamedDecl *ND) {
@ -770,8 +773,6 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
}
// Only certain other types are valid as prefixes; enumerate them.
// FIXME: can we get ElaboratedTypes here?
// FIXME: SubstTemplateTypeParmType?
switch (type->getTypeClass()) {
case Type::Builtin:
case Type::Complex:
@ -795,12 +796,19 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
case Type::Attributed:
case Type::Auto:
case Type::PackExpansion:
case Type::SubstTemplateTypeParmPack:
case Type::ObjCObject:
case Type::ObjCInterface:
case Type::ObjCObjectPointer:
llvm_unreachable("type is illegal as a nested name specifier");
case Type::SubstTemplateTypeParmPack:
// FIXME: not clear how to mangle this!
// template <class T...> class A {
// template <class U...> void foo(decltype(T::foo(U())) x...);
// };
Out << "_SUBSTPACK_";
break;
// <unresolved-type> ::= <template-param>
// ::= <decltype>
// ::= <template-template-param> <template-args>
@ -828,10 +836,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
// <unresolved-type> ::= <existing-substitution> [ <template-args> ]
case Type::SubstTemplateTypeParm: {
if (recursive) Out << 'N';
bool wasSubstituted = mangleSubstitution(QualType(type, 0));
assert(wasSubstituted && "no substitution for outer template argument?");
(void) wasSubstituted;
mangleExistingSubstitution(QualType(type, 0));
return;
}
@ -851,14 +856,42 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
case Type::TemplateSpecialization: {
const TemplateSpecializationType *tst
= cast<TemplateSpecializationType>(type);
TemplateDecl *temp = tst->getTemplateName().getAsTemplateDecl();
TemplateName name = tst->getTemplateName();
switch (name.getKind()) {
case TemplateName::Template:
case TemplateName::QualifiedTemplate: {
TemplateDecl *temp = name.getAsTemplateDecl();
// If the base is a template template parameter, this is an
// unresolved type.
assert(temp && "no template for template specialization type");
if (isa<TemplateTemplateParmDecl>(temp)) goto unresolvedType;
// If the base is a template template parameter, this is an
// unresolved type.
assert(temp && "no template for template specialization type");
if (isa<TemplateTemplateParmDecl>(temp)) goto unresolvedType;
mangleSourceName(temp->getIdentifier());
break;
}
case TemplateName::OverloadedTemplate:
case TemplateName::DependentTemplate:
llvm_unreachable("invalid base for a template specialization type");
case TemplateName::SubstTemplateTemplateParm: {
SubstTemplateTemplateParmStorage *subst
= name.getAsSubstTemplateTemplateParm();
mangleExistingSubstitution(subst->getReplacement());
break;
}
case TemplateName::SubstTemplateTemplateParmPack: {
// FIXME: not clear how to mangle this!
// template <template <class U> class T...> class A {
// template <class U...> void foo(decltype(T<U>::foo) x...);
// };
Out << "_SUBSTPACK_";
break;
}
}
mangleSourceName(temp->getIdentifier());
mangleUnresolvedTemplateArgs(tst->getArgs(), tst->getNumArgs());
break;
}
@ -1381,9 +1414,11 @@ void CXXNameMangler::mangleType(TemplateName TN) {
}
case TemplateName::SubstTemplateTemplateParmPack: {
SubstTemplateTemplateParmPackStorage *SubstPack
= TN.getAsSubstTemplateTemplateParmPack();
mangleTemplateParameter(SubstPack->getParameterPack()->getIndex());
// FIXME: not clear how to mangle this!
// template <template <class> class T...> class A {
// template <template <class> class U...> void foo(B<T,U> x...);
// };
Out << "_SUBSTPACK_";
break;
}
}
@ -1827,7 +1862,11 @@ void CXXNameMangler::mangleType(const TemplateTypeParmType *T) {
// <type> ::= <template-param>
void CXXNameMangler::mangleType(const SubstTemplateTypeParmPackType *T) {
mangleTemplateParameter(T->getReplacedParameter()->getIndex());
// FIXME: not clear how to mangle this!
// template <class T...> class A {
// template <class U...> void foo(T(*)(U) x...);
// };
Out << "_SUBSTPACK_";
}
// <type> ::= P <type> # pointer-to
@ -2511,8 +2550,11 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
}
case Expr::SubstNonTypeTemplateParmPackExprClass:
mangleTemplateParameter(
cast<SubstNonTypeTemplateParmPackExpr>(E)->getParameterPack()->getIndex());
// FIXME: not clear how to mangle this!
// template <unsigned N...> class A {
// template <class U...> void foo(U (&x)[N]...);
// };
Out << "_SUBSTPACK_";
break;
case Expr::DependentScopeDeclRefExprClass: {
@ -2872,6 +2914,18 @@ void CXXNameMangler::mangleTemplateParameter(unsigned Index) {
Out << 'T' << (Index - 1) << '_';
}
void CXXNameMangler::mangleExistingSubstitution(QualType type) {
bool result = mangleSubstitution(type);
assert(result && "no existing substitution for type");
(void) result;
}
void CXXNameMangler::mangleExistingSubstitution(TemplateName tname) {
bool result = mangleSubstitution(tname);
assert(result && "no existing substitution for template name");
(void) result;
}
// <substitution> ::= S <seq-id> _
// ::= S_
bool CXXNameMangler::mangleSubstitution(const NamedDecl *ND) {

Просмотреть файл

@ -748,8 +748,6 @@ namespace test30 {
void test() {
A<B>::foo<int>(0);
// FIXME: it's not clear what this mangling should be; maybe this?
// call void @_ZN6test301AINS_1BEE3fooIiEEvDTclsrS1_IT_EE2fnEE(
// Currently it's 1B instead of S1_.
// CHECK: call void @_ZN6test301AINS_1BEE3fooIiEEvDTclsrS1_IT_EE2fnEE(
}
}