summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-04-29 01:23:20 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-04-29 01:23:20 +0000
commitec24bbe332b4c341fc32328ee6aafa7b72aa1df7 (patch)
tree6e343bd054192a75448d6682c24d037a571da34b
parent23323e25f896cf44e6d4519ef38f066e45fe408f (diff)
downloadbcm5719-llvm-ec24bbe332b4c341fc32328ee6aafa7b72aa1df7.tar.gz
bcm5719-llvm-ec24bbe332b4c341fc32328ee6aafa7b72aa1df7.zip
PR27549: fix bug that resulted in us giving a translation-unit-scope variable a
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. llvm-svn: 267969
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp2
-rw-r--r--clang/test/CodeGenCXX/c-linkage.cpp4
-rw-r--r--clang/test/CodeGenCXX/extern-c.cpp19
3 files changed, 20 insertions, 5 deletions
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 7ad464e1d91..62b60d7b892 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -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) {
diff --git a/clang/test/CodeGenCXX/c-linkage.cpp b/clang/test/CodeGenCXX/c-linkage.cpp
index a70a22ef08c..0f4c3277253 100644
--- a/clang/test/CodeGenCXX/c-linkage.cpp
+++ b/clang/test/CodeGenCXX/c-linkage.cpp
@@ -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);
diff --git a/clang/test/CodeGenCXX/extern-c.cpp b/clang/test/CodeGenCXX/extern-c.cpp
index 5b59a38ba0d..1046915fcaa 100644
--- a/clang/test/CodeGenCXX/extern-c.cpp
+++ b/clang/test/CodeGenCXX/extern-c.cpp
@@ -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
}
OpenPOWER on IntegriCloud