teak-llvm/clang/test/CodeGenCXX/anonymous-namespaces.cpp
Richard Smith df963a38a9 DR1113: anonymous namespaces formally give their contents internal linkage.
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
2017-09-22 22:21:44 +00:00

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