xref: /aosp_15_r20/external/clang/test/SemaCXX/linkage.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // This is an IR generation test because the calculation of visibility
2*67e74705SXin Li // during IR gen will cause linkage to be implicitly recomputed and
3*67e74705SXin Li // compared against the earlier cached value.  If we had a way of
4*67e74705SXin Li // testing linkage directly in Sema, that would be better.
5*67e74705SXin Li 
6*67e74705SXin Li // RUN: %clang_cc1 -Werror -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
7*67e74705SXin Li 
8*67e74705SXin Li // CHECK: @_ZZN5test61A3fooEvE3bar = linkonce_odr global i32 0, align 4
9*67e74705SXin Li 
10*67e74705SXin Li // PR8926
11*67e74705SXin Li namespace test0 {
12*67e74705SXin Li   typedef struct {
footest0::__anoncc7fa7fe010813*67e74705SXin Li     void *foo() { return 0; }
14*67e74705SXin Li   } A;
15*67e74705SXin Li 
16*67e74705SXin Li   // CHECK: define linkonce_odr i8* @_ZN5test01A3fooEv(
17*67e74705SXin Li 
test(A * a)18*67e74705SXin Li   void test(A *a) {
19*67e74705SXin Li     a->foo();
20*67e74705SXin Li   }
21*67e74705SXin Li }
22*67e74705SXin Li 
23*67e74705SXin Li namespace test1 {
24*67e74705SXin Li   typedef struct {
footest1::__anoncc7fa7fe020825*67e74705SXin Li     template <unsigned n> void *foo() { return 0; }
26*67e74705SXin Li 
footest1::__anoncc7fa7fe020827*67e74705SXin Li     void foo() {
28*67e74705SXin Li       foo<0>();
29*67e74705SXin Li     }
30*67e74705SXin Li   } A;
31*67e74705SXin Li 
32*67e74705SXin Li   // CHECK: define linkonce_odr void @_ZN5test11A3fooEv(
33*67e74705SXin Li   // another at the end
34*67e74705SXin Li 
test(A * a)35*67e74705SXin Li   void test(A *a) {
36*67e74705SXin Li     a->foo();
37*67e74705SXin Li   }
38*67e74705SXin Li }
39*67e74705SXin Li 
40*67e74705SXin Li namespace test2 {
41*67e74705SXin Li   typedef struct {
42*67e74705SXin Li     template <unsigned n> struct B {
footest2::__anoncc7fa7fe0308::B43*67e74705SXin Li       void *foo() { return 0; }
44*67e74705SXin Li     };
45*67e74705SXin Li 
footest2::__anoncc7fa7fe030846*67e74705SXin Li     void foo(B<0> *b) {
47*67e74705SXin Li       b->foo();
48*67e74705SXin Li     }
49*67e74705SXin Li   } A;
50*67e74705SXin Li 
51*67e74705SXin Li   // CHECK: define linkonce_odr void @_ZN5test21A3fooEPNS0_1BILj0EEE(
52*67e74705SXin Li 
test(A * a)53*67e74705SXin Li   void test(A *a) {
54*67e74705SXin Li     a->foo(0);
55*67e74705SXin Li   }
56*67e74705SXin Li }
57*67e74705SXin Li 
58*67e74705SXin Li namespace test3 {
59*67e74705SXin Li   namespace { struct A {}; }
60*67e74705SXin Li 
61*67e74705SXin Li   // CHECK: define internal void @_ZN5test34testENS_12_GLOBAL__N_11AE(
test(A a)62*67e74705SXin Li   void test(A a) {}
force()63*67e74705SXin Li   void force() { test(A()); }
64*67e74705SXin Li 
65*67e74705SXin Li   // CHECK: define void @test3(
test3(A a)66*67e74705SXin Li   extern "C" void test3(A a) {}
67*67e74705SXin Li }
68*67e74705SXin Li 
69*67e74705SXin Li namespace {
70*67e74705SXin Li   // CHECK: define void @test4(
test4(void)71*67e74705SXin Li   extern "C" void test4(void) {}
72*67e74705SXin Li }
73*67e74705SXin Li 
74*67e74705SXin Li // PR9316: Ensure that even non-namespace-scope function declarations in
75*67e74705SXin Li // a C declaration context respect that over the anonymous namespace.
76*67e74705SXin Li extern "C" {
77*67e74705SXin Li   namespace {
78*67e74705SXin Li     struct X {
f__anoncc7fa7fe0611::X79*67e74705SXin Li       int f() {
80*67e74705SXin Li         extern int g();
81*67e74705SXin Li         extern int a;
82*67e74705SXin Li 
83*67e74705SXin Li         // Test both for mangling in the code generation and warnings from use
84*67e74705SXin Li         // of internal, undefined names via -Werror.
85*67e74705SXin Li         // CHECK: call i32 @g(
86*67e74705SXin Li         // CHECK: load i32, i32* @a,
87*67e74705SXin Li         return g() + a;
88*67e74705SXin Li       }
89*67e74705SXin Li     };
90*67e74705SXin Li   }
91*67e74705SXin Li   // Force the above function to be emitted by codegen.
test(X & x)92*67e74705SXin Li   int test(X& x) {
93*67e74705SXin Li     return x.f();
94*67e74705SXin Li   }
95*67e74705SXin Li }
96*67e74705SXin Li 
97*67e74705SXin Li // CHECK: define linkonce_odr i8* @_ZN5test11A3fooILj0EEEPvv(
98*67e74705SXin Li // CHECK: define linkonce_odr i8* @_ZN5test21A1BILj0EE3fooEv(
99*67e74705SXin Li 
100*67e74705SXin Li namespace test5 {
101*67e74705SXin Li   struct foo {
102*67e74705SXin Li   };
103*67e74705SXin Li   extern "C" {
104*67e74705SXin Li     const foo bar[]  = {
105*67e74705SXin Li     };
106*67e74705SXin Li   }
107*67e74705SXin Li }
108*67e74705SXin Li 
109*67e74705SXin Li // Test that we don't compute linkage too hastily before we're done
110*67e74705SXin Li // processing a record decl.  rdar://15928125
111*67e74705SXin Li namespace test6 {
112*67e74705SXin Li   typedef struct {
footest6::__anoncc7fa7fe0708113*67e74705SXin Li     int foo() {
114*67e74705SXin Li       // Tested at top of file.
115*67e74705SXin Li       static int bar = 0;
116*67e74705SXin Li       return bar++;
117*67e74705SXin Li     }
118*67e74705SXin Li   } A;
119*67e74705SXin Li 
test()120*67e74705SXin Li   void test() {
121*67e74705SXin Li     A a;
122*67e74705SXin Li     a.foo();
123*67e74705SXin Li   }
124*67e74705SXin Li }
125