diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ItaniumMangle.cpp | 92 |
1 files changed, 73 insertions, 19 deletions
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 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) { |