diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 9e647ad410..205e887fea 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -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 A { + // template void foo(decltype(T::foo(U())) x...); + // }; + Out << "_SUBSTPACK_"; + break; + // ::= // ::= // ::= @@ -828,10 +836,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, // ::= [ ] 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(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(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(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