[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