xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
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