]> granicus.if.org Git - clang/commitdiff
Make mangling work with anonymous tag types. Doug, please review
authorAnders Carlsson <andersca@mac.com>
Sat, 7 Mar 2009 23:57:03 +0000 (23:57 +0000)
committerAnders Carlsson <andersca@mac.com>
Sat, 7 Mar 2009 23:57:03 +0000 (23:57 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66353 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/Mangle.cpp
test/CodeGenCXX/mangle.cpp

index 490936f625d0b8a40951626593e4b5a7859c30a8..34c88fbba5ab41a28739f4326d681a76f5edcd4a 100644 (file)
@@ -43,6 +43,7 @@ namespace {
     void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
     void mangleCVQualifiers(unsigned Quals);
     void mangleType(QualType T);
+    void mangleType(const TypedefType *T);
     void mangleType(const BuiltinType *T);
     void mangleType(const FunctionType *T);
     void mangleBareFunctionType(const FunctionType *T, bool MangleReturnType);
@@ -329,16 +330,15 @@ void CXXNameMangler::mangleCVQualifiers(unsigned Quals) {
 }
 
 void CXXNameMangler::mangleType(QualType T) {
-  // Only operate on the canonical type!
-  T = Context.getCanonicalType(T);
-
   // FIXME: Should we have a TypeNodes.def to make this easier? (YES!)
 
   //  <type> ::= <CV-qualifiers> <type>
   mangleCVQualifiers(T.getCVRQualifiers());
 
+  if (const TypedefType *TT = dyn_cast<TypedefType>(T.getTypePtr()))
+    mangleType(TT);
   //         ::= <builtin-type>
-  if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr()))
+  else if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr()))
     mangleType(BT);
   //         ::= <function-type>
   else if (const FunctionType *FT = dyn_cast<FunctionType>(T.getTypePtr()))
@@ -382,13 +382,27 @@ void CXXNameMangler::mangleType(QualType T) {
   } else if (const ObjCInterfaceType *IT = 
              dyn_cast<ObjCInterfaceType>(T.getTypePtr())) {
     mangleType(IT);
-  }
+  } 
   // FIXME:  ::= G <type>   # imaginary (C 2000)
   // FIXME:  ::= U <source-name> <type>     # vendor extended type qualifier
   else
     assert(false && "Cannot mangle unknown type");
 }
 
+void CXXNameMangler::mangleType(const TypedefType *T) {
+  QualType DeclTy = T->getDecl()->getUnderlyingType();
+  
+  if (const TagType *TT = dyn_cast<TagType>(DeclTy)) {
+    // If the tag type is anonymous, use the name of the typedef.
+    if (!TT->getDecl()->getIdentifier()) {
+      mangleName(T->getDecl());
+      return;
+    }
+  }
+  
+  mangleType(DeclTy);
+}
+
 void CXXNameMangler::mangleType(const BuiltinType *T) {
   //  <builtin-type> ::= v  # void
   //                 ::= w  # wchar_t
index 7b92c85046f0de6df47ddefdf2807c56eefd9d1d..1c98df590bcf76d6d03541e8af86fb283d6683cb 100644 (file)
@@ -1,9 +1,21 @@
-// RUN: clang -emit-llvm %s -o - | grep _ZplRK1YRA100_P1X
+// RUN: clang -emit-llvm %s -o %t &&
 
 // FIXME: This test is intentionally trivial, because we can't yet
 // CodeGen anything real in C++.
 struct X { };
 struct Y { };
-  
+
+// RUN: grep _ZplRK1YRA100_P1X %t | count 1 &&
 bool operator+(const Y&, X* (&xs)[100]) { return false; }
 
+// RUN: grep _Z1f1s %t | count 1 &&
+typedef struct { int a; } s;
+void f(s) { }
+
+// RUN: grep _Z1f1e %t| count 1 &&
+typedef enum { foo } e;
+void f(e) { }
+
+// RUN: grep _Z1f1u %t | count 1
+typedef union { int a; } u;
+void f(u) { }