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 8struct S { 9 S(); 10 ~S(); 11}; 12 13S 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 37void 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 45void 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 98class A { 99 public: 100 A() {} 101 ~A() {} 102 int a; 103}; 104 105template<typename T> 106class B { 107 public: 108 static A foo; 109}; 110 111template<typename T> A B<T>::foo; 112 113inline 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 127inline 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 146inline 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 155struct T { 156 enum e { foo, bar, baz }; 157 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 165inline 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 185int f(); 186inline 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 192namespace 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 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 209void 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