mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-20 12:05:48 -04:00

This doesn't affect our code generation in any material way -- we already give such declarations internal linkage from a codegen perspective -- but it has some subtle effects on code validity. We suppress the 'L' (internal linkage) marker for mangled names in anonymous namespaces, because it is redundant (the information is already carried by the namespace); this deviates from GCC's behavior if a variable or function in an anonymous namespace is redundantly declared 'static' (where GCC does include the 'L'), but GCC's behavior is incoherent because such a declaration can be validly declared with or without the 'static'. We still deviate from the standard in one regard here: extern "C" declarations in anonymous namespaces are still granted external linkage. Changing those does not appear to have been an intentional consequence of the standard change in DR1113. llvm-svn: 314037
85 lines
1.8 KiB
C++
85 lines
1.8 KiB
C++
// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin10 -emit-llvm %s -o - > %t
|
|
// RUN: FileCheck %s -check-prefix=CHECK-1 < %t
|
|
// RUN: FileCheck %s -check-prefix=CHECK-2 < %t
|
|
|
|
int f();
|
|
|
|
namespace {
|
|
// CHECK-1: @_ZN12_GLOBAL__N_11bE = internal global i32 0
|
|
// CHECK-1: @_ZN12_GLOBAL__N_11cE = internal global i32 0
|
|
// CHECK-1: @_ZN12_GLOBAL__N_12c2E = internal global i32 0
|
|
// CHECK-1: @_ZN12_GLOBAL__N_11D1dE = internal global i32 0
|
|
// CHECK-1: @_ZN12_GLOBAL__N_11aE = internal global i32 0
|
|
int a = 0;
|
|
|
|
int b = f();
|
|
|
|
static int c = f();
|
|
|
|
// Note, we can't use an 'L' mangling for c or c2 (like GCC does) based on
|
|
// the 'static' specifier, because the variable can be redeclared without it.
|
|
extern int c2;
|
|
int g() { return c2; }
|
|
static int c2 = f();
|
|
|
|
class D {
|
|
static int d;
|
|
};
|
|
|
|
int D::d = f();
|
|
|
|
// Check for generation of a VTT with internal linkage
|
|
// CHECK-1: @_ZTSN12_GLOBAL__N_11X1EE = internal constant
|
|
struct X {
|
|
struct EBase { };
|
|
struct E : public virtual EBase { virtual ~E() {} };
|
|
};
|
|
|
|
// CHECK-1-LABEL: define internal i32 @_ZN12_GLOBAL__N_13fooEv()
|
|
int foo() {
|
|
return 32;
|
|
}
|
|
|
|
// CHECK-1-LABEL: define internal i32 @_ZN12_GLOBAL__N_11A3fooEv()
|
|
namespace A {
|
|
int foo() {
|
|
return 45;
|
|
}
|
|
}
|
|
}
|
|
|
|
int concrete() {
|
|
return a + foo() + A::foo();
|
|
}
|
|
|
|
void test_XE() { throw X::E(); }
|
|
|
|
// Miscompile on llvmc plugins.
|
|
namespace test2 {
|
|
struct A {
|
|
template <class T> struct B {
|
|
static void foo() {}
|
|
};
|
|
};
|
|
namespace {
|
|
struct C;
|
|
}
|
|
|
|
// CHECK-2-LABEL: define void @_ZN5test24testEv()
|
|
// CHECK-2: call void @_ZN5test21A1BINS_12_GLOBAL__N_11CEE3fooEv()
|
|
void test() {
|
|
A::B<C>::foo();
|
|
}
|
|
|
|
// CHECK-2-LABEL: define internal void @_ZN5test21A1BINS_12_GLOBAL__N_11CEE3fooEv()
|
|
}
|
|
|
|
namespace {
|
|
|
|
int bar() {
|
|
extern int a;
|
|
return a;
|
|
}
|
|
|
|
} // namespace
|