• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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