[cfe-commits] r105606 - in /cfe/trunk: lib/CodeGen/Mangle.cpp test/CodeGenCXX/mangle-unnamed.cpp

Anders Carlsson andersca at mac.com
Tue Jun 8 07:49:03 PDT 2010


Author: andersca
Date: Tue Jun  8 09:49:03 2010
New Revision: 105606

URL: http://llvm.org/viewvc/llvm-project?rev=105606&view=rev
Log:
Correctly mangle static variables of anonymous struct/union type.

Modified:
    cfe/trunk/lib/CodeGen/Mangle.cpp
    cfe/trunk/test/CodeGenCXX/mangle-unnamed.cpp

Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=105606&r1=105605&r2=105606&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Tue Jun  8 09:49:03 2010
@@ -598,6 +598,28 @@
   mangleUnqualifiedName(0, Name, KnownArity);
 }
 
+static const FieldDecl *FindFirstNamedDataMember(const RecordDecl *RD) {
+  assert(RD->isAnonymousStructOrUnion() &&
+         "Expected anonymous struct or union!");
+  
+  for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+       I != E; ++I) {
+    const FieldDecl *FD = *I;
+    
+    if (FD->getIdentifier())
+      return FD;
+    
+    if (const RecordType *RT = FD->getType()->getAs<RecordType>()) {
+      if (const FieldDecl *NamedDataMember = 
+          FindFirstNamedDataMember(RT->getDecl()))
+        return NamedDataMember;
+    }
+  }
+
+  // We didn't find a named data member.
+  return 0;
+}
+
 void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
                                            DeclarationName Name,
                                            unsigned KnownArity) {
@@ -630,6 +652,28 @@
       }
     }
 
+    if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
+      // We must have an anonymous union or struct declaration.
+      const RecordDecl *RD = 
+        cast<RecordDecl>(VD->getType()->getAs<RecordType>()->getDecl());
+      
+      // Itanium C++ ABI 5.1.2:
+      //
+      //   For the purposes of mangling, the name of an anonymous union is
+      //   considered to be the name of the first named data member found by a
+      //   pre-order, depth-first, declaration-order walk of the data members of
+      //   the anonymous union. If there is no such data member (i.e., if all of
+      //   the data members in the union are unnamed), then there is no way for
+      //   a program to refer to the anonymous union, and there is therefore no
+      //   need to mangle its name.
+      const FieldDecl *FD = FindFirstNamedDataMember(RD);
+      assert(FD && "Didn't find a named data member!");
+      assert(FD->getIdentifier() && "Data member name isn't an identifier!");
+      
+      mangleSourceName(FD->getIdentifier());
+      break;
+    }
+    
     // We must have an anonymous struct.
     const TagDecl *TD = cast<TagDecl>(ND);
     if (const TypedefDecl *D = TD->getTypedefForAnonDecl()) {

Modified: cfe/trunk/test/CodeGenCXX/mangle-unnamed.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-unnamed.cpp?rev=105606&r1=105605&r2=105606&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-unnamed.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-unnamed.cpp Tue Jun  8 09:49:03 2010
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm-only -verify %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s
 
 struct S {
   virtual ~S() { }
@@ -37,3 +37,35 @@
 };
 
 int f4() { return A().a(); }
+
+int f5() {
+  static union {
+    int a;
+  };
+  
+  // CHECK: _ZZ2f5vE1a
+  return a;
+}
+
+int f6() {
+  static union {
+    union {
+      int : 1;
+    };
+    int b;
+  };
+  
+  // CHECK: _ZZ2f6vE1b
+  return b;
+}
+
+int f7() {
+  static union {
+    union {
+      int b;
+    } a;
+  };
+  
+  // CHECK: _ZZ2f7vE1a
+  return a.b;
+}





More information about the cfe-commits mailing list