Be more thorough about mangling unresolved types.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134011 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 81c6543..9f30f6e 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -256,9 +256,6 @@
DeclarationName name,
unsigned KnownArity = UnknownArity);
- static bool isUnresolvedType(const Type *type);
- void mangleUnresolvedType(const Type *type);
-
void mangleName(const TemplateDecl *TD,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs);
@@ -703,31 +700,6 @@
}
}
-/// Returns true if the given type, appearing within an
-/// unresolved-name, should be mangled as an unresolved-type.
-bool CXXNameMangler::isUnresolvedType(const Type *type) {
- // <unresolved-type> ::= <template-param>
- // ::= <decltype>
- // ::= <template-template-param> <template-args>
- // (this last is not official yet)
-
- if (isa<TemplateTypeParmType>(type)) return true;
- if (isa<DecltypeType>(type)) return true;
- // typeof?
- if (const TemplateSpecializationType *tst =
- dyn_cast<TemplateSpecializationType>(type)) {
- TemplateDecl *temp = tst->getTemplateName().getAsTemplateDecl();
- if (temp && isa<TemplateTemplateParmDecl>(temp))
- return true;
- }
- return false;
-}
-
-void CXXNameMangler::mangleUnresolvedType(const Type *type) {
- // This seems to be do everything we want.
- mangleType(QualType(type, 0));
-}
-
/// Mangle everything prior to the base-unresolved-name in an unresolved-name.
///
/// \param firstQualifierLookup - the entity found by unqualified lookup
@@ -795,45 +767,118 @@
} else {
// Otherwise, all the cases want this.
Out << "sr";
-
- if (isUnresolvedType(type)) {
- // We only get here recursively if we're followed by identifiers.
- if (recursive) Out << 'N';
- mangleUnresolvedType(type);
-
- // We never want to print 'E' directly after an unresolved-type,
- // so we return directly.
- return;
- }
}
- assert(!isUnresolvedType(type));
-
// Only certain other types are valid as prefixes; enumerate them.
// FIXME: can we get ElaboratedTypes here?
// FIXME: SubstTemplateTypeParmType?
- if (const TagType *t = dyn_cast<TagType>(type)) {
- mangleSourceName(t->getDecl()->getIdentifier());
- } else if (const TypedefType *t = dyn_cast<TypedefType>(type)) {
- mangleSourceName(t->getDecl()->getIdentifier());
- } else if (const UnresolvedUsingType *t
- = dyn_cast<UnresolvedUsingType>(type)) {
- mangleSourceName(t->getDecl()->getIdentifier());
- } else if (const DependentNameType *t
- = dyn_cast<DependentNameType>(type)) {
- mangleSourceName(t->getIdentifier());
- } else if (const TemplateSpecializationType *tst
- = dyn_cast<TemplateSpecializationType>(type)) {
+ switch (type->getTypeClass()) {
+ case Type::Builtin:
+ case Type::Complex:
+ case Type::Pointer:
+ case Type::BlockPointer:
+ case Type::LValueReference:
+ case Type::RValueReference:
+ case Type::MemberPointer:
+ case Type::ConstantArray:
+ case Type::IncompleteArray:
+ case Type::VariableArray:
+ case Type::DependentSizedArray:
+ case Type::DependentSizedExtVector:
+ case Type::Vector:
+ case Type::ExtVector:
+ case Type::FunctionProto:
+ case Type::FunctionNoProto:
+ case Type::Enum:
+ case Type::Paren:
+ case Type::Elaborated:
+ 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");
+
+ // <unresolved-type> ::= <template-param>
+ // ::= <decltype>
+ // ::= <template-template-param> <template-args>
+ // (this last is not official yet)
+ case Type::TypeOfExpr:
+ case Type::TypeOf:
+ case Type::Decltype:
+ case Type::TemplateTypeParm:
+ case Type::UnaryTransform:
+ unresolvedType:
+ assert(!qualifier->getPrefix());
+
+ // We only get here recursively if we're followed by identifiers.
+ if (recursive) Out << 'N';
+
+ // This seems to do everything we want.
+ mangleType(QualType(type, 0));
+
+ // We never want to print 'E' directly after an unresolved-type,
+ // so we return directly.
+ return;
+
+ // Substituted template type parameters should only come up with
+ // enclosing templates.
+ // <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;
+ return;
+ }
+
+ case Type::Typedef:
+ mangleSourceName(cast<TypedefType>(type)->getDecl()->getIdentifier());
+ break;
+
+ case Type::UnresolvedUsing:
+ mangleSourceName(cast<UnresolvedUsingType>(type)->getDecl()
+ ->getIdentifier());
+ break;
+
+ case Type::Record:
+ mangleSourceName(cast<RecordType>(type)->getDecl()->getIdentifier());
+ break;
+
+ case Type::TemplateSpecialization: {
+ const TemplateSpecializationType *tst
+ = cast<TemplateSpecializationType>(type);
TemplateDecl *temp = tst->getTemplateName().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());
mangleUnresolvedTemplateArgs(tst->getArgs(), tst->getNumArgs());
- } else if (const DependentTemplateSpecializationType *tst
- = dyn_cast<DependentTemplateSpecializationType>(type)) {
+ break;
+ }
+
+ case Type::InjectedClassName:
+ mangleSourceName(cast<InjectedClassNameType>(type)->getDecl()
+ ->getIdentifier());
+ break;
+
+ case Type::DependentName:
+ mangleSourceName(cast<DependentNameType>(type)->getIdentifier());
+ break;
+
+ case Type::DependentTemplateSpecialization: {
+ const DependentTemplateSpecializationType *tst
+ = cast<DependentTemplateSpecializationType>(type);
mangleSourceName(tst->getIdentifier());
mangleUnresolvedTemplateArgs(tst->getArgs(), tst->getNumArgs());
- } else {
- llvm_unreachable("unexpected type in nested name specifier!");
+ break;
+ }
}
break;
}