xref: /aosp_15_r20/external/clang/test/Layout/ms-x86-vtordisp.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fno-rtti -fms-extensions -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>&1 \
2*67e74705SXin Li // RUN:            | FileCheck %s
3*67e74705SXin Li // RUN: %clang_cc1 -fno-rtti -fms-extensions -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
4*67e74705SXin Li // RUN:            | FileCheck %s -check-prefix CHECK-X64
5*67e74705SXin Li 
6*67e74705SXin Li extern "C" int printf(const char *fmt, ...);
7*67e74705SXin Li 
8*67e74705SXin Li struct B0 {
9*67e74705SXin Li 	int a;
B0B010*67e74705SXin Li 	B0() : a(0xf00000B0) {}
fB011*67e74705SXin Li 	virtual void f() { printf("B0"); }
12*67e74705SXin Li };
13*67e74705SXin Li 
14*67e74705SXin Li struct __declspec(align(16)) B1 {
15*67e74705SXin Li 	int a;
B1B116*67e74705SXin Li 	B1() : a(0xf00000B1) {}
fB117*67e74705SXin Li 	virtual void f() { printf("B1"); }
18*67e74705SXin Li };
19*67e74705SXin Li 
20*67e74705SXin Li struct __declspec(align(16)) Align16 {};
21*67e74705SXin Li struct __declspec(align(32)) Align32 {};
22*67e74705SXin Li struct VAlign16 : virtual Align16 {};
23*67e74705SXin Li struct VAlign32 : virtual Align32 {};
24*67e74705SXin Li 
25*67e74705SXin Li struct A : virtual B0, virtual B1 {
26*67e74705SXin Li 	int a;
AA27*67e74705SXin Li 	A() : a(0xf000000A) {}
fA28*67e74705SXin Li 	virtual void f() { printf("A"); }
gA29*67e74705SXin Li 	virtual void g() { printf("A"); }
30*67e74705SXin Li };
31*67e74705SXin Li 
32*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
33*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
34*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
35*67e74705SXin Li // CHECK-NEXT:    0 | struct A
36*67e74705SXin Li // CHECK-NEXT:    0 |   (A vftable pointer)
37*67e74705SXin Li // CHECK-NEXT:    4 |   (A vbtable pointer)
38*67e74705SXin Li // CHECK-NEXT:    8 |   int a
39*67e74705SXin Li // CHECK-NEXT:   16 |   (vtordisp for vbase B0)
40*67e74705SXin Li // CHECK-NEXT:   20 |   struct B0 (virtual base)
41*67e74705SXin Li // CHECK-NEXT:   20 |     (B0 vftable pointer)
42*67e74705SXin Li // CHECK-NEXT:   24 |     int a
43*67e74705SXin Li // CHECK-NEXT:   44 |   (vtordisp for vbase B1)
44*67e74705SXin Li // CHECK-NEXT:   48 |   struct B1 (virtual base)
45*67e74705SXin Li // CHECK-NEXT:   48 |     (B1 vftable pointer)
46*67e74705SXin Li // CHECK-NEXT:   52 |     int a
47*67e74705SXin Li // CHECK-NEXT:      | [sizeof=64, align=16
48*67e74705SXin Li // CHECK-NEXT:      |  nvsize=12, nvalign=16]
49*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
50*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
51*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
52*67e74705SXin Li // CHECK-X64-NEXT:    0 | struct A
53*67e74705SXin Li // CHECK-X64-NEXT:    0 |   (A vftable pointer)
54*67e74705SXin Li // CHECK-X64-NEXT:    8 |   (A vbtable pointer)
55*67e74705SXin Li // CHECK-X64-NEXT:   16 |   int a
56*67e74705SXin Li // CHECK-X64-NEXT:   36 |   (vtordisp for vbase B0)
57*67e74705SXin Li // CHECK-X64-NEXT:   40 |   struct B0 (virtual base)
58*67e74705SXin Li // CHECK-X64-NEXT:   40 |     (B0 vftable pointer)
59*67e74705SXin Li // CHECK-X64-NEXT:   48 |     int a
60*67e74705SXin Li // CHECK-X64-NEXT:   76 |   (vtordisp for vbase B1)
61*67e74705SXin Li // CHECK-X64-NEXT:   80 |   struct B1 (virtual base)
62*67e74705SXin Li // CHECK-X64-NEXT:   80 |     (B1 vftable pointer)
63*67e74705SXin Li // CHECK-X64-NEXT:   88 |     int a
64*67e74705SXin Li // CHECK-X64-NEXT:      | [sizeof=96, align=16
65*67e74705SXin Li // CHECK-X64-NEXT:      |  nvsize=24, nvalign=16]
66*67e74705SXin Li 
67*67e74705SXin Li struct C : virtual B0, virtual B1, VAlign32 {
68*67e74705SXin Li 	int a;
CC69*67e74705SXin Li 	C() : a(0xf000000C) {}
fC70*67e74705SXin Li 	virtual void f() { printf("C"); }
gC71*67e74705SXin Li 	virtual void g() { printf("C"); }
72*67e74705SXin Li };
73*67e74705SXin Li 
74*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
75*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
76*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
77*67e74705SXin Li // CHECK-NEXT:    0 | struct C
78*67e74705SXin Li // CHECK-NEXT:    0 |   (C vftable pointer)
79*67e74705SXin Li // CHECK-NEXT:   32 |   struct VAlign32 (base)
80*67e74705SXin Li // CHECK-NEXT:   32 |     (VAlign32 vbtable pointer)
81*67e74705SXin Li // CHECK-NEXT:   36 |   int a
82*67e74705SXin Li // CHECK-NEXT:   64 |   (vtordisp for vbase B0)
83*67e74705SXin Li // CHECK-NEXT:   68 |   struct B0 (virtual base)
84*67e74705SXin Li // CHECK-NEXT:   68 |     (B0 vftable pointer)
85*67e74705SXin Li // CHECK-NEXT:   72 |     int a
86*67e74705SXin Li // CHECK-NEXT:  108 |   (vtordisp for vbase B1)
87*67e74705SXin Li // CHECK-NEXT:  112 |   struct B1 (virtual base)
88*67e74705SXin Li // CHECK-NEXT:  112 |     (B1 vftable pointer)
89*67e74705SXin Li // CHECK-NEXT:  116 |     int a
90*67e74705SXin Li // CHECK-NEXT:  128 |   struct Align32 (virtual base) (empty)
91*67e74705SXin Li // CHECK-NEXT:      | [sizeof=128, align=32
92*67e74705SXin Li // CHECK-NEXT:      |  nvsize=64, nvalign=32]
93*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
94*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
95*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
96*67e74705SXin Li // CHECK-X64-NEXT:    0 | struct C
97*67e74705SXin Li // CHECK-X64-NEXT:    0 |   (C vftable pointer)
98*67e74705SXin Li // CHECK-X64-NEXT:   32 |   struct VAlign32 (base)
99*67e74705SXin Li // CHECK-X64-NEXT:   32 |     (VAlign32 vbtable pointer)
100*67e74705SXin Li // CHECK-X64-NEXT:   40 |   int a
101*67e74705SXin Li // CHECK-X64-NEXT:   68 |   (vtordisp for vbase B0)
102*67e74705SXin Li // CHECK-X64-NEXT:   72 |   struct B0 (virtual base)
103*67e74705SXin Li // CHECK-X64-NEXT:   72 |     (B0 vftable pointer)
104*67e74705SXin Li // CHECK-X64-NEXT:   80 |     int a
105*67e74705SXin Li // CHECK-X64-NEXT:  108 |   (vtordisp for vbase B1)
106*67e74705SXin Li // CHECK-X64-NEXT:  112 |   struct B1 (virtual base)
107*67e74705SXin Li // CHECK-X64-NEXT:  112 |     (B1 vftable pointer)
108*67e74705SXin Li // CHECK-X64-NEXT:  120 |     int a
109*67e74705SXin Li // CHECK-X64-NEXT:  128 |   struct Align32 (virtual base) (empty)
110*67e74705SXin Li // CHECK-X64-NEXT:      | [sizeof=128, align=32
111*67e74705SXin Li // CHECK-X64-NEXT:      |  nvsize=64, nvalign=32]
112*67e74705SXin Li 
113*67e74705SXin Li struct __declspec(align(32)) D : virtual B0, virtual B1  {
114*67e74705SXin Li 	int a;
DD115*67e74705SXin Li 	D() : a(0xf000000D) {}
fD116*67e74705SXin Li 	virtual void f() { printf("D"); }
gD117*67e74705SXin Li 	virtual void g() { printf("D"); }
118*67e74705SXin Li };
119*67e74705SXin Li 
120*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
121*67e74705SXin Li // CHECK-NEXT:    0 | struct D
122*67e74705SXin Li // CHECK-NEXT:    0 |   (D vftable pointer)
123*67e74705SXin Li // CHECK-NEXT:    4 |   (D vbtable pointer)
124*67e74705SXin Li // CHECK-NEXT:    8 |   int a
125*67e74705SXin Li // CHECK-NEXT:   32 |   (vtordisp for vbase B0)
126*67e74705SXin Li // CHECK-NEXT:   36 |   struct B0 (virtual base)
127*67e74705SXin Li // CHECK-NEXT:   36 |     (B0 vftable pointer)
128*67e74705SXin Li // CHECK-NEXT:   40 |     int a
129*67e74705SXin Li // CHECK-NEXT:   76 |   (vtordisp for vbase B1)
130*67e74705SXin Li // CHECK-NEXT:   80 |   struct B1 (virtual base)
131*67e74705SXin Li // CHECK-NEXT:   80 |     (B1 vftable pointer)
132*67e74705SXin Li // CHECK-NEXT:   84 |     int a
133*67e74705SXin Li // CHECK-NEXT:      | [sizeof=96, align=32
134*67e74705SXin Li // CHECK-NEXT:      |  nvsize=12, nvalign=32]
135*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
136*67e74705SXin Li // CHECK-X64-NEXT:    0 | struct D
137*67e74705SXin Li // CHECK-X64-NEXT:    0 |   (D vftable pointer)
138*67e74705SXin Li // CHECK-X64-NEXT:    8 |   (D vbtable pointer)
139*67e74705SXin Li // CHECK-X64-NEXT:   16 |   int a
140*67e74705SXin Li // CHECK-X64-NEXT:   36 |   (vtordisp for vbase B0)
141*67e74705SXin Li // CHECK-X64-NEXT:   40 |   struct B0 (virtual base)
142*67e74705SXin Li // CHECK-X64-NEXT:   40 |     (B0 vftable pointer)
143*67e74705SXin Li // CHECK-X64-NEXT:   48 |     int a
144*67e74705SXin Li // CHECK-X64-NEXT:   76 |   (vtordisp for vbase B1)
145*67e74705SXin Li // CHECK-X64-NEXT:   80 |   struct B1 (virtual base)
146*67e74705SXin Li // CHECK-X64-NEXT:   80 |     (B1 vftable pointer)
147*67e74705SXin Li // CHECK-X64-NEXT:   88 |     int a
148*67e74705SXin Li // CHECK-X64-NEXT:      | [sizeof=96, align=32
149*67e74705SXin Li // CHECK-X64-NEXT:      |  nvsize=24, nvalign=32]
150*67e74705SXin Li 
151*67e74705SXin Li struct AT {
~ATAT152*67e74705SXin Li 	virtual ~AT(){}
153*67e74705SXin Li };
154*67e74705SXin Li struct CT : virtual AT {
155*67e74705SXin Li 	virtual ~CT();
156*67e74705SXin Li };
~CT()157*67e74705SXin Li CT::~CT(){}
158*67e74705SXin Li 
159*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
160*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
161*67e74705SXin Li // CHECK-NEXT:    0 | struct CT
162*67e74705SXin Li // CHECK-NEXT:    0 |   (CT vbtable pointer)
163*67e74705SXin Li // CHECK-NEXT:    4 |   struct AT (virtual base)
164*67e74705SXin Li // CHECK-NEXT:    4 |     (AT vftable pointer)
165*67e74705SXin Li // CHECK-NEXT:      | [sizeof=8, align=4
166*67e74705SXin Li // CHECK-NEXT:      |  nvsize=4, nvalign=4]
167*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
168*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
169*67e74705SXin Li // CHECK-X64-NEXT:    0 | struct CT
170*67e74705SXin Li // CHECK-X64-NEXT:    0 |   (CT vbtable pointer)
171*67e74705SXin Li // CHECK-X64-NEXT:    8 |   struct AT (virtual base)
172*67e74705SXin Li // CHECK-X64-NEXT:    8 |     (AT vftable pointer)
173*67e74705SXin Li // CHECK-X64-NEXT:      | [sizeof=16, align=8
174*67e74705SXin Li // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
175*67e74705SXin Li 
176*67e74705SXin Li struct XA {
XAXA177*67e74705SXin Li 	XA() { printf("XA"); }
178*67e74705SXin Li 	long long ll;
179*67e74705SXin Li };
180*67e74705SXin Li struct XB : XA {
XBXB181*67e74705SXin Li 	XB() { printf("XB"); }
fooXB182*67e74705SXin Li 	virtual void foo() {}
183*67e74705SXin Li 	int b;
184*67e74705SXin Li };
185*67e74705SXin Li struct XC : virtual XB {
XCXC186*67e74705SXin Li 	XC() { printf("XC"); }
fooXC187*67e74705SXin Li 	virtual void foo() {}
188*67e74705SXin Li };
189*67e74705SXin Li 
190*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
191*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
192*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
193*67e74705SXin Li // CHECK-NEXT:    0 | struct XC
194*67e74705SXin Li // CHECK-NEXT:    0 |   (XC vbtable pointer)
195*67e74705SXin Li // CHECK-NEXT:    4 |   (vtordisp for vbase XB)
196*67e74705SXin Li // CHECK-NEXT:    8 |   struct XB (virtual base)
197*67e74705SXin Li // CHECK-NEXT:    8 |     (XB vftable pointer)
198*67e74705SXin Li // CHECK-NEXT:   16 |     struct XA (base)
199*67e74705SXin Li // CHECK-NEXT:   16 |       long long ll
200*67e74705SXin Li // CHECK-NEXT:   24 |     int b
201*67e74705SXin Li // CHECK-NEXT:      | [sizeof=32, align=8
202*67e74705SXin Li // CHECK-NEXT:      |  nvsize=4, nvalign=8]
203*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
204*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
205*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
206*67e74705SXin Li // CHECK-X64-NEXT:    0 | struct XC
207*67e74705SXin Li // CHECK-X64-NEXT:    0 |   (XC vbtable pointer)
208*67e74705SXin Li // CHECK-X64-NEXT:   12 |   (vtordisp for vbase XB)
209*67e74705SXin Li // CHECK-X64-NEXT:   16 |   struct XB (virtual base)
210*67e74705SXin Li // CHECK-X64-NEXT:   16 |     (XB vftable pointer)
211*67e74705SXin Li // CHECK-X64-NEXT:   24 |     struct XA (base)
212*67e74705SXin Li // CHECK-X64-NEXT:   24 |       long long ll
213*67e74705SXin Li // CHECK-X64-NEXT:   32 |     int b
214*67e74705SXin Li // CHECK-X64-NEXT:      | [sizeof=40, align=8
215*67e74705SXin Li // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
216*67e74705SXin Li 
217*67e74705SXin Li namespace pragma_test1 {
218*67e74705SXin Li // No overrides means no vtordisps by default.
219*67e74705SXin Li struct A { virtual ~A(); virtual void foo(); int a; };
220*67e74705SXin Li struct B : virtual A { virtual ~B(); virtual void bar(); int b; };
221*67e74705SXin Li struct C : virtual B { int c; };
222*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
223*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
224*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
225*67e74705SXin Li // CHECK-NEXT:    0 | struct pragma_test1::C
226*67e74705SXin Li // CHECK-NEXT:    0 |   (C vbtable pointer)
227*67e74705SXin Li // CHECK-NEXT:    4 |   int c
228*67e74705SXin Li // CHECK-NEXT:    8 |   struct pragma_test1::A (virtual base)
229*67e74705SXin Li // CHECK-NEXT:    8 |     (A vftable pointer)
230*67e74705SXin Li // CHECK-NEXT:   12 |     int a
231*67e74705SXin Li // CHECK-NEXT:   16 |   struct pragma_test1::B (virtual base)
232*67e74705SXin Li // CHECK-NEXT:   16 |     (B vftable pointer)
233*67e74705SXin Li // CHECK-NEXT:   20 |     (B vbtable pointer)
234*67e74705SXin Li // CHECK-NEXT:   24 |     int b
235*67e74705SXin Li // CHECK-NEXT:      | [sizeof=28, align=4
236*67e74705SXin Li // CHECK-NEXT:      |  nvsize=8, nvalign=4]
237*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
238*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
239*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
240*67e74705SXin Li }
241*67e74705SXin Li 
242*67e74705SXin Li namespace pragma_test2 {
243*67e74705SXin Li struct A { virtual ~A(); virtual void foo(); int a; };
244*67e74705SXin Li #pragma vtordisp(push,2)
245*67e74705SXin Li struct B : virtual A { virtual ~B(); virtual void bar(); int b; };
246*67e74705SXin Li struct C : virtual B { int c; };
247*67e74705SXin Li #pragma vtordisp(pop)
248*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
249*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
250*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
251*67e74705SXin Li // CHECK-NEXT:    0 | struct pragma_test2::C
252*67e74705SXin Li // CHECK-NEXT:    0 |   (C vbtable pointer)
253*67e74705SXin Li // CHECK-NEXT:    4 |   int c
254*67e74705SXin Li // CHECK-NEXT:    8 |   (vtordisp for vbase A)
255*67e74705SXin Li // CHECK-NEXT:   12 |   struct pragma_test2::A (virtual base)
256*67e74705SXin Li // CHECK-NEXT:   12 |     (A vftable pointer)
257*67e74705SXin Li // CHECK-NEXT:   16 |     int a
258*67e74705SXin Li //   By adding a virtual method and vftable to B, now we need a vtordisp.
259*67e74705SXin Li // CHECK-NEXT:   20 |   (vtordisp for vbase B)
260*67e74705SXin Li // CHECK-NEXT:   24 |   struct pragma_test2::B (virtual base)
261*67e74705SXin Li // CHECK-NEXT:   24 |     (B vftable pointer)
262*67e74705SXin Li // CHECK-NEXT:   28 |     (B vbtable pointer)
263*67e74705SXin Li // CHECK-NEXT:   32 |     int b
264*67e74705SXin Li // CHECK-NEXT:      | [sizeof=36, align=4
265*67e74705SXin Li // CHECK-NEXT:      |  nvsize=8, nvalign=4]
266*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
267*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
268*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
269*67e74705SXin Li }
270*67e74705SXin Li 
271*67e74705SXin Li namespace pragma_test3 {
272*67e74705SXin Li struct A { virtual ~A(); virtual void foo(); int a; };
273*67e74705SXin Li #pragma vtordisp(push,2)
274*67e74705SXin Li struct B : virtual A { virtual ~B(); virtual void foo(); int b; };
275*67e74705SXin Li struct C : virtual B { int c; };
276*67e74705SXin Li #pragma vtordisp(pop)
277*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
278*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
279*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
280*67e74705SXin Li // CHECK-NEXT:    0 | struct pragma_test3::C
281*67e74705SXin Li // CHECK-NEXT:    0 |   (C vbtable pointer)
282*67e74705SXin Li // CHECK-NEXT:    4 |   int c
283*67e74705SXin Li // CHECK-NEXT:    8 |   (vtordisp for vbase A)
284*67e74705SXin Li // CHECK-NEXT:   12 |   struct pragma_test3::A (virtual base)
285*67e74705SXin Li // CHECK-NEXT:   12 |     (A vftable pointer)
286*67e74705SXin Li // CHECK-NEXT:   16 |     int a
287*67e74705SXin Li //   No vtordisp before B!  It doesn't have its own vftable.
288*67e74705SXin Li // CHECK-NEXT:   20 |   struct pragma_test3::B (virtual base)
289*67e74705SXin Li // CHECK-NEXT:   20 |     (B vbtable pointer)
290*67e74705SXin Li // CHECK-NEXT:   24 |     int b
291*67e74705SXin Li // CHECK-NEXT:      | [sizeof=28, align=4
292*67e74705SXin Li // CHECK-NEXT:      |  nvsize=8, nvalign=4]
293*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
294*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
295*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
296*67e74705SXin Li }
297*67e74705SXin Li 
298*67e74705SXin Li namespace pragma_test4 {
299*67e74705SXin Li struct A {
300*67e74705SXin Li   A();
301*67e74705SXin Li   virtual void foo();
302*67e74705SXin Li   int a;
303*67e74705SXin Li };
304*67e74705SXin Li 
305*67e74705SXin Li // Make sure the pragma applies to class template decls before they've been
306*67e74705SXin Li // instantiated.
307*67e74705SXin Li #pragma vtordisp(push,2)
308*67e74705SXin Li template <typename T>
309*67e74705SXin Li struct B : virtual A {
310*67e74705SXin Li   B();
311*67e74705SXin Li   virtual ~B();
312*67e74705SXin Li   virtual void bar();
313*67e74705SXin Li   T b;
314*67e74705SXin Li };
315*67e74705SXin Li #pragma vtordisp(pop)
316*67e74705SXin Li 
317*67e74705SXin Li struct C : virtual B<int> { int c; };
318*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
319*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
320*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
321*67e74705SXin Li // CHECK-NEXT:    0 | struct pragma_test4::C
322*67e74705SXin Li // CHECK-NEXT:    0 |   (C vbtable pointer)
323*67e74705SXin Li // CHECK-NEXT:    4 |   int c
324*67e74705SXin Li //   Pragma applies to B, which has vbase A.
325*67e74705SXin Li // CHECK-NEXT:    8 |   (vtordisp for vbase A)
326*67e74705SXin Li // CHECK-NEXT:   12 |   struct pragma_test4::A (virtual base)
327*67e74705SXin Li // CHECK-NEXT:   12 |     (A vftable pointer)
328*67e74705SXin Li // CHECK-NEXT:   16 |     int a
329*67e74705SXin Li //   Pragma does not apply to C, and B doesn't usually need a vtordisp in C.
330*67e74705SXin Li // CHECK-NEXT:   20 |   struct pragma_test4::B<int> (virtual base)
331*67e74705SXin Li // CHECK-NEXT:   20 |     (B vftable pointer)
332*67e74705SXin Li // CHECK-NEXT:   24 |     (B vbtable pointer)
333*67e74705SXin Li // CHECK-NEXT:   28 |     int b
334*67e74705SXin Li // CHECK-NEXT:      | [sizeof=32, align=4
335*67e74705SXin Li // CHECK-NEXT:      |  nvsize=8, nvalign=4]
336*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
337*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
338*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
339*67e74705SXin Li }
340*67e74705SXin Li 
341*67e74705SXin Li struct GA {
funGA342*67e74705SXin Li 	virtual void fun() {}
343*67e74705SXin Li };
344*67e74705SXin Li struct GB: public GA {};
345*67e74705SXin Li struct GC: public virtual GA {
funGC346*67e74705SXin Li 	virtual void fun() {}
GCGC347*67e74705SXin Li 	GC() {}
348*67e74705SXin Li };
349*67e74705SXin Li struct GD: public virtual GC, public virtual GB {};
350*67e74705SXin Li 
351*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
352*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
353*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
354*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
355*67e74705SXin Li // CHECK-NEXT:    0 | struct GD
356*67e74705SXin Li // CHECK-NEXT:    0 |   (GD vbtable pointer)
357*67e74705SXin Li // CHECK-NEXT:    4 |   (vtordisp for vbase GA)
358*67e74705SXin Li // CHECK-NEXT:    8 |   struct GA (virtual base)
359*67e74705SXin Li // CHECK-NEXT:    8 |     (GA vftable pointer)
360*67e74705SXin Li // CHECK-NEXT:   12 |   struct GC (virtual base)
361*67e74705SXin Li // CHECK-NEXT:   12 |     (GC vbtable pointer)
362*67e74705SXin Li // CHECK-NEXT:   16 |   struct GB (virtual base)
363*67e74705SXin Li // CHECK-NEXT:   16 |     struct GA (primary base)
364*67e74705SXin Li // CHECK-NEXT:   16 |       (GA vftable pointer)
365*67e74705SXin Li // CHECK-NEXT:      | [sizeof=20, align=4
366*67e74705SXin Li // CHECK-NEXT:      |  nvsize=4, nvalign=4]
367*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
368*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
369*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
370*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
371*67e74705SXin Li // CHECK-X64-NEXT:    0 | struct GD
372*67e74705SXin Li // CHECK-X64-NEXT:    0 |   (GD vbtable pointer)
373*67e74705SXin Li // CHECK-X64-NEXT:   12 |   (vtordisp for vbase GA)
374*67e74705SXin Li // CHECK-X64-NEXT:   16 |   struct GA (virtual base)
375*67e74705SXin Li // CHECK-X64-NEXT:   16 |     (GA vftable pointer)
376*67e74705SXin Li // CHECK-X64-NEXT:   24 |   struct GC (virtual base)
377*67e74705SXin Li // CHECK-X64-NEXT:   24 |     (GC vbtable pointer)
378*67e74705SXin Li // CHECK-X64-NEXT:   32 |   struct GB (virtual base)
379*67e74705SXin Li // CHECK-X64-NEXT:   32 |     struct GA (primary base)
380*67e74705SXin Li // CHECK-X64-NEXT:   32 |       (GA vftable pointer)
381*67e74705SXin Li // CHECK-X64-NEXT:      | [sizeof=40, align=8
382*67e74705SXin Li // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
383*67e74705SXin Li 
384*67e74705SXin Li struct HA {
funHA385*67e74705SXin Li   virtual void fun() {}
386*67e74705SXin Li };
387*67e74705SXin Li #pragma vtordisp(push, 2)
388*67e74705SXin Li struct HB : virtual HA {};
389*67e74705SXin Li #pragma vtordisp(pop)
390*67e74705SXin Li #pragma vtordisp(push, 0)
391*67e74705SXin Li struct HC : virtual HB {};
392*67e74705SXin Li #pragma vtordisp(pop)
393*67e74705SXin Li 
394*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
395*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
396*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
397*67e74705SXin Li // CHECK-NEXT:    0 | struct HC
398*67e74705SXin Li // CHECK-NEXT:    0 |   (HC vbtable pointer)
399*67e74705SXin Li // CHECK-NEXT:    4 |   (vtordisp for vbase HA)
400*67e74705SXin Li // CHECK-NEXT:    8 |   struct HA (virtual base)
401*67e74705SXin Li // CHECK-NEXT:    8 |     (HA vftable pointer)
402*67e74705SXin Li // CHECK-NEXT:   12 |   struct HB (virtual base)
403*67e74705SXin Li // CHECK-NEXT:   12 |     (HB vbtable pointer)
404*67e74705SXin Li // CHECK-NEXT:      | [sizeof=16, align=4
405*67e74705SXin Li // CHECK-NEXT:      |  nvsize=4, nvalign=4]
406*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
407*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
408*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
409*67e74705SXin Li // CHECK-X64-NEXT:    0 | struct HC
410*67e74705SXin Li // CHECK-X64-NEXT:    0 |   (HC vbtable pointer)
411*67e74705SXin Li // CHECK-X64-NEXT:   12 |   (vtordisp for vbase HA)
412*67e74705SXin Li // CHECK-X64-NEXT:   16 |   struct HA (virtual base)
413*67e74705SXin Li // CHECK-X64-NEXT:   16 |     (HA vftable pointer)
414*67e74705SXin Li // CHECK-X64-NEXT:   24 |   struct HB (virtual base)
415*67e74705SXin Li // CHECK-X64-NEXT:   24 |     (HB vbtable pointer)
416*67e74705SXin Li // CHECK-X64-NEXT:      | [sizeof=32, align=8
417*67e74705SXin Li // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
418*67e74705SXin Li 
419*67e74705SXin Li struct IA {
420*67e74705SXin Li   virtual void f();
421*67e74705SXin Li };
422*67e74705SXin Li struct __declspec(dllexport) IB : virtual IA {
423*67e74705SXin Li   virtual void f() = 0;
IBIB424*67e74705SXin Li   IB() {}
425*67e74705SXin Li };
426*67e74705SXin Li 
427*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
428*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
429*67e74705SXin Li // CHECK-NEXT:    0 | struct IB
430*67e74705SXin Li // CHECK-NEXT:    0 |   (IB vbtable pointer)
431*67e74705SXin Li // CHECK-NEXT:    4 |   struct IA (virtual base)
432*67e74705SXin Li // CHECK-NEXT:    4 |     (IA vftable pointer)
433*67e74705SXin Li // CHECK-NEXT:      | [sizeof=8, align=4
434*67e74705SXin Li // CHECK-NEXT:      |  nvsize=4, nvalign=4]
435*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
436*67e74705SXin Li // CHECK-X64: *** Dumping AST Record Layout
437*67e74705SXin Li // CHECK-X64-NEXT:    0 | struct IB
438*67e74705SXin Li // CHECK-X64-NEXT:    0 |   (IB vbtable pointer)
439*67e74705SXin Li // CHECK-X64-NEXT:    8 |   struct IA (virtual base)
440*67e74705SXin Li // CHECK-X64-NEXT:    8 |     (IA vftable pointer)
441*67e74705SXin Li // CHECK-X64-NEXT:      | [sizeof=16, align=8
442*67e74705SXin Li // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
443*67e74705SXin Li 
444*67e74705SXin Li int a[
445*67e74705SXin Li sizeof(A)+
446*67e74705SXin Li sizeof(C)+
447*67e74705SXin Li sizeof(D)+
448*67e74705SXin Li sizeof(CT)+
449*67e74705SXin Li sizeof(XC)+
450*67e74705SXin Li sizeof(pragma_test1::C)+
451*67e74705SXin Li sizeof(pragma_test2::C)+
452*67e74705SXin Li sizeof(pragma_test3::C)+
453*67e74705SXin Li sizeof(pragma_test4::C)+
454*67e74705SXin Li sizeof(GD)+
455*67e74705SXin Li sizeof(HC)+
456*67e74705SXin Li sizeof(IB)+
457*67e74705SXin Li 0];
458