[cfe-commits] r134011 - in /cfe/trunk: lib/AST/ASTContext.cpp lib/AST/ItaniumMangle.cpp test/CodeGenCXX/mangle.cpp
John McCall
rjmccall at apple.com
Tue Jun 28 09:49:24 PDT 2011
Author: rjmccall
Date: Tue Jun 28 11:49:23 2011
New Revision: 134011
URL: http://llvm.org/viewvc/llvm-project?rev=134011&view=rev
Log:
Be more thorough about mangling unresolved types.
Modified:
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/ItaniumMangle.cpp
cfe/trunk/test/CodeGenCXX/mangle.cpp
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=134011&r1=134010&r2=134011&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Jun 28 11:49:23 2011
@@ -753,7 +753,7 @@
#define NON_CANONICAL_TYPE(Class, Base)
#define DEPENDENT_TYPE(Class, Base) case Type::Class:
#include "clang/AST/TypeNodes.def"
- assert(false && "Should not see dependent types");
+ llvm_unreachable("Should not see dependent types");
break;
case Type::FunctionNoProto:
Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=134011&r1=134010&r2=134011&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Tue Jun 28 11:49:23 2011
@@ -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;
}
Modified: cfe/trunk/test/CodeGenCXX/mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle.cpp?rev=134011&r1=134010&r2=134011&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle.cpp Tue Jun 28 11:49:23 2011
@@ -711,3 +711,45 @@
b<A>(f);
}
}
+
+// An injected class name type in a unresolved-name.
+namespace test28 {
+ template <class T> struct A {
+ enum { bit };
+ };
+
+ template <class T> void foo(decltype(A<T>::A::bit) x);
+
+ void test() {
+ foo<char>(A<char>::bit);
+ // CHECK: call void @_ZN6test283fooIcEEvDtsr1AIT_E1AE3bitE(
+ }
+}
+
+// An enclosing template type parameter in an unresolved-name.
+namespace test29 {
+ template <class T> struct A {
+ template <class U> static void foo(decltype(T::fn(U())) x);
+ };
+ struct B { static int fn(int); static long fn(long); };
+
+ void test() {
+ A<B>::foo<int>(0);
+ // CHECK: call void @_ZN6test291AINS_1BEE3fooIiEEvDTclsrS1_2fncvT__EEE(
+ }
+}
+
+// An enclosing template template parameter in an unresolved-name.
+namespace test30 {
+ template <template <class> class T> struct A {
+ template <class U> static void foo(decltype(T<U>::fn()) x);
+ };
+ template <class T> struct B { static T fn(); };
+
+ void test() {
+ A<B>::foo<int>(0);
+ // FIXME: it's not clear what this mangling should be; maybe this?
+ // call void @_ZN6test301AINS_1BEE3fooIiEEvDTclsrS1_IT_EE2fnEE(
+ // Currently it's 1B instead of S1_.
+ }
+}
More information about the cfe-commits
mailing list