]> granicus.if.org Git - clang/commitdiff
PR27549: fix bug that resulted in us giving a translation-unit-scope variable a
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 29 Apr 2016 01:23:20 +0000 (01:23 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 29 Apr 2016 01:23:20 +0000 (01:23 +0000)
mangled name if it happened to be declared in an 'extern "C++"' context. This
also causes us to use the '_ZL' mangling rather than the '_Z' mangling for
internal-linkage entities that are wrapped in a language linkage construct.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@267969 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ItaniumMangle.cpp
test/CodeGenCXX/c-linkage.cpp
test/CodeGenCXX/extern-c.cpp

index 7ad464e1d912118bf685f144da2e6cb1762d3e01..62b60d7b89200b46bee8e41cd6abdbbce7616c7d 100644 (file)
@@ -79,7 +79,7 @@ static const DeclContext *getEffectiveDeclContext(const Decl *D) {
     if (FD->isExternC())
       return FD->getASTContext().getTranslationUnitDecl();
 
-  return DC;
+  return DC->getRedeclContext();
 }
 
 static const DeclContext *getEffectiveParentContext(const DeclContext *DC) {
index a70a22ef08c79dd4045583cb69b63d955443f22d..0f4c3277253f72dcc8a25fe79be3e381fbe6b55a 100644 (file)
@@ -15,10 +15,10 @@ extern "C" {
 extern "C" {
   static void test2_f() {
   }
-  // CHECK-LABEL: define internal {{.*}}void @_Z7test2_fv
+  // CHECK-LABEL: define internal {{.*}}void @_ZL7test2_fv
   static void test2_f(int x) {
   }
-  // CHECK-LABEL: define internal {{.*}}void @_Z7test2_fi
+  // CHECK-LABEL: define internal {{.*}}void @_ZL7test2_fi
   void test2_use() {
     test2_f();
     test2_f(42);
index 5b59a38ba0d793a1faad3d77fd790c6e7831709c..1046915fcaa2cae84adf4cb5d9e436b989f8600c 100644 (file)
@@ -16,8 +16,23 @@ extern "C" struct d;
 // CHECK-NOT: should_not_appear
 extern "C++" int should_not_appear;
 
+// CHECK: @_ZN3foo10extern_cxxE = global
+extern "C++" int extern_cxx = 0;
+
 }
 
+// CHECK-NOT: @global_a = global
+extern "C" int global_a;
+
+// CHECK: @global_b = global
+extern "C" int global_b = 0;
+
+// CHECK-NOT: should_not_appear
+extern "C++" int should_not_appear;
+
+// CHECK: @extern_cxx = global
+extern "C++" int extern_cxx = 0;
+
 namespace test1 {
   namespace {
     struct X {};
@@ -59,10 +74,10 @@ extern "C" {
 
   // CHECK-NOT: @unused
   // CHECK-NOT: @duplicate_internal
-  // CHECK: @internal_var = internal alias i32, i32* @_Z12internal_var
+  // CHECK: @internal_var = internal alias i32, i32* @_ZL12internal_var
   // CHECK-NOT: @unused
   // CHECK-NOT: @duplicate_internal
-  // CHECK: @internal_fn = internal alias i32 (), i32 ()* @_Z11internal_fnv
+  // CHECK: @internal_fn = internal alias i32 (), i32 ()* @_ZL11internal_fnv
   // CHECK-NOT: @unused
   // CHECK-NOT: @duplicate_internal
 }