1*67e74705SXin Li // RUN: %clang_cc1 -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts %s 2>/dev/null \
2*67e74705SXin Li // RUN: | FileCheck %s
3*67e74705SXin Li
4*67e74705SXin Li #pragma pack(push, 8)
5*67e74705SXin Li
6*67e74705SXin Li class B {
7*67e74705SXin Li public:
b()8*67e74705SXin Li virtual void b(){}
9*67e74705SXin Li int b_field;
10*67e74705SXin Li protected:
11*67e74705SXin Li private:
12*67e74705SXin Li };
13*67e74705SXin Li
14*67e74705SXin Li class A : public B {
15*67e74705SXin Li public:
16*67e74705SXin Li int a_field;
a()17*67e74705SXin Li virtual void a(){}
18*67e74705SXin Li char one;
19*67e74705SXin Li protected:
20*67e74705SXin Li private:
21*67e74705SXin Li };
22*67e74705SXin Li
23*67e74705SXin Li class D {
24*67e74705SXin Li public:
b()25*67e74705SXin Li virtual void b(){}
26*67e74705SXin Li double a;
27*67e74705SXin Li };
28*67e74705SXin Li
29*67e74705SXin Li class C : public virtual A,
30*67e74705SXin Li public D, public B {
31*67e74705SXin Li public:
32*67e74705SXin Li double c1_field;
33*67e74705SXin Li int c2_field;
34*67e74705SXin Li double c3_field;
35*67e74705SXin Li int c4_field;
foo()36*67e74705SXin Li virtual void foo(){}
bar()37*67e74705SXin Li virtual void bar(){}
38*67e74705SXin Li protected:
39*67e74705SXin Li private:
40*67e74705SXin Li };
41*67e74705SXin Li
42*67e74705SXin Li struct BaseStruct
43*67e74705SXin Li {
BaseStructBaseStruct44*67e74705SXin Li BaseStruct(){}
45*67e74705SXin Li double v0;
46*67e74705SXin Li float v1;
47*67e74705SXin Li C fg;
48*67e74705SXin Li };
49*67e74705SXin Li
50*67e74705SXin Li struct DerivedStruct : public BaseStruct {
51*67e74705SXin Li int x;
52*67e74705SXin Li };
53*67e74705SXin Li
54*67e74705SXin Li struct G
55*67e74705SXin Li {
56*67e74705SXin Li int g_field;
57*67e74705SXin Li };
58*67e74705SXin Li
59*67e74705SXin Li struct H : public G,
60*67e74705SXin Li public virtual D
61*67e74705SXin Li {
62*67e74705SXin Li };
63*67e74705SXin Li
64*67e74705SXin Li struct I : public virtual D
65*67e74705SXin Li {
~II66*67e74705SXin Li virtual ~I(){}
67*67e74705SXin Li double q;
68*67e74705SXin Li };
69*67e74705SXin Li
70*67e74705SXin Li struct K
71*67e74705SXin Li {
72*67e74705SXin Li int k;
73*67e74705SXin Li };
74*67e74705SXin Li
75*67e74705SXin Li struct L
76*67e74705SXin Li {
77*67e74705SXin Li int l;
78*67e74705SXin Li };
79*67e74705SXin Li
80*67e74705SXin Li struct M : public virtual K
81*67e74705SXin Li {
82*67e74705SXin Li int m;
83*67e74705SXin Li };
84*67e74705SXin Li
85*67e74705SXin Li struct N : public L, public M
86*67e74705SXin Li {
fN87*67e74705SXin Li virtual void f(){}
88*67e74705SXin Li };
89*67e74705SXin Li
90*67e74705SXin Li struct O : public H, public G {
foO91*67e74705SXin Li virtual void fo(){}
92*67e74705SXin Li };
93*67e74705SXin Li
94*67e74705SXin Li struct P : public M, public virtual L {
95*67e74705SXin Li int p;
96*67e74705SXin Li };
97*67e74705SXin Li
98*67e74705SXin Li struct R {};
99*67e74705SXin Li
100*67e74705SXin Li class IA {
101*67e74705SXin Li public:
~IA()102*67e74705SXin Li virtual ~IA(){}
103*67e74705SXin Li virtual void ia() = 0;
104*67e74705SXin Li };
105*67e74705SXin Li
106*67e74705SXin Li class ICh : public virtual IA {
107*67e74705SXin Li public:
~ICh()108*67e74705SXin Li virtual ~ICh(){}
ia()109*67e74705SXin Li virtual void ia(){}
iCh()110*67e74705SXin Li virtual void iCh(){}
111*67e74705SXin Li };
112*67e74705SXin Li
113*67e74705SXin Li struct f {
asdf114*67e74705SXin Li virtual int asd() {return -90;}
115*67e74705SXin Li };
116*67e74705SXin Li
117*67e74705SXin Li struct s : public virtual f {
~ss118*67e74705SXin Li virtual ~s(){}
119*67e74705SXin Li int r;
asds120*67e74705SXin Li virtual int asd() {return -9;}
121*67e74705SXin Li };
122*67e74705SXin Li
123*67e74705SXin Li struct sd : virtual s, virtual ICh {
~sdsd124*67e74705SXin Li virtual ~sd(){}
125*67e74705SXin Li int q;
126*67e74705SXin Li char y;
asdsd127*67e74705SXin Li virtual int asd() {return -1;}
128*67e74705SXin Li };
129*67e74705SXin Li struct AV {
130*67e74705SXin Li virtual void foo();
131*67e74705SXin Li };
132*67e74705SXin Li struct BV : AV {
133*67e74705SXin Li };
134*67e74705SXin Li struct CV : virtual BV {
135*67e74705SXin Li CV();
136*67e74705SXin Li virtual void foo();
137*67e74705SXin Li };
138*67e74705SXin Li struct DV : BV {
139*67e74705SXin Li };
140*67e74705SXin Li struct EV : CV, DV {
141*67e74705SXin Li };
142*67e74705SXin Li #pragma pack(pop)
143*67e74705SXin Li
144*67e74705SXin Li // This needs only for building layouts.
145*67e74705SXin Li // Without this clang doesn`t dump record layouts.
main()146*67e74705SXin Li int main() {
147*67e74705SXin Li // This avoid "Can't yet mangle constructors!" for MS ABI.
148*67e74705SXin Li C* c;
149*67e74705SXin Li c->foo();
150*67e74705SXin Li DerivedStruct* v;
151*67e74705SXin Li H* g;
152*67e74705SXin Li BaseStruct* u;
153*67e74705SXin Li I* i;
154*67e74705SXin Li N* n;
155*67e74705SXin Li O* o;
156*67e74705SXin Li P* p;
157*67e74705SXin Li R* r;
158*67e74705SXin Li sd *h;
159*67e74705SXin Li EV *j;
160*67e74705SXin Li return 0;
161*67e74705SXin Li }
162*67e74705SXin Li
163*67e74705SXin Li // CHECK: 0 | class D
164*67e74705SXin Li // CHECK-NEXT: 0 | (D vftable pointer)
165*67e74705SXin Li // CHECK-NEXT: 8 | double a
166*67e74705SXin Li
167*67e74705SXin Li // CHECK-NEXT: sizeof=16, align=8
168*67e74705SXin Li // CHECK-NEXT: nvsize=16, nvalign=8
169*67e74705SXin Li
170*67e74705SXin Li // CHECK: %class.D = type { i32 (...)**, double }
171*67e74705SXin Li
172*67e74705SXin Li // CHECK: 0 | class B
173*67e74705SXin Li // CHECK-NEXT: 0 | (B vftable pointer)
174*67e74705SXin Li // CHECK-NEXT: 4 | int b_field
175*67e74705SXin Li
176*67e74705SXin Li // CHECK-NEXT: sizeof=8, align=4
177*67e74705SXin Li // CHECK-NEXT: nvsize=8, nvalign=4
178*67e74705SXin Li
179*67e74705SXin Li // CHECK: %class.B = type { i32 (...)**, i32 }
180*67e74705SXin Li
181*67e74705SXin Li // CHECK: 0 | class A
182*67e74705SXin Li // CHECK-NEXT: 0 | class B (primary base)
183*67e74705SXin Li // CHECK-NEXT: 0 | (B vftable pointer)
184*67e74705SXin Li // CHECK-NEXT: 4 | int b_field
185*67e74705SXin Li // CHECK-NEXT: 8 | int a_field
186*67e74705SXin Li // CHECK-NEXT: 12 | char one
187*67e74705SXin Li
188*67e74705SXin Li // CHECK-NEXT: sizeof=16, align=4
189*67e74705SXin Li // CHECK-NEXT: nvsize=16, nvalign=4
190*67e74705SXin Li
191*67e74705SXin Li // CHECK: 0 | class C
192*67e74705SXin Li // CHECK-NEXT: 0 | class D (primary base)
193*67e74705SXin Li // CHECK-NEXT: 0 | (D vftable pointer)
194*67e74705SXin Li // CHECK-NEXT: 8 | double a
195*67e74705SXin Li // CHECK-NEXT: 16 | class B (base)
196*67e74705SXin Li // CHECK-NEXT: 16 | (B vftable pointer)
197*67e74705SXin Li // CHECK-NEXT: 20 | int b_field
198*67e74705SXin Li // CHECK-NEXT: 24 | (C vbtable pointer)
199*67e74705SXin Li // CHECK-NEXT: 32 | double c1_field
200*67e74705SXin Li // CHECK-NEXT: 40 | int c2_field
201*67e74705SXin Li // CHECK-NEXT: 48 | double c3_field
202*67e74705SXin Li // CHECK-NEXT: 56 | int c4_field
203*67e74705SXin Li // CHECK-NEXT: 64 | class A (virtual base)
204*67e74705SXin Li // CHECK-NEXT: 64 | class B (primary base)
205*67e74705SXin Li // CHECK-NEXT: 64 | (B vftable pointer)
206*67e74705SXin Li // CHECK-NEXT: 68 | int b_field
207*67e74705SXin Li // CHECK-NEXT: 72 | int a_field
208*67e74705SXin Li // CHECK-NEXT: 76 | char one
209*67e74705SXin Li
210*67e74705SXin Li // CHECK-NEXT: sizeof=80, align=8
211*67e74705SXin Li // CHECK-NEXT: nvsize=64, nvalign=8
212*67e74705SXin Li
213*67e74705SXin Li // CHECK: %class.A = type { %class.B, i32, i8 }
214*67e74705SXin Li
215*67e74705SXin Li // CHECK: %class.C = type { %class.D, %class.B, i32*, double, i32, double, i32, [4 x i8], %class.A }
216*67e74705SXin Li // CHECK: %class.C.base = type { %class.D, %class.B, i32*, double, i32, double, i32 }
217*67e74705SXin Li
218*67e74705SXin Li // CHECK: 0 | struct BaseStruct
219*67e74705SXin Li // CHECK-NEXT: 0 | double v0
220*67e74705SXin Li // CHECK-NEXT: 8 | float v1
221*67e74705SXin Li // CHECK-NEXT: 16 | class C fg
222*67e74705SXin Li // CHECK-NEXT: 16 | class D (primary base)
223*67e74705SXin Li // CHECK-NEXT: 16 | (D vftable pointer)
224*67e74705SXin Li // CHECK-NEXT: 24 | double a
225*67e74705SXin Li // CHECK-NEXT: 32 | class B (base)
226*67e74705SXin Li // CHECK-NEXT: 32 | (B vftable pointer)
227*67e74705SXin Li // CHECK-NEXT: 36 | int b_field
228*67e74705SXin Li // CHECK-NEXT: 40 | (C vbtable pointer)
229*67e74705SXin Li // CHECK-NEXT: 48 | double c1_field
230*67e74705SXin Li // CHECK-NEXT: 56 | int c2_field
231*67e74705SXin Li // CHECK-NEXT: 64 | double c3_field
232*67e74705SXin Li // CHECK-NEXT: 72 | int c4_field
233*67e74705SXin Li // CHECK-NEXT: 80 | class A (virtual base)
234*67e74705SXin Li // CHECK-NEXT: 80 | class B (primary base)
235*67e74705SXin Li // CHECK-NEXT: 80 | (B vftable pointer)
236*67e74705SXin Li // CHECK-NEXT: 84 | int b_field
237*67e74705SXin Li // CHECK-NEXT: 88 | int a_field
238*67e74705SXin Li // CHECK-NEXT: 92 | char one
239*67e74705SXin Li // CHECK-NEXT: sizeof=96, align=8
240*67e74705SXin Li // CHECK-NEXT: nvsize=96, nvalign=8
241*67e74705SXin Li
242*67e74705SXin Li // CHECK: %struct.BaseStruct = type { double, float, %class.C }
243*67e74705SXin Li
244*67e74705SXin Li // CHECK: 0 | struct DerivedStruct
245*67e74705SXin Li // CHECK-NEXT: 0 | struct BaseStruct (base)
246*67e74705SXin Li // CHECK-NEXT: 0 | double v0
247*67e74705SXin Li // CHECK-NEXT: 8 | float v1
248*67e74705SXin Li // CHECK-NEXT: 16 | class C fg
249*67e74705SXin Li // CHECK-NEXT: 16 | class D (primary base)
250*67e74705SXin Li // CHECK-NEXT: 16 | (D vftable pointer)
251*67e74705SXin Li // CHECK-NEXT: 24 | double a
252*67e74705SXin Li // CHECK-NEXT: 32 | class B (base)
253*67e74705SXin Li // CHECK-NEXT: 32 | (B vftable pointer)
254*67e74705SXin Li // CHECK-NEXT: 36 | int b_field
255*67e74705SXin Li // CHECK-NEXT: 40 | (C vbtable pointer)
256*67e74705SXin Li // CHECK-NEXT: 48 | double c1_field
257*67e74705SXin Li // CHECK-NEXT: 56 | int c2_field
258*67e74705SXin Li // CHECK-NEXT: 64 | double c3_field
259*67e74705SXin Li // CHECK-NEXT: 72 | int c4_field
260*67e74705SXin Li // CHECK-NEXT: 80 | class A (virtual base)
261*67e74705SXin Li // CHECK-NEXT: 80 | class B (primary base)
262*67e74705SXin Li // CHECK-NEXT: 80 | (B vftable pointer)
263*67e74705SXin Li // CHECK-NEXT: 84 | int b_field
264*67e74705SXin Li // CHECK-NEXT: 88 | int a_field
265*67e74705SXin Li // CHECK-NEXT: 92 | char one
266*67e74705SXin Li // CHECK-NEXT: 96 | int x
267*67e74705SXin Li // CHECK-NEXT: sizeof=104, align=8
268*67e74705SXin Li // CHECK-NEXT: nvsize=104, nvalign=8
269*67e74705SXin Li
270*67e74705SXin Li // CHECK: %struct.DerivedStruct = type { %struct.BaseStruct, i32 }
271*67e74705SXin Li
272*67e74705SXin Li // CHECK: 0 | struct G
273*67e74705SXin Li // CHECK-NEXT: 0 | int g_field
274*67e74705SXin Li // CHECK-NEXT: sizeof=4, align=4
275*67e74705SXin Li // CHECK-NEXT: nvsize=4, nvalign=4
276*67e74705SXin Li
277*67e74705SXin Li // CHECK: 0 | struct H
278*67e74705SXin Li // CHECK-NEXT: 0 | struct G (base)
279*67e74705SXin Li // CHECK-NEXT: 0 | int g_field
280*67e74705SXin Li // CHECK-NEXT: 4 | (H vbtable pointer)
281*67e74705SXin Li // CHECK-NEXT: 8 | class D (virtual base)
282*67e74705SXin Li // CHECK-NEXT: 8 | (D vftable pointer)
283*67e74705SXin Li // CHECK-NEXT: 16 | double a
284*67e74705SXin Li // CHECK-NEXT: sizeof=24, align=8
285*67e74705SXin Li // CHECK-NEXT: nvsize=8, nvalign=8
286*67e74705SXin Li
287*67e74705SXin Li // CHECK: %struct.H = type { %struct.G, i32*, %class.D }
288*67e74705SXin Li
289*67e74705SXin Li // CHECK: 0 | struct I
290*67e74705SXin Li // CHECK-NEXT: 0 | (I vftable pointer)
291*67e74705SXin Li // CHECK-NEXT: 8 | (I vbtable pointer)
292*67e74705SXin Li // CHECK-NEXT: 16 | double q
293*67e74705SXin Li // CHECK-NEXT: 24 | class D (virtual base)
294*67e74705SXin Li // CHECK-NEXT: 24 | (D vftable pointer)
295*67e74705SXin Li // CHECK-NEXT: 32 | double a
296*67e74705SXin Li // CHECK-NEXT: sizeof=40, align=8
297*67e74705SXin Li // CHECK-NEXT: nvsize=24, nvalign=8
298*67e74705SXin Li
299*67e74705SXin Li // CHECK: %struct.I = type { i32 (...)**, [4 x i8], i32*, double, %class.D }
300*67e74705SXin Li // CHECK: %struct.I.base = type { i32 (...)**, [4 x i8], i32*, double }
301*67e74705SXin Li
302*67e74705SXin Li // CHECK: 0 | struct L
303*67e74705SXin Li // CHECK-NEXT: 0 | int l
304*67e74705SXin Li // CHECK-NEXT: sizeof=4, align=4
305*67e74705SXin Li // CHECK-NEXT: nvsize=4, nvalign=4
306*67e74705SXin Li
307*67e74705SXin Li // CHECK: 0 | struct K
308*67e74705SXin Li // CHECK-NEXT: 0 | int k
309*67e74705SXin Li // CHECK-NEXT: sizeof=4, align=4
310*67e74705SXin Li // CHECK-NEXT: nvsize=4, nvalign=4
311*67e74705SXin Li
312*67e74705SXin Li // CHECK: 0 | struct M
313*67e74705SXin Li // CHECK-NEXT: 0 | (M vbtable pointer)
314*67e74705SXin Li // CHECK-NEXT: 4 | int m
315*67e74705SXin Li // CHECK-NEXT: 8 | struct K (virtual base)
316*67e74705SXin Li // CHECK-NEXT: 8 | int k
317*67e74705SXin Li // CHECK-NEXT: sizeof=12, align=4
318*67e74705SXin Li
319*67e74705SXin Li //CHECK: %struct.M = type { i32*, i32, %struct.K }
320*67e74705SXin Li //CHECK: %struct.M.base = type { i32*, i32 }
321*67e74705SXin Li
322*67e74705SXin Li // CHECK: 0 | struct N
323*67e74705SXin Li // CHECK-NEXT: 0 | (N vftable pointer)
324*67e74705SXin Li // CHECK-NEXT: 4 | struct L (base)
325*67e74705SXin Li // CHECK-NEXT: 4 | int l
326*67e74705SXin Li // CHECK-NEXT: 8 | struct M (base)
327*67e74705SXin Li // CHECK-NEXT: 8 | (M vbtable pointer)
328*67e74705SXin Li // CHECK-NEXT: 12 | int m
329*67e74705SXin Li // CHECK-NEXT: 16 | struct K (virtual base)
330*67e74705SXin Li // CHECK-NEXT: 16 | int k
331*67e74705SXin Li // CHECK-NEXT: sizeof=20, align=4
332*67e74705SXin Li // CHECK-NEXT: nvsize=16, nvalign=4
333*67e74705SXin Li
334*67e74705SXin Li //CHECK: %struct.N = type { i32 (...)**, %struct.L, %struct.M.base, %struct.K }
335*67e74705SXin Li
336*67e74705SXin Li // CHECK: 0 | struct O
337*67e74705SXin Li // CHECK-NEXT: 0 | (O vftable pointer)
338*67e74705SXin Li // CHECK-NEXT: 8 | struct H (base)
339*67e74705SXin Li // CHECK-NEXT: 8 | struct G (base)
340*67e74705SXin Li // CHECK-NEXT: 8 | int g_field
341*67e74705SXin Li // CHECK-NEXT: 12 | (H vbtable pointer)
342*67e74705SXin Li // CHECK-NEXT: 16 | struct G (base)
343*67e74705SXin Li // CHECK-NEXT: 16 | int g_field
344*67e74705SXin Li // CHECK-NEXT: 24 | class D (virtual base)
345*67e74705SXin Li // CHECK-NEXT: 24 | (D vftable pointer)
346*67e74705SXin Li // CHECK-NEXT: 32 | double a
347*67e74705SXin Li // CHECK-NEXT: | [sizeof=40, align=8
348*67e74705SXin Li // CHECK-NEXT: | nvsize=24, nvalign=8]
349*67e74705SXin Li
350*67e74705SXin Li // CHECK: struct.O = type { i32 (...)**, [4 x i8], %struct.H.base, %struct.G, %class.D }
351*67e74705SXin Li // CHECK: struct.O.base = type { i32 (...)**, [4 x i8], %struct.H.base, %struct.G, [4 x i8] }
352*67e74705SXin Li
353*67e74705SXin Li
354*67e74705SXin Li // CHECK: 0 | struct P
355*67e74705SXin Li // CHECK-NEXT: 0 | struct M (base)
356*67e74705SXin Li // CHECK-NEXT: 0 | (M vbtable pointer)
357*67e74705SXin Li // CHECK-NEXT: 4 | int m
358*67e74705SXin Li // CHECK-NEXT: 8 | int p
359*67e74705SXin Li // CHECK-NEXT: 12 | struct K (virtual base)
360*67e74705SXin Li // CHECK-NEXT: 12 | int k
361*67e74705SXin Li // CHECK-NEXT: 16 | struct L (virtual base)
362*67e74705SXin Li // CHECK-NEXT: 16 | int l
363*67e74705SXin Li // CHECK-NEXT: sizeof=20, align=4
364*67e74705SXin Li // CHECK-NEXT: nvsize=12, nvalign=4
365*67e74705SXin Li
366*67e74705SXin Li //CHECK: %struct.P = type { %struct.M.base, i32, %struct.K, %struct.L }
367*67e74705SXin Li
368*67e74705SXin Li // CHECK: 0 | struct R (empty)
369*67e74705SXin Li // CHECK-NEXT: sizeof=1, align=1
370*67e74705SXin Li // CHECK-NEXT: nvsize=0, nvalign=1
371*67e74705SXin Li
372*67e74705SXin Li //CHECK: %struct.R = type { i8 }
373*67e74705SXin Li
374*67e74705SXin Li // CHECK: 0 | struct f
375*67e74705SXin Li // CHECK-NEXT: 0 | (f vftable pointer)
376*67e74705SXin Li // CHECK-NEXT: sizeof=4, align=4
377*67e74705SXin Li // CHECK-NEXT: nvsize=4, nvalign=4
378*67e74705SXin Li
379*67e74705SXin Li // CHECK: 0 | struct s
380*67e74705SXin Li // CHECK-NEXT: 0 | (s vftable pointer)
381*67e74705SXin Li // CHECK-NEXT: 4 | (s vbtable pointer)
382*67e74705SXin Li // CHECK-NEXT: 8 | int r
383*67e74705SXin Li // CHECK-NEXT: 12 | (vtordisp for vbase f)
384*67e74705SXin Li // CHECK-NEXT: 16 | struct f (virtual base)
385*67e74705SXin Li // CHECK-NEXT: 16 | (f vftable pointer)
386*67e74705SXin Li // CHECK-NEXT: sizeof=20, align=4
387*67e74705SXin Li // CHECK-NEXT: nvsize=12, nvalign=4
388*67e74705SXin Li
389*67e74705SXin Li // CHECK: 0 | class IA
390*67e74705SXin Li // CHECK-NEXT: 0 | (IA vftable pointer)
391*67e74705SXin Li // CHECK-NEXT: sizeof=4, align=4
392*67e74705SXin Li // CHECK-NEXT: nvsize=4, nvalign=4
393*67e74705SXin Li
394*67e74705SXin Li // CHECK: 0 | class ICh
395*67e74705SXin Li // CHECK-NEXT: 0 | (ICh vftable pointer)
396*67e74705SXin Li // CHECK-NEXT: 4 | (ICh vbtable pointer)
397*67e74705SXin Li // CHECK-NEXT: 8 | (vtordisp for vbase IA)
398*67e74705SXin Li // CHECK-NEXT: 12 | class IA (virtual base)
399*67e74705SXin Li // CHECK-NEXT: 12 | (IA vftable pointer)
400*67e74705SXin Li // CHECK-NEXT: sizeof=16, align=4
401*67e74705SXin Li // CHECK-NEXT: nvsize=8, nvalign=4
402*67e74705SXin Li
403*67e74705SXin Li // CHECK: 0 | struct sd
404*67e74705SXin Li // CHECK-NEXT: 0 | (sd vbtable pointer)
405*67e74705SXin Li // CHECK-NEXT: 4 | int q
406*67e74705SXin Li // CHECK-NEXT: 8 | char y
407*67e74705SXin Li // CHECK-NEXT: 12 | (vtordisp for vbase f)
408*67e74705SXin Li // CHECK-NEXT: 16 | struct f (virtual base)
409*67e74705SXin Li // CHECK-NEXT: 16 | (f vftable pointer)
410*67e74705SXin Li // CHECK-NEXT: 20 | struct s (virtual base)
411*67e74705SXin Li // CHECK-NEXT: 20 | (s vftable pointer)
412*67e74705SXin Li // CHECK-NEXT: 24 | (s vbtable pointer)
413*67e74705SXin Li // CHECK-NEXT: 28 | int r
414*67e74705SXin Li // CHECK-NEXT: 32 | (vtordisp for vbase IA)
415*67e74705SXin Li // CHECK-NEXT: 36 | class IA (virtual base)
416*67e74705SXin Li // CHECK-NEXT: 36 | (IA vftable pointer)
417*67e74705SXin Li // CHECK-NEXT: 40 | class ICh (virtual base)
418*67e74705SXin Li // CHECK-NEXT: 40 | (ICh vftable pointer)
419*67e74705SXin Li // CHECK-NEXT: 44 | (ICh vbtable pointer)
420*67e74705SXin Li // CHECK-NEXT: sizeof=48, align=4
421*67e74705SXin Li // CHECK-NEXT: nvsize=12, nvalign=4
422*67e74705SXin Li
423*67e74705SXin Li // CHECK: %struct.f = type { i32 (...)** }
424*67e74705SXin Li // CHECK: %struct.s = type { i32 (...)**, i32*, i32, i32, %struct.f }
425*67e74705SXin Li // CHECK: %class.IA = type { i32 (...)** }
426*67e74705SXin Li // CHECK: %class.ICh = type { i32 (...)**, i32*, i32, %class.IA }
427*67e74705SXin Li // CHECK: %struct.sd = type { i32*, i32, i8, i32, %struct.f, %struct.s.base, i32, %class.IA, %class.ICh.base }
428*67e74705SXin Li
429*67e74705SXin Li // CHECK: 0 | struct AV
430*67e74705SXin Li // CHECK-NEXT: 0 | (AV vftable pointer)
431*67e74705SXin Li // CHECK-NEXT: sizeof=4, align=4
432*67e74705SXin Li // CHECK-NEXT: nvsize=4, nvalign=4
433*67e74705SXin Li
434*67e74705SXin Li
435*67e74705SXin Li // CHECK: 0 | struct BV
436*67e74705SXin Li // CHECK-NEXT: 0 | struct AV (primary base)
437*67e74705SXin Li // CHECK-NEXT: 0 | (AV vftable pointer)
438*67e74705SXin Li // CHECK-NEXT: sizeof=4, align=4
439*67e74705SXin Li // CHECK-NEXT: nvsize=4, nvalign=4
440*67e74705SXin Li
441*67e74705SXin Li
442*67e74705SXin Li // CHECK: 0 | struct CV
443*67e74705SXin Li // CHECK-NEXT: 0 | (CV vbtable pointer)
444*67e74705SXin Li // CHECK-NEXT: 4 | (vtordisp for vbase BV)
445*67e74705SXin Li // CHECK-NEXT: 8 | struct BV (virtual base)
446*67e74705SXin Li // CHECK-NEXT: 8 | struct AV (primary base)
447*67e74705SXin Li // CHECK-NEXT: 8 | (AV vftable pointer)
448*67e74705SXin Li // CHECK-NEXT: sizeof=12, align=4
449*67e74705SXin Li // CHECK-NEXT: nvsize=4, nvalign=4
450*67e74705SXin Li
451*67e74705SXin Li // CHECK: %struct.AV = type { i32 (...)** }
452*67e74705SXin Li // CHECK: %struct.BV = type { %struct.AV }
453*67e74705SXin Li // CHECK: %struct.CV = type { i32*, i32, %struct.BV }
454*67e74705SXin Li // CHECK: %struct.CV.base = type { i32* }
455*67e74705SXin Li
456*67e74705SXin Li // CHECK: 0 | struct DV
457*67e74705SXin Li // CHECK-NEXT: 0 | struct BV (primary base)
458*67e74705SXin Li // CHECK-NEXT: 0 | struct AV (primary base)
459*67e74705SXin Li // CHECK-NEXT: 0 | (AV vftable pointer)
460*67e74705SXin Li // CHECK-NEXT: sizeof=4, align=4
461*67e74705SXin Li // CHECK-NEXT: nvsize=4, nvalign=4
462*67e74705SXin Li
463*67e74705SXin Li // CHECK: %struct.DV = type { %struct.BV }
464*67e74705SXin Li
465*67e74705SXin Li // CHECK: 0 | struct EV
466*67e74705SXin Li // CHECK-NEXT: 0 | struct DV (primary base)
467*67e74705SXin Li // CHECK-NEXT: 0 | struct BV (primary base)
468*67e74705SXin Li // CHECK-NEXT: 0 | struct AV (primary base)
469*67e74705SXin Li // CHECK-NEXT: 0 | (AV vftable pointer)
470*67e74705SXin Li // CHECK-NEXT: 4 | struct CV (base)
471*67e74705SXin Li // CHECK-NEXT: 4 | (CV vbtable pointer)
472*67e74705SXin Li // CHECK-NEXT: 8 | (vtordisp for vbase BV)
473*67e74705SXin Li // CHECK-NEXT: 12 | struct BV (virtual base)
474*67e74705SXin Li // CHECK-NEXT: 12 | struct AV (primary base)
475*67e74705SXin Li // CHECK-NEXT: 12 | (AV vftable pointer)
476*67e74705SXin Li // CHECK-NEXT: sizeof=16, align=4
477*67e74705SXin Li // CHECK-NEXT: nvsize=8, nvalign=4
478*67e74705SXin Li
479*67e74705SXin Li // CHECK: %struct.EV = type { %struct.DV, %struct.CV.base, i32, %struct.BV }
480*67e74705SXin Li // CHECK: %struct.EV.base = type { %struct.DV, %struct.CV.base }
481*67e74705SXin Li
482*67e74705SXin Li // Overriding a method means that all the vbases containing that
483*67e74705SXin Li // method need a vtordisp. Note: this code will cause an error in cl.exe.
484*67e74705SXin Li namespace test1 {
485*67e74705SXin Li struct A { virtual void foo(); };
486*67e74705SXin Li struct B : A {};
487*67e74705SXin Li struct C : virtual A, virtual B { C(); virtual void foo(); };
test()488*67e74705SXin Li void test() { C *c; }
489*67e74705SXin Li
490*67e74705SXin Li // CHECK: 0 | struct test1::C
491*67e74705SXin Li // CHECK-NEXT: 0 | (C vbtable pointer)
492*67e74705SXin Li // CHECK-NEXT: 4 | (vtordisp for vbase A)
493*67e74705SXin Li // CHECK-NEXT: 8 | struct test1::A (virtual base)
494*67e74705SXin Li // CHECK-NEXT: 8 | (A vftable pointer)
495*67e74705SXin Li // CHECK-NEXT: 12 | (vtordisp for vbase B)
496*67e74705SXin Li // CHECK-NEXT: 16 | struct test1::B (virtual base)
497*67e74705SXin Li // CHECK-NEXT: 16 | struct test1::A (primary base)
498*67e74705SXin Li // CHECK-NEXT: 16 | (A vftable pointer)
499*67e74705SXin Li // CHECK-NEXT: sizeof=20, align=4
500*67e74705SXin Li // CHECK-NEXT: nvsize=4, nvalign=4
501*67e74705SXin Li }
502