1// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
2// RUN:            | FileCheck %s
3// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
4// RUN:            | FileCheck %s -check-prefix CHECK-X64
5
6extern "C" int printf(const char *fmt, ...);
7
8struct B0 { int a; B0() : a(0xf00000B0) { printf("B0 = %p\n", this); } virtual void f() { printf("B0"); } };
9struct B1 { int a; B1() : a(0xf00000B1) { printf("B1 = %p\n", this); } virtual void g() { printf("B1"); } };
10struct B2 { int a; B2() : a(0xf00000B2) { printf("B1 = %p\n", this); } };
11struct B0X { int a; B0X() : a(0xf00000B0) {} };
12struct B1X { int a; B1X() : a(0xf00000B1) {} virtual void f() { printf("B0"); } };
13struct B2X : virtual B1X { int a; B2X() : a(0xf00000B2) {} };
14
15struct A : virtual B0 {
16};
17
18// CHECK: *** Dumping AST Record Layout
19// CHECK: *** Dumping AST Record Layout
20// CHECK-NEXT:    0 | struct A
21// CHECK-NEXT:    0 |   (A vbtable pointer)
22// CHECK-NEXT:    4 |   struct B0 (virtual base)
23// CHECK-NEXT:    4 |     (B0 vftable pointer)
24// CHECK-NEXT:    8 |     int a
25// CHECK-NEXT:      | [sizeof=12, align=4
26// CHECK-NEXT:      |  nvsize=4, nvalign=4]
27// CHECK-X64: *** Dumping AST Record Layout
28// CHECK-X64: *** Dumping AST Record Layout
29// CHECK-X64-NEXT:    0 | struct A
30// CHECK-X64-NEXT:    0 |   (A vbtable pointer)
31// CHECK-X64-NEXT:    8 |   struct B0 (virtual base)
32// CHECK-X64-NEXT:    8 |     (B0 vftable pointer)
33// CHECK-X64-NEXT:   16 |     int a
34// CHECK-X64-NEXT:      | [sizeof=24, align=8
35// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
36
37struct B : virtual B0 {
38	virtual void f() { printf("B"); }
39};
40
41// CHECK: *** Dumping AST Record Layout
42// CHECK-NEXT:    0 | struct B
43// CHECK-NEXT:    0 |   (B vbtable pointer)
44// CHECK-NEXT:    4 |   struct B0 (virtual base)
45// CHECK-NEXT:    4 |     (B0 vftable pointer)
46// CHECK-NEXT:    8 |     int a
47// CHECK-NEXT:      | [sizeof=12, align=4
48// CHECK-NEXT:      |  nvsize=4, nvalign=4]
49// CHECK-X64: *** Dumping AST Record Layout
50// CHECK-X64-NEXT:    0 | struct B
51// CHECK-X64-NEXT:    0 |   (B vbtable pointer)
52// CHECK-X64-NEXT:    8 |   struct B0 (virtual base)
53// CHECK-X64-NEXT:    8 |     (B0 vftable pointer)
54// CHECK-X64-NEXT:   16 |     int a
55// CHECK-X64-NEXT:      | [sizeof=24, align=8
56// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
57
58struct C : virtual B0 {
59	virtual void g() { printf("A"); }
60};
61
62// CHECK: *** Dumping AST Record Layout
63// CHECK-NEXT:    0 | struct C
64// CHECK-NEXT:    0 |   (C vftable pointer)
65// CHECK-NEXT:    4 |   (C vbtable pointer)
66// CHECK-NEXT:    8 |   struct B0 (virtual base)
67// CHECK-NEXT:    8 |     (B0 vftable pointer)
68// CHECK-NEXT:   12 |     int a
69// CHECK-NEXT:      | [sizeof=16, align=4
70// CHECK-NEXT:      |  nvsize=8, nvalign=4]
71// CHECK-X64: *** Dumping AST Record Layout
72// CHECK-X64-NEXT:    0 | struct C
73// CHECK-X64-NEXT:    0 |   (C vftable pointer)
74// CHECK-X64-NEXT:    8 |   (C vbtable pointer)
75// CHECK-X64-NEXT:   16 |   struct B0 (virtual base)
76// CHECK-X64-NEXT:   16 |     (B0 vftable pointer)
77// CHECK-X64-NEXT:   24 |     int a
78// CHECK-X64-NEXT:      | [sizeof=32, align=8
79// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
80
81struct D : virtual B2, virtual B0 {
82	virtual void f() { printf("D"); }
83	virtual void g() { printf("D"); }
84};
85
86// CHECK: *** Dumping AST Record Layout
87// CHECK: *** Dumping AST Record Layout
88// CHECK-NEXT:    0 | struct D
89// CHECK-NEXT:    0 |   (D vftable pointer)
90// CHECK-NEXT:    4 |   (D vbtable pointer)
91// CHECK-NEXT:    8 |   struct B2 (virtual base)
92// CHECK-NEXT:    8 |     int a
93// CHECK-NEXT:   12 |   struct B0 (virtual base)
94// CHECK-NEXT:   12 |     (B0 vftable pointer)
95// CHECK-NEXT:   16 |     int a
96// CHECK-NEXT:      | [sizeof=20, align=4
97// CHECK-NEXT:      |  nvsize=8, nvalign=4]
98// CHECK-X64: *** Dumping AST Record Layout
99// CHECK-X64: *** Dumping AST Record Layout
100// CHECK-X64-NEXT:    0 | struct D
101// CHECK-X64-NEXT:    0 |   (D vftable pointer)
102// CHECK-X64-NEXT:    8 |   (D vbtable pointer)
103// CHECK-X64-NEXT:   16 |   struct B2 (virtual base)
104// CHECK-X64-NEXT:   16 |     int a
105// CHECK-X64-NEXT:   24 |   struct B0 (virtual base)
106// CHECK-X64-NEXT:   24 |     (B0 vftable pointer)
107// CHECK-X64-NEXT:   32 |     int a
108// CHECK-X64-NEXT:      | [sizeof=40, align=8
109// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
110
111struct E : B0, virtual B1 {
112	virtual void f() { printf("E"); }
113	virtual void g() { printf("E"); }
114};
115
116// CHECK: *** Dumping AST Record Layout
117// CHECK: *** Dumping AST Record Layout
118// CHECK-NEXT:    0 | struct E
119// CHECK-NEXT:    0 |   struct B0 (primary base)
120// CHECK-NEXT:    0 |     (B0 vftable pointer)
121// CHECK-NEXT:    4 |     int a
122// CHECK-NEXT:    8 |   (E vbtable pointer)
123// CHECK-NEXT:   12 |   struct B1 (virtual base)
124// CHECK-NEXT:   12 |     (B1 vftable pointer)
125// CHECK-NEXT:   16 |     int a
126// CHECK-NEXT:      | [sizeof=20, align=4
127// CHECK-NEXT:      |  nvsize=12, nvalign=4]
128// CHECK-X64: *** Dumping AST Record Layout
129// CHECK-X64: *** Dumping AST Record Layout
130// CHECK-X64-NEXT:    0 | struct E
131// CHECK-X64-NEXT:    0 |   struct B0 (primary base)
132// CHECK-X64-NEXT:    0 |     (B0 vftable pointer)
133// CHECK-X64-NEXT:    8 |     int a
134// CHECK-X64-NEXT:   16 |   (E vbtable pointer)
135// CHECK-X64-NEXT:   24 |   struct B1 (virtual base)
136// CHECK-X64-NEXT:   24 |     (B1 vftable pointer)
137// CHECK-X64-NEXT:   32 |     int a
138// CHECK-X64-NEXT:      | [sizeof=40, align=8
139// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
140
141struct F : virtual B0, virtual B1 {
142};
143
144// CHECK: *** Dumping AST Record Layout
145// CHECK-NEXT:    0 | struct F
146// CHECK-NEXT:    0 |   (F vbtable pointer)
147// CHECK-NEXT:    4 |   struct B0 (virtual base)
148// CHECK-NEXT:    4 |     (B0 vftable pointer)
149// CHECK-NEXT:    8 |     int a
150// CHECK-NEXT:   12 |   struct B1 (virtual base)
151// CHECK-NEXT:   12 |     (B1 vftable pointer)
152// CHECK-NEXT:   16 |     int a
153// CHECK-NEXT:      | [sizeof=20, align=4
154// CHECK-NEXT:      |  nvsize=4, nvalign=4]
155// CHECK-X64: *** Dumping AST Record Layout
156// CHECK-X64-NEXT:    0 | struct F
157// CHECK-X64-NEXT:    0 |   (F vbtable pointer)
158// CHECK-X64-NEXT:    8 |   struct B0 (virtual base)
159// CHECK-X64-NEXT:    8 |     (B0 vftable pointer)
160// CHECK-X64-NEXT:   16 |     int a
161// CHECK-X64-NEXT:   24 |   struct B1 (virtual base)
162// CHECK-X64-NEXT:   24 |     (B1 vftable pointer)
163// CHECK-X64-NEXT:   32 |     int a
164// CHECK-X64-NEXT:      | [sizeof=40, align=8
165// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
166
167struct AX : B0X, B1X { int a; AX() : a(0xf000000A) {} virtual void f() { printf("A"); } };
168
169// CHECK: *** Dumping AST Record Layout
170// CHECK: *** Dumping AST Record Layout
171// CHECK: *** Dumping AST Record Layout
172// CHECK-NEXT:    0 | struct AX
173// CHECK-NEXT:    0 |   struct B1X (primary base)
174// CHECK-NEXT:    0 |     (B1X vftable pointer)
175// CHECK-NEXT:    4 |     int a
176// CHECK-NEXT:    8 |   struct B0X (base)
177// CHECK-NEXT:    8 |     int a
178// CHECK-NEXT:   12 |   int a
179// CHECK-NEXT:      | [sizeof=16, align=4
180// CHECK-NEXT:      |  nvsize=16, nvalign=4]
181// CHECK-X64: *** Dumping AST Record Layout
182// CHECK-X64: *** Dumping AST Record Layout
183// CHECK-X64: *** Dumping AST Record Layout
184// CHECK-X64-NEXT:    0 | struct AX
185// CHECK-X64-NEXT:    0 |   struct B1X (primary base)
186// CHECK-X64-NEXT:    0 |     (B1X vftable pointer)
187// CHECK-X64-NEXT:    8 |     int a
188// CHECK-X64-NEXT:   16 |   struct B0X (base)
189// CHECK-X64-NEXT:   16 |     int a
190// CHECK-X64-NEXT:   20 |   int a
191// CHECK-X64-NEXT:      | [sizeof=24, align=8
192// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
193
194struct BX : B0X, B1X { int a; BX() : a(0xf000000B) {} virtual void g() { printf("B"); } };
195
196// CHECK: *** Dumping AST Record Layout
197// CHECK-NEXT:    0 | struct BX
198// CHECK-NEXT:    0 |   struct B1X (primary base)
199// CHECK-NEXT:    0 |     (B1X vftable pointer)
200// CHECK-NEXT:    4 |     int a
201// CHECK-NEXT:    8 |   struct B0X (base)
202// CHECK-NEXT:    8 |     int a
203// CHECK-NEXT:   12 |   int a
204// CHECK-NEXT:      | [sizeof=16, align=4
205// CHECK-NEXT:      |  nvsize=16, nvalign=4]
206// CHECK-X64: *** Dumping AST Record Layout
207// CHECK-X64-NEXT:    0 | struct BX
208// CHECK-X64-NEXT:    0 |   struct B1X (primary base)
209// CHECK-X64-NEXT:    0 |     (B1X vftable pointer)
210// CHECK-X64-NEXT:    8 |     int a
211// CHECK-X64-NEXT:   16 |   struct B0X (base)
212// CHECK-X64-NEXT:   16 |     int a
213// CHECK-X64-NEXT:   20 |   int a
214// CHECK-X64-NEXT:      | [sizeof=24, align=8
215// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
216
217struct CX : B0X, B2X { int a; CX() : a(0xf000000C) {} virtual void g() { printf("C"); } };
218
219// CHECK: *** Dumping AST Record Layout
220// CHECK: *** Dumping AST Record Layout
221// CHECK-NEXT:    0 | struct CX
222// CHECK-NEXT:    0 |   (CX vftable pointer)
223// CHECK-NEXT:    4 |   struct B0X (base)
224// CHECK-NEXT:    4 |     int a
225// CHECK-NEXT:    8 |   struct B2X (base)
226// CHECK-NEXT:    8 |     (B2X vbtable pointer)
227// CHECK-NEXT:   12 |     int a
228// CHECK-NEXT:   16 |   int a
229// CHECK-NEXT:   20 |   struct B1X (virtual base)
230// CHECK-NEXT:   20 |     (B1X vftable pointer)
231// CHECK-NEXT:   24 |     int a
232// CHECK-NEXT:      | [sizeof=28, align=4
233// CHECK-NEXT:      |  nvsize=20, nvalign=4]
234// CHECK-X64: *** Dumping AST Record Layout
235// CHECK-X64: *** Dumping AST Record Layout
236// CHECK-X64-NEXT:    0 | struct CX
237// CHECK-X64-NEXT:    0 |   (CX vftable pointer)
238// CHECK-X64-NEXT:    8 |   struct B0X (base)
239// CHECK-X64-NEXT:    8 |     int a
240// CHECK-X64-NEXT:   16 |   struct B2X (base)
241// CHECK-X64-NEXT:   16 |     (B2X vbtable pointer)
242// CHECK-X64-NEXT:   24 |     int a
243// CHECK-X64-NEXT:   32 |   int a
244// CHECK-X64-NEXT:   40 |   struct B1X (virtual base)
245// CHECK-X64-NEXT:   40 |     (B1X vftable pointer)
246// CHECK-X64-NEXT:   48 |     int a
247// CHECK-X64-NEXT:      | [sizeof=56, align=8
248// CHECK-X64-NEXT:      |  nvsize=40, nvalign=8]
249
250struct DX : virtual B1X { int a; DX() : a(0xf000000D) {} virtual void f() { printf("D"); } };
251
252// CHECK: *** Dumping AST Record Layout
253// CHECK-NEXT:    0 | struct DX
254// CHECK-NEXT:    0 |   (DX vbtable pointer)
255// CHECK-NEXT:    4 |   int a
256// CHECK-NEXT:    8 |   (vtordisp for vbase B1X)
257// CHECK-NEXT:   12 |   struct B1X (virtual base)
258// CHECK-NEXT:   12 |     (B1X vftable pointer)
259// CHECK-NEXT:   16 |     int a
260// CHECK-NEXT:      | [sizeof=20, align=4
261// CHECK-NEXT:      |  nvsize=8, nvalign=4]
262// CHECK-X64: *** Dumping AST Record Layout
263// CHECK-X64-NEXT:    0 | struct DX
264// CHECK-X64-NEXT:    0 |   (DX vbtable pointer)
265// CHECK-X64-NEXT:    8 |   int a
266// CHECK-X64-NEXT:   20 |   (vtordisp for vbase B1X)
267// CHECK-X64-NEXT:   24 |   struct B1X (virtual base)
268// CHECK-X64-NEXT:   24 |     (B1X vftable pointer)
269// CHECK-X64-NEXT:   32 |     int a
270// CHECK-X64-NEXT:      | [sizeof=40, align=8
271// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
272
273struct EX : virtual B1X { int a; EX() : a(0xf000000E) {} virtual void g() { printf("E"); } };
274
275// CHECK: *** Dumping AST Record Layout
276// CHECK-NEXT:    0 | struct EX
277// CHECK-NEXT:    0 |   (EX vftable pointer)
278// CHECK-NEXT:    4 |   (EX vbtable pointer)
279// CHECK-NEXT:    8 |   int a
280// CHECK-NEXT:   12 |   struct B1X (virtual base)
281// CHECK-NEXT:   12 |     (B1X vftable pointer)
282// CHECK-NEXT:   16 |     int a
283// CHECK-NEXT:      | [sizeof=20, align=4
284// CHECK-NEXT:      |  nvsize=12, nvalign=4]
285// CHECK-X64: *** Dumping AST Record Layout
286// CHECK-X64-NEXT:    0 | struct EX
287// CHECK-X64-NEXT:    0 |   (EX vftable pointer)
288// CHECK-X64-NEXT:    8 |   (EX vbtable pointer)
289// CHECK-X64-NEXT:   16 |   int a
290// CHECK-X64-NEXT:   24 |   struct B1X (virtual base)
291// CHECK-X64-NEXT:   24 |     (B1X vftable pointer)
292// CHECK-X64-NEXT:   32 |     int a
293// CHECK-X64-NEXT:      | [sizeof=40, align=8
294// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
295
296struct FX : virtual B1X { int a; FX() : a(0xf000000F) {} };
297
298// CHECK: *** Dumping AST Record Layout
299// CHECK-NEXT:    0 | struct FX
300// CHECK-NEXT:    0 |   (FX vbtable pointer)
301// CHECK-NEXT:    4 |   int a
302// CHECK-NEXT:    8 |   struct B1X (virtual base)
303// CHECK-NEXT:    8 |     (B1X vftable pointer)
304// CHECK-NEXT:   12 |     int a
305// CHECK-NEXT:      | [sizeof=16, align=4
306// CHECK-NEXT:      |  nvsize=8, nvalign=4]
307// CHECK-X64: *** Dumping AST Record Layout
308// CHECK-X64-NEXT:    0 | struct FX
309// CHECK-X64-NEXT:    0 |   (FX vbtable pointer)
310// CHECK-X64-NEXT:    8 |   int a
311// CHECK-X64-NEXT:   16 |   struct B1X (virtual base)
312// CHECK-X64-NEXT:   16 |     (B1X vftable pointer)
313// CHECK-X64-NEXT:   24 |     int a
314// CHECK-X64-NEXT:      | [sizeof=32, align=8
315// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
316
317int a[
318sizeof(A)+
319sizeof(B)+
320sizeof(C)+
321sizeof(D)+
322sizeof(E)+
323sizeof(F)+
324sizeof(AX)+
325sizeof(BX)+
326sizeof(CX)+
327sizeof(DX)+
328sizeof(EX)+
329sizeof(FX)];
330