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