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