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