|
@@ -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;
|
|
|
+
|
|
|
+ mangleSourceName(temp->getIdentifier());
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- // 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;
|
|
|
+ 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) {
|