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
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 9e647ad..205e887 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -237,6 +237,9 @@
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 @@
}
// 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 @@
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 @@
// <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 @@
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());
+ 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;
+ }
+ }
+
mangleUnresolvedTemplateArgs(tst->getArgs(), tst->getNumArgs());
break;
}
@@ -1381,9 +1414,11 @@
}
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 @@
// <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 @@
}
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 @@
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) {