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