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 { B0() { printf("B0 = %p\n", this); } };
9struct B1 { B1() { printf("B1 = %p\n", this); } };
10struct B2 { B2() { printf("B2 = %p\n", this); } };
11struct B3 { B3() { printf("B3 = %p\n", this); } };
12struct B4 { B4() { printf("B4 = %p\n", this); } };
13struct B5 { B5() { printf("B5 = %p\n", this); } };
14struct __declspec(align(2)) B6 { B6() { printf("B6 = %p\n", this); } };
15struct __declspec(align(16)) B7 { B7() { printf("B7 = %p\n", this); } };
16struct B8 { char c[5]; B8() { printf("B8 = %p\n", this); } };
17struct B9 { char c[6]; B9() { printf("B9 = %p\n", this); } };
18struct B10 { char c[7]; B10() { printf("B10 = %p\n", this); } };
19struct B11 { char c[8]; B11() { printf("B11 = %p\n", this); } };
20struct B0X { B0X() { printf("B0 = %p\n", this); } };
21struct B1X { B1X() { printf("B1 = %p\n", this); } };
22struct __declspec(align(16)) B2X { B2X() { printf("B2 = %p\n", this); } };
23struct __declspec(align(2)) B3X { B3X() { printf("B3 = %p\n", this); } };
24struct B4X { B4X() { printf("B4 = %p\n", this); } };
25struct B5X { B5X() { printf("B5 = %p\n", this); } };
26struct B6X { B6X() { printf("B6 = %p\n", this); } };
27struct B8X { short a; B8X() : a(0x000000B8) { printf("B8 = %p\n", this); } };
28
29struct AA : B8, B1, virtual B0 {
30	int a;
31	AA() : a(0x000000AA) { printf("AA = %p\n", this); }
32};
33
34// CHECK: *** Dumping AST Record Layout
35// CHECK: *** Dumping AST Record Layout
36// CHECK: *** Dumping AST Record Layout
37// CHECK: *** Dumping AST Record Layout
38// CHECK-NEXT:    0 | struct AA
39// CHECK-NEXT:    0 |   struct B8 (base)
40// CHECK-NEXT:    0 |     char [5] c
41// CHECK-NEXT:   13 |   struct B1 (base) (empty)
42// CHECK-NEXT:    8 |   (AA vbtable pointer)
43// CHECK-NEXT:   16 |   int a
44// CHECK-NEXT:   20 |   struct B0 (virtual base) (empty)
45// CHECK-NEXT:      | [sizeof=20, align=4
46// CHECK-NEXT:      |  nvsize=20, nvalign=4]
47// CHECK-X64: *** Dumping AST Record Layout
48// CHECK-X64: *** Dumping AST Record Layout
49// CHECK-X64: *** Dumping AST Record Layout
50// CHECK-X64: *** Dumping AST Record Layout
51// CHECK-X64-NEXT:    0 | struct AA
52// CHECK-X64-NEXT:    0 |   struct B8 (base)
53// CHECK-X64-NEXT:    0 |     char [5] c
54// CHECK-X64-NEXT:   17 |   struct B1 (base) (empty)
55// CHECK-X64-NEXT:    8 |   (AA vbtable pointer)
56// CHECK-X64-NEXT:   20 |   int a
57// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
58// CHECK-X64-NEXT:      | [sizeof=24, align=8
59// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
60
61struct AB : B8, B1, virtual B0 {
62	short a;
63	AB() : a(0x000000AB) { printf("AB = %p\n", this); }
64};
65
66// CHECK: *** Dumping AST Record Layout
67// CHECK-NEXT:    0 | struct AB
68// CHECK-NEXT:    0 |   struct B8 (base)
69// CHECK-NEXT:    0 |     char [5] c
70// CHECK-NEXT:   13 |   struct B1 (base) (empty)
71// CHECK-NEXT:    8 |   (AB vbtable pointer)
72// CHECK-NEXT:   14 |   short a
73// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
74// CHECK-NEXT:      | [sizeof=16, align=4
75// CHECK-NEXT:      |  nvsize=16, nvalign=4]
76// CHECK-X64: *** Dumping AST Record Layout
77// CHECK-X64-NEXT:    0 | struct AB
78// CHECK-X64-NEXT:    0 |   struct B8 (base)
79// CHECK-X64-NEXT:    0 |     char [5] c
80// CHECK-X64-NEXT:   17 |   struct B1 (base) (empty)
81// CHECK-X64-NEXT:    8 |   (AB vbtable pointer)
82// CHECK-X64-NEXT:   18 |   short a
83// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
84// CHECK-X64-NEXT:      | [sizeof=24, align=8
85// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
86
87struct AC : B8, B1, virtual B0 {
88	char a;
89	AC() : a(0x000000AC) { printf("AC = %p\n", this); }
90};
91
92// CHECK: *** Dumping AST Record Layout
93// CHECK-NEXT:    0 | struct AC
94// CHECK-NEXT:    0 |   struct B8 (base)
95// CHECK-NEXT:    0 |     char [5] c
96// CHECK-NEXT:   12 |   struct B1 (base) (empty)
97// CHECK-NEXT:    8 |   (AC vbtable pointer)
98// CHECK-NEXT:   12 |   char a
99// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
100// CHECK-NEXT:      | [sizeof=16, align=4
101// CHECK-NEXT:      |  nvsize=16, nvalign=4]
102// CHECK-X64: *** Dumping AST Record Layout
103// CHECK-X64-NEXT:    0 | struct AC
104// CHECK-X64-NEXT:    0 |   struct B8 (base)
105// CHECK-X64-NEXT:    0 |     char [5] c
106// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
107// CHECK-X64-NEXT:    8 |   (AC vbtable pointer)
108// CHECK-X64-NEXT:   16 |   char a
109// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
110// CHECK-X64-NEXT:      | [sizeof=24, align=8
111// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
112
113struct AD : B8, B1, virtual B0 {
114	AD() { printf("AD = %p\n", this); }
115};
116
117// CHECK: *** Dumping AST Record Layout
118// CHECK-NEXT:    0 | struct AD
119// CHECK-NEXT:    0 |   struct B8 (base)
120// CHECK-NEXT:    0 |     char [5] c
121// CHECK-NEXT:   12 |   struct B1 (base) (empty)
122// CHECK-NEXT:    8 |   (AD vbtable pointer)
123// CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
124// CHECK-NEXT:      | [sizeof=12, align=4
125// CHECK-NEXT:      |  nvsize=12, nvalign=4]
126// CHECK-X64: *** Dumping AST Record Layout
127// CHECK-X64-NEXT:    0 | struct AD
128// CHECK-X64-NEXT:    0 |   struct B8 (base)
129// CHECK-X64-NEXT:    0 |     char [5] c
130// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
131// CHECK-X64-NEXT:    8 |   (AD vbtable pointer)
132// CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
133// CHECK-X64-NEXT:      | [sizeof=16, align=8
134// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
135
136struct AA1 : B9, B1, virtual B0 {
137	int a;
138	AA1() : a(0x00000AA1) { printf("AA1 = %p\n", this); }
139};
140
141// CHECK: *** Dumping AST Record Layout
142// CHECK: *** Dumping AST Record Layout
143// CHECK-NEXT:    0 | struct AA1
144// CHECK-NEXT:    0 |   struct B9 (base)
145// CHECK-NEXT:    0 |     char [6] c
146// CHECK-NEXT:   14 |   struct B1 (base) (empty)
147// CHECK-NEXT:    8 |   (AA1 vbtable pointer)
148// CHECK-NEXT:   16 |   int a
149// CHECK-NEXT:   20 |   struct B0 (virtual base) (empty)
150// CHECK-NEXT:      | [sizeof=20, align=4
151// CHECK-NEXT:      |  nvsize=20, nvalign=4]
152// CHECK-X64: *** Dumping AST Record Layout
153// CHECK-X64: *** Dumping AST Record Layout
154// CHECK-X64-NEXT:    0 | struct AA1
155// CHECK-X64-NEXT:    0 |   struct B9 (base)
156// CHECK-X64-NEXT:    0 |     char [6] c
157// CHECK-X64-NEXT:   18 |   struct B1 (base) (empty)
158// CHECK-X64-NEXT:    8 |   (AA1 vbtable pointer)
159// CHECK-X64-NEXT:   20 |   int a
160// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
161// CHECK-X64-NEXT:      | [sizeof=24, align=8
162// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
163
164struct AB1 : B9, B1, virtual B0 {
165	short a;
166	AB1() : a(0x00000AB1) { printf("AB1 = %p\n", this); }
167};
168
169// CHECK: *** Dumping AST Record Layout
170// CHECK-NEXT:    0 | struct AB1
171// CHECK-NEXT:    0 |   struct B9 (base)
172// CHECK-NEXT:    0 |     char [6] c
173// CHECK-NEXT:   12 |   struct B1 (base) (empty)
174// CHECK-NEXT:    8 |   (AB1 vbtable pointer)
175// CHECK-NEXT:   12 |   short a
176// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
177// CHECK-NEXT:      | [sizeof=16, align=4
178// CHECK-NEXT:      |  nvsize=16, nvalign=4]
179// CHECK-X64: *** Dumping AST Record Layout
180// CHECK-X64-NEXT:    0 | struct AB1
181// CHECK-X64-NEXT:    0 |   struct B9 (base)
182// CHECK-X64-NEXT:    0 |     char [6] c
183// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
184// CHECK-X64-NEXT:    8 |   (AB1 vbtable pointer)
185// CHECK-X64-NEXT:   16 |   short a
186// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
187// CHECK-X64-NEXT:      | [sizeof=24, align=8
188// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
189
190struct AC1 : B9, B1, virtual B0 {
191	char a;
192	AC1() : a(0x000000C1) { printf("AC1 = %p\n", this); }
193};
194
195// CHECK: *** Dumping AST Record Layout
196// CHECK-NEXT:    0 | struct AC1
197// CHECK-NEXT:    0 |   struct B9 (base)
198// CHECK-NEXT:    0 |     char [6] c
199// CHECK-NEXT:   12 |   struct B1 (base) (empty)
200// CHECK-NEXT:    8 |   (AC1 vbtable pointer)
201// CHECK-NEXT:   12 |   char a
202// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
203// CHECK-NEXT:      | [sizeof=16, align=4
204// CHECK-NEXT:      |  nvsize=16, nvalign=4]
205// CHECK-X64: *** Dumping AST Record Layout
206// CHECK-X64-NEXT:    0 | struct AC1
207// CHECK-X64-NEXT:    0 |   struct B9 (base)
208// CHECK-X64-NEXT:    0 |     char [6] c
209// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
210// CHECK-X64-NEXT:    8 |   (AC1 vbtable pointer)
211// CHECK-X64-NEXT:   16 |   char a
212// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
213// CHECK-X64-NEXT:      | [sizeof=24, align=8
214// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
215
216struct AD1 : B9, B1, virtual B0 {
217	AD1() { printf("AD1 = %p\n", this); }
218};
219
220// CHECK: *** Dumping AST Record Layout
221// CHECK-NEXT:    0 | struct AD1
222// CHECK-NEXT:    0 |   struct B9 (base)
223// CHECK-NEXT:    0 |     char [6] c
224// CHECK-NEXT:   12 |   struct B1 (base) (empty)
225// CHECK-NEXT:    8 |   (AD1 vbtable pointer)
226// CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
227// CHECK-NEXT:      | [sizeof=12, align=4
228// CHECK-NEXT:      |  nvsize=12, nvalign=4]
229// CHECK-X64: *** Dumping AST Record Layout
230// CHECK-X64-NEXT:    0 | struct AD1
231// CHECK-X64-NEXT:    0 |   struct B9 (base)
232// CHECK-X64-NEXT:    0 |     char [6] c
233// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
234// CHECK-X64-NEXT:    8 |   (AD1 vbtable pointer)
235// CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
236// CHECK-X64-NEXT:      | [sizeof=16, align=8
237// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
238
239struct AA2 : B10, B1, virtual B0 {
240	int a;
241	AA2() : a(0x00000AA2) { printf("AA2 = %p\n", this); }
242};
243
244// CHECK: *** Dumping AST Record Layout
245// CHECK: *** Dumping AST Record Layout
246// CHECK-NEXT:    0 | struct AA2
247// CHECK-NEXT:    0 |   struct B10 (base)
248// CHECK-NEXT:    0 |     char [7] c
249// CHECK-NEXT:   15 |   struct B1 (base) (empty)
250// CHECK-NEXT:    8 |   (AA2 vbtable pointer)
251// CHECK-NEXT:   16 |   int a
252// CHECK-NEXT:   20 |   struct B0 (virtual base) (empty)
253// CHECK-NEXT:      | [sizeof=20, align=4
254// CHECK-NEXT:      |  nvsize=20, nvalign=4]
255// CHECK-X64: *** Dumping AST Record Layout
256// CHECK-X64: *** Dumping AST Record Layout
257// CHECK-X64-NEXT:    0 | struct AA2
258// CHECK-X64-NEXT:    0 |   struct B10 (base)
259// CHECK-X64-NEXT:    0 |     char [7] c
260// CHECK-X64-NEXT:   19 |   struct B1 (base) (empty)
261// CHECK-X64-NEXT:    8 |   (AA2 vbtable pointer)
262// CHECK-X64-NEXT:   20 |   int a
263// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
264// CHECK-X64-NEXT:      | [sizeof=24, align=8
265// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
266
267struct AB2 : B10, B1, virtual B0 {
268	short a;
269	AB2() : a(0x00000AB2) { printf("AB2 = %p\n", this); }
270};
271
272// CHECK: *** Dumping AST Record Layout
273// CHECK-NEXT:    0 | struct AB2
274// CHECK-NEXT:    0 |   struct B10 (base)
275// CHECK-NEXT:    0 |     char [7] c
276// CHECK-NEXT:   13 |   struct B1 (base) (empty)
277// CHECK-NEXT:    8 |   (AB2 vbtable pointer)
278// CHECK-NEXT:   14 |   short a
279// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
280// CHECK-NEXT:      | [sizeof=16, align=4
281// CHECK-NEXT:      |  nvsize=16, nvalign=4]
282// CHECK-X64: *** Dumping AST Record Layout
283// CHECK-X64-NEXT:    0 | struct AB2
284// CHECK-X64-NEXT:    0 |   struct B10 (base)
285// CHECK-X64-NEXT:    0 |     char [7] c
286// CHECK-X64-NEXT:   17 |   struct B1 (base) (empty)
287// CHECK-X64-NEXT:    8 |   (AB2 vbtable pointer)
288// CHECK-X64-NEXT:   18 |   short a
289// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
290// CHECK-X64-NEXT:      | [sizeof=24, align=8
291// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
292
293struct AC2 : B10, B1, virtual B0 {
294	char a;
295	AC2() : a(0x000000C2) { printf("AC2 = %p\n", this); }
296};
297
298// CHECK: *** Dumping AST Record Layout
299// CHECK-NEXT:    0 | struct AC2
300// CHECK-NEXT:    0 |   struct B10 (base)
301// CHECK-NEXT:    0 |     char [7] c
302// CHECK-NEXT:   12 |   struct B1 (base) (empty)
303// CHECK-NEXT:    8 |   (AC2 vbtable pointer)
304// CHECK-NEXT:   12 |   char a
305// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
306// CHECK-NEXT:      | [sizeof=16, align=4
307// CHECK-NEXT:      |  nvsize=16, nvalign=4]
308// CHECK-X64: *** Dumping AST Record Layout
309// CHECK-X64-NEXT:    0 | struct AC2
310// CHECK-X64-NEXT:    0 |   struct B10 (base)
311// CHECK-X64-NEXT:    0 |     char [7] c
312// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
313// CHECK-X64-NEXT:    8 |   (AC2 vbtable pointer)
314// CHECK-X64-NEXT:   16 |   char a
315// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
316// CHECK-X64-NEXT:      | [sizeof=24, align=8
317// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
318
319struct AD2 : B10, B1, virtual B0 {
320	AD2() { printf("AD2 = %p\n", this); }
321};
322
323// CHECK: *** Dumping AST Record Layout
324// CHECK-NEXT:    0 | struct AD2
325// CHECK-NEXT:    0 |   struct B10 (base)
326// CHECK-NEXT:    0 |     char [7] c
327// CHECK-NEXT:   12 |   struct B1 (base) (empty)
328// CHECK-NEXT:    8 |   (AD2 vbtable pointer)
329// CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
330// CHECK-NEXT:      | [sizeof=12, align=4
331// CHECK-NEXT:      |  nvsize=12, nvalign=4]
332// CHECK-X64: *** Dumping AST Record Layout
333// CHECK-X64-NEXT:    0 | struct AD2
334// CHECK-X64-NEXT:    0 |   struct B10 (base)
335// CHECK-X64-NEXT:    0 |     char [7] c
336// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
337// CHECK-X64-NEXT:    8 |   (AD2 vbtable pointer)
338// CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
339// CHECK-X64-NEXT:      | [sizeof=16, align=8
340// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
341
342struct AA3 : B11, B1, virtual B0 {
343	int a;
344	AA3() : a(0x00000AA3) { printf("AA3 = %p\n", this); }
345};
346
347// CHECK: *** Dumping AST Record Layout
348// CHECK: *** Dumping AST Record Layout
349// CHECK-NEXT:    0 | struct AA3
350// CHECK-NEXT:    0 |   struct B11 (base)
351// CHECK-NEXT:    0 |     char [8] c
352// CHECK-NEXT:   12 |   struct B1 (base) (empty)
353// CHECK-NEXT:    8 |   (AA3 vbtable pointer)
354// CHECK-NEXT:   12 |   int a
355// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
356// CHECK-NEXT:      | [sizeof=16, align=4
357// CHECK-NEXT:      |  nvsize=16, nvalign=4]
358// CHECK-X64: *** Dumping AST Record Layout
359// CHECK-X64: *** Dumping AST Record Layout
360// CHECK-X64-NEXT:    0 | struct AA3
361// CHECK-X64-NEXT:    0 |   struct B11 (base)
362// CHECK-X64-NEXT:    0 |     char [8] c
363// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
364// CHECK-X64-NEXT:    8 |   (AA3 vbtable pointer)
365// CHECK-X64-NEXT:   16 |   int a
366// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
367// CHECK-X64-NEXT:      | [sizeof=24, align=8
368// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
369
370struct AB3 : B11, B1, virtual B0 {
371	short a;
372	AB3() : a(0x00000AB3) { printf("AB3 = %p\n", this); }
373};
374
375// CHECK: *** Dumping AST Record Layout
376// CHECK-NEXT:    0 | struct AB3
377// CHECK-NEXT:    0 |   struct B11 (base)
378// CHECK-NEXT:    0 |     char [8] c
379// CHECK-NEXT:   12 |   struct B1 (base) (empty)
380// CHECK-NEXT:    8 |   (AB3 vbtable pointer)
381// CHECK-NEXT:   12 |   short a
382// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
383// CHECK-NEXT:      | [sizeof=16, align=4
384// CHECK-NEXT:      |  nvsize=16, nvalign=4]
385// CHECK-X64: *** Dumping AST Record Layout
386// CHECK-X64-NEXT:    0 | struct AB3
387// CHECK-X64-NEXT:    0 |   struct B11 (base)
388// CHECK-X64-NEXT:    0 |     char [8] c
389// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
390// CHECK-X64-NEXT:    8 |   (AB3 vbtable pointer)
391// CHECK-X64-NEXT:   16 |   short a
392// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
393// CHECK-X64-NEXT:      | [sizeof=24, align=8
394// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
395
396struct AC3 : B11, B1, virtual B0 {
397	char a;
398	AC3() : a(0x000000C3) { printf("AC3 = %p\n", this); }
399};
400
401// CHECK: *** Dumping AST Record Layout
402// CHECK-NEXT:    0 | struct AC3
403// CHECK-NEXT:    0 |   struct B11 (base)
404// CHECK-NEXT:    0 |     char [8] c
405// CHECK-NEXT:   12 |   struct B1 (base) (empty)
406// CHECK-NEXT:    8 |   (AC3 vbtable pointer)
407// CHECK-NEXT:   12 |   char a
408// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
409// CHECK-NEXT:      | [sizeof=16, align=4
410// CHECK-NEXT:      |  nvsize=16, nvalign=4]
411// CHECK-X64: *** Dumping AST Record Layout
412// CHECK-X64-NEXT:    0 | struct AC3
413// CHECK-X64-NEXT:    0 |   struct B11 (base)
414// CHECK-X64-NEXT:    0 |     char [8] c
415// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
416// CHECK-X64-NEXT:    8 |   (AC3 vbtable pointer)
417// CHECK-X64-NEXT:   16 |   char a
418// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
419// CHECK-X64-NEXT:      | [sizeof=24, align=8
420// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
421
422struct AD3 : B11, B1, virtual B0 {
423	AD3() { printf("AD3 = %p\n", this); }
424};
425
426// CHECK: *** Dumping AST Record Layout
427// CHECK-NEXT:    0 | struct AD3
428// CHECK-NEXT:    0 |   struct B11 (base)
429// CHECK-NEXT:    0 |     char [8] c
430// CHECK-NEXT:   12 |   struct B1 (base) (empty)
431// CHECK-NEXT:    8 |   (AD3 vbtable pointer)
432// CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
433// CHECK-NEXT:      | [sizeof=12, align=4
434// CHECK-NEXT:      |  nvsize=12, nvalign=4]
435// CHECK-X64: *** Dumping AST Record Layout
436// CHECK-X64-NEXT:    0 | struct AD3
437// CHECK-X64-NEXT:    0 |   struct B11 (base)
438// CHECK-X64-NEXT:    0 |     char [8] c
439// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
440// CHECK-X64-NEXT:    8 |   (AD3 vbtable pointer)
441// CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
442// CHECK-X64-NEXT:      | [sizeof=16, align=8
443// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
444
445struct B : B1, B2, virtual B0 {
446	B() { printf("B = %p\n", this); }
447};
448
449// CHECK: *** Dumping AST Record Layout
450// CHECK: *** Dumping AST Record Layout
451// CHECK-NEXT:    0 | struct B
452// CHECK-NEXT:    0 |   struct B1 (base) (empty)
453// CHECK-NEXT:    8 |   struct B2 (base) (empty)
454// CHECK-NEXT:    4 |   (B vbtable pointer)
455// CHECK-NEXT:    8 |   struct B0 (virtual base) (empty)
456// CHECK-NEXT:      | [sizeof=8, align=4
457// CHECK-NEXT:      |  nvsize=8, nvalign=4]
458// CHECK-X64: *** Dumping AST Record Layout
459// CHECK-X64: *** Dumping AST Record Layout
460// CHECK-X64-NEXT:    0 | struct B
461// CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
462// CHECK-X64-NEXT:   16 |   struct B2 (base) (empty)
463// CHECK-X64-NEXT:    8 |   (B vbtable pointer)
464// CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
465// CHECK-X64-NEXT:      | [sizeof=16, align=8
466// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
467
468struct C : B1, B2, B3, virtual B0 {
469	char a;
470	C() : a(0x0000000C) { printf("C = %p\n", this); }
471};
472
473// CHECK: *** Dumping AST Record Layout
474// CHECK: *** Dumping AST Record Layout
475// CHECK-NEXT:    0 | struct C
476// CHECK-NEXT:    0 |   struct B1 (base) (empty)
477// CHECK-NEXT:    1 |   struct B2 (base) (empty)
478// CHECK-NEXT:    8 |   struct B3 (base) (empty)
479// CHECK-NEXT:    4 |   (C vbtable pointer)
480// CHECK-NEXT:    8 |   char a
481// CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
482// CHECK-NEXT:      | [sizeof=12, align=4
483// CHECK-NEXT:      |  nvsize=12, nvalign=4]
484// CHECK-X64: *** Dumping AST Record Layout
485// CHECK-X64: *** Dumping AST Record Layout
486// CHECK-X64-NEXT:    0 | struct C
487// CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
488// CHECK-X64-NEXT:    1 |   struct B2 (base) (empty)
489// CHECK-X64-NEXT:   16 |   struct B3 (base) (empty)
490// CHECK-X64-NEXT:    8 |   (C vbtable pointer)
491// CHECK-X64-NEXT:   16 |   char a
492// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
493// CHECK-X64-NEXT:      | [sizeof=24, align=8
494// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
495
496struct D : B1, B2, B3, B4, B5, virtual B0 {
497	int a;
498	D() : a(0x0000000D) { printf("D = %p\n", this); }
499};
500
501// CHECK: *** Dumping AST Record Layout
502// CHECK: *** Dumping AST Record Layout
503// CHECK: *** Dumping AST Record Layout
504// CHECK-NEXT:    0 | struct D
505// CHECK-NEXT:    0 |   struct B1 (base) (empty)
506// CHECK-NEXT:    1 |   struct B2 (base) (empty)
507// CHECK-NEXT:    2 |   struct B3 (base) (empty)
508// CHECK-NEXT:    3 |   struct B4 (base) (empty)
509// CHECK-NEXT:    8 |   struct B5 (base) (empty)
510// CHECK-NEXT:    4 |   (D vbtable pointer)
511// CHECK-NEXT:    8 |   int a
512// CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
513// CHECK-NEXT:      | [sizeof=12, align=4
514// CHECK-NEXT:      |  nvsize=12, nvalign=4]
515// CHECK-X64: *** Dumping AST Record Layout
516// CHECK-X64: *** Dumping AST Record Layout
517// CHECK-X64: *** Dumping AST Record Layout
518// CHECK-X64-NEXT:    0 | struct D
519// CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
520// CHECK-X64-NEXT:    1 |   struct B2 (base) (empty)
521// CHECK-X64-NEXT:    2 |   struct B3 (base) (empty)
522// CHECK-X64-NEXT:    3 |   struct B4 (base) (empty)
523// CHECK-X64-NEXT:   16 |   struct B5 (base) (empty)
524// CHECK-X64-NEXT:    8 |   (D vbtable pointer)
525// CHECK-X64-NEXT:   16 |   int a
526// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
527// CHECK-X64-NEXT:      | [sizeof=24, align=8
528// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
529
530struct E : B1, B6, B3, B4, B5, virtual B0 {
531	int a;
532	E() : a(0x0000000E) { printf("E = %p\n", this); }
533};
534
535// CHECK: *** Dumping AST Record Layout
536// CHECK: *** Dumping AST Record Layout
537// CHECK-NEXT:    0 | struct E
538// CHECK-NEXT:    0 |   struct B1 (base) (empty)
539// CHECK-NEXT:    2 |   struct B6 (base) (empty)
540// CHECK-NEXT:    3 |   struct B3 (base) (empty)
541// CHECK-NEXT:    4 |   struct B4 (base) (empty)
542// CHECK-NEXT:   13 |   struct B5 (base) (empty)
543// CHECK-NEXT:    8 |   (E vbtable pointer)
544// CHECK-NEXT:   16 |   int a
545// CHECK-NEXT:   20 |   struct B0 (virtual base) (empty)
546// CHECK-NEXT:      | [sizeof=20, align=4
547// CHECK-NEXT:      |  nvsize=20, nvalign=4]
548// CHECK-X64: *** Dumping AST Record Layout
549// CHECK-X64: *** Dumping AST Record Layout
550// CHECK-X64-NEXT:    0 | struct E
551// CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
552// CHECK-X64-NEXT:    2 |   struct B6 (base) (empty)
553// CHECK-X64-NEXT:    3 |   struct B3 (base) (empty)
554// CHECK-X64-NEXT:    4 |   struct B4 (base) (empty)
555// CHECK-X64-NEXT:   17 |   struct B5 (base) (empty)
556// CHECK-X64-NEXT:    8 |   (E vbtable pointer)
557// CHECK-X64-NEXT:   20 |   int a
558// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
559// CHECK-X64-NEXT:      | [sizeof=24, align=8
560// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
561
562struct F : B1, B6, B4, B8, B5, virtual B0 {
563	int a;
564	F() : a(0x0000000F) { printf("&a = %p\n", &a); printf("F = %p\n", this); }
565};
566
567// CHECK: *** Dumping AST Record Layout
568// CHECK-NEXT:    0 | struct F
569// CHECK-NEXT:    0 |   struct B1 (base) (empty)
570// CHECK-NEXT:    2 |   struct B6 (base) (empty)
571// CHECK-NEXT:    3 |   struct B4 (base) (empty)
572// CHECK-NEXT:    3 |   struct B8 (base)
573// CHECK-NEXT:    3 |     char [5] c
574// CHECK-NEXT:   12 |   struct B5 (base) (empty)
575// CHECK-NEXT:    8 |   (F vbtable pointer)
576// CHECK-NEXT:   12 |   int a
577// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
578// CHECK-NEXT:      | [sizeof=16, align=4
579// CHECK-NEXT:      |  nvsize=16, nvalign=4]
580// CHECK-X64: *** Dumping AST Record Layout
581// CHECK-X64-NEXT:    0 | struct F
582// CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
583// CHECK-X64-NEXT:    2 |   struct B6 (base) (empty)
584// CHECK-X64-NEXT:    3 |   struct B4 (base) (empty)
585// CHECK-X64-NEXT:    3 |   struct B8 (base)
586// CHECK-X64-NEXT:    3 |     char [5] c
587// CHECK-X64-NEXT:   16 |   struct B5 (base) (empty)
588// CHECK-X64-NEXT:    8 |   (F vbtable pointer)
589// CHECK-X64-NEXT:   16 |   int a
590// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
591// CHECK-X64-NEXT:      | [sizeof=24, align=8
592// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
593
594struct G : B8, B1, virtual B0 {
595	int a;
596	__declspec(align(16)) int a1;
597	G() : a(0x00000010), a1(0xf0000010) { printf("G = %p\n", this); }
598};
599
600// CHECK: *** Dumping AST Record Layout
601// CHECK-NEXT:    0 | struct G
602// CHECK-NEXT:    0 |   struct B8 (base)
603// CHECK-NEXT:    0 |     char [5] c
604// CHECK-NEXT:   21 |   struct B1 (base) (empty)
605// CHECK-NEXT:    8 |   (G vbtable pointer)
606// CHECK-NEXT:   24 |   int a
607// CHECK-NEXT:   32 |   int a1
608// CHECK-NEXT:   48 |   struct B0 (virtual base) (empty)
609// CHECK-NEXT:      | [sizeof=48, align=16
610// CHECK-NEXT:      |  nvsize=48, nvalign=16]
611// CHECK-X64: *** Dumping AST Record Layout
612// CHECK-X64-NEXT:    0 | struct G
613// CHECK-X64-NEXT:    0 |   struct B8 (base)
614// CHECK-X64-NEXT:    0 |     char [5] c
615// CHECK-X64-NEXT:   21 |   struct B1 (base) (empty)
616// CHECK-X64-NEXT:    8 |   (G vbtable pointer)
617// CHECK-X64-NEXT:   24 |   int a
618// CHECK-X64-NEXT:   32 |   int a1
619// CHECK-X64-NEXT:   48 |   struct B0 (virtual base) (empty)
620// CHECK-X64-NEXT:      | [sizeof=48, align=16
621// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
622
623struct AX : B1X, B2X, B3X, B4X, virtual B0X {
624	int a;
625	AX() : a(0x0000000A) { printf(" A = %p\n", this); }
626};
627
628// CHECK: *** Dumping AST Record Layout
629// CHECK: *** Dumping AST Record Layout
630// CHECK: *** Dumping AST Record Layout
631// CHECK: *** Dumping AST Record Layout
632// CHECK: *** Dumping AST Record Layout
633// CHECK: *** Dumping AST Record Layout
634// CHECK-NEXT:    0 | struct AX
635// CHECK-NEXT:    0 |   struct B1X (base) (empty)
636// CHECK-NEXT:   16 |   struct B2X (base) (empty)
637// CHECK-NEXT:   18 |   struct B3X (base) (empty)
638// CHECK-NEXT:   35 |   struct B4X (base) (empty)
639// CHECK-NEXT:   20 |   (AX vbtable pointer)
640// CHECK-NEXT:   36 |   int a
641// CHECK-NEXT:   48 |   struct B0X (virtual base) (empty)
642// CHECK-NEXT:      | [sizeof=48, align=16
643// CHECK-NEXT:      |  nvsize=48, nvalign=16]
644// CHECK-X64: *** Dumping AST Record Layout
645// CHECK-X64: *** Dumping AST Record Layout
646// CHECK-X64: *** Dumping AST Record Layout
647// CHECK-X64: *** Dumping AST Record Layout
648// CHECK-X64: *** Dumping AST Record Layout
649// CHECK-X64: *** Dumping AST Record Layout
650// CHECK-X64-NEXT:    0 | struct AX
651// CHECK-X64-NEXT:    0 |   struct B1X (base) (empty)
652// CHECK-X64-NEXT:   16 |   struct B2X (base) (empty)
653// CHECK-X64-NEXT:   18 |   struct B3X (base) (empty)
654// CHECK-X64-NEXT:   35 |   struct B4X (base) (empty)
655// CHECK-X64-NEXT:   24 |   (AX vbtable pointer)
656// CHECK-X64-NEXT:   36 |   int a
657// CHECK-X64-NEXT:   48 |   struct B0X (virtual base) (empty)
658// CHECK-X64-NEXT:      | [sizeof=48, align=16
659// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
660
661struct BX : B2X, B1X, B3X, B4X, virtual B0X {
662	int a;
663	BX() : a(0x0000000B) { printf(" B = %p\n", this); }
664};
665
666// CHECK: *** Dumping AST Record Layout
667// CHECK-NEXT:    0 | struct BX
668// CHECK-NEXT:    0 |   struct B2X (base) (empty)
669// CHECK-NEXT:    1 |   struct B1X (base) (empty)
670// CHECK-NEXT:    2 |   struct B3X (base) (empty)
671// CHECK-NEXT:   19 |   struct B4X (base) (empty)
672// CHECK-NEXT:    4 |   (BX vbtable pointer)
673// CHECK-NEXT:   20 |   int a
674// CHECK-NEXT:   32 |   struct B0X (virtual base) (empty)
675// CHECK-NEXT:      | [sizeof=32, align=16
676// CHECK-NEXT:      |  nvsize=32, nvalign=16]
677// CHECK-X64: *** Dumping AST Record Layout
678// CHECK-X64-NEXT:    0 | struct BX
679// CHECK-X64-NEXT:    0 |   struct B2X (base) (empty)
680// CHECK-X64-NEXT:    1 |   struct B1X (base) (empty)
681// CHECK-X64-NEXT:    2 |   struct B3X (base) (empty)
682// CHECK-X64-NEXT:   19 |   struct B4X (base) (empty)
683// CHECK-X64-NEXT:    8 |   (BX vbtable pointer)
684// CHECK-X64-NEXT:   20 |   int a
685// CHECK-X64-NEXT:   32 |   struct B0X (virtual base) (empty)
686// CHECK-X64-NEXT:      | [sizeof=32, align=16
687// CHECK-X64-NEXT:      |  nvsize=32, nvalign=16]
688
689struct CX : B1X, B3X, B2X, virtual B0X {
690	int a;
691	CX() : a(0x0000000C) { printf(" C = %p\n", this); }
692};
693
694// CHECK: *** Dumping AST Record Layout
695// CHECK-NEXT:    0 | struct CX
696// CHECK-NEXT:    0 |   struct B1X (base) (empty)
697// CHECK-NEXT:    2 |   struct B3X (base) (empty)
698// CHECK-NEXT:   32 |   struct B2X (base) (empty)
699// CHECK-NEXT:   16 |   (CX vbtable pointer)
700// CHECK-NEXT:   32 |   int a
701// CHECK-NEXT:   48 |   struct B0X (virtual base) (empty)
702// CHECK-NEXT:      | [sizeof=48, align=16
703// CHECK-NEXT:      |  nvsize=48, nvalign=16]
704// CHECK-X64: *** Dumping AST Record Layout
705// CHECK-X64-NEXT:    0 | struct CX
706// CHECK-X64-NEXT:    0 |   struct B1X (base) (empty)
707// CHECK-X64-NEXT:    2 |   struct B3X (base) (empty)
708// CHECK-X64-NEXT:   32 |   struct B2X (base) (empty)
709// CHECK-X64-NEXT:   16 |   (CX vbtable pointer)
710// CHECK-X64-NEXT:   32 |   int a
711// CHECK-X64-NEXT:   48 |   struct B0X (virtual base) (empty)
712// CHECK-X64-NEXT:      | [sizeof=48, align=16
713// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
714
715struct DX : B8X, B1X, virtual B0X {
716	int a;
717	DX() : a(0x0000000D) { printf(" D = %p\n", this); }
718};
719
720// CHECK: *** Dumping AST Record Layout
721// CHECK: *** Dumping AST Record Layout
722// CHECK-NEXT:    0 | struct DX
723// CHECK-NEXT:    0 |   struct B8X (base)
724// CHECK-NEXT:    0 |     short a
725// CHECK-NEXT:   10 |   struct B1X (base) (empty)
726// CHECK-NEXT:    4 |   (DX vbtable pointer)
727// CHECK-NEXT:   12 |   int a
728// CHECK-NEXT:   16 |   struct B0X (virtual base) (empty)
729// CHECK-NEXT:      | [sizeof=16, align=4
730// CHECK-NEXT:      |  nvsize=16, nvalign=4]
731// CHECK-X64: *** Dumping AST Record Layout
732// CHECK-X64: *** Dumping AST Record Layout
733// CHECK-X64-NEXT:    0 | struct DX
734// CHECK-X64-NEXT:    0 |   struct B8X (base)
735// CHECK-X64-NEXT:    0 |     short a
736// CHECK-X64-NEXT:   18 |   struct B1X (base) (empty)
737// CHECK-X64-NEXT:    8 |   (DX vbtable pointer)
738// CHECK-X64-NEXT:   20 |   int a
739// CHECK-X64-NEXT:   24 |   struct B0X (virtual base) (empty)
740// CHECK-X64-NEXT:      | [sizeof=24, align=8
741// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
742
743
744struct C0 {};
745struct C1 : public C0 { int C1F0; };
746struct C2 : public C1, public C0 {};
747
748// CHECK: *** Dumping AST Record Layout
749// CHECK: *** Dumping AST Record Layout
750// CHECK: *** Dumping AST Record Layout
751// CHECK-NEXT:    0 | struct C2
752// CHECK-NEXT:    0 |   struct C1 (base)
753// CHECK-NEXT:    0 |     struct C0 (base) (empty)
754// CHECK-NEXT:    0 |     int C1F0
755// CHECK-NEXT:    5 |   struct C0 (base) (empty)
756// CHECK-NEXT:      | [sizeof=8, align=4
757// CHECK-NEXT:      |  nvsize=8, nvalign=4]
758// CHECK-X64: *** Dumping AST Record Layout
759// CHECK-X64: *** Dumping AST Record Layout
760// CHECK-X64: *** Dumping AST Record Layout
761// CHECK-X64-NEXT:    0 | struct C2
762// CHECK-X64-NEXT:    0 |   struct C1 (base)
763// CHECK-X64-NEXT:    0 |     struct C0 (base) (empty)
764// CHECK-X64-NEXT:    0 |     int C1F0
765// CHECK-X64-NEXT:    5 |   struct C0 (base) (empty)
766// CHECK-X64-NEXT:      | [sizeof=8, align=4
767// CHECK-X64-NEXT:      |  nvsize=8, nvalign=4]
768
769struct JA { char a; };
770struct JB {
771  char a;
772  virtual void f() {}
773};
774struct JC { char a; };
775struct JD : JA, JB, virtual JC {};
776
777// CHECK: *** Dumping AST Record Layout
778// CHECK: *** Dumping AST Record Layout
779// CHECK: *** Dumping AST Record Layout
780// CHECK: *** Dumping AST Record Layout
781// CHECK-NEXT:    0 | struct JD
782// CHECK-NEXT:    0 |   struct JB (primary base)
783// CHECK-NEXT:    0 |     (JB vftable pointer)
784// CHECK-NEXT:    4 |     char a
785// CHECK-NEXT:   12 |   struct JA (base)
786// CHECK-NEXT:   12 |     char a
787// CHECK-NEXT:    8 |   (JD vbtable pointer)
788// CHECK-NEXT:   16 |   struct JC (virtual base)
789// CHECK-NEXT:   16 |     char a
790// CHECK-NEXT:      | [sizeof=17, align=4
791// CHECK-NEXT:      |  nvsize=16, nvalign=4]
792// CHECK-X64: *** Dumping AST Record Layout
793// CHECK-X64: *** Dumping AST Record Layout
794// CHECK-X64: *** Dumping AST Record Layout
795// CHECK-X64: *** Dumping AST Record Layout
796// CHECK-X64-NEXT:    0 | struct JD
797// CHECK-X64-NEXT:    0 |   struct JB (primary base)
798// CHECK-X64-NEXT:    0 |     (JB vftable pointer)
799// CHECK-X64-NEXT:    8 |     char a
800// CHECK-X64-NEXT:   24 |   struct JA (base)
801// CHECK-X64-NEXT:   24 |     char a
802// CHECK-X64-NEXT:   16 |   (JD vbtable pointer)
803// CHECK-X64-NEXT:   32 |   struct JC (virtual base)
804// CHECK-X64-NEXT:   32 |     char a
805// CHECK-X64-NEXT:      | [sizeof=40, align=8
806// CHECK-X64-NEXT:      |  nvsize=32, nvalign=8]
807
808int a[
809sizeof(AA)+
810sizeof(AB)+
811sizeof(AC)+
812sizeof(AD)+
813sizeof(AA1)+
814sizeof(AB1)+
815sizeof(AC1)+
816sizeof(AD1)+
817sizeof(AA2)+
818sizeof(AB2)+
819sizeof(AC2)+
820sizeof(AD2)+
821sizeof(AA3)+
822sizeof(AB3)+
823sizeof(AC3)+
824sizeof(AD3)+
825sizeof(B)+
826sizeof(C)+
827sizeof(D)+
828sizeof(E)+
829sizeof(F)+
830sizeof(G)+
831sizeof(AX)+
832sizeof(BX)+
833sizeof(CX)+
834sizeof(DX)+
835sizeof(C2)+
836sizeof(JD)+
8370];
838