1 | // RUN: %clang_cc1 -std=c++11 -triple i386-linux -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=ITANIUM |
2 | // RUN: %clang_cc1 -std=c++11 -triple x86_64-darwin -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=ITANIUM |
3 | // RUN: %clang_cc1 -std=c++11 -triple arm64-ehabi -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=ITANIUM |
4 | // RUN: %clang_cc1 -std=c++11 -triple i386-windows -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=MSABI --check-prefix=WIN32 |
5 | // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=MSABI --check-prefix=WIN64 |
6 | |
7 | // PR12219 |
8 | struct A { A(int); virtual ~A(); }; |
9 | struct B : A { using A::A; ~B(); }; |
10 | B::~B() {} |
11 | |
12 | B b(123); |
13 | |
14 | struct C { template<typename T> C(T); }; |
15 | struct D : C { using C::C; }; |
16 | D d(123); |
17 | |
18 | // ITANIUM-LABEL: define void @_ZN1BD2Ev |
19 | // ITANIUM-LABEL: define void @_ZN1BD1Ev |
20 | // ITANIUM-LABEL: define void @_ZN1BD0Ev |
21 | // WIN32-LABEL: define {{.*}}void @"??1B@@UAE@XZ" |
22 | // WIN64-LABEL: define {{.*}}void @"??1B@@UEAA@XZ" |
23 | |
24 | // ITANIUM-LABEL: define linkonce_odr void @_ZN1BCI11AEi( |
25 | // ITANIUM: call void @_ZN1BCI21AEi( |
26 | |
27 | // ITANIUM-LABEL: define linkonce_odr void @_ZN1DCI11CIiEET_( |
28 | // ITANIUM: call void @_ZN1DCI21CIiEET_( |
29 | |
30 | // WIN32-LABEL: define internal {{.*}} @"??0B@@QAE@H@Z"( |
31 | // WIN32: call {{.*}} @"??0A@@QAE@H@Z"( |
32 | // WIN64-LABEL: define internal {{.*}} @"??0B@@QEAA@H@Z"( |
33 | // WIN64: call {{.*}} @"??0A@@QEAA@H@Z"( |
34 | |
35 | // WIN32-LABEL: define internal {{.*}} @"??0D@@QAE@H@Z"( |
36 | // WIN32: call {{.*}} @"??$?0H@C@@QAE@H@Z" |
37 | // WIN64-LABEL: define internal {{.*}} @"??0D@@QEAA@H@Z"( |
38 | // WIN64: call {{.*}} @"??$?0H@C@@QEAA@H@Z" |
39 | |
40 | struct Q { Q(int); Q(const Q&); ~Q(); }; |
41 | struct Z { Z(); Z(int); ~Z(); int n; }; |
42 | |
43 | namespace noninline_nonvirt { |
44 | struct A { A(int, Q&&, void *__attribute__((pass_object_size(0)))); int n; }; |
45 | struct B : Z, A { Z z; using A::A; }; |
46 | B b(1, 2, &b); |
47 | // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init |
48 | // ITANIUM: call void @_ZN1QC1Ei({{.*}} %[[TMP:.*]], i32 2) |
49 | // ITANIUM: call void @_ZN17noninline_nonvirt1BCI1NS_1AEEiO1QPvU17pass_object_size0({{.*}} @_ZN17noninline_nonvirt1bE, i32 1, {{.*}} %[[TMP]], i8* {{.*}} @_ZN17noninline_nonvirt1bE{{.*}}, i{{32|64}} 12) |
50 | // ITANIUM: call void @_ZN1QD1Ev({{.*}} %[[TMP]]) |
51 | // ITANIUM: call i32 @__cxa_atexit( |
52 | |
53 | // Complete object ctor for B delegates to base object ctor. |
54 | // ITANIUM-LABEL: define linkonce_odr void @_ZN17noninline_nonvirt1BCI1NS_1AEEiO1QPvU17pass_object_size0( |
55 | // ITANIUM: call void @_ZN17noninline_nonvirt1BCI2NS_1AEEiO1QPvU17pass_object_size0({{.*}}, i32 {{.*}}, %{{.*}}* {{.*}}, i8* {{.*}}, i{{32|64}} {{.*}}) |
56 | |
57 | // In MSABI, we don't have ctor variants. B ctor forwards to A ctor. |
58 | // MSABI-LABEL: define internal {{.*}} @"??0B@noninline_nonvirt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}) |
59 | // MSABI: call {{.*}} @"??0Z@@Q{{AE|EAA}}@XZ"( |
60 | // MSABI: call {{.*}} @"??0A@noninline_nonvirt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}) |
61 | // MSABI: call {{.*}} @"??0Z@@Q{{AE|EAA}}@XZ"( |
62 | |
63 | struct C : B { using B::B; }; |
64 | C c(1, 2, &c); |
65 | // Complete object ctor for C delegates. |
66 | // ITANIUM-LABEL: define linkonce_odr void @_ZN17noninline_nonvirt1CCI1NS_1AEEiO1QPvU17pass_object_size0( |
67 | // ITANIUM: call void @_ZN17noninline_nonvirt1CCI2NS_1AEEiO1QPvU17pass_object_size0({{.*}}, i32 {{.*}}, %{{.*}}* {{.*}}, i8* {{.*}}, i{{32|64}} {{.*}}) |
68 | |
69 | // MSABI-LABEL: define internal {{.*}} @"??0C@noninline_nonvirt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}) |
70 | // MSABI: call {{.*}} @"??0B@noninline_nonvirt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}) |
71 | } |
72 | |
73 | namespace noninline_virt { |
74 | struct A { A(int, Q&&, void *__attribute__((pass_object_size(0)))); int n; }; |
75 | struct B : Z, virtual A { Z z; using A::A; }; |
76 | B b(1, 2, &b); |
77 | // Complete object ctor forwards to A ctor then constructs Zs. |
78 | // ITANIUM-LABEL: define linkonce_odr void @_ZN14noninline_virt1BCI1NS_1AEEiO1QPvU17pass_object_size0( |
79 | // ITANIUM: call void @_ZN14noninline_virt1AC2EiO1QPvU17pass_object_size0({{.*}} %{{.*}}, i32 %{{.*}}, %{{.*}}* {{.*}}, i8* {{.*}}, i{{32|64}} %{{.*}} |
80 | // ITANIUM: call void @_ZN1ZC2Ev( |
81 | // ITANIUM: store {{.*}} @_ZTVN14noninline_virt1BE |
82 | // ITANIUM: call void @_ZN1ZC1Ev( |
83 | |
84 | // MSABI-LABEL: define internal {{.*}} @"??0B@noninline_virt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}, i32 %{{.*}}) |
85 | // MSABI: %[[COMPLETE:.*]] = icmp ne |
86 | // MSABI: br i1 %[[COMPLETE]], |
87 | // MSABI: call {{.*}} @"??0A@noninline_virt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}) |
88 | // MSABI: br |
89 | // MSABI: call {{.*}} @"??0Z@@Q{{AE|EAA}}@XZ"( |
90 | // MSABI: call {{.*}} @"??0Z@@Q{{AE|EAA}}@XZ"( |
91 | |
92 | struct C : B { using B::B; }; |
93 | C c(1, 2, &c); |
94 | // Complete object ctor forwards to A ctor, then calls B's base inheriting |
95 | // constructor, which takes no arguments other than the this pointer and VTT. |
96 | // ITANIUM_LABEL: define linkonce_odr void @_ZN14noninline_virt1CCI1NS_1AEEiO1QPvU17pass_object_size0( |
97 | // ITANIUM: call void @_ZN14noninline_virt1AC2EiO1QPvU17pass_object_size0({{.*}} %{{.*}}, i32 %{{.*}}, %{{.*}}* {{.*}}, i8* %{{.*}}, i{{32|64}} %{{.*}}) |
98 | // ITANIUM: call void @_ZN14noninline_virt1BCI2NS_1AEEiO1QPvU17pass_object_size0(%{{.*}}* %{{.*}}, i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @_ZTTN14noninline_virt1CE, i64 0, i64 1)) |
99 | // ITANIUM: store {{.*}} @_ZTVN14noninline_virt1CE |
100 | |
101 | // C constructor forwards to B constructor and A constructor. We pass the args |
102 | // to both. FIXME: Can we pass undef here instead, for the base object |
103 | // constructor call? |
104 | // MSABI-LABEL: define internal {{.*}} @"??0C@noninline_virt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}, i32 %{{.*}}) |
105 | // MSABI: %[[COMPLETE:.*]] = icmp ne |
106 | // MSABI: br i1 %[[COMPLETE]], |
107 | // MSABI: call {{.*}} @"??0A@noninline_virt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}) |
108 | // MSABI: br |
109 | // MSABI: call {{.*}} @"??0B@noninline_virt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}, i32 0) |
110 | } |
111 | |
112 | // For MSABI only, check that inalloca arguments result in inlining. |
113 | namespace inalloca_nonvirt { |
114 | struct A { A(Q, int, Q, Q&&); int n; }; |
115 | struct B : Z, A { Z z; using A::A; }; |
116 | B b(1, 2, 3, 4); |
117 | // No inlining implied for Itanium. |
118 | // ITANIUM-LABEL: define linkonce_odr void @_ZN16inalloca_nonvirt1BCI1NS_1AEE1QiS1_OS1_( |
119 | // ITANIUM: call void @_ZN16inalloca_nonvirt1BCI2NS_1AEE1QiS1_OS1_( |
120 | |
121 | // MSABI-LABEL: define internal void @"??__Eb@inalloca_nonvirt@@YAXXZ"( |
122 | |
123 | // On Win32, the inalloca call can't be forwarded so we force inlining. |
124 | // WIN32: %[[TMP:.*]] = alloca |
125 | // WIN32: call i8* @llvm.stacksave() |
126 | // WIN32: %[[ARGMEM:.*]] = alloca inalloca |
127 | // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"(%{{.*}}* %[[TMP]], i32 4) |
128 | // WIN32: %[[ARG3:.*]] = getelementptr {{.*}} %[[ARGMEM]] |
129 | // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"({{.*}}* %[[ARG3]], i32 3) |
130 | // WIN32: %[[ARG1:.*]] = getelementptr {{.*}} %[[ARGMEM]] |
131 | // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"({{.*}}* %[[ARG1]], i32 1) |
132 | // WIN32: call {{.*}} @"??0Z@@QAE@XZ"( |
133 | // WIN32: %[[ARG2:.*]] = getelementptr {{.*}} %[[ARGMEM]] |
134 | // WIN32: store i32 2, i32* %[[ARG2]] |
135 | // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]] |
136 | // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]] |
137 | // WIN32: call {{.*}} @"??0A@inalloca_nonvirt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]]) |
138 | // WIN32: call void @llvm.stackrestore( |
139 | // WIN32: call {{.*}} @"??0Z@@QAE@XZ"( |
140 | // WIN32: call {{.*}} @"??1Q@@QAE@XZ"( |
141 | |
142 | // On Win64, the Q arguments would be destroyed in the callee. We don't yet |
143 | // support that in the non-inlined case, so we force inlining. |
144 | // WIN64: %[[TMP:.*]] = alloca |
145 | // WIN64: %[[ARG3:.*]] = alloca |
146 | // WIN64: %[[ARG1:.*]] = alloca |
147 | // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[TMP]], i32 4) |
148 | // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[ARG3]], i32 3) |
149 | // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[ARG1]], i32 1) |
150 | // WIN64: call {{.*}} @"??0Z@@QEAA@XZ"( |
151 | // WIN64: call {{.*}} @"??0A@inalloca_nonvirt@@QEAA@UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]]) |
152 | // WIN64: call {{.*}} @"??0Z@@QEAA@XZ"( |
153 | // WIN64: call void @"??1Q@@QEAA@XZ"({{.*}}* %[[TMP]]) |
154 | |
155 | struct C : B { using B::B; }; |
156 | C c(1, 2, 3, 4); |
157 | // MSABI-LABEL: define internal void @"??__Ec@inalloca_nonvirt@@YAXXZ"( |
158 | |
159 | // On Win32, the inalloca call can't be forwarded so we force inlining. |
160 | // WIN32: %[[TMP:.*]] = alloca |
161 | // WIN32: call i8* @llvm.stacksave() |
162 | // WIN32: %[[ARGMEM:.*]] = alloca inalloca |
163 | // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"(%{{.*}}* %[[TMP]], i32 4) |
164 | // WIN32: %[[ARG3:.*]] = getelementptr {{.*}} %[[ARGMEM]] |
165 | // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"({{.*}}* %[[ARG3]], i32 3) |
166 | // WIN32: %[[ARG1:.*]] = getelementptr {{.*}} %[[ARGMEM]] |
167 | // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"({{.*}}* %[[ARG1]], i32 1) |
168 | // WIN32: call {{.*}} @"??0Z@@QAE@XZ"( |
169 | // WIN32: %[[ARG2:.*]] = getelementptr {{.*}} %[[ARGMEM]] |
170 | // WIN32: store i32 2, i32* %[[ARG2]] |
171 | // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]] |
172 | // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]] |
173 | // WIN32: call {{.*}} @"??0A@inalloca_nonvirt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]]) |
174 | // WIN32: call void @llvm.stackrestore( |
175 | // WIN32: call {{.*}} @"??0Z@@QAE@XZ"( |
176 | // WIN32: call {{.*}} @"??1Q@@QAE@XZ"( |
177 | |
178 | // On Win64, the Q arguments would be destroyed in the callee. We don't yet |
179 | // support that in the non-inlined case, so we force inlining. |
180 | // WIN64: %[[TMP:.*]] = alloca |
181 | // WIN64: %[[ARG3:.*]] = alloca |
182 | // WIN64: %[[ARG1:.*]] = alloca |
183 | // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[TMP]], i32 4) |
184 | // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[ARG3]], i32 3) |
185 | // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[ARG1]], i32 1) |
186 | // WIN64: call {{.*}} @"??0Z@@QEAA@XZ"( |
187 | // WIN64: call {{.*}} @"??0A@inalloca_nonvirt@@QEAA@UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]]) |
188 | // WIN64: call {{.*}} @"??0Z@@QEAA@XZ"( |
189 | // WIN64: call void @"??1Q@@QEAA@XZ"({{.*}}* %[[TMP]]) |
190 | } |
191 | |
192 | namespace inalloca_virt { |
193 | struct A { A(Q, int, Q, Q&&); int n; }; |
194 | struct B : Z, virtual A { Z z; using A::A; }; |
195 | B b(1, 2, 3, 4); |
196 | |
197 | // MSABI-LABEL: define internal void @"??__Eb@inalloca_virt@@YAXXZ"( |
198 | |
199 | // On Win32, the inalloca call can't be forwarded so we force inlining. |
200 | // WIN32: %[[TMP:.*]] = alloca |
201 | // WIN32: call i8* @llvm.stacksave() |
202 | // WIN32: %[[ARGMEM:.*]] = alloca inalloca |
203 | // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"(%{{.*}}* %[[TMP]], i32 4) |
204 | // WIN32: %[[ARG3:.*]] = getelementptr {{.*}} %[[ARGMEM]] |
205 | // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"({{.*}}* %[[ARG3]], i32 3) |
206 | // WIN32: %[[ARG1:.*]] = getelementptr {{.*}} %[[ARGMEM]] |
207 | // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"({{.*}}* %[[ARG1]], i32 1) |
208 | // FIXME: It's dumb to round-trip this though memory and generate a branch. |
209 | // WIN32: store i32 1, i32* %[[IS_MOST_DERIVED_ADDR:.*]] |
210 | // WIN32: %[[IS_MOST_DERIVED:.*]] = load i32, i32* %[[IS_MOST_DERIVED_ADDR]] |
211 | // WIN32: %[[IS_MOST_DERIVED_i1:.*]] = icmp ne i32 %[[IS_MOST_DERIVED]], 0 |
212 | // WIN32: br i1 %[[IS_MOST_DERIVED_i1]] |
213 | // |
214 | // WIN32: store {{.*}} @"??_8B@inalloca_virt@@7B@" |
215 | // WIN32: %[[ARG2:.*]] = getelementptr {{.*}} %[[ARGMEM]] |
216 | // WIN32: store i32 2, i32* %[[ARG2]] |
217 | // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]] |
218 | // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]] |
219 | // WIN32: call {{.*}} @"??0A@inalloca_virt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]]) |
220 | // WIN32: call void @llvm.stackrestore( |
221 | // WIN32: br |
222 | // |
223 | // Note that if we jumped directly to here we would fail to stackrestore and |
224 | // destroy the parameters, but that's not actually possible. |
225 | // WIN32: call {{.*}} @"??0Z@@QAE@XZ"( |
226 | // WIN32: call {{.*}} @"??0Z@@QAE@XZ"( |
227 | // WIN32: call {{.*}} @"??1Q@@QAE@XZ"( |
228 | |
229 | // On Win64, the Q arguments would be destroyed in the callee. We don't yet |
230 | // support that in the non-inlined case, so we force inlining. |
231 | // WIN64: %[[TMP:.*]] = alloca |
232 | // WIN64: %[[ARG3:.*]] = alloca |
233 | // WIN64: %[[ARG1:.*]] = alloca |
234 | // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[TMP]], i32 4) |
235 | // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[ARG3]], i32 3) |
236 | // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[ARG1]], i32 1) |
237 | // WIN64: br i1 |
238 | // WIN64: call {{.*}} @"??0A@inalloca_virt@@QEAA@UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]]) |
239 | // WIN64: br |
240 | // WIN64: call {{.*}} @"??0Z@@QEAA@XZ"( |
241 | // WIN64: call {{.*}} @"??0Z@@QEAA@XZ"( |
242 | // WIN64: call void @"??1Q@@QEAA@XZ"({{.*}}* %[[TMP]]) |
243 | |
244 | struct C : B { using B::B; }; |
245 | C c(1, 2, 3, 4); |
246 | // ITANIUM-LABEL: define linkonce_odr void @_ZN13inalloca_virt1CD1Ev( |
247 | |
248 | // MSABI-LABEL: define internal void @"??__Ec@inalloca_virt@@YAXXZ"( |
249 | |
250 | // On Win32, the inalloca call can't be forwarded so we force inlining. |
251 | // WIN32: %[[TMP:.*]] = alloca |
252 | // WIN32: call i8* @llvm.stacksave() |
253 | // WIN32: %[[ARGMEM:.*]] = alloca inalloca |
254 | // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"(%{{.*}}* %[[TMP]], i32 4) |
255 | // WIN32: %[[ARG3:.*]] = getelementptr {{.*}} %[[ARGMEM]] |
256 | // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"({{.*}}* %[[ARG3]], i32 3) |
257 | // WIN32: %[[ARG1:.*]] = getelementptr {{.*}} %[[ARGMEM]] |
258 | // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"({{.*}}* %[[ARG1]], i32 1) |
259 | // WIN32: store i32 1, i32* %[[IS_MOST_DERIVED_ADDR:.*]] |
260 | // WIN32: %[[IS_MOST_DERIVED:.*]] = load i32, i32* %[[IS_MOST_DERIVED_ADDR]] |
261 | // WIN32: %[[IS_MOST_DERIVED_i1:.*]] = icmp ne i32 %[[IS_MOST_DERIVED]], 0 |
262 | // WIN32: br i1 %[[IS_MOST_DERIVED_i1]] |
263 | // |
264 | // WIN32: store {{.*}} @"??_8C@inalloca_virt@@7B@" |
265 | // WIN32: %[[ARG2:.*]] = getelementptr {{.*}} %[[ARGMEM]] |
266 | // WIN32: store i32 2, i32* %[[ARG2]] |
267 | // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]] |
268 | // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]] |
269 | // WIN32: call {{.*}} @"??0A@inalloca_virt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]]) |
270 | // WIN32: call void @llvm.stackrestore( |
271 | // WIN32: br |
272 | // |
273 | // WIN32: call {{.*}} @"??0Z@@QAE@XZ"( |
274 | // WIN32: call {{.*}} @"??0Z@@QAE@XZ"( |
275 | // WIN32: call {{.*}} @"??1Q@@QAE@XZ"( |
276 | |
277 | // On Win64, the Q arguments would be destroyed in the callee. We don't yet |
278 | // support that in the non-inlined case, so we force inlining. |
279 | // WIN64: %[[TMP:.*]] = alloca |
280 | // WIN64: %[[ARG3:.*]] = alloca |
281 | // WIN64: %[[ARG1:.*]] = alloca |
282 | // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[TMP]], i32 4) |
283 | // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[ARG3]], i32 3) |
284 | // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[ARG1]], i32 1) |
285 | // WIN64: br i1 |
286 | // WIN64: store {{.*}} @"??_8C@inalloca_virt@@7B@" |
287 | // WIN64: call {{.*}} @"??0A@inalloca_virt@@QEAA@UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]]) |
288 | // WIN64: call {{.*}} @"??0Z@@QEAA@XZ"( |
289 | // WIN64: call {{.*}} @"??0Z@@QEAA@XZ"( |
290 | // WIN64: call void @"??1Q@@QEAA@XZ"({{.*}}* %[[TMP]]) |
291 | } |
292 | |
293 | namespace inline_nonvirt { |
294 | struct A { A(Q, int, Q, Q&&, ...); int n; }; |
295 | struct B : Z, A { Z z; using A::A; }; |
296 | B b(1, 2, 3, 4, 5, 6); |
297 | // Inlined all the way down to the A ctor. |
298 | // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init |
299 | // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 1) |
300 | // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 3) |
301 | // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 4) |
302 | // ITANIUM: %[[Z_BASE:.*]] = bitcast %{{.*}}* %[[THIS:.*]] to |
303 | // ITANIUM: call void @_ZN1ZC2Ev( |
304 | // ITANIUM: %[[B_CAST:.*]] = bitcast {{.*}} %[[THIS]] |
305 | // ITANIUM: %[[A_CAST:.*]] = getelementptr {{.*}} %[[B_CAST]], i{{32|64}} 4 |
306 | // ITANIUM: %[[A:.*]] = bitcast {{.*}} %[[A_CAST]] |
307 | // ITANIUM: call void ({{.*}}, ...) @_ZN14inline_nonvirt1AC2E1QiS1_OS1_z(%{{.*}}* %[[A]], {{.*}}, i32 2, {{.*}}, {{.*}}, i32 5, i32 6) |
308 | // ITANIUM: %[[Z_MEMBER:.*]] = getelementptr {{.*}} %[[THIS]], i32 0, i32 2 |
309 | // ITANIUM: call void @_ZN1ZC1Ev({{.*}} %[[Z_MEMBER]]) |
310 | // ITANIUM: call void @_ZN1QD1Ev( |
311 | // ITANIUM: call void @_ZN1QD1Ev( |
312 | // ITANIUM: call void @_ZN1QD1Ev( |
313 | |
314 | struct C : B { using B::B; }; |
315 | C c(1, 2, 3, 4, 5, 6); |
316 | // Inlined all the way down to the A ctor. |
317 | // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init |
318 | // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 1) |
319 | // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 3) |
320 | // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 4) |
321 | // ITANIUM: %[[Z_BASE:.*]] = bitcast %{{.*}}* %[[THIS:.*]] to |
322 | // ITANIUM: call void @_ZN1ZC2Ev( |
323 | // ITANIUM: %[[B_CAST:.*]] = bitcast {{.*}} %[[THIS]] |
324 | // ITANIUM: %[[A_CAST:.*]] = getelementptr {{.*}} %[[B_CAST]], i{{32|64}} 4 |
325 | // ITANIUM: %[[A:.*]] = bitcast {{.*}} %[[A_CAST]] |
326 | // ITANIUM: call void ({{.*}}, ...) @_ZN14inline_nonvirt1AC2E1QiS1_OS1_z(%{{.*}}* %[[A]], {{.*}}, i32 2, {{.*}}, {{.*}}, i32 5, i32 6) |
327 | // ITANIUM: %[[Z_MEMBER:.*]] = getelementptr {{.*}} %{{.*}}, i32 0, i32 2 |
328 | // ITANIUM: call void @_ZN1ZC1Ev({{.*}} %[[Z_MEMBER]]) |
329 | // ITANIUM: call void @_ZN1QD1Ev( |
330 | // ITANIUM: call void @_ZN1QD1Ev( |
331 | // ITANIUM: call void @_ZN1QD1Ev( |
332 | } |
333 | |
334 | namespace inline_virt { |
335 | struct A { A(Q, int, Q, Q&&, ...); int n; }; |
336 | struct B : Z, virtual A { Z z; using A::A; }; |
337 | B b(1, 2, 3, 4, 5, 6); |
338 | // Inlined all the way down to the A ctor. |
339 | // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init |
340 | // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 1) |
341 | // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 3) |
342 | // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 4) |
343 | // ITANIUM: %[[B_CAST:.*]] = bitcast {{.*}} %[[THIS:.*]] |
344 | // ITANIUM: %[[A_CAST:.*]] = getelementptr {{.*}} %[[B_CAST]], i{{32|64}} {{12|16}} |
345 | // ITANIUM: %[[A:.*]] = bitcast {{.*}} %[[A_CAST]] |
346 | // ITANIUM: call void ({{.*}}, ...) @_ZN11inline_virt1AC2E1QiS1_OS1_z(%{{.*}}* %[[A]], {{.*}}, i32 2, {{.*}}, {{.*}}, i32 5, i32 6) |
347 | // ITANIUM: call void @_ZN1ZC2Ev( |
348 | // ITANIUM: call void @_ZN1ZC1Ev( |
349 | // ITANIUM: call void @_ZN1QD1Ev( |
350 | // ITANIUM: call void @_ZN1QD1Ev( |
351 | // ITANIUM: call void @_ZN1QD1Ev( |
352 | |
353 | struct C : B { using B::B; }; |
354 | C c(1, 2, 3, 4, 5, 6); |
355 | // Inlined all the way down to the A ctor, except that we can just call the |
356 | // B base inheriting constructor to construct that portion (it doesn't need |
357 | // the forwarded arguments). |
358 | // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init |
359 | // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 1) |
360 | // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 3) |
361 | // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 4) |
362 | // ITANIUM: %[[B_CAST:.*]] = bitcast {{.*}} %[[THIS:.*]] |
363 | // ITANIUM: %[[A_CAST:.*]] = getelementptr {{.*}} %[[B_CAST]], i{{32|64}} {{12|16}} |
364 | // ITANIUM: %[[A:.*]] = bitcast {{.*}} %[[A_CAST]] |
365 | // ITANIUM: call void ({{.*}}, ...) @_ZN11inline_virt1AC2E1QiS1_OS1_z(%{{.*}}* %[[A]], {{.*}}, i32 2, {{.*}}, {{.*}}, i32 5, i32 6) |
366 | // ITANIUM: call void @_ZN11inline_virt1BCI2NS_1AEE1QiS1_OS1_z({{[^,]*}}, i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @_ZTTN11inline_virt1CE, i64 0, i64 1)) |
367 | // ITANIUM: store {{.*}} @_ZTVN11inline_virt1CE |
368 | // ITANIUM: call void @_ZN1QD1Ev( |
369 | // ITANIUM: call void @_ZN1QD1Ev( |
370 | // ITANIUM: call void @_ZN1QD1Ev( |
371 | |
372 | // B base object inheriting constructor does not get passed arguments. |
373 | // ITANIUM-LABEL: define linkonce_odr void @_ZN11inline_virt1BCI2NS_1AEE1QiS1_OS1_z( |
374 | // ITANIUM-NOT: call |
375 | // ITANIUM: call void @_ZN1ZC2Ev( |
376 | // ITANIUM-NOT: call |
377 | // VTT -> vtable |
378 | // ITANIUM: store |
379 | // ITANIUM-NOT: call |
380 | // ITANIUM: call void @_ZN1ZC1Ev( |
381 | // ITANIUM-NOT: call |
382 | // ITANIUM: } |
383 | } |
384 | |
385 | // ITANIUM-LABEL: define linkonce_odr void @_ZN1BCI21AEi( |
386 | // ITANIUM: call void @_ZN1AC2Ei( |
387 | |
388 | // ITANIUM-LABEL: define linkonce_odr void @_ZN1DCI21CIiEET_( |
389 | // ITANIUM: call void @_ZN1CC2IiEET_( |
390 | |
391 | // ITANIUM-LABEL: define linkonce_odr void @_ZN17noninline_nonvirt1BCI2NS_1AEEiO1QPvU17pass_object_size0( |
392 | // ITANIUM: call void @_ZN1ZC2Ev( |
393 | // ITANIUM: call void @_ZN17noninline_nonvirt1AC2EiO1QPvU17pass_object_size0( |
394 | |
395 | // ITANIUM-LABEL: define linkonce_odr void @_ZN17noninline_nonvirt1CCI2NS_1AEEiO1QPvU17pass_object_size0( |
396 | // ITANIUM: call void @_ZN17noninline_nonvirt1BCI2NS_1AEEiO1QPvU17pass_object_size0( |
397 | |