xref: /aosp_15_r20/external/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 %s -std=c++1y -triple=x86_64-pc-linux -emit-llvm -o - | FileCheck --check-prefix=ELF --check-prefix=ALL %s
2*67e74705SXin Li // RUN: %clang_cc1 %s -std=c++1y -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck --check-prefix=MACHO --check-prefix=ALL %s
3*67e74705SXin Li 
4*67e74705SXin Li // ALL: ; ModuleID
5*67e74705SXin Li 
6*67e74705SXin Li extern "C" int foo();
7*67e74705SXin Li 
8*67e74705SXin Li template<typename T> struct A { static int a; };
9*67e74705SXin Li template<typename T> int A<T>::a = foo();
10*67e74705SXin Li 
11*67e74705SXin Li // ALLK-NOT: @_ZN1AIcE1aE
12*67e74705SXin Li template<> int A<char>::a;
13*67e74705SXin Li 
14*67e74705SXin Li // ALL: @_ZN1AIbE1aE = global i32 10
15*67e74705SXin Li template<> int A<bool>::a = 10;
16*67e74705SXin Li 
17*67e74705SXin Li // ALL: @llvm.global_ctors = appending global [8 x { i32, void ()*, i8* }]
18*67e74705SXin Li 
19*67e74705SXin Li // ELF: [{ i32, void ()*, i8* } { i32 65535, void ()* @[[unordered1:[^,]*]], i8* bitcast (i32* @_ZN1AIsE1aE to i8*) },
20*67e74705SXin Li // MACHO: [{ i32, void ()*, i8* } { i32 65535, void ()* @[[unordered1:[^,]*]], i8* null },
21*67e74705SXin Li 
22*67e74705SXin Li // ELF:  { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered2:[^,]*]], i8* bitcast (i16* @_Z1xIsE to i8*) },
23*67e74705SXin Li // MACHO:  { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered2:[^,]*]], i8* null },
24*67e74705SXin Li 
25*67e74705SXin Li // ELF:  { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered3:[^,]*]], i8* bitcast (i32* @_ZN2ns1aIiE1iE to i8*) },
26*67e74705SXin Li // MACHO:  { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered3:[^,]*]], i8* null },
27*67e74705SXin Li 
28*67e74705SXin Li // ELF:  { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered4:[^,]*]], i8* bitcast (i32* @_ZN2ns1b1iIiEE to i8*) },
29*67e74705SXin Li // MACHO:  { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered4:[^,]*]], i8* null },
30*67e74705SXin Li 
31*67e74705SXin Li // ELF:  { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered5:[^,]*]], i8* bitcast (i32* @_ZN1AIvE1aE to i8*) },
32*67e74705SXin Li // MACHO:  { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered5:[^,]*]], i8* null },
33*67e74705SXin Li 
34*67e74705SXin Li // ELF:  { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered6:[^,]*]], i8* @_Z1xIcE },
35*67e74705SXin Li // MACHO:  { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered6:[^,]*]], i8* null },
36*67e74705SXin Li 
37*67e74705SXin Li // ALL:  { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered7:[^,]*]], i8* null },
38*67e74705SXin Li 
39*67e74705SXin Li // ALL:  { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp, i8* null }]
40*67e74705SXin Li 
41*67e74705SXin Li template int A<short>::a;  // Unordered
42*67e74705SXin Li int b = foo();
43*67e74705SXin Li int c = foo();
44*67e74705SXin Li int d = A<void>::a; // Unordered
45*67e74705SXin Li 
46*67e74705SXin Li // An explicit specialization is ordered, and goes in __GLOBAL_sub_I_static_member_variable_explicit_specialization.cpp.
47*67e74705SXin Li template<> struct A<int> { static int a; };
48*67e74705SXin Li int A<int>::a = foo();
49*67e74705SXin Li 
50*67e74705SXin Li template<typename T> struct S { static T x; static T y; };
51*67e74705SXin Li template<> int S<int>::x = foo();
52*67e74705SXin Li template<> int S<int>::y = S<int>::x;
53*67e74705SXin Li 
54*67e74705SXin Li template<typename T> T x = foo();
55*67e74705SXin Li template short x<short>;  // Unordered
56*67e74705SXin Li template<> int x<int> = foo();
57*67e74705SXin Li int e = x<char>; // Unordered
58*67e74705SXin Li 
59*67e74705SXin Li namespace ns {
60*67e74705SXin Li template <typename T> struct a {
61*67e74705SXin Li   static int i;
62*67e74705SXin Li };
63*67e74705SXin Li template<typename T> int a<T>::i = foo();
64*67e74705SXin Li template struct a<int>;
65*67e74705SXin Li 
66*67e74705SXin Li struct b {
67*67e74705SXin Li   template <typename T> static T i;
68*67e74705SXin Li };
69*67e74705SXin Li template<typename T> T b::i = foo();
70*67e74705SXin Li template int b::i<int>;
71*67e74705SXin Li }
72*67e74705SXin Li 
73*67e74705SXin Li namespace {
74*67e74705SXin Li template<typename T> struct Internal { static int a; };
75*67e74705SXin Li template<typename T> int Internal<T>::a = foo();
76*67e74705SXin Li }
77*67e74705SXin Li int *use_internal_a = &Internal<int>::a;
78*67e74705SXin Li 
79*67e74705SXin Li // ALL: define internal void @[[unordered1]](
80*67e74705SXin Li // ALL: call i32 @foo()
81*67e74705SXin Li // ALL: store {{.*}} @_ZN1AIsE1aE
82*67e74705SXin Li // ALL: ret
83*67e74705SXin Li 
84*67e74705SXin Li // ALL: define internal void @[[unordered2]](
85*67e74705SXin Li // ALL: call i32 @foo()
86*67e74705SXin Li // ALL: store {{.*}} @_Z1xIsE
87*67e74705SXin Li // ALL: ret
88*67e74705SXin Li 
89*67e74705SXin Li // ALL: define internal void @[[unordered3]](
90*67e74705SXin Li // ALL: call i32 @foo()
91*67e74705SXin Li // ALL: store {{.*}} @_ZN2ns1aIiE1iE
92*67e74705SXin Li // ALL: ret
93*67e74705SXin Li 
94*67e74705SXin Li // ALL: define internal void @[[unordered4]](
95*67e74705SXin Li // ALL: call i32 @foo()
96*67e74705SXin Li // ALL: store {{.*}} @_ZN2ns1b1iIiEE
97*67e74705SXin Li // ALL: ret
98*67e74705SXin Li 
99*67e74705SXin Li // ALL: define internal void @[[unordered5]](
100*67e74705SXin Li // ALL: call i32 @foo()
101*67e74705SXin Li // ALL: store {{.*}} @_ZN1AIvE1aE
102*67e74705SXin Li // ALL: ret
103*67e74705SXin Li 
104*67e74705SXin Li // ALL: define internal void @[[unordered6]](
105*67e74705SXin Li // ALL: call i32 @foo()
106*67e74705SXin Li // ALL: store {{.*}} @_Z1xIcE
107*67e74705SXin Li // ALL: ret
108*67e74705SXin Li 
109*67e74705SXin Li // ALL: define internal void @[[unordered7]](
110*67e74705SXin Li // ALL: call i32 @foo()
111*67e74705SXin Li // ALL: store {{.*}} @_ZN12_GLOBAL__N_18InternalIiE1aE
112*67e74705SXin Li // ALL: ret
113*67e74705SXin Li 
114*67e74705SXin Li // ALL: define internal void @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp()
115*67e74705SXin Li //   We call unique stubs for every ordered dynamic initializer in the TU.
116*67e74705SXin Li // ALL: call
117*67e74705SXin Li // ALL: call
118*67e74705SXin Li // ALL: call
119*67e74705SXin Li // ALL: call
120*67e74705SXin Li // ALL: call
121*67e74705SXin Li // ALL: call
122*67e74705SXin Li // ALL: call
123*67e74705SXin Li // ALL: call
124*67e74705SXin Li // ALL-NOT: call
125*67e74705SXin Li // ALL: ret
126