From: Anders Carlsson Date: Sat, 7 Mar 2009 23:57:03 +0000 (+0000) Subject: Make mangling work with anonymous tag types. Doug, please review X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b1d947b1011cb559be5745153f292b2dfb46b8e6;p=clang Make mangling work with anonymous tag types. Doug, please review git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66353 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index 490936f625..34c88fbba5 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -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!) // ::= mangleCVQualifiers(T.getCVRQualifiers()); + if (const TypedefType *TT = dyn_cast(T.getTypePtr())) + mangleType(TT); // ::= - if (const BuiltinType *BT = dyn_cast(T.getTypePtr())) + else if (const BuiltinType *BT = dyn_cast(T.getTypePtr())) mangleType(BT); // ::= else if (const FunctionType *FT = dyn_cast(T.getTypePtr())) @@ -382,13 +382,27 @@ void CXXNameMangler::mangleType(QualType T) { } else if (const ObjCInterfaceType *IT = dyn_cast(T.getTypePtr())) { mangleType(IT); - } + } // FIXME: ::= G # imaginary (C 2000) // FIXME: ::= U # 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(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) { // ::= v # void // ::= w # wchar_t diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index 7b92c85046..1c98df590b 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/test/CodeGenCXX/mangle.cpp @@ -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) { }