[cfe-commits] r116752 - in /cfe/trunk: lib/CodeGen/Mangle.cpp test/CodeGenCXX/mangle-abi-examples.cpp test/CodeGenCXX/mangle-local-class-vtables.cpp test/CodeGenCXX/mangle-local-classes-nested.cpp

John McCall rjmccall at apple.com
Mon Oct 18 14:28:45 PDT 2010


Author: rjmccall
Date: Mon Oct 18 16:28:44 2010
New Revision: 116752

URL: http://llvm.org/viewvc/llvm-project?rev=116752&view=rev
Log:
Fix some bugs in local class mangling brought up in PR8355.
Patch by Richard Smith!


Added:
    cfe/trunk/test/CodeGenCXX/mangle-abi-examples.cpp
    cfe/trunk/test/CodeGenCXX/mangle-local-class-vtables.cpp
    cfe/trunk/test/CodeGenCXX/mangle-local-classes-nested.cpp
Modified:
    cfe/trunk/lib/CodeGen/Mangle.cpp

Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=116752&r1=116751&r2=116752&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Mon Oct 18 16:28:44 2010
@@ -99,14 +99,14 @@
 
 namespace {
 
-static const DeclContext *GetLocalClassFunctionDeclContext(
-                                                      const DeclContext *DC) {
-  if (isa<CXXRecordDecl>(DC)) {
-    while (!DC->isNamespace() && !DC->isTranslationUnit() &&
-           !isa<FunctionDecl>(DC))
-      DC = DC->getParent();
-    if (isa<FunctionDecl>(DC))
-      return DC;
+static const CXXRecordDecl *GetLocalClassDecl(const NamedDecl *ND) {
+  const DeclContext *DC = dyn_cast<DeclContext>(ND);
+  if (!DC)
+    DC = ND->getDeclContext();
+  while (!DC->isNamespace() && !DC->isTranslationUnit()) {
+    if (isa<FunctionDecl>(DC->getParent()))
+      return dyn_cast<CXXRecordDecl>(DC);
+    DC = DC->getParent();
   }
   return 0;
 }
@@ -433,16 +433,15 @@
   //
   const DeclContext *DC = ND->getDeclContext();
 
-  if (GetLocalClassFunctionDeclContext(DC)) {
-    mangleLocalName(ND);
-    return;
-  }
-
   // If this is an extern variable declared locally, the relevant DeclContext
   // is that of the containing namespace, or the translation unit.
   if (isa<FunctionDecl>(DC) && ND->hasLinkage())
     while (!DC->isNamespace() && !DC->isTranslationUnit())
       DC = DC->getParent();
+  else if (GetLocalClassDecl(ND)) {
+    mangleLocalName(ND);
+    return;
+  }
 
   while (isa<LinkageSpecDecl>(DC))
     DC = DC->getParent();
@@ -853,15 +852,18 @@
 
   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC)) {
    mangleObjCMethodName(MD);
-  }
-  else if (const DeclContext *CDC = GetLocalClassFunctionDeclContext(DC)) {
-    mangleFunctionEncoding(cast<FunctionDecl>(CDC));
+  } else if (const CXXRecordDecl *RD = GetLocalClassDecl(ND)) {
+    mangleFunctionEncoding(cast<FunctionDecl>(RD->getDeclContext()));
     Out << 'E';
-    mangleNestedName(ND, DC, true /*NoFunction*/);
 
-    // FIXME. This still does not cover all cases.
+    // Mangle the name relative to the closest enclosing function.
+    if (ND == RD) // equality ok because RD derived from ND above
+      mangleUnqualifiedName(ND);
+    else
+      mangleNestedName(ND, DC, true /*NoFunction*/);
+
     unsigned disc;
-    if (Context.getNextDiscriminator(ND, disc)) {
+    if (Context.getNextDiscriminator(RD, disc)) {
       if (disc < 10)
         Out << '_' << disc;
       else

Added: cfe/trunk/test/CodeGenCXX/mangle-abi-examples.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-abi-examples.cpp?rev=116752&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-abi-examples.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/mangle-abi-examples.cpp Mon Oct 18 16:28:44 2010
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: @_ZTVZ3foovEN1C1DE =
+// CHECK: @_ZTVZN1A3fooEiE1B =
+// CHECK: define {{.*}} @_ZZZ3foovEN1C3barEvEN1E3bazEv(
+
+// Itanium C++ ABI examples.
+struct A {
+  void foo (int) {
+    struct B { virtual ~B() {} };
+    B();
+  }
+};
+void foo () {
+  struct C {
+    struct D { virtual ~D() {} };
+    void bar () {
+      struct E {
+        void baz() { }
+      };
+      E().baz();
+    }
+  };
+  A().foo(0);
+  C::D();
+  C().bar();
+}

Added: cfe/trunk/test/CodeGenCXX/mangle-local-class-vtables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-local-class-vtables.cpp?rev=116752&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-local-class-vtables.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/mangle-local-class-vtables.cpp Mon Oct 18 16:28:44 2010
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: @_ZTVZN1J1KEvE1C = {{.*}} @_ZTIZN1J1KEvE1C {{.*}} @_ZZN1J1KEvENK1C1FEv 
+// CHECK: @_ZTIZN1J1KEvE1C = {{.*}} @_ZTSZN1J1KEvE1C
+// CHECK: @_ZTVZ1GvE1C_1 = {{.*}} @_ZTIZ1GvE1C_1 {{.*}} @_ZZ1GvENK1C1FE_1v 
+// CHECK: @_ZTIZ1GvE1C_1 = {{.*}} @_ZTSZ1GvE1C_1
+// CHECK: @_ZTVZ1GvE1C_0 = {{.*}} @_ZTIZ1GvE1C_0 {{.*}} @_ZZ1GvENK1C1FE_0v 
+// CHECK: @_ZTIZ1GvE1C_0 = {{.*}} @_ZTSZ1GvE1C_0
+// CHECK: @_ZTVZ1GvE1C = {{.*}} @_ZTIZ1GvE1C {{.*}} @_ZZ1GvENK1C1FEv 
+// CHECK: @_ZTIZ1GvE1C = {{.*}} @_ZTSZ1GvE1C
+
+// CHECK: define {{.*}} @_ZZN1J1KEvEN1CC2Ev(
+// CHECK: define {{.*}} @_ZZN1J1KEvENK1C1FEv(
+// CHECK: define {{.*}} @_ZZ1GvEN1CC2E_1v(
+// CHECK: define {{.*}} @_ZZ1GvENK1C1FE_1v(
+// CHECK: define {{.*}} @_ZZ1GvENK1C1HE_1v(
+// CHECK: define {{.*}} @_ZZ1GvEN1CC2E_0v(
+// CHECK: define {{.*}} @_ZZ1GvENK1C1FE_0v(
+// CHECK: define {{.*}} @_ZZ1GvENK1C1GE_0v(
+// CHECK: define {{.*}} @_ZZ1GvEN1CC2Ev(
+// CHECK: define {{.*}} @_ZZ1GvENK1C1FEv(
+
+struct I { 
+  virtual void F() const = 0;
+};
+
+void Go(const I &i);
+
+void G() { 
+  { 
+    struct C : I { 
+      void F() const {}
+    };
+    Go(C());
+  }
+  { 
+    struct C : I { 
+      void F() const { G(); }
+      void G() const {}
+    };
+    Go(C());
+  }
+  { 
+    struct C : I { 
+      void F() const { H(); }
+      void H() const {}
+    };
+    Go(C());
+  }
+}
+
+struct J {
+  void K();
+};
+
+void J::K() {
+  struct C : I {
+    void F() const {}
+  };
+  Go(C());
+}

Added: cfe/trunk/test/CodeGenCXX/mangle-local-classes-nested.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-local-classes-nested.cpp?rev=116752&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-local-classes-nested.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/mangle-local-classes-nested.cpp Mon Oct 18 16:28:44 2010
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: @_ZTVZZ1HvEN1S1IEvE1S = 
+
+// CHECK: define {{.*}} @_Z2L1v(
+// CHECK: define {{.*}} @_ZZ2L1vEN1S2L2Ev(
+// CHECK: define {{.*}} @_ZZ2L1vEN1S2L2E_0v(
+// CHECK: define {{.*}} @_ZZ1FvEN1S1T1S1T1GEv(
+// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2E_0vEN1S3L3cEv(
+// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2E_0vEN1S3L3dE_0v(
+// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2EvEN1S3L3aEv(
+// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2EvEN1S3L3bE_0v(
+
+void L1() {
+  {
+    struct S {
+      void L2() {
+        {
+          struct S {
+            void L3a() {}
+          };
+          S().L3a();
+        }
+        {
+          struct S {
+            void L3b() {}
+          };
+          S().L3b();
+        }
+      }
+    };
+    S().L2();
+  }
+  {
+    struct S {
+      void L2() {
+        {
+          struct S {
+            void L3c() {}
+          };
+          S().L3c();
+        }
+        {
+          struct S {
+            void L3d() {}
+          };
+          S().L3d();
+        }
+      }
+    };
+    S().L2();
+  }
+}
+
+void F() {
+  struct S {
+    struct T {
+      struct S {
+        struct T {
+          void G() {}
+        };
+      };
+    };
+  };
+  S::T::S::T().G();
+}
+
+struct B { virtual void Foo() = 0; };
+void G(const B &);
+
+void H() {
+  struct S {
+    void I() {
+      struct S : B {
+        virtual void Foo() {}
+      };
+      G(S());
+    }
+  };
+  S().I();
+}





More information about the cfe-commits mailing list