xref: /aosp_15_r20/external/clang/test/Sema/ms_class_layout.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
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