1*67e74705SXin Li // RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t
2*67e74705SXin Li // RUN: FileCheck %s < %t
3*67e74705SXin Li // RUN: FileCheck --check-prefix=CHECK2 %s < %t
4*67e74705SXin Li
5*67e74705SXin Li // For now, just make sure x86_64 doesn't crash.
6*67e74705SXin Li // RUN: %clang_cc1 %s -fno-rtti -triple=x86_64-pc-win32 -emit-llvm -o %t
7*67e74705SXin Li
8*67e74705SXin Li struct VBase {
9*67e74705SXin Li virtual ~VBase();
10*67e74705SXin Li virtual void foo();
11*67e74705SXin Li virtual void bar();
12*67e74705SXin Li int field;
13*67e74705SXin Li };
14*67e74705SXin Li
15*67e74705SXin Li struct B : virtual VBase {
16*67e74705SXin Li B();
17*67e74705SXin Li virtual ~B();
18*67e74705SXin Li virtual void foo();
19*67e74705SXin Li virtual void bar();
20*67e74705SXin Li };
21*67e74705SXin Li
B()22*67e74705SXin Li B::B() {
23*67e74705SXin Li // CHECK-LABEL: define x86_thiscallcc %struct.B* @"\01??0B@@QAE@XZ"
24*67e74705SXin Li // CHECK: %[[THIS:.*]] = load %struct.B*, %struct.B**
25*67e74705SXin Li // CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
26*67e74705SXin Li
27*67e74705SXin Li // Don't check the INIT_VBASES case as it's covered by the ctor tests.
28*67e74705SXin Li
29*67e74705SXin Li // CHECK: %[[SKIP_VBASES]]
30*67e74705SXin Li // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
31*67e74705SXin Li // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0
32*67e74705SXin Li // ...
33*67e74705SXin Li // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
34*67e74705SXin Li // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %{{.*}}
35*67e74705SXin Li // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
36*67e74705SXin Li // CHECK: store i32 (...)** bitcast ([3 x i8*]* @"\01??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
37*67e74705SXin Li
38*67e74705SXin Li // Initialize vtorDisp:
39*67e74705SXin Li // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
40*67e74705SXin Li // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0
41*67e74705SXin Li // ...
42*67e74705SXin Li // CHECK: %[[VBASE_OFFSET:.*]] = add nsw i32 0, %{{.*}}
43*67e74705SXin Li // CHECK: %[[VTORDISP_VAL:.*]] = sub i32 %[[VBASE_OFFSET]], 8
44*67e74705SXin Li // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
45*67e74705SXin Li // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %[[VBASE_OFFSET]]
46*67e74705SXin Li // CHECK: %[[VTORDISP_i8:.*]] = getelementptr i8, i8* %[[VBASE_i8]], i32 -4
47*67e74705SXin Li // CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_i8]] to i32*
48*67e74705SXin Li // CHECK: store i32 %[[VTORDISP_VAL]], i32* %[[VTORDISP_PTR]]
49*67e74705SXin Li
50*67e74705SXin Li // CHECK: ret
51*67e74705SXin Li }
52*67e74705SXin Li
~B()53*67e74705SXin Li B::~B() {
54*67e74705SXin Li // CHECK-LABEL: define x86_thiscallcc void @"\01??1B@@UAE@XZ"
55*67e74705SXin Li // Adjust the this parameter:
56*67e74705SXin Li // CHECK: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* {{.*}} to i8*
57*67e74705SXin Li // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_PARAM_i8]], i32 -8
58*67e74705SXin Li // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B*
59*67e74705SXin Li // CHECK: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR:.*]], align 4
60*67e74705SXin Li // CHECK: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
61*67e74705SXin Li
62*67e74705SXin Li // Restore the vfptr that could have been changed by a subclass.
63*67e74705SXin Li // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
64*67e74705SXin Li // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0
65*67e74705SXin Li // ...
66*67e74705SXin Li // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
67*67e74705SXin Li // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %{{.*}}
68*67e74705SXin Li // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
69*67e74705SXin Li // CHECK: store i32 (...)** bitcast ([3 x i8*]* @"\01??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
70*67e74705SXin Li
71*67e74705SXin Li // Initialize vtorDisp:
72*67e74705SXin Li // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
73*67e74705SXin Li // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0
74*67e74705SXin Li // ...
75*67e74705SXin Li // CHECK: %[[VBASE_OFFSET:.*]] = add nsw i32 0, %{{.*}}
76*67e74705SXin Li // CHECK: %[[VTORDISP_VAL:.*]] = sub i32 %[[VBASE_OFFSET]], 8
77*67e74705SXin Li // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
78*67e74705SXin Li // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %[[VBASE_OFFSET]]
79*67e74705SXin Li // CHECK: %[[VTORDISP_i8:.*]] = getelementptr i8, i8* %[[VBASE_i8]], i32 -4
80*67e74705SXin Li // CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_i8]] to i32*
81*67e74705SXin Li // CHECK: store i32 %[[VTORDISP_VAL]], i32* %[[VTORDISP_PTR]]
82*67e74705SXin Li
83*67e74705SXin Li foo(); // Avoid the "trivial destructor" optimization.
84*67e74705SXin Li
85*67e74705SXin Li // CHECK: ret
86*67e74705SXin Li
87*67e74705SXin Li // CHECK2-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DB@@UAE@XZ"(%struct.B*
88*67e74705SXin Li // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** {{.*}}
89*67e74705SXin Li // CHECK2: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
90*67e74705SXin Li // CHECK2: %[[B_i8:.*]] = getelementptr i8, i8* %[[THIS_i8]], i32 8
91*67e74705SXin Li // CHECK2: %[[B:.*]] = bitcast i8* %[[B_i8]] to %struct.B*
92*67e74705SXin Li // CHECK2: call x86_thiscallcc void @"\01??1B@@UAE@XZ"(%struct.B* %[[B]])
93*67e74705SXin Li // CHECK2: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
94*67e74705SXin Li // CHECK2: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 8
95*67e74705SXin Li // CHECK2: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.VBase*
96*67e74705SXin Li // CHECK2: call x86_thiscallcc void @"\01??1VBase@@UAE@XZ"(%struct.VBase* %[[VBASE]])
97*67e74705SXin Li // CHECK2: ret
98*67e74705SXin Li
99*67e74705SXin Li // CHECK2-LABEL: define linkonce_odr x86_thiscallcc i8* @"\01??_GB@@UAEPAXI@Z"
100*67e74705SXin Li // CHECK2: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* {{.*}} to i8*
101*67e74705SXin Li // CHECK2: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_PARAM_i8:.*]], i32 -8
102*67e74705SXin Li // CHECK2: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B*
103*67e74705SXin Li // CHECK2: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR:.*]], align 4
104*67e74705SXin Li // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
105*67e74705SXin Li // CHECK2: call x86_thiscallcc void @"\01??_DB@@UAE@XZ"(%struct.B* %[[THIS]])
106*67e74705SXin Li // ...
107*67e74705SXin Li // CHECK2: ret
108*67e74705SXin Li }
109*67e74705SXin Li
foo()110*67e74705SXin Li void B::foo() {
111*67e74705SXin Li // CHECK-LABEL: define x86_thiscallcc void @"\01?foo@B@@UAEXXZ"(i8*
112*67e74705SXin Li //
113*67e74705SXin Li // B::foo gets 'this' cast to VBase* in ECX (i.e. this+8) so we
114*67e74705SXin Li // need to adjust 'this' before use.
115*67e74705SXin Li //
116*67e74705SXin Li // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B*, align 4
117*67e74705SXin Li // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -8
118*67e74705SXin Li // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B*
119*67e74705SXin Li // CHECK: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR]], align 4
120*67e74705SXin Li
121*67e74705SXin Li field = 42;
122*67e74705SXin Li // CHECK: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
123*67e74705SXin Li // CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
124*67e74705SXin Li // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS8]], i32 0
125*67e74705SXin Li // CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
126*67e74705SXin Li // CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
127*67e74705SXin Li // CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
128*67e74705SXin Li // CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
129*67e74705SXin Li // CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
130*67e74705SXin Li // CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
131*67e74705SXin Li // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS8]], i32 %[[VBOFFSET]]
132*67e74705SXin Li // CHECK: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.VBase*
133*67e74705SXin Li // CHECK: %[[FIELD:.*]] = getelementptr inbounds %struct.VBase, %struct.VBase* %[[VBASE]], i32 0, i32 1
134*67e74705SXin Li // CHECK: store i32 42, i32* %[[FIELD]], align 4
135*67e74705SXin Li //
136*67e74705SXin Li // CHECK: ret void
137*67e74705SXin Li }
138*67e74705SXin Li
call_vbase_bar(B * obj)139*67e74705SXin Li void call_vbase_bar(B *obj) {
140*67e74705SXin Li // CHECK-LABEL: define void @"\01?call_vbase_bar@@YAXPAUB@@@Z"(%struct.B* %obj)
141*67e74705SXin Li // CHECK: %[[OBJ:.*]] = load %struct.B
142*67e74705SXin Li
143*67e74705SXin Li obj->bar();
144*67e74705SXin Li // When calling a vbase's virtual method, one needs to adjust 'this'
145*67e74705SXin Li // at the caller site.
146*67e74705SXin Li //
147*67e74705SXin Li // CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
148*67e74705SXin Li // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0
149*67e74705SXin Li // CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
150*67e74705SXin Li // CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
151*67e74705SXin Li // CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
152*67e74705SXin Li // CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
153*67e74705SXin Li // CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
154*67e74705SXin Li // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
155*67e74705SXin Li // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VBASE_i8]] to void (i8*)***
156*67e74705SXin Li // CHECK: %[[VFTABLE:.*]] = load void (i8*)**, void (i8*)*** %[[VFPTR]]
157*67e74705SXin Li // CHECK: %[[VFUN:.*]] = getelementptr inbounds void (i8*)*, void (i8*)** %[[VFTABLE]], i64 2
158*67e74705SXin Li // CHECK: %[[VFUN_VALUE:.*]] = load void (i8*)*, void (i8*)** %[[VFUN]]
159*67e74705SXin Li //
160*67e74705SXin Li // CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
161*67e74705SXin Li // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0
162*67e74705SXin Li // CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
163*67e74705SXin Li // CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
164*67e74705SXin Li // CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
165*67e74705SXin Li // CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
166*67e74705SXin Li // CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
167*67e74705SXin Li // CHECK: %[[VBASE:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
168*67e74705SXin Li //
169*67e74705SXin Li // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](i8* %[[VBASE]])
170*67e74705SXin Li //
171*67e74705SXin Li // CHECK: ret void
172*67e74705SXin Li }
173*67e74705SXin Li
delete_B(B * obj)174*67e74705SXin Li void delete_B(B *obj) {
175*67e74705SXin Li // CHECK-LABEL: define void @"\01?delete_B@@YAXPAUB@@@Z"(%struct.B* %obj)
176*67e74705SXin Li // CHECK: %[[OBJ:.*]] = load %struct.B
177*67e74705SXin Li
178*67e74705SXin Li delete obj;
179*67e74705SXin Li // CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
180*67e74705SXin Li // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0
181*67e74705SXin Li // CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
182*67e74705SXin Li // CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
183*67e74705SXin Li // CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
184*67e74705SXin Li // CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
185*67e74705SXin Li // CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
186*67e74705SXin Li // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
187*67e74705SXin Li // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VBASE_i8]] to i8* (%struct.B*, i32)***
188*67e74705SXin Li // CHECK: %[[VFTABLE:.*]] = load i8* (%struct.B*, i32)**, i8* (%struct.B*, i32)*** %[[VFPTR]]
189*67e74705SXin Li // CHECK: %[[VFUN:.*]] = getelementptr inbounds i8* (%struct.B*, i32)*, i8* (%struct.B*, i32)** %[[VFTABLE]], i64 0
190*67e74705SXin Li // CHECK: %[[VFUN_VALUE:.*]] = load i8* (%struct.B*, i32)*, i8* (%struct.B*, i32)** %[[VFUN]]
191*67e74705SXin Li //
192*67e74705SXin Li // CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
193*67e74705SXin Li // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0
194*67e74705SXin Li // CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
195*67e74705SXin Li // CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
196*67e74705SXin Li // CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
197*67e74705SXin Li // CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
198*67e74705SXin Li // CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
199*67e74705SXin Li // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
200*67e74705SXin Li // CHECK: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.B*
201*67e74705SXin Li //
202*67e74705SXin Li // CHECK: call x86_thiscallcc i8* %[[VFUN_VALUE]](%struct.B* %[[VBASE]], i32 1)
203*67e74705SXin Li // CHECK: ret void
204*67e74705SXin Li }
205*67e74705SXin Li
call_complete_dtor()206*67e74705SXin Li void call_complete_dtor() {
207*67e74705SXin Li // CHECK-LABEL: define void @"\01?call_complete_dtor@@YAXXZ"
208*67e74705SXin Li B b;
209*67e74705SXin Li // CHECK: call x86_thiscallcc %struct.B* @"\01??0B@@QAE@XZ"(%struct.B* %[[B:.*]], i32 1)
210*67e74705SXin Li // CHECK-NOT: getelementptr
211*67e74705SXin Li // CHECK: call x86_thiscallcc void @"\01??_DB@@UAE@XZ"(%struct.B* %[[B]])
212*67e74705SXin Li // CHECK: ret
213*67e74705SXin Li }
214*67e74705SXin Li
215*67e74705SXin Li struct C : B {
216*67e74705SXin Li C();
217*67e74705SXin Li // has an implicit vdtor.
218*67e74705SXin Li };
219*67e74705SXin Li
220*67e74705SXin Li // Used to crash on an assertion.
C()221*67e74705SXin Li C::C() {
222*67e74705SXin Li // CHECK-LABEL: define x86_thiscallcc %struct.C* @"\01??0C@@QAE@XZ"
223*67e74705SXin Li }
224*67e74705SXin Li
225*67e74705SXin Li namespace multiple_vbases {
226*67e74705SXin Li struct A {
227*67e74705SXin Li virtual void a();
228*67e74705SXin Li };
229*67e74705SXin Li
230*67e74705SXin Li struct B {
231*67e74705SXin Li virtual void b();
232*67e74705SXin Li };
233*67e74705SXin Li
234*67e74705SXin Li struct C {
235*67e74705SXin Li virtual void c();
236*67e74705SXin Li };
237*67e74705SXin Li
238*67e74705SXin Li struct D : virtual A, virtual B, virtual C {
239*67e74705SXin Li virtual void a();
240*67e74705SXin Li virtual void b();
241*67e74705SXin Li virtual void c();
242*67e74705SXin Li D();
243*67e74705SXin Li };
244*67e74705SXin Li
D()245*67e74705SXin Li D::D() {
246*67e74705SXin Li // CHECK-LABEL: define x86_thiscallcc %"struct.multiple_vbases::D"* @"\01??0D@multiple_vbases@@QAE@XZ"
247*67e74705SXin Li // Just make sure we emit 3 vtordisps after initializing vfptrs.
248*67e74705SXin Li // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7D@multiple_vbases@@6BA@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
249*67e74705SXin Li // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7D@multiple_vbases@@6BB@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
250*67e74705SXin Li // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7D@multiple_vbases@@6BC@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
251*67e74705SXin Li // ...
252*67e74705SXin Li // CHECK: store i32 %{{.*}}, i32* %{{.*}}
253*67e74705SXin Li // CHECK: store i32 %{{.*}}, i32* %{{.*}}
254*67e74705SXin Li // CHECK: store i32 %{{.*}}, i32* %{{.*}}
255*67e74705SXin Li // CHECK: ret
256*67e74705SXin Li }
257*67e74705SXin Li }
258*67e74705SXin Li
259*67e74705SXin Li namespace diamond {
260*67e74705SXin Li struct A {
261*67e74705SXin Li A();
262*67e74705SXin Li virtual ~A();
263*67e74705SXin Li };
264*67e74705SXin Li
265*67e74705SXin Li struct B : virtual A {
266*67e74705SXin Li B();
267*67e74705SXin Li ~B();
268*67e74705SXin Li };
269*67e74705SXin Li
270*67e74705SXin Li struct C : virtual A {
271*67e74705SXin Li C();
272*67e74705SXin Li ~C();
273*67e74705SXin Li int c1, c2, c3;
274*67e74705SXin Li };
275*67e74705SXin Li
276*67e74705SXin Li struct Z {
277*67e74705SXin Li int z;
278*67e74705SXin Li };
279*67e74705SXin Li
280*67e74705SXin Li struct D : virtual Z, B, C {
281*67e74705SXin Li D();
282*67e74705SXin Li ~D();
283*67e74705SXin Li } d;
284*67e74705SXin Li
~D()285*67e74705SXin Li D::~D() {
286*67e74705SXin Li // CHECK-LABEL: define x86_thiscallcc void @"\01??1D@diamond@@UAE@XZ"(%"struct.diamond::D"*)
287*67e74705SXin Li // CHECK: %[[ARG_i8:.*]] = bitcast %"struct.diamond::D"* %{{.*}} to i8*
288*67e74705SXin Li // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ARG_i8]], i32 -24
289*67e74705SXin Li // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %"struct.diamond::D"*
290*67e74705SXin Li // CHECK: store %"struct.diamond::D"* %[[THIS]], %"struct.diamond::D"** %[[THIS_VAL:.*]], align 4
291*67e74705SXin Li // CHECK: %[[THIS:.*]] = load %"struct.diamond::D"*, %"struct.diamond::D"** %[[THIS_VAL]]
292*67e74705SXin Li // CHECK: %[[D_i8:.*]] = bitcast %"struct.diamond::D"* %[[THIS]] to i8*
293*67e74705SXin Li // CHECK: %[[C_i8:.*]] = getelementptr inbounds i8, i8* %[[D_i8]], i32 4
294*67e74705SXin Li // CHECK: %[[C:.*]] = bitcast i8* %[[C_i8]] to %"struct.diamond::C"*
295*67e74705SXin Li // CHECK: %[[C_i8:.*]] = bitcast %"struct.diamond::C"* %[[C]] to i8*
296*67e74705SXin Li // CHECK: %[[ARG_i8:.*]] = getelementptr i8, i8* %{{.*}}, i32 16
297*67e74705SXin Li // FIXME: We might consider changing the dtor this parameter type to i8*.
298*67e74705SXin Li // CHECK: %[[ARG:.*]] = bitcast i8* %[[ARG_i8]] to %"struct.diamond::C"*
299*67e74705SXin Li // CHECK: call x86_thiscallcc void @"\01??1C@diamond@@UAE@XZ"(%"struct.diamond::C"* %[[ARG]])
300*67e74705SXin Li
301*67e74705SXin Li // CHECK: %[[B:.*]] = bitcast %"struct.diamond::D"* %[[THIS]] to %"struct.diamond::B"*
302*67e74705SXin Li // CHECK: %[[B_i8:.*]] = bitcast %"struct.diamond::B"* %[[B]] to i8*
303*67e74705SXin Li // CHECK: %[[ARG_i8:.*]] = getelementptr i8, i8* %[[B_i8]], i32 4
304*67e74705SXin Li // CHECK: %[[ARG:.*]] = bitcast i8* %[[ARG_i8]] to %"struct.diamond::B"*
305*67e74705SXin Li // CHECK: call x86_thiscallcc void @"\01??1B@diamond@@UAE@XZ"(%"struct.diamond::B"* %[[ARG]])
306*67e74705SXin Li // CHECK: ret void
307*67e74705SXin Li }
308*67e74705SXin Li
309*67e74705SXin Li }
310*67e74705SXin Li
311*67e74705SXin Li namespace test2 {
312*67e74705SXin Li struct A { A(); };
Btest2::B313*67e74705SXin Li struct B : virtual A { B() {} };
Ctest2::C314*67e74705SXin Li struct C : B, A { C() {} };
315*67e74705SXin Li
316*67e74705SXin Li // PR18435: Order mattered here. We were generating code for the delegating
317*67e74705SXin Li // call to B() from C().
callC()318*67e74705SXin Li void callC() { C x; }
319*67e74705SXin Li
320*67e74705SXin Li // CHECK-LABEL: define linkonce_odr x86_thiscallcc %"struct.test2::C"* @"\01??0C@test2@@QAE@XZ"
321*67e74705SXin Li // CHECK: (%"struct.test2::C"* returned %this, i32 %is_most_derived)
322*67e74705SXin Li // CHECK: br i1
323*67e74705SXin Li // Virtual bases
324*67e74705SXin Li // CHECK: call x86_thiscallcc %"struct.test2::A"* @"\01??0A@test2@@QAE@XZ"(%"struct.test2::A"* %{{.*}})
325*67e74705SXin Li // CHECK: br label
326*67e74705SXin Li // Non-virtual bases
327*67e74705SXin Li // CHECK: call x86_thiscallcc %"struct.test2::B"* @"\01??0B@test2@@QAE@XZ"(%"struct.test2::B"* %{{.*}}, i32 0)
328*67e74705SXin Li // CHECK: call x86_thiscallcc %"struct.test2::A"* @"\01??0A@test2@@QAE@XZ"(%"struct.test2::A"* %{{.*}})
329*67e74705SXin Li // CHECK: ret
330*67e74705SXin Li
331*67e74705SXin Li // CHECK2-LABEL: define linkonce_odr x86_thiscallcc %"struct.test2::B"* @"\01??0B@test2@@QAE@XZ"
332*67e74705SXin Li // CHECK2: (%"struct.test2::B"* returned %this, i32 %is_most_derived)
333*67e74705SXin Li // CHECK2: call x86_thiscallcc %"struct.test2::A"* @"\01??0A@test2@@QAE@XZ"(%"struct.test2::A"* %{{.*}})
334*67e74705SXin Li // CHECK2: ret
335*67e74705SXin Li
336*67e74705SXin Li }
337*67e74705SXin Li
338*67e74705SXin Li namespace test3 {
339*67e74705SXin Li // PR19104: A non-virtual call of a virtual method doesn't use vftable thunks,
340*67e74705SXin Li // so requires only static adjustment which is different to the one used
341*67e74705SXin Li // for virtual calls.
342*67e74705SXin Li struct A {
343*67e74705SXin Li virtual void foo();
344*67e74705SXin Li };
345*67e74705SXin Li
346*67e74705SXin Li struct B : virtual A {
347*67e74705SXin Li virtual void bar();
348*67e74705SXin Li };
349*67e74705SXin Li
350*67e74705SXin Li struct C : virtual A {
351*67e74705SXin Li virtual void foo();
352*67e74705SXin Li };
353*67e74705SXin Li
354*67e74705SXin Li struct D : B, C {
355*67e74705SXin Li virtual void bar();
356*67e74705SXin Li int field; // Laid out between C and A subobjects in D.
357*67e74705SXin Li };
358*67e74705SXin Li
bar()359*67e74705SXin Li void D::bar() {
360*67e74705SXin Li // CHECK-LABEL: define x86_thiscallcc void @"\01?bar@D@test3@@UAEXXZ"(%"struct.test3::D"* %this)
361*67e74705SXin Li
362*67e74705SXin Li C::foo();
363*67e74705SXin Li // Shouldn't need any vbtable lookups. All we have to do is adjust to C*,
364*67e74705SXin Li // then compensate for the adjustment performed in the C::foo() prologue.
365*67e74705SXin Li // CHECK-NOT: load i8*, i8**
366*67e74705SXin Li // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test3::D"* %{{.*}} to i8*
367*67e74705SXin Li // CHECK: %[[C_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 8
368*67e74705SXin Li // CHECK: %[[C:.*]] = bitcast i8* %[[C_i8]] to %"struct.test3::C"*
369*67e74705SXin Li // CHECK: %[[C_i8:.*]] = bitcast %"struct.test3::C"* %[[C]] to i8*
370*67e74705SXin Li // CHECK: %[[ARG:.*]] = getelementptr i8, i8* %[[C_i8]], i32 4
371*67e74705SXin Li // CHECK: call x86_thiscallcc void @"\01?foo@C@test3@@UAEXXZ"(i8* %[[ARG]])
372*67e74705SXin Li // CHECK: ret
373*67e74705SXin Li }
374*67e74705SXin Li }
375*67e74705SXin Li
376*67e74705SXin Li namespace test4{
377*67e74705SXin Li // PR19172: We used to merge method vftable locations wrong.
378*67e74705SXin Li
379*67e74705SXin Li struct A {
~Atest4::A380*67e74705SXin Li virtual ~A() {}
381*67e74705SXin Li };
382*67e74705SXin Li
383*67e74705SXin Li struct B {
~Btest4::B384*67e74705SXin Li virtual ~B() {}
385*67e74705SXin Li };
386*67e74705SXin Li
387*67e74705SXin Li struct C : virtual A, B {
388*67e74705SXin Li virtual ~C();
389*67e74705SXin Li };
390*67e74705SXin Li
391*67e74705SXin Li void foo(void*);
392*67e74705SXin Li
~C()393*67e74705SXin Li C::~C() {
394*67e74705SXin Li // CHECK-LABEL: define x86_thiscallcc void @"\01??1C@test4@@UAE@XZ"(%"struct.test4::C"* %this)
395*67e74705SXin Li
396*67e74705SXin Li // In this case "this" points to the most derived class, so no GEPs needed.
397*67e74705SXin Li // CHECK-NOT: getelementptr
398*67e74705SXin Li // CHECK-NOT: bitcast
399*67e74705SXin Li // CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::C"* %{{.*}} to i32 (...)***
400*67e74705SXin Li // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7C@test4@@6BB@1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
401*67e74705SXin Li
402*67e74705SXin Li foo(this);
403*67e74705SXin Li // CHECK: ret
404*67e74705SXin Li }
405*67e74705SXin Li
destroy(C * obj)406*67e74705SXin Li void destroy(C *obj) {
407*67e74705SXin Li // CHECK-LABEL: define void @"\01?destroy@test4@@YAXPAUC@1@@Z"(%"struct.test4::C"* %obj)
408*67e74705SXin Li
409*67e74705SXin Li delete obj;
410*67e74705SXin Li // CHECK: %[[VPTR:.*]] = bitcast %"struct.test4::C"* %[[OBJ:.*]] to i8* (%"struct.test4::C"*, i32)***
411*67e74705SXin Li // CHECK: %[[VFTABLE:.*]] = load i8* (%"struct.test4::C"*, i32)**, i8* (%"struct.test4::C"*, i32)*** %[[VPTR]]
412*67e74705SXin Li // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds i8* (%"struct.test4::C"*, i32)*, i8* (%"struct.test4::C"*, i32)** %[[VFTABLE]], i64 0
413*67e74705SXin Li // CHECK: %[[VFUN:.*]] = load i8* (%"struct.test4::C"*, i32)*, i8* (%"struct.test4::C"*, i32)** %[[VFTENTRY]]
414*67e74705SXin Li // CHECK: call x86_thiscallcc i8* %[[VFUN]](%"struct.test4::C"* %[[OBJ]], i32 1)
415*67e74705SXin Li // CHECK: ret
416*67e74705SXin Li }
417*67e74705SXin Li
418*67e74705SXin Li struct D {
419*67e74705SXin Li virtual void d();
420*67e74705SXin Li };
421*67e74705SXin Li
422*67e74705SXin Li // The first non-virtual base doesn't have a vdtor,
423*67e74705SXin Li // but "this adjustment" is not needed.
424*67e74705SXin Li struct E : D, B, virtual A {
425*67e74705SXin Li virtual ~E();
426*67e74705SXin Li };
427*67e74705SXin Li
~E()428*67e74705SXin Li E::~E() {
429*67e74705SXin Li // CHECK-LABEL: define x86_thiscallcc void @"\01??1E@test4@@UAE@XZ"(%"struct.test4::E"* %this)
430*67e74705SXin Li
431*67e74705SXin Li // In this case "this" points to the most derived class, so no GEPs needed.
432*67e74705SXin Li // CHECK-NOT: getelementptr
433*67e74705SXin Li // CHECK-NOT: bitcast
434*67e74705SXin Li // CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::E"* %{{.*}} to i32 (...)***
435*67e74705SXin Li // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7E@test4@@6BD@1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
436*67e74705SXin Li foo(this);
437*67e74705SXin Li }
438*67e74705SXin Li
destroy(E * obj)439*67e74705SXin Li void destroy(E *obj) {
440*67e74705SXin Li // CHECK-LABEL: define void @"\01?destroy@test4@@YAXPAUE@1@@Z"(%"struct.test4::E"* %obj)
441*67e74705SXin Li
442*67e74705SXin Li // CHECK-NOT: getelementptr
443*67e74705SXin Li // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test4::E"* %[[OBJ:.*]] to i8*
444*67e74705SXin Li // CHECK: %[[B_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 4
445*67e74705SXin Li // CHECK: %[[VPTR:.*]] = bitcast i8* %[[B_i8]] to i8* (%"struct.test4::E"*, i32)***
446*67e74705SXin Li // CHECK: %[[VFTABLE:.*]] = load i8* (%"struct.test4::E"*, i32)**, i8* (%"struct.test4::E"*, i32)*** %[[VPTR]]
447*67e74705SXin Li // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds i8* (%"struct.test4::E"*, i32)*, i8* (%"struct.test4::E"*, i32)** %[[VFTABLE]], i64 0
448*67e74705SXin Li // CHECK: %[[VFUN:.*]] = load i8* (%"struct.test4::E"*, i32)*, i8* (%"struct.test4::E"*, i32)** %[[VFTENTRY]]
449*67e74705SXin Li // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test4::E"* %[[OBJ]] to i8*
450*67e74705SXin Li // CHECK: %[[B_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 4
451*67e74705SXin Li // FIXME: in fact, the call should take i8* and the bitcast is redundant.
452*67e74705SXin Li // CHECK: %[[B_as_E:.*]] = bitcast i8* %[[B_i8]] to %"struct.test4::E"*
453*67e74705SXin Li // CHECK: call x86_thiscallcc i8* %[[VFUN]](%"struct.test4::E"* %[[B_as_E]], i32 1)
454*67e74705SXin Li delete obj;
455*67e74705SXin Li }
456*67e74705SXin Li
457*67e74705SXin Li }
458*67e74705SXin Li
459*67e74705SXin Li namespace test5 {
460*67e74705SXin Li // PR25370: Don't zero-initialize vbptrs in virtual bases.
461*67e74705SXin Li struct A {
462*67e74705SXin Li virtual void f();
463*67e74705SXin Li };
464*67e74705SXin Li
465*67e74705SXin Li struct B : virtual A {
466*67e74705SXin Li int Field;
467*67e74705SXin Li };
468*67e74705SXin Li
469*67e74705SXin Li struct C : B {
470*67e74705SXin Li C();
471*67e74705SXin Li };
472*67e74705SXin Li
C()473*67e74705SXin Li C::C() : B() {}
474*67e74705SXin Li // CHECK-LABEL: define x86_thiscallcc %"struct.test5::C"* @"\01??0C@test5@@QAE@XZ"(
475*67e74705SXin Li // CHECK: %[[THIS:.*]] = load %"struct.test5::C"*, %"struct.test5::C"**
476*67e74705SXin Li // CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
477*67e74705SXin Li
478*67e74705SXin Li // CHECK: %[[SKIP_VBASES]]
479*67e74705SXin Li // CHECK: %[[B:.*]] = bitcast %"struct.test5::C"* %[[THIS]] to %"struct.test5::B"*
480*67e74705SXin Li // CHECK: %[[B_i8:.*]] = bitcast %"struct.test5::B"* %[[B]] to i8*
481*67e74705SXin Li // CHECK: %[[FIELD:.*]] = getelementptr inbounds i8, i8* %[[B_i8]], i32 4
482*67e74705SXin Li // CHECK: call void @llvm.memset.p0i8.i32(i8* %[[FIELD]], i8 0, i32 4, i32 4, i1 false)
483*67e74705SXin Li }
484*67e74705SXin Li
485*67e74705SXin Li namespace pr27621 {
486*67e74705SXin Li // Devirtualization through a static_cast used to make us compute the 'this'
487*67e74705SXin Li // adjustment for B::g instead of C::g. When we directly call C::g, 'this' is a
488*67e74705SXin Li // B*, and the prologue of C::g will adjust it to a C*.
489*67e74705SXin Li struct A { virtual void f(); };
490*67e74705SXin Li struct B { virtual void g(); };
491*67e74705SXin Li struct C final : A, B {
492*67e74705SXin Li virtual void h();
493*67e74705SXin Li void g() override;
494*67e74705SXin Li };
callit(C * p)495*67e74705SXin Li void callit(C *p) {
496*67e74705SXin Li static_cast<B*>(p)->g();
497*67e74705SXin Li }
498*67e74705SXin Li // CHECK-LABEL: define void @"\01?callit@pr27621@@YAXPAUC@1@@Z"(%"struct.pr27621::C"* %{{.*}})
499*67e74705SXin Li // CHECK: %[[B_i8:.*]] = getelementptr i8, i8* %{{.*}}, i32 4
500*67e74705SXin Li // CHECK: call x86_thiscallcc void @"\01?g@C@pr27621@@UAEXXZ"(i8* %[[B_i8]])
501*67e74705SXin Li }
502*67e74705SXin Li
503*67e74705SXin Li namespace test6 {
504*67e74705SXin Li class A {};
505*67e74705SXin Li class B : virtual A {};
506*67e74705SXin Li class C : virtual B {
507*67e74705SXin Li virtual void m_fn1();
508*67e74705SXin Li float field;
509*67e74705SXin Li };
510*67e74705SXin Li class D : C {
511*67e74705SXin Li D();
512*67e74705SXin Li };
D()513*67e74705SXin Li D::D() : C() {}
514*67e74705SXin Li // CHECK-LABEL: define x86_thiscallcc %"class.test6::D"* @"\01??0D@test6@@AAE@XZ"(
515*67e74705SXin Li // CHECK: %[[THIS:.*]] = load %"class.test6::D"*, %"class.test6::D"**
516*67e74705SXin Li // CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
517*67e74705SXin Li
518*67e74705SXin Li // CHECK: %[[SKIP_VBASES]]
519*67e74705SXin Li // CHECK: %[[C:.*]] = bitcast %"class.test6::D"* %[[THIS]] to %"class.test6::C"*
520*67e74705SXin Li // CHECK: %[[C_i8:.*]] = bitcast %"class.test6::C"* %[[C]] to i8*
521*67e74705SXin Li // CHECK: %[[FIELD:.*]] = getelementptr inbounds i8, i8* %[[C_i8]], i32 8
522*67e74705SXin Li // CHECK: call void @llvm.memset.p0i8.i32(i8* %[[FIELD]], i8 0, i32 4, i32 4, i1 false)
523*67e74705SXin Li }
524