1*67e74705SXin Li // RUN: %clang_cc1 -fms-extensions -fno-threadsafe-statics -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
2*67e74705SXin Li
3*67e74705SXin Li // CHECK: @llvm.global_ctors = appending global [5 x { i32, void ()*, i8* }] [
4*67e74705SXin Li // CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Eselectany1@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"\01?selectany1@@3US@@A", i32 0, i32 0) },
5*67e74705SXin Li // CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Eselectany2@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"\01?selectany2@@3US@@A", i32 0, i32 0) },
6*67e74705SXin Li // CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Es@?$ExportedTemplate@H@@2US@@A@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"\01?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0) },
7*67e74705SXin Li // CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ", i8* bitcast (%class.A* @"\01?foo@?$B@H@@2VA@@A" to i8*) },
8*67e74705SXin Li // CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp, i8* null }
9*67e74705SXin Li // CHECK: ]
10*67e74705SXin Li
11*67e74705SXin Li struct S {
12*67e74705SXin Li S();
13*67e74705SXin Li ~S();
14*67e74705SXin Li };
15*67e74705SXin Li
16*67e74705SXin Li S s;
17*67e74705SXin Li
18*67e74705SXin Li // CHECK: define internal void @"\01??__Es@@YAXXZ"()
19*67e74705SXin Li // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"
20*67e74705SXin Li // CHECK: call i32 @atexit(void ()* @"\01??__Fs@@YAXXZ")
21*67e74705SXin Li // CHECK: ret void
22*67e74705SXin Li
23*67e74705SXin Li // CHECK: define internal void @"\01??__Fs@@YAXXZ"()
24*67e74705SXin Li // CHECK: call x86_thiscallcc void @"\01??1S@@QAE@XZ"
25*67e74705SXin Li // CHECK: ret void
26*67e74705SXin Li
27*67e74705SXin Li // These globals should have initializers comdat associative with the global.
28*67e74705SXin Li // See @llvm.global_ctors above.
29*67e74705SXin Li __declspec(selectany) S selectany1;
30*67e74705SXin Li __declspec(selectany) S selectany2;
31*67e74705SXin Li // CHECK: define linkonce_odr void @"\01??__Eselectany1@@YAXXZ"() {{.*}} comdat
32*67e74705SXin Li // CHECK-NOT: @"\01??_Bselectany1
33*67e74705SXin Li // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"
34*67e74705SXin Li // CHECK: ret void
35*67e74705SXin Li // CHECK: define linkonce_odr void @"\01??__Eselectany2@@YAXXZ"() {{.*}} comdat
36*67e74705SXin Li // CHECK-NOT: @"\01??_Bselectany2
37*67e74705SXin Li // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"
38*67e74705SXin Li // CHECK: ret void
39*67e74705SXin Li
40*67e74705SXin Li // The implicitly instantiated static data member should have initializer
41*67e74705SXin Li // comdat associative with the global.
42*67e74705SXin Li template <typename T> struct __declspec(dllexport) ExportedTemplate {
43*67e74705SXin Li static S s;
44*67e74705SXin Li };
45*67e74705SXin Li template <typename T> S ExportedTemplate<T>::s;
useExportedTemplate(ExportedTemplate<int> x)46*67e74705SXin Li void useExportedTemplate(ExportedTemplate<int> x) {
47*67e74705SXin Li (void)x.s;
48*67e74705SXin Li }
49*67e74705SXin Li
StaticLocal()50*67e74705SXin Li void StaticLocal() {
51*67e74705SXin Li static S TheS;
52*67e74705SXin Li }
53*67e74705SXin Li
54*67e74705SXin Li // CHECK-LABEL: define void @"\01?StaticLocal@@YAXXZ"()
55*67e74705SXin Li // CHECK: load i32, i32* @"\01?$S1@?1??StaticLocal@@YAXXZ@4IA"
56*67e74705SXin Li // CHECK: store i32 {{.*}}, i32* @"\01?$S1@?1??StaticLocal@@YAXXZ@4IA"
57*67e74705SXin Li // CHECK: ret
58*67e74705SXin Li
MultipleStatics()59*67e74705SXin Li void MultipleStatics() {
60*67e74705SXin Li static S S1;
61*67e74705SXin Li static S S2;
62*67e74705SXin Li static S S3;
63*67e74705SXin Li static S S4;
64*67e74705SXin Li static S S5;
65*67e74705SXin Li static S S6;
66*67e74705SXin Li static S S7;
67*67e74705SXin Li static S S8;
68*67e74705SXin Li static S S9;
69*67e74705SXin Li static S S10;
70*67e74705SXin Li static S S11;
71*67e74705SXin Li static S S12;
72*67e74705SXin Li static S S13;
73*67e74705SXin Li static S S14;
74*67e74705SXin Li static S S15;
75*67e74705SXin Li static S S16;
76*67e74705SXin Li static S S17;
77*67e74705SXin Li static S S18;
78*67e74705SXin Li static S S19;
79*67e74705SXin Li static S S20;
80*67e74705SXin Li static S S21;
81*67e74705SXin Li static S S22;
82*67e74705SXin Li static S S23;
83*67e74705SXin Li static S S24;
84*67e74705SXin Li static S S25;
85*67e74705SXin Li static S S26;
86*67e74705SXin Li static S S27;
87*67e74705SXin Li static S S28;
88*67e74705SXin Li static S S29;
89*67e74705SXin Li static S S30;
90*67e74705SXin Li static S S31;
91*67e74705SXin Li static S S32;
92*67e74705SXin Li static S S33;
93*67e74705SXin Li static S S34;
94*67e74705SXin Li static S S35;
95*67e74705SXin Li }
96*67e74705SXin Li // CHECK-LABEL: define void @"\01?MultipleStatics@@YAXXZ"()
97*67e74705SXin Li // CHECK: load i32, i32* @"\01?$S1@?1??MultipleStatics@@YAXXZ@4IA"
98*67e74705SXin Li // CHECK: and i32 {{.*}}, 1
99*67e74705SXin Li // CHECK: and i32 {{.*}}, 2
100*67e74705SXin Li // CHECK: and i32 {{.*}}, 4
101*67e74705SXin Li // CHECK: and i32 {{.*}}, 8
102*67e74705SXin Li // CHECK: and i32 {{.*}}, 16
103*67e74705SXin Li // ...
104*67e74705SXin Li // CHECK: and i32 {{.*}}, -2147483648
105*67e74705SXin Li // CHECK: load i32, i32* @"\01?$S1@?1??MultipleStatics@@[email protected]"
106*67e74705SXin Li // CHECK: and i32 {{.*}}, 1
107*67e74705SXin Li // CHECK: and i32 {{.*}}, 2
108*67e74705SXin Li // CHECK: and i32 {{.*}}, 4
109*67e74705SXin Li // CHECK: ret
110*67e74705SXin Li
111*67e74705SXin Li // Force WeakODRLinkage by using templates
112*67e74705SXin Li class A {
113*67e74705SXin Li public:
A()114*67e74705SXin Li A() {}
~A()115*67e74705SXin Li ~A() {}
116*67e74705SXin Li int a;
117*67e74705SXin Li };
118*67e74705SXin Li
119*67e74705SXin Li template<typename T>
120*67e74705SXin Li class B {
121*67e74705SXin Li public:
122*67e74705SXin Li static A foo;
123*67e74705SXin Li };
124*67e74705SXin Li
125*67e74705SXin Li template<typename T> A B<T>::foo;
126*67e74705SXin Li
UnreachableStatic()127*67e74705SXin Li inline S &UnreachableStatic() {
128*67e74705SXin Li if (0) {
129*67e74705SXin Li static S s; // bit 1
130*67e74705SXin Li return s;
131*67e74705SXin Li }
132*67e74705SXin Li static S s; // bit 2
133*67e74705SXin Li return s;
134*67e74705SXin Li }
135*67e74705SXin Li
136*67e74705SXin Li // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.S* @"\01?UnreachableStatic@@YAAAUS@@XZ"() {{.*}} comdat
137*67e74705SXin Li // CHECK: and i32 {{.*}}, 2
138*67e74705SXin Li // CHECK: or i32 {{.*}}, 2
139*67e74705SXin Li // CHECK: ret
140*67e74705SXin Li
getS()141*67e74705SXin Li inline S &getS() {
142*67e74705SXin Li static S TheS;
143*67e74705SXin Li return TheS;
144*67e74705SXin Li }
145*67e74705SXin Li
146*67e74705SXin Li // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.S* @"\01?getS@@YAAAUS@@XZ"() {{.*}} comdat
147*67e74705SXin Li // CHECK: load i32, i32* @"\01??_B?1??getS@@YAAAUS@@XZ@51"
148*67e74705SXin Li // CHECK: and i32 {{.*}}, 1
149*67e74705SXin Li // CHECK: icmp ne i32 {{.*}}, 0
150*67e74705SXin Li // CHECK: br i1
151*67e74705SXin Li // init:
152*67e74705SXin Li // CHECK: or i32 {{.*}}, 1
153*67e74705SXin Li // CHECK: store i32 {{.*}}, i32* @"\01??_B?1??getS@@YAAAUS@@XZ@51"
154*67e74705SXin Li // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"(%struct.S* @"\01?TheS@?1??getS@@YAAAUS@@XZ@4U2@A")
155*67e74705SXin Li // CHECK: call i32 @atexit(void ()* @"\01??__FTheS@?1??getS@@YAAAUS@@XZ@YAXXZ")
156*67e74705SXin Li // CHECK: br label
157*67e74705SXin Li // init.end:
158*67e74705SXin Li // CHECK: ret %struct.S* @"\01?TheS@?1??getS@@YAAAUS@@XZ@4U2@A"
159*67e74705SXin Li
enum_in_function()160*67e74705SXin Li inline int enum_in_function() {
161*67e74705SXin Li // CHECK-LABEL: define linkonce_odr i32 @"\01?enum_in_function@@YAHXZ"() {{.*}} comdat
162*67e74705SXin Li static enum e { foo, bar, baz } x;
163*67e74705SXin Li // CHECK: @"\01?x@?1??enum_in_function@@YAHXZ@4W4e@?1??1@YAHXZ@A"
164*67e74705SXin Li static int y;
165*67e74705SXin Li // CHECK: @"\01?y@?1??enum_in_function@@YAHXZ@4HA"
166*67e74705SXin Li return x + y;
167*67e74705SXin Li };
168*67e74705SXin Li
169*67e74705SXin Li struct T {
170*67e74705SXin Li enum e { foo, bar, baz };
enum_in_structT171*67e74705SXin Li int enum_in_struct() {
172*67e74705SXin Li // CHECK-LABEL: define linkonce_odr x86_thiscallcc i32 @"\01?enum_in_struct@T@@QAEHXZ"({{.*}}) {{.*}} comdat
173*67e74705SXin Li static int x;
174*67e74705SXin Li // CHECK: @"\01?x@?1??enum_in_struct@T@@QAEHXZ@4HA"
175*67e74705SXin Li return x++;
176*67e74705SXin Li }
177*67e74705SXin Li };
178*67e74705SXin Li
switch_test(int x)179*67e74705SXin Li inline int switch_test(int x) {
180*67e74705SXin Li // CHECK-LABEL: define linkonce_odr i32 @"\01?switch_test@@YAHH@Z"(i32 %x) {{.*}} comdat
181*67e74705SXin Li switch (x) {
182*67e74705SXin Li static int a;
183*67e74705SXin Li // CHECK: @"\01?a@?3??switch_test@@YAHH@Z@4HA"
184*67e74705SXin Li case 0:
185*67e74705SXin Li a++;
186*67e74705SXin Li return 1;
187*67e74705SXin Li case 1:
188*67e74705SXin Li static int b;
189*67e74705SXin Li // CHECK: @"\01?b@?3??switch_test@@YAHH@Z@4HA"
190*67e74705SXin Li return b++;
191*67e74705SXin Li case 2: {
192*67e74705SXin Li static int c;
193*67e74705SXin Li // CHECK: @"\01?c@?4??switch_test@@YAHH@Z@4HA"
194*67e74705SXin Li return b + c++;
195*67e74705SXin Li }
196*67e74705SXin Li };
197*67e74705SXin Li }
198*67e74705SXin Li
199*67e74705SXin Li int f();
switch_test2()200*67e74705SXin Li inline void switch_test2() {
201*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @"\01?switch_test2@@YAXXZ"() {{.*}} comdat
202*67e74705SXin Li // CHECK: @"\01?x@?2??switch_test2@@YAXXZ@4HA"
203*67e74705SXin Li switch (1) default: static int x = f();
204*67e74705SXin Li }
205*67e74705SXin Li
206*67e74705SXin Li namespace DynamicDLLImportInitVSMangling {
207*67e74705SXin Li // Failing to pop the ExprEvalContexts when instantiating a dllimport var with
208*67e74705SXin Li // dynamic initializer would cause subsequent static local numberings to be
209*67e74705SXin Li // incorrect.
210*67e74705SXin Li struct NonPOD { NonPOD(); };
211*67e74705SXin Li template <typename T> struct A { static NonPOD x; };
212*67e74705SXin Li template <typename T> NonPOD A<T>::x;
213*67e74705SXin Li template struct __declspec(dllimport) A<int>;
214*67e74705SXin Li
switch_test3()215*67e74705SXin Li inline int switch_test3() {
216*67e74705SXin Li // CHECK-LABEL: define linkonce_odr i32 @"\01?switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ"() {{.*}} comdat
217*67e74705SXin Li static int local;
218*67e74705SXin Li // CHECK: @"\01?local@?1??switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ@4HA"
219*67e74705SXin Li return local++;
220*67e74705SXin Li }
221*67e74705SXin Li }
222*67e74705SXin Li
force_usage()223*67e74705SXin Li void force_usage() {
224*67e74705SXin Li UnreachableStatic();
225*67e74705SXin Li getS();
226*67e74705SXin Li (void)B<int>::foo; // (void) - force usage
227*67e74705SXin Li enum_in_function();
228*67e74705SXin Li (void)&T::enum_in_struct;
229*67e74705SXin Li switch_test(1);
230*67e74705SXin Li switch_test2();
231*67e74705SXin Li DynamicDLLImportInitVSMangling::switch_test3();
232*67e74705SXin Li }
233*67e74705SXin Li
234*67e74705SXin Li // CHECK: define linkonce_odr void @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ"() {{.*}} comdat
235*67e74705SXin Li // CHECK-NOT: and
236*67e74705SXin Li // CHECK-NOT: ?_Bfoo@
237*67e74705SXin Li // CHECK: call x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"
238*67e74705SXin Li // CHECK: call i32 @atexit(void ()* @"\01??__Ffoo@?$B@H@@2VA@@A@YAXXZ")
239*67e74705SXin Li // CHECK: ret void
240*67e74705SXin Li
241*67e74705SXin Li // CHECK: define linkonce_odr x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"({{.*}}) {{.*}} comdat
242*67e74705SXin Li
243*67e74705SXin Li // CHECK: define linkonce_odr x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}}) {{.*}} comdat
244*67e74705SXin Li
245*67e74705SXin Li // CHECK: define internal void @"\01??__Ffoo@?$B@H@@2VA@@A@YAXXZ"
246*67e74705SXin Li // CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"{{.*}}foo
247*67e74705SXin Li // CHECK: ret void
248*67e74705SXin Li
249*67e74705SXin Li // CHECK: define internal void @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp()
250*67e74705SXin Li // CHECK: call void @"\01??__Es@@YAXXZ"()
251*67e74705SXin Li // CHECK: ret void
252