@@ -70,3 +70,264 @@ DelegatingWithZeroing::DelegatingWithZeroing(int) : DelegatingWithZeroing() {}
7070// OGCG: store i32 %[[I_ARG]], ptr %[[I_ADDR]]
7171// OGCG: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
7272// OGCG: call void @llvm.memset.p0.i64(ptr align 4 %[[THIS]], i8 0, i64 4, i1 false)
73+
74+ void other ();
75+
76+ class Base {
77+ public:
78+ Base () { squawk (); }
79+
80+ virtual void squawk ();
81+ };
82+
83+ class Derived : public virtual Base {
84+ public:
85+ Derived ();
86+ Derived (const void *inVoid);
87+
88+ virtual void squawk ();
89+ };
90+
91+ Derived::Derived () : Derived(nullptr ) { other (); }
92+ Derived::Derived (const void *inVoid) { squawk (); }
93+
94+ // Note: OGCG emits the constructors in a different order.
95+ // OGCG: define {{.*}} void @_ZN7DerivedC2Ev(ptr {{.*}} %[[THIS_ARG:.*]], ptr {{.*}} %[[VTT_ARG:.*]])
96+ // OGCG: %[[THIS_ADDR:.*]] = alloca ptr
97+ // OGCG: %[[VTT_ADDR:.*]] = alloca ptr
98+ // OGCG: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
99+ // OGCG: store ptr %[[VTT_ARG]], ptr %[[VTT_ADDR]]
100+ // OGCG: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
101+ // OGCG: %[[VTT:.*]] = load ptr, ptr %[[VTT_ADDR]]
102+ // OGCG: call void @_ZN7DerivedC2EPKv(ptr {{.*}} %[[THIS]], ptr {{.*}} %[[VTT]], ptr {{.*}} null)
103+ // OGCG: call void @_Z5otherv()
104+ // OGCG: ret void
105+
106+ // CIR: cir.func {{.*}} @_ZN7DerivedC2EPKv(
107+ // CIR-SAME: %[[THIS_ARG:.*]]: !cir.ptr<!rec_Derived>
108+ // CIR-SAME: %[[VTT_ARG:.*]]: !cir.ptr<!cir.ptr<!void>>
109+ // CIR-SAME: %[[INVOID_ARG:.*]]: !cir.ptr<!void>
110+ // CIR: %[[THIS_ADDR:.*]] = cir.alloca {{.*}} ["this", init]
111+ // CIR: %[[VTT_ADDR:.*]] = cir.alloca {{.*}} ["vtt", init]
112+ // CIR: %[[INVOID_ADDR:.*]] = cir.alloca {{.*}} ["inVoid", init]
113+ // CIR: cir.store %[[THIS_ARG]], %[[THIS_ADDR]]
114+ // CIR: cir.store %[[VTT_ARG]], %[[VTT_ADDR]]
115+ // CIR: cir.store %[[INVOID_ARG]], %[[INVOID_ADDR]]
116+ // CIR: %[[THIS:.*]] = cir.load %[[THIS_ADDR]]
117+ // CIR: %[[VTT:.*]] = cir.load{{.*}} %[[VTT_ADDR]]
118+ // CIR: %[[VPTR_GLOBAL_ADDR:.*]] = cir.vtt.address_point %[[VTT]] : !cir.ptr<!cir.ptr<!void>>, offset = 0 -> !cir.ptr<!cir.ptr<!void>>
119+ // CIR: %[[VPTR_PTR:.*]] = cir.cast(bitcast, %[[VPTR_GLOBAL_ADDR]] : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!cir.vptr>
120+ // CIR: %[[VPTR:.*]] = cir.load{{.*}} %[[VPTR_PTR]] : !cir.ptr<!cir.vptr>, !cir.vptr
121+ // CIR: %[[VPTR_ADDR:.*]] = cir.vtable.get_vptr %[[THIS]] : !cir.ptr<!rec_Derived> -> !cir.ptr<!cir.vptr>
122+ // CIR: cir.store{{.*}} %[[VPTR]], %[[VPTR_ADDR]] : !cir.vptr, !cir.ptr<!cir.vptr>
123+ // CIR: %[[VPTR_BASE_ADDR:.*]] = cir.vtt.address_point %[[VTT]] : !cir.ptr<!cir.ptr<!void>>, offset = 1 -> !cir.ptr<!cir.ptr<!void>>
124+ // CIR: %[[VPTR_BASE_PTR:.*]] = cir.cast(bitcast, %[[VPTR_BASE_ADDR]] : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!cir.vptr>
125+ // CIR: %[[VPTR_BASE:.*]] = cir.load{{.*}} %[[VPTR_BASE_PTR]] : !cir.ptr<!cir.vptr>, !cir.vptr
126+ // CIR: %[[VPTR_DERIVED_ADDR:.*]] = cir.vtable.get_vptr %[[THIS]] : !cir.ptr<!rec_Derived> -> !cir.ptr<!cir.vptr>
127+ // CIR: %[[VPTR_DERIVED:.*]] = cir.load{{.*}} %[[VPTR_DERIVED_ADDR]] : !cir.ptr<!cir.vptr>, !cir.vptr
128+ // CIR: %[[VPTR_DERIVED_AS_I8PTR:.*]] = cir.cast(bitcast, %[[VPTR_DERIVED]] : !cir.vptr), !cir.ptr<!u8i>
129+ // CIR: %[[BASE_LOC_OFFSET:.*]] = cir.const #cir.int<-32> : !s64i
130+ // CIR: %[[BASE_OFFSET_PTR:.*]] = cir.ptr_stride(%[[VPTR_DERIVED_AS_I8PTR]] : !cir.ptr<!u8i>, %[[BASE_LOC_OFFSET]] : !s64i), !cir.ptr<!u8i>
131+ // CIR: %[[BASE_OFFSET_I64PTR:.*]] = cir.cast(bitcast, %[[BASE_OFFSET_PTR]] : !cir.ptr<!u8i>), !cir.ptr<!s64i>
132+ // CIR: %[[BASE_OFFSET:.*]] = cir.load{{.*}} %[[BASE_OFFSET_I64PTR]] : !cir.ptr<!s64i>, !s64i
133+ // CIR: %[[THIS_AS_I8PTR:.*]] = cir.cast(bitcast, %[[THIS]] : !cir.ptr<!rec_Derived>), !cir.ptr<!u8i>
134+ // CIR: %[[BASE_PTR:.*]] = cir.ptr_stride(%[[THIS_AS_I8PTR]] : !cir.ptr<!u8i>, %[[BASE_OFFSET]] : !s64i), !cir.ptr<!u8i>
135+ // CIR: %[[BASE_AS_I8PTR:.*]] = cir.cast(bitcast, %[[BASE_PTR]] : !cir.ptr<!u8i>), !cir.ptr<!rec_Derived>
136+ // CIR: %[[BASE_VPTR_ADDR:.*]] = cir.vtable.get_vptr %[[BASE_AS_I8PTR]] : !cir.ptr<!rec_Derived> -> !cir.ptr<!cir.vptr>
137+ // CIR: cir.store{{.*}} %[[VPTR_BASE]], %[[BASE_VPTR_ADDR]] : !cir.vptr, !cir.ptr<!cir.vptr>
138+ // CIR: %[[VPTR_BASE_ADDR:.*]] = cir.vtable.get_vptr %[[THIS]] : !cir.ptr<!rec_Derived> -> !cir.ptr<!cir.vptr>
139+ // CIR: %[[VPTR_BASE:.*]] = cir.load{{.*}} %[[VPTR_BASE_ADDR]] : !cir.ptr<!cir.vptr>, !cir.vptr
140+ // CIR: %[[SQUAWK_FN_ADDR:.*]] = cir.vtable.get_virtual_fn_addr %[[VPTR_BASE]][0] : !cir.vptr -> !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!rec_Derived>)>>>
141+ // CIR: %[[SQUAWK:.*]] = cir.load{{.*}} %[[SQUAWK_FN_ADDR]] : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!rec_Derived>)>>>, !cir.ptr<!cir.func<(!cir.ptr<!rec_Derived>)>>
142+ // CIR: cir.call %[[SQUAWK]](%[[THIS]]) : (!cir.ptr<!cir.func<(!cir.ptr<!rec_Derived>)>>, !cir.ptr<!rec_Derived>) -> ()
143+ // CIR: cir.return
144+
145+ // LLVM: define {{.*}} void @_ZN7DerivedC2EPKv(ptr %[[THIS_ARG:.*]], ptr %[[VTT_ARG:.*]], ptr %[[INVOID_ARG:.*]])
146+ // LLVM: %[[THIS_ADDR:.*]] = alloca ptr
147+ // LLVM: %[[VTT_ADDR:.*]] = alloca ptr
148+ // LLVM: %[[INVOID_ADDR:.*]] = alloca ptr
149+ // LLVM: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
150+ // LLVM: store ptr %[[VTT_ARG]], ptr %[[VTT_ADDR]]
151+ // LLVM: store ptr %[[INVOID_ARG]], ptr %[[INVOID_ADDR]]
152+ // LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
153+ // LLVM: %[[VTT:.*]] = load ptr, ptr %[[VTT_ADDR]]
154+ // LLVM: %[[VPTR:.*]] = load ptr, ptr %[[VTT]]
155+ // LLVM: store ptr %[[VPTR]], ptr %[[THIS]]
156+ // LLVM: %[[VTT_ADDR:.*]] = getelementptr inbounds ptr, ptr %[[VTT]], i32 1
157+ // LLVM: %[[VPTR_BASE:.*]] = load ptr, ptr %[[VTT_ADDR]]
158+ // LLVM: %[[VPTR:.*]] = load ptr, ptr %[[THIS]]
159+ // LLVM: %[[BASE_OFFSET_ADDR:.*]] = getelementptr i8, ptr %[[VPTR]], i64 -32
160+ // LLVM: %[[BASE_OFFSET:.*]] = load i64, ptr %[[BASE_OFFSET_ADDR]]
161+ // LLVM: %[[BASE_PTR:.*]] = getelementptr i8, ptr %[[THIS]], i64 %[[BASE_OFFSET]]
162+ // LLVM: store ptr %[[VPTR_BASE]], ptr %[[BASE_PTR]]
163+ // LLVM: %[[VPTR:.*]] = load ptr, ptr %[[THIS]]
164+ // LLVM: %[[SQUAWK_FN_ADDR:.*]] = getelementptr inbounds ptr, ptr %[[VPTR]], i32 0
165+ // LLVM: %[[SQUAWK:.*]] = load ptr, ptr %[[SQUAWK_FN_ADDR]]
166+ // LLVM: call void %[[SQUAWK]](ptr %[[THIS]])
167+ // LLVM: ret void
168+
169+ // OGCG: define {{.*}} void @_ZN7DerivedC2EPKv(ptr {{.*}} %[[THIS_ARG:.*]], ptr {{.*}} %[[VTT_ARG:.*]], ptr {{.*}} %[[INVOID_ARG:.*]])
170+ // OGCG: %[[THIS_ADDR:.*]] = alloca ptr
171+ // OGCG: %[[VTT_ADDR:.*]] = alloca ptr
172+ // OGCG: %[[INVOID_ADDR:.*]] = alloca ptr
173+ // OGCG: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
174+ // OGCG: store ptr %[[VTT_ARG]], ptr %[[VTT_ADDR]]
175+ // OGCG: store ptr %[[INVOID_ARG]], ptr %[[INVOID_ADDR]]
176+ // OGCG: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
177+ // OGCG: %[[VTT:.*]] = load ptr, ptr %[[VTT_ADDR]]
178+ // OGCG: %[[VPTR:.*]] = load ptr, ptr %[[VTT]]
179+ // OGCG: store ptr %[[VPTR]], ptr %[[THIS]]
180+ // OGCG: %[[VTT_ADDR:.*]] = getelementptr inbounds ptr, ptr %[[VTT]], i64 1
181+ // OGCG: %[[VPTR_BASE:.*]] = load ptr, ptr %[[VTT_ADDR]]
182+ // OGCG: %[[VPTR:.*]] = load ptr, ptr %[[THIS]]
183+ // OGCG: %[[BASE_OFFSET_ADDR:.*]] = getelementptr i8, ptr %[[VPTR]], i64 -32
184+ // OGCG: %[[BASE_OFFSET:.*]] = load i64, ptr %[[BASE_OFFSET_ADDR]]
185+ // OGCG: %[[BASE_PTR:.*]] = getelementptr inbounds i8, ptr %[[THIS]], i64 %[[BASE_OFFSET]]
186+ // OGCG: store ptr %[[VPTR_BASE]], ptr %[[BASE_PTR]]
187+ // OGCG: %[[VPTR:.*]] = load ptr, ptr %[[THIS]]
188+ // OGCG: %[[SQUAWK_FN_ADDR:.*]] = getelementptr inbounds ptr, ptr %[[VPTR]], i64 0
189+ // OGCG: %[[SQUAWK:.*]] = load ptr, ptr %[[SQUAWK_FN_ADDR]]
190+ // OGCG: call void %[[SQUAWK]](ptr {{.*}} %[[THIS]])
191+ // OGCG: ret void
192+
193+ // CIR: cir.func {{.*}} @_ZN7DerivedC2Ev(%[[THIS_ARG:.*]]: !cir.ptr<!rec_Derived> {{.*}}, %[[VTT_ARG:.*]]: !cir.ptr<!cir.ptr<!void>> {{.*}})
194+ // CIR: %[[THIS_ADDR:.*]] = cir.alloca {{.*}} ["this", init]
195+ // CIR: %[[VTT_ADDR:.*]] = cir.alloca {{.*}} ["vtt", init]
196+ // CIR: cir.store %[[THIS_ARG]], %[[THIS_ADDR]]
197+ // CIR: cir.store %[[VTT_ARG]], %[[VTT_ADDR]]
198+ // CIR: %[[THIS:.*]] = cir.load %[[THIS_ADDR]]
199+ // CIR: %[[VTT:.*]] = cir.load {{.*}} %[[VTT_ADDR]]
200+ // CIR: %[[NULLPTR:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!void>
201+ // CIR: cir.call @_ZN7DerivedC2EPKv(%[[THIS]], %[[VTT]], %[[NULLPTR]]) : (!cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>) -> ()
202+ // CIR: cir.call @_Z5otherv() : () -> ()
203+ // CIR: cir.return
204+
205+ // LLVM: define {{.*}} void @_ZN7DerivedC2Ev(ptr %[[THIS_ARG:.*]], ptr %[[VTT_ARG:.*]])
206+ // LLVM: %[[THIS_ADDR:.*]] = alloca ptr
207+ // LLVM: %[[VTT_ADDR:.*]] = alloca ptr
208+ // LLVM: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
209+ // LLVM: store ptr %[[VTT_ARG]], ptr %[[VTT_ADDR]]
210+ // LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
211+ // LLVM: %[[VTT:.*]] = load ptr, ptr %[[VTT_ADDR]]
212+ // LLVM: call void @_ZN7DerivedC2EPKv(ptr %[[THIS]], ptr %[[VTT]], ptr null)
213+ // LLVM: call void @_Z5otherv()
214+ // LLVM: ret void
215+
216+ // See above for the OGCG _ZN7DerivedC2Ev constructor.
217+
218+ // CIR: cir.func {{.*}} @_ZN4BaseC2Ev(%[[THIS_ARG:.*]]: !cir.ptr<!rec_Base> {{.*}})
219+ // CIR: %[[THIS_ADDR:.*]] = cir.alloca {{.*}} ["this", init]
220+ // CIR: cir.store %[[THIS_ARG]], %[[THIS_ADDR]]
221+ // CIR: %[[THIS:.*]] = cir.load %[[THIS_ADDR]]
222+ // CIR: %[[VTT_ADDR_POINT:.*]] = cir.vtable.address_point(@_ZTV4Base, address_point = <index = 0, offset = 2>) : !cir.vptr
223+ // CIR: %[[VPTR_ADDR:.*]] = cir.vtable.get_vptr %[[THIS]] : !cir.ptr<!rec_Base> -> !cir.ptr<!cir.vptr>
224+ // CIR: cir.store{{.*}} %[[VTT_ADDR_POINT]], %[[VPTR_ADDR]] : !cir.vptr, !cir.ptr<!cir.vptr>
225+ // CIR: %[[VPTR_ADDR:.*]] = cir.vtable.get_vptr %[[THIS]] : !cir.ptr<!rec_Base> -> !cir.ptr<!cir.vptr>
226+ // CIR: %[[VPTR:.*]] = cir.load{{.*}} %[[VPTR_ADDR]] : !cir.ptr<!cir.vptr>, !cir.vptr
227+ // CIR: %[[VIRTUAL_FN_ADDR:.*]] = cir.vtable.get_virtual_fn_addr %[[VPTR]][0] : !cir.vptr -> !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!rec_Base>)>>>
228+ // CIR: %[[VIRTUAL_FN:.*]] = cir.load{{.*}} %[[VIRTUAL_FN_ADDR]] : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!rec_Base>)>>>, !cir.ptr<!cir.func<(!cir.ptr<!rec_Base>)>>
229+ // CIR: cir.call %[[VIRTUAL_FN]](%[[THIS]]) : (!cir.ptr<!cir.func<(!cir.ptr<!rec_Base>)>>, !cir.ptr<!rec_Base>) -> ()
230+ // CIR: cir.return
231+
232+ // LLVM: define {{.*}} void @_ZN4BaseC2Ev(ptr %[[THIS_ARG:.*]])
233+ // LLVM: %[[THIS_ADDR:.*]] = alloca ptr
234+ // LLVM: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
235+ // LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
236+ // LLVM: store ptr getelementptr inbounds nuw (i8, ptr @_ZTV4Base, i64 16), ptr %[[THIS]]
237+ // LLVM: %[[VPTR:.*]] = load ptr, ptr %[[THIS]]
238+ // LLVM: %[[SQUAWK_ADDR:.*]] = getelementptr inbounds ptr, ptr %[[VPTR]], i32 0
239+ // LLVM: %[[SQUAWK:.*]] = load ptr, ptr %[[SQUAWK_ADDR]]
240+ // LLVM: call void %[[SQUAWK]](ptr %[[THIS]])
241+ // LLVM: ret void
242+
243+ // The base constructor is emitted last for OGCG.
244+ // The _ZN7DerivedC1Ev constructor is emitted earlier for OGCG.
245+
246+ // OGCG: define {{.*}} void @_ZN7DerivedC1Ev(ptr {{.*}} %[[THIS_ARG:.*]])
247+ // OGCG: %[[THIS_ADDR:.*]] = alloca ptr
248+ // OGCG: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
249+ // OGCG: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
250+ // OGCG: call void @_ZN7DerivedC1EPKv(ptr {{.*}} %[[THIS]], ptr {{.*}} null)
251+ // OGCG: call void @_Z5otherv()
252+ // OGCG: ret void
253+
254+ // CIR: cir.func {{.*}} @_ZN7DerivedC1EPKv(%[[THIS_ARG:.*]]: !cir.ptr<!rec_Derived> {{.*}}, %[[INVOID_ARG:.*]]: !cir.ptr<!void> {{.*}})
255+ // CIR: %[[THIS_ADDR:.*]] = cir.alloca {{.*}} ["this", init]
256+ // CIR: %[[INVOID_ADDR:.*]] = cir.alloca {{.*}} ["inVoid", init]
257+ // CIR: cir.store %[[THIS_ARG]], %[[THIS_ADDR]]
258+ // CIR: cir.store %[[INVOID_ARG]], %[[INVOID_ADDR]]
259+ // CIR: %[[THIS:.*]] = cir.load %[[THIS_ADDR]]
260+ // CIR: %[[BASE:.*]] = cir.base_class_addr %[[THIS]] : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
261+ // CIR: cir.call @_ZN4BaseC2Ev(%[[BASE]])
262+ // CIR: %[[VPTR_GLOBAL:.*]] = cir.vtable.address_point(@_ZTV7Derived, address_point = <index = 0, offset = 4>) : !cir.vptr
263+ // CIR: %[[VPTR_ADDR:.*]] = cir.vtable.get_vptr %[[THIS]] : !cir.ptr<!rec_Derived> -> !cir.ptr<!cir.vptr>
264+ // CIR: cir.store{{.*}} %[[VPTR_GLOBAL]], %[[VPTR_ADDR]] : !cir.vptr, !cir.ptr<!cir.vptr>
265+ // CIR: %[[VPTR_GLOBAL:.*]] = cir.vtable.address_point(@_ZTV7Derived, address_point = <index = 0, offset = 4>) : !cir.vptr
266+ // CIR: %[[VPTR_ADDR:.*]] = cir.vtable.get_vptr %[[THIS]] : !cir.ptr<!rec_Derived> -> !cir.ptr<!cir.vptr>
267+ // CIR: cir.store{{.*}} %[[VPTR_GLOBAL]], %[[VPTR_ADDR]] : !cir.vptr, !cir.ptr<!cir.vptr>
268+ // CIR: %[[VPTR_ADDR:.*]] = cir.vtable.get_vptr %[[THIS]] : !cir.ptr<!rec_Derived> -> !cir.ptr<!cir.vptr>
269+ // CIR: %[[VPTR:.*]] = cir.load{{.*}} %[[VPTR_ADDR]] : !cir.ptr<!cir.vptr>, !cir.vptr
270+ // CIR: %[[SQUAWK_ADDR:.*]] = cir.vtable.get_virtual_fn_addr %[[VPTR]][0] : !cir.vptr -> !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!rec_Derived>)>>>
271+ // CIR: %[[SQUAWK:.*]] = cir.load{{.*}} %[[SQUAWK_ADDR]] : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!rec_Derived>)>>>, !cir.ptr<!cir.func<(!cir.ptr<!rec_Derived>)>>
272+ // CIR: cir.call %[[SQUAWK]](%[[THIS]])
273+ // CIR: cir.return
274+
275+ // LLVM: define {{.*}} void @_ZN7DerivedC1EPKv(ptr %[[THIS_ARG:.*]], ptr %[[INVOID_ARG:.*]])
276+ // LLVM: %[[THIS_ADDR:.*]] = alloca ptr
277+ // LLVM: %[[INVOID_ADDR:.*]] = alloca ptr
278+ // LLVM: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
279+ // LLVM: store ptr %[[INVOID_ARG]], ptr %[[INVOID_ADDR]]
280+ // LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
281+ // LLVM: call void @_ZN4BaseC2Ev(ptr %[[THIS]])
282+ // LLVM: store ptr getelementptr inbounds nuw (i8, ptr @_ZTV7Derived, i64 32), ptr %[[THIS]]
283+ // LLVM: store ptr getelementptr inbounds nuw (i8, ptr @_ZTV7Derived, i64 32), ptr %[[THIS]]
284+ // LLVM: %[[VPTR:.*]] = load ptr, ptr %[[THIS]]
285+ // LLVM: %[[SQUAWK_ADDR:.*]] = getelementptr inbounds ptr, ptr %[[VPTR]], i32 0
286+ // LLVM: %[[SQUAWK:.*]] = load ptr, ptr %[[SQUAWK_ADDR]]
287+ // LLVM: call void %[[SQUAWK]](ptr %[[THIS]])
288+ // LLVM: ret void
289+
290+ // OGCG: define {{.*}} void @_ZN7DerivedC1EPKv(ptr {{.*}} %[[THIS_ARG:.*]], ptr {{.*}} %[[INVOID_ARG:.*]])
291+ // OGCG: %[[THIS_ADDR:.*]] = alloca ptr
292+ // OGCG: %[[INVOID_ADDR:.*]] = alloca ptr
293+ // OGCG: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
294+ // OGCG: store ptr %[[INVOID_ARG]], ptr %[[INVOID_ADDR]]
295+ // OGCG: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
296+ // OGCG: call void @_ZN4BaseC2Ev(ptr {{.*}} %[[THIS]])
297+ // OGCG: store ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV7Derived, i32 0, i32 0, i32 4), ptr %[[THIS]]
298+ // OGCG: store ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV7Derived, i32 0, i32 0, i32 4), ptr %[[THIS]]
299+ // OGCG: %[[VPTR:.*]] = load ptr, ptr %[[THIS]]
300+ // OGCG: %[[SQUAWK_ADDR:.*]] = getelementptr inbounds ptr, ptr %[[VPTR]], i64 0
301+ // OGCG: %[[SQUAWK:.*]] = load ptr, ptr %[[SQUAWK_ADDR]]
302+ // OGCG: call void %[[SQUAWK]](ptr {{.*}} %[[THIS]])
303+ // OGCG: ret void
304+
305+ // CIR: cir.func {{.*}} @_ZN7DerivedC1Ev(%[[THIS_ARG:.*]]: !cir.ptr<!rec_Derived> {{.*}})
306+ // CIR: %[[THIS_ADDR:.*]] = cir.alloca {{.*}} ["this", init]
307+ // CIR: cir.store %[[THIS_ARG]], %[[THIS_ADDR]]
308+ // CIR: %[[THIS:.*]] = cir.load %[[THIS_ADDR]]
309+ // CIR: %[[NULLPTR:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!void>
310+ // CIR: cir.call @_ZN7DerivedC1EPKv(%[[THIS]], %[[NULLPTR]]) : (!cir.ptr<!rec_Derived>, !cir.ptr<!void>) -> ()
311+ // CIR: cir.call @_Z5otherv() : () -> ()
312+ // CIR: cir.return
313+
314+ // LLVM: define {{.*}} void @_ZN7DerivedC1Ev(ptr %[[THIS_ARG:.*]])
315+ // LLVM: %[[THIS_ADDR:.*]] = alloca ptr
316+ // LLVM: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
317+ // LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
318+ // LLVM: call void @_ZN7DerivedC1EPKv(ptr %[[THIS]], ptr null)
319+ // LLVM: call void @_Z5otherv()
320+ // LLVM: ret void
321+
322+ // The _ZN7DerivedC1Ev constructor was emitted earlier for OGCG.
323+
324+ // OGCG: define {{.*}} void @_ZN4BaseC2Ev(ptr {{.*}} %[[THIS_ARG:.*]])
325+ // OGCG: %[[THIS_ADDR:.*]] = alloca ptr
326+ // OGCG: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
327+ // OGCG: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
328+ // OGCG: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV4Base, i32 0, i32 0, i32 2), ptr %[[THIS]]
329+ // OGCG: %[[VPTR:.*]] = load ptr, ptr %[[THIS]]
330+ // OGCG: %[[SQUAWK_ADDR:.*]] = getelementptr inbounds ptr, ptr %[[VPTR]], i64 0
331+ // OGCG: %[[SQUAWK:.*]] = load ptr, ptr %[[SQUAWK_ADDR]]
332+ // OGCG: call void %[[SQUAWK]](ptr {{.*}} %[[THIS]])
333+ // OGCG: ret void
0 commit comments