1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -emit-llvm %s -o - -mconstructor-aliases -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s 2*f4a2713aSLionel Sambuc 3*f4a2713aSLionel Sambuc // CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()* }] 4*f4a2713aSLionel Sambuc // CHECK: [{ i32, void ()* } { i32 65535, void ()* @"\01??__Efoo@?$B@H@@YAXXZ" }, 5*f4a2713aSLionel Sambuc // CHECK: { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }] 6*f4a2713aSLionel Sambuc 7*f4a2713aSLionel Sambuc struct S { 8*f4a2713aSLionel Sambuc S(); 9*f4a2713aSLionel Sambuc ~S(); 10*f4a2713aSLionel Sambuc }; 11*f4a2713aSLionel Sambuc 12*f4a2713aSLionel Sambuc S s; 13*f4a2713aSLionel Sambuc 14*f4a2713aSLionel Sambuc // CHECK: define internal void @"\01??__Es@@YAXXZ"() [[NUW:#[0-9]+]] 15*f4a2713aSLionel Sambuc // CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ" 16*f4a2713aSLionel Sambuc // CHECK: call i32 @atexit(void ()* @"\01??__Fs@@YAXXZ") 17*f4a2713aSLionel Sambuc // CHECK: ret void 18*f4a2713aSLionel Sambuc 19*f4a2713aSLionel Sambuc // CHECK: define internal void @"\01??__Fs@@YAXXZ"() [[NUW]] { 20*f4a2713aSLionel Sambuc // CHECK: call x86_thiscallcc void @"\01??1S@@QAE@XZ" 21*f4a2713aSLionel Sambuc // CHECK: ret void 22*f4a2713aSLionel Sambuc 23*f4a2713aSLionel Sambuc void StaticLocal() { 24*f4a2713aSLionel Sambuc static S TheS; 25*f4a2713aSLionel Sambuc } 26*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @"\01?StaticLocal@@YAXXZ"() 27*f4a2713aSLionel Sambuc // CHECK: load i32* @"\01?$S1@?1??StaticLocal@@YAXXZ@4IA" 28*f4a2713aSLionel Sambuc // CHECK: store i32 {{.*}}, i32* @"\01?$S1@?1??StaticLocal@@YAXXZ@4IA" 29*f4a2713aSLionel Sambuc // CHECK: ret 30*f4a2713aSLionel Sambuc 31*f4a2713aSLionel Sambuc void MultipleStatics() { 32*f4a2713aSLionel Sambuc static S S1; 33*f4a2713aSLionel Sambuc static S S2; 34*f4a2713aSLionel Sambuc static S S3; 35*f4a2713aSLionel Sambuc static S S4; 36*f4a2713aSLionel Sambuc static S S5; 37*f4a2713aSLionel Sambuc static S S6; 38*f4a2713aSLionel Sambuc static S S7; 39*f4a2713aSLionel Sambuc static S S8; 40*f4a2713aSLionel Sambuc static S S9; 41*f4a2713aSLionel Sambuc static S S10; 42*f4a2713aSLionel Sambuc static S S11; 43*f4a2713aSLionel Sambuc static S S12; 44*f4a2713aSLionel Sambuc static S S13; 45*f4a2713aSLionel Sambuc static S S14; 46*f4a2713aSLionel Sambuc static S S15; 47*f4a2713aSLionel Sambuc static S S16; 48*f4a2713aSLionel Sambuc static S S17; 49*f4a2713aSLionel Sambuc static S S18; 50*f4a2713aSLionel Sambuc static S S19; 51*f4a2713aSLionel Sambuc static S S20; 52*f4a2713aSLionel Sambuc static S S21; 53*f4a2713aSLionel Sambuc static S S22; 54*f4a2713aSLionel Sambuc static S S23; 55*f4a2713aSLionel Sambuc static S S24; 56*f4a2713aSLionel Sambuc static S S25; 57*f4a2713aSLionel Sambuc static S S26; 58*f4a2713aSLionel Sambuc static S S27; 59*f4a2713aSLionel Sambuc static S S28; 60*f4a2713aSLionel Sambuc static S S29; 61*f4a2713aSLionel Sambuc static S S30; 62*f4a2713aSLionel Sambuc static S S31; 63*f4a2713aSLionel Sambuc static S S32; 64*f4a2713aSLionel Sambuc static S S33; 65*f4a2713aSLionel Sambuc static S S34; 66*f4a2713aSLionel Sambuc static S S35; 67*f4a2713aSLionel Sambuc } 68*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @"\01?MultipleStatics@@YAXXZ"() 69*f4a2713aSLionel Sambuc // CHECK: load i32* @"\01?$S1@?1??MultipleStatics@@YAXXZ@4IA" 70*f4a2713aSLionel Sambuc // CHECK: and i32 {{.*}}, 1 71*f4a2713aSLionel Sambuc // CHECK: and i32 {{.*}}, 2 72*f4a2713aSLionel Sambuc // CHECK: and i32 {{.*}}, 4 73*f4a2713aSLionel Sambuc // CHECK: and i32 {{.*}}, 8 74*f4a2713aSLionel Sambuc // CHECK: and i32 {{.*}}, 16 75*f4a2713aSLionel Sambuc // ... 76*f4a2713aSLionel Sambuc // CHECK: and i32 {{.*}}, -2147483648 77*f4a2713aSLionel Sambuc // CHECK: load i32* @"\01?$S1@?1??MultipleStatics@@YAXXZ@4IA1" 78*f4a2713aSLionel Sambuc // CHECK: and i32 {{.*}}, 1 79*f4a2713aSLionel Sambuc // CHECK: and i32 {{.*}}, 2 80*f4a2713aSLionel Sambuc // CHECK: and i32 {{.*}}, 4 81*f4a2713aSLionel Sambuc // CHECK: ret 82*f4a2713aSLionel Sambuc 83*f4a2713aSLionel Sambuc // Force WeakODRLinkage by using templates 84*f4a2713aSLionel Sambuc class A { 85*f4a2713aSLionel Sambuc public: 86*f4a2713aSLionel Sambuc A() {} 87*f4a2713aSLionel Sambuc ~A() {} 88*f4a2713aSLionel Sambuc }; 89*f4a2713aSLionel Sambuc 90*f4a2713aSLionel Sambuc template<typename T> 91*f4a2713aSLionel Sambuc class B { 92*f4a2713aSLionel Sambuc public: 93*f4a2713aSLionel Sambuc static A foo; 94*f4a2713aSLionel Sambuc }; 95*f4a2713aSLionel Sambuc 96*f4a2713aSLionel Sambuc template<typename T> A B<T>::foo; 97*f4a2713aSLionel Sambuc 98*f4a2713aSLionel Sambuc inline S &UnreachableStatic() { 99*f4a2713aSLionel Sambuc if (0) { 100*f4a2713aSLionel Sambuc static S s; // bit 1 101*f4a2713aSLionel Sambuc return s; 102*f4a2713aSLionel Sambuc } 103*f4a2713aSLionel Sambuc static S s; // bit 2 104*f4a2713aSLionel Sambuc return s; 105*f4a2713aSLionel Sambuc } 106*f4a2713aSLionel Sambuc 107*f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr %struct.S* @"\01?UnreachableStatic@@YAAAUS@@XZ"() 108*f4a2713aSLionel Sambuc // CHECK: and i32 {{.*}}, 2 109*f4a2713aSLionel Sambuc // CHECK: or i32 {{.*}}, 2 110*f4a2713aSLionel Sambuc // CHECK: ret 111*f4a2713aSLionel Sambuc 112*f4a2713aSLionel Sambuc inline S &getS() { 113*f4a2713aSLionel Sambuc static S TheS; 114*f4a2713aSLionel Sambuc return TheS; 115*f4a2713aSLionel Sambuc } 116*f4a2713aSLionel Sambuc 117*f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr %struct.S* @"\01?getS@@YAAAUS@@XZ" 118*f4a2713aSLionel Sambuc // CHECK: load i32* @"\01??_B?1??getS@@YAAAUS@@XZ@51" 119*f4a2713aSLionel Sambuc // CHECK: and i32 {{.*}}, 1 120*f4a2713aSLionel Sambuc // CHECK: icmp ne i32 {{.*}}, 0 121*f4a2713aSLionel Sambuc // CHECK: br i1 122*f4a2713aSLionel Sambuc // init: 123*f4a2713aSLionel Sambuc // CHECK: or i32 {{.*}}, 1 124*f4a2713aSLionel Sambuc // CHECK: store i32 {{.*}}, i32* @"\01??_B?1??getS@@YAAAUS@@XZ@51" 125*f4a2713aSLionel Sambuc // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"(%struct.S* @"\01?TheS@?1??getS@@YAAAUS@@XZ@4U2@A") 126*f4a2713aSLionel Sambuc // CHECK: call i32 @atexit(void ()* @"\01??__FTheS@?1??getS@@YAAAUS@@XZ@YAXXZ") 127*f4a2713aSLionel Sambuc // CHECK: br label 128*f4a2713aSLionel Sambuc // init.end: 129*f4a2713aSLionel Sambuc // CHECK: ret %struct.S* @"\01?TheS@?1??getS@@YAAAUS@@XZ@4U2@A" 130*f4a2713aSLionel Sambuc 131*f4a2713aSLionel Sambuc void force_usage() { 132*f4a2713aSLionel Sambuc UnreachableStatic(); 133*f4a2713aSLionel Sambuc getS(); 134*f4a2713aSLionel Sambuc (void)B<int>::foo; // (void) - force usage 135*f4a2713aSLionel Sambuc } 136*f4a2713aSLionel Sambuc 137*f4a2713aSLionel Sambuc // CHECK: define internal void @"\01??__Efoo@?$B@H@@YAXXZ"() [[NUW]] 138*f4a2713aSLionel Sambuc // CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ" 139*f4a2713aSLionel Sambuc // CHECK: call i32 @atexit(void ()* @"\01??__Ffoo@?$B@H@@YAXXZ") 140*f4a2713aSLionel Sambuc // CHECK: ret void 141*f4a2713aSLionel Sambuc 142*f4a2713aSLionel Sambuc // CHECK: define linkonce_odr x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ" 143*f4a2713aSLionel Sambuc 144*f4a2713aSLionel Sambuc // CHECK: define linkonce_odr x86_thiscallcc void @"\01??1A@@QAE@XZ" 145*f4a2713aSLionel Sambuc 146*f4a2713aSLionel Sambuc // CHECK: define internal void @"\01??__Ffoo@?$B@H@@YAXXZ" 147*f4a2713aSLionel Sambuc // CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"{{.*}}foo 148*f4a2713aSLionel Sambuc // CHECK: ret void 149*f4a2713aSLionel Sambuc 150*f4a2713aSLionel Sambuc // CHECK: define internal void @_GLOBAL__I_a() [[NUW]] { 151*f4a2713aSLionel Sambuc // CHECK: call void @"\01??__Es@@YAXXZ"() 152*f4a2713aSLionel Sambuc // CHECK: ret void 153*f4a2713aSLionel Sambuc 154*f4a2713aSLionel Sambuc // CHECK: attributes [[NUW]] = { nounwind } 155