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 
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 
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:
100   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 
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 
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 
146 void force_usage() {
147   UnreachableStatic();
148   getS();
149   (void)B<int>::foo;  // (void) - force usage
150 }
151 
152 // CHECK: define linkonce_odr void @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ"()
153 // CHECK-NOT: and
154 // CHECK-NOT: ?_Bfoo@
155 // CHECK: call x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"
156 // CHECK: call i32 @atexit(void ()* @"\01??__Ffoo@?$B@H@@2VA@@A@YAXXZ")
157 // CHECK: ret void
158 
159 // CHECK: define linkonce_odr x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"
160 
161 // CHECK: define linkonce_odr x86_thiscallcc void @"\01??1A@@QAE@XZ"
162 
163 // CHECK: define internal void @"\01??__Ffoo@?$B@H@@2VA@@A@YAXXZ"
164 // CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"{{.*}}foo
165 // CHECK: ret void
166 
167 // CHECK: define internal void @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp()
168 // CHECK: call void @"\01??__Es@@YAXXZ"()
169 // CHECK: ret void
170