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