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__declspec(align(4096)) char buffer[4096];
8
9struct AT {};
10
11struct V : AT {
12	char c;
13	V() {
14		printf("V   - this: %d\n", (int)((char*)this - buffer));
15	}
16};
17
18struct AT0 {
19	union { struct { int a; AT t; } y; int b; } x;
20	char c;
21	AT0() {
22		printf("AT0 - this: %d\n", (int)((char*)this - buffer));
23	}
24};
25
26struct AT1 : V {
27	int a;
28	AT1() {
29		printf("AT1 - this: %d\n", (int)((char*)this - buffer));
30	}
31};
32
33struct AT2 {
34	AT0 t;
35	char AT2FieldName0;
36	AT2() {
37		printf("AT2 - this: %d\n", (int)((char*)this - buffer));
38		printf("AT2 - Fiel: %d\n", (int)((char*)&AT2FieldName0 - buffer));
39	}
40};
41
42struct AT3 : AT2, AT1 {
43	AT3() {
44		printf("AT3 - this: %d\n", (int)((char*)this - buffer));
45	}
46};
47
48// CHECK: *** Dumping AST Record Layout
49// CHECK: *** Dumping AST Record Layout
50// CHECK: *** Dumping AST Record Layout
51// CHECK: *** Dumping AST Record Layout
52// CHECK: *** Dumping AST Record Layout
53// CHECK: *** Dumping AST Record Layout
54// CHECK: *** Dumping AST Record Layout
55// CHECK: *** Dumping AST Record Layout
56// CHECK-NEXT:    0 | struct AT3
57// CHECK-NEXT:    0 |   struct AT2 (base)
58// CHECK-NEXT:    0 |     struct AT0 t
59// CHECK-NEXT:    0 |       union AT0::(anonymous at {{.*}} x
60// CHECK-NEXT:    0 |         struct AT0::(anonymous at {{.*}} y
61// CHECK-NEXT:    0 |           int a
62// CHECK-NEXT:    4 |           struct AT t (empty)
63// CHECK:         0 |         int b
64// CHECK:         8 |       char c
65// CHECK:        12 |     char AT2FieldName0
66// CHECK-NEXT:   20 |   struct AT1 (base)
67// CHECK-NEXT:   20 |     struct V (base)
68// CHECK-NEXT:   20 |       struct AT (base) (empty)
69// CHECK-NEXT:   20 |       char c
70// CHECK-NEXT:   24 |     int a
71// CHECK-NEXT:      | [sizeof=28, align=4
72// CHECK-NEXT:      |  nvsize=28, nvalign=4]
73// CHECK-X64: *** Dumping AST Record Layout
74// CHECK-X64: *** Dumping AST Record Layout
75// CHECK-X64: *** Dumping AST Record Layout
76// CHECK-X64: *** Dumping AST Record Layout
77// CHECK-X64: *** Dumping AST Record Layout
78// CHECK-X64: *** Dumping AST Record Layout
79// CHECK-X64: *** Dumping AST Record Layout
80// CHECK-X64: *** Dumping AST Record Layout
81// CHECK-X64-NEXT:    0 | struct AT3
82// CHECK-X64-NEXT:    0 |   struct AT2 (base)
83// CHECK-X64-NEXT:    0 |     struct AT0 t
84// CHECK-X64-NEXT:    0 |       union AT0::(anonymous at {{.*}} x
85// CHECK-X64-NEXT:    0 |         struct AT0::(anonymous at {{.*}} y
86// CHECK-X64-NEXT:    0 |           int a
87// CHECK-X64-NEXT:    4 |           struct AT t (empty)
88// CHECK-X64:         0 |         int b
89// CHECK-X64:         8 |       char c
90// CHECK-X64:        12 |     char AT2FieldName0
91// CHECK-X64-NEXT:   20 |   struct AT1 (base)
92// CHECK-X64-NEXT:   20 |     struct V (base)
93// CHECK-X64-NEXT:   20 |       struct AT (base) (empty)
94// CHECK-X64-NEXT:   20 |       char c
95// CHECK-X64-NEXT:   24 |     int a
96// CHECK-X64-NEXT:      | [sizeof=28, align=4
97// CHECK-X64-NEXT:      |  nvsize=28, nvalign=4]
98
99struct BT0 {
100	BT0() {
101		printf("BT0 - this: %d\n", (int)((char*)this - buffer));
102	}
103};
104
105struct BT2 : BT0 {
106	char BT2FieldName0;
107	BT2() {
108		printf("BT2 - this: %d\n", (int)((char*)this - buffer));
109		printf("BT2 - Fiel: %d\n", (int)((char*)&BT2FieldName0 - buffer));
110	}
111};
112
113struct BT3 : BT0, BT2 {
114	BT3() {
115		printf("BT3 - this: %d\n", (int)((char*)this - buffer));
116	}
117};
118
119// CHECK: *** Dumping AST Record Layout
120// CHECK: *** Dumping AST Record Layout
121// CHECK: *** Dumping AST Record Layout
122// CHECK-NEXT:    0 | struct BT3
123// CHECK-NEXT:    0 |   struct BT0 (base) (empty)
124// CHECK-NEXT:    1 |   struct BT2 (base)
125// CHECK-NEXT:    1 |     struct BT0 (base) (empty)
126// CHECK-NEXT:    1 |     char BT2FieldName0
127// CHECK-NEXT:      | [sizeof=2, align=1
128// CHECK-NEXT:      |  nvsize=2, nvalign=1]
129// CHECK-X64: *** Dumping AST Record Layout
130// CHECK-X64: *** Dumping AST Record Layout
131// CHECK-X64: *** Dumping AST Record Layout
132// CHECK-X64-NEXT:    0 | struct BT3
133// CHECK-X64-NEXT:    0 |   struct BT0 (base) (empty)
134// CHECK-X64-NEXT:    1 |   struct BT2 (base)
135// CHECK-X64-NEXT:    1 |     struct BT0 (base) (empty)
136// CHECK-X64-NEXT:    1 |     char BT2FieldName0
137// CHECK-X64-NEXT:      | [sizeof=2, align=1
138// CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
139
140struct T0 : AT {
141	T0() {
142		printf("T0 (this) : %d\n", (int)((char*)this - buffer));
143	}
144};
145
146struct T1 : T0 {
147	char a;
148	T1() {
149		printf("T1 (this) : %d\n", (int)((char*)this - buffer));
150		printf("T1 (fiel) : %d\n", (int)((char*)&a - buffer));
151	}
152};
153
154struct T2 : AT {
155	char a;
156	T2() {
157		printf("T2 (this) : %d\n", (int)((char*)this - buffer));
158		printf("T2 (fiel) : %d\n", (int)((char*)&a - buffer));
159	}
160};
161
162struct __declspec(align(1)) T3 : virtual T1, virtual T2 {
163	T3() {
164		printf("T3 (this) : %d\n", (int)((char*)this - buffer));
165	}
166};
167
168// CHECK: *** Dumping AST Record Layout
169// CHECK: *** Dumping AST Record Layout
170// CHECK: *** Dumping AST Record Layout
171// CHECK: *** Dumping AST Record Layout
172// CHECK-NEXT:    0 | struct T3
173// CHECK-NEXT:    0 |   (T3 vbtable pointer)
174// CHECK-NEXT:    4 |   struct T1 (virtual base)
175// CHECK-NEXT:    4 |     struct T0 (base) (empty)
176// CHECK-NEXT:    4 |       struct AT (base) (empty)
177// CHECK-NEXT:    4 |     char a
178// CHECK-NEXT:   12 |   struct T2 (virtual base)
179// CHECK-NEXT:   12 |     struct AT (base) (empty)
180// CHECK-NEXT:   12 |     char a
181// CHECK-NEXT:      | [sizeof=16, align=4
182// CHECK-NEXT:      |  nvsize=4, nvalign=4]
183// CHECK-X64: *** Dumping AST Record Layout
184// CHECK-X64: *** Dumping AST Record Layout
185// CHECK-X64: *** Dumping AST Record Layout
186// CHECK-X64: *** Dumping AST Record Layout
187// CHECK-X64-NEXT:    0 | struct T3
188// CHECK-X64-NEXT:    0 |   (T3 vbtable pointer)
189// CHECK-X64-NEXT:    8 |   struct T1 (virtual base)
190// CHECK-X64-NEXT:    8 |     struct T0 (base) (empty)
191// CHECK-X64-NEXT:    8 |       struct AT (base) (empty)
192// CHECK-X64-NEXT:    8 |     char a
193// CHECK-X64-NEXT:   16 |   struct T2 (virtual base)
194// CHECK-X64-NEXT:   16 |     struct AT (base) (empty)
195// CHECK-X64-NEXT:   16 |     char a
196// CHECK-X64-NEXT:      | [sizeof=24, align=8
197// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
198
199struct B {};
200struct C { int a; };
201struct D : B, virtual C { B b; };
202struct E : D, B {};
203// CHECK: *** Dumping AST Record Layout
204// CHECK: *** Dumping AST Record Layout
205// CHECK: *** Dumping AST Record Layout
206// CHECK: *** Dumping AST Record Layout
207// CHECK-NEXT:    0 | struct E
208// CHECK-NEXT:    0 |   struct D (base)
209// CHECK-NEXT:    4 |     struct B (base) (empty)
210// CHECK-NEXT:    0 |     (D vbtable pointer)
211// CHECK-NEXT:    4 |     struct B b (empty)
212// CHECK:         8 |   struct B (base) (empty)
213// CHECK-NEXT:    8 |   struct C (virtual base)
214// CHECK-NEXT:    8 |     int a
215// CHECK-NEXT:      | [sizeof=12, align=4
216// CHECK-NEXT:      |  nvsize=8, nvalign=4]
217// CHECK-X64: *** Dumping AST Record Layout
218// CHECK-X64: *** Dumping AST Record Layout
219// CHECK-X64: *** Dumping AST Record Layout
220// CHECK-X64: *** Dumping AST Record Layout
221// CHECK-X64-NEXT:   0 | struct E
222// CHECK-X64-NEXT:   0 |   struct D (base)
223// CHECK-X64-NEXT:   8 |     struct B (base) (empty)
224// CHECK-X64-NEXT:   0 |     (D vbtable pointer)
225// CHECK-X64-NEXT:   8 |     struct B b (empty)
226// CHECK-X64:       16 |   struct B (base) (empty)
227// CHECK-X64-NEXT:  16 |   struct C (virtual base)
228// CHECK-X64-NEXT:  16 |     int a
229// CHECK-X64-NEXT:     | [sizeof=24, align=8
230// CHECK-X64-NEXT:     |  nvsize=16, nvalign=8]
231
232struct F : virtual D, virtual B {};
233// CHECK: *** Dumping AST Record Layout
234// CHECK-NEXT:    0 | struct F
235// CHECK-NEXT:    0 |   (F vbtable pointer)
236// CHECK-NEXT:    4 |   struct C (virtual base)
237// CHECK-NEXT:    4 |     int a
238// CHECK-NEXT:    8 |   struct D (virtual base)
239// CHECK-NEXT:   12 |     struct B (base) (empty)
240// CHECK-NEXT:    8 |     (D vbtable pointer)
241// CHECK-NEXT:   12 |     struct B b (empty)
242// CHECK:        16 |   struct B (virtual base) (empty)
243// CHECK-NEXT:      | [sizeof=16, align=4
244// CHECK-NEXT:      |  nvsize=4, nvalign=4]
245// CHECK-X64: *** Dumping AST Record Layout
246// CHECK-X64-NEXT:    0 | struct F
247// CHECK-X64-NEXT:    0 |   (F vbtable pointer)
248// CHECK-X64-NEXT:    8 |   struct C (virtual base)
249// CHECK-X64-NEXT:    8 |     int a
250// CHECK-X64-NEXT:   16 |   struct D (virtual base)
251// CHECK-X64-NEXT:   24 |     struct B (base) (empty)
252// CHECK-X64-NEXT:   16 |     (D vbtable pointer)
253// CHECK-X64-NEXT:   24 |     struct B b (empty)
254// CHECK-X64:        32 |   struct B (virtual base) (empty)
255// CHECK-X64-NEXT:      | [sizeof=32, align=8
256// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
257
258struct JC0 {
259	JC0() { printf("JC0 : %d\n", (int)((char*)this - buffer)); }
260};
261struct JC1 : JC0 {
262	virtual void f() {}
263	JC1() { printf("JC1 : %d\n", (int)((char*)this - buffer)); }
264};
265struct JC2 : JC1 {
266	JC2() { printf("JC2 : %d\n", (int)((char*)this - buffer)); }
267};
268struct JC4 : JC1, JC2 {
269	JC4() { printf("JC4 : %d\n", (int)((char*)this - buffer)); }
270};
271
272// CHECK: *** Dumping AST Record Layout
273// CHECK: *** Dumping AST Record Layout
274// CHECK: *** Dumping AST Record Layout
275// CHECK: *** Dumping AST Record Layout
276// CHECK-NEXT:    0 | struct JC4
277// CHECK-NEXT:    0 |   struct JC1 (primary base)
278// CHECK-NEXT:    0 |     (JC1 vftable pointer)
279// CHECK-NEXT:    4 |     struct JC0 (base) (empty)
280// CHECK-NEXT:    8 |   struct JC2 (base)
281// CHECK-NEXT:    8 |     struct JC1 (primary base)
282// CHECK-NEXT:    8 |       (JC1 vftable pointer)
283// CHECK-NEXT:   12 |       struct JC0 (base) (empty)
284// CHECK-NEXT:      | [sizeof=12, align=4
285// CHECK-NEXT:      |  nvsize=12, nvalign=4]
286// CHECK-X64: *** Dumping AST Record Layout
287// CHECK-X64: *** Dumping AST Record Layout
288// CHECK-X64: *** Dumping AST Record Layout
289// CHECK-X64: *** Dumping AST Record Layout
290// CHECK-X64-NEXT:    0 | struct JC4
291// CHECK-X64-NEXT:    0 |   struct JC1 (primary base)
292// CHECK-X64-NEXT:    0 |     (JC1 vftable pointer)
293// CHECK-X64-NEXT:    8 |     struct JC0 (base) (empty)
294// CHECK-X64-NEXT:   16 |   struct JC2 (base)
295// CHECK-X64-NEXT:   16 |     struct JC1 (primary base)
296// CHECK-X64-NEXT:   16 |       (JC1 vftable pointer)
297// CHECK-X64-NEXT:   24 |       struct JC0 (base) (empty)
298// CHECK-X64-NEXT:      | [sizeof=24, align=8
299// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
300
301struct RA {};
302struct RB { char c; };
303struct RV {};
304struct RW { char c; };
305struct RY { RY() { printf("%Id\n", (char*)this - buffer); } };
306struct RX0 : RB, RA {};
307struct RX1 : RA, RB {};
308struct RX2 : RA { char a; };
309struct RX3 : RA { RB a; };
310struct RX4 { RA a; char b; };
311struct RX5 { RA a; RB b; };
312struct RX6 : virtual RV { RB a; };
313struct RX7 : virtual RW { RA a; };
314struct RX8 : RA, virtual RW {};
315
316struct RZ0 : RX0, RY {};
317// CHECK: *** Dumping AST Record Layout
318// CHECK: *** Dumping AST Record Layout
319// CHECK: *** Dumping AST Record Layout
320// CHECK: *** Dumping AST Record Layout
321// CHECK: *** Dumping AST Record Layout
322// CHECK-NEXT:    0 | struct RZ0
323// CHECK-NEXT:    0 |   struct RX0 (base)
324// CHECK-NEXT:    0 |     struct RB (base)
325// CHECK-NEXT:    0 |       char c
326// CHECK-NEXT:    1 |     struct RA (base) (empty)
327// CHECK-NEXT:    2 |   struct RY (base) (empty)
328// CHECK-NEXT:      | [sizeof=2, align=1
329// CHECK-NEXT:      |  nvsize=2, nvalign=1]
330// CHECK-X64: *** Dumping AST Record Layout
331// CHECK-X64: *** Dumping AST Record Layout
332// CHECK-X64: *** Dumping AST Record Layout
333// CHECK-X64: *** Dumping AST Record Layout
334// CHECK-X64: *** Dumping AST Record Layout
335// CHECK-X64-NEXT:    0 | struct RZ0
336// CHECK-X64-NEXT:    0 |   struct RX0 (base)
337// CHECK-X64-NEXT:    0 |     struct RB (base)
338// CHECK-X64-NEXT:    0 |       char c
339// CHECK-X64-NEXT:    1 |     struct RA (base) (empty)
340// CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
341// CHECK-X64-NEXT:      | [sizeof=2, align=1
342// CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
343
344struct RZ1 : RX1, RY {};
345// CHECK: *** Dumping AST Record Layout
346// CHECK: *** Dumping AST Record Layout
347// CHECK-NEXT:    0 | struct RZ1
348// CHECK-NEXT:    0 |   struct RX1 (base)
349// CHECK-NEXT:    0 |     struct RA (base) (empty)
350// CHECK-NEXT:    0 |     struct RB (base)
351// CHECK-NEXT:    0 |       char c
352// CHECK-NEXT:    1 |   struct RY (base) (empty)
353// CHECK-NEXT:      | [sizeof=1, align=1
354// CHECK-NEXT:      |  nvsize=1, nvalign=1]
355// CHECK-X64: *** Dumping AST Record Layout
356// CHECK-X64: *** Dumping AST Record Layout
357// CHECK-X64-NEXT:    0 | struct RZ1
358// CHECK-X64-NEXT:    0 |   struct RX1 (base)
359// CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
360// CHECK-X64-NEXT:    0 |     struct RB (base)
361// CHECK-X64-NEXT:    0 |       char c
362// CHECK-X64-NEXT:    1 |   struct RY (base) (empty)
363// CHECK-X64-NEXT:      | [sizeof=1, align=1
364// CHECK-X64-NEXT:      |  nvsize=1, nvalign=1]
365
366struct RZ2 : RX2, RY {};
367// CHECK: *** Dumping AST Record Layout
368// CHECK: *** Dumping AST Record Layout
369// CHECK-NEXT:    0 | struct RZ2
370// CHECK-NEXT:    0 |   struct RX2 (base)
371// CHECK-NEXT:    0 |     struct RA (base) (empty)
372// CHECK-NEXT:    0 |     char a
373// CHECK-NEXT:    2 |   struct RY (base) (empty)
374// CHECK-NEXT:      | [sizeof=2, align=1
375// CHECK-NEXT:      |  nvsize=2, nvalign=1]
376// CHECK-X64: *** Dumping AST Record Layout
377// CHECK-X64: *** Dumping AST Record Layout
378// CHECK-X64-NEXT:    0 | struct RZ2
379// CHECK-X64-NEXT:    0 |   struct RX2 (base)
380// CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
381// CHECK-X64-NEXT:    0 |     char a
382// CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
383// CHECK-X64-NEXT:      | [sizeof=2, align=1
384// CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
385
386struct RZ3 : RX3, RY {};
387// CHECK: *** Dumping AST Record Layout
388// CHECK: *** Dumping AST Record Layout
389// CHECK-NEXT:    0 | struct RZ3
390// CHECK-NEXT:    0 |   struct RX3 (base)
391// CHECK-NEXT:    0 |     struct RA (base) (empty)
392// CHECK-NEXT:    0 |     struct RB a
393// CHECK-NEXT:    0 |       char c
394// CHECK-NEXT:      |     [sizeof=1, align=1
395// CHECK-NEXT:      |      nvsize=1, nvalign=1]
396// CHECK-NEXT:    1 |   struct RY (base) (empty)
397// CHECK-NEXT:      | [sizeof=1, align=1
398// CHECK-NEXT:      |  nvsize=1, nvalign=1]
399// CHECK-X64: *** Dumping AST Record Layout
400// CHECK-X64: *** Dumping AST Record Layout
401// CHECK-X64-NEXT:    0 | struct RZ3
402// CHECK-X64-NEXT:    0 |   struct RX3 (base)
403// CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
404// CHECK-X64-NEXT:    0 |     struct RB a
405// CHECK-X64-NEXT:    0 |       char c
406// CHECK-X64-NEXT:      |     [sizeof=1, align=1
407// CHECK-X64-NEXT:      |      nvsize=1, nvalign=1]
408// CHECK-X64-NEXT:    1 |   struct RY (base) (empty)
409// CHECK-X64-NEXT:      | [sizeof=1, align=1
410// CHECK-X64-NEXT:      |  nvsize=1, nvalign=1]
411
412struct RZ4 : RX4, RY {};
413// CHECK: *** Dumping AST Record Layout
414// CHECK: *** Dumping AST Record Layout
415// CHECK-NEXT:    0 | struct RZ4
416// CHECK-NEXT:    0 |   struct RX4 (base)
417// CHECK-NEXT:    0 |     struct RA a (empty)
418// CHECK-NEXT:      |     [sizeof=1, align=1
419// CHECK-NEXT:      |      nvsize=0, nvalign=1]
420// CHECK-NEXT:    1 |     char b
421// CHECK-NEXT:    3 |   struct RY (base) (empty)
422// CHECK-NEXT:      | [sizeof=3, align=1
423// CHECK-NEXT:      |  nvsize=3, nvalign=1]
424// CHECK-X64: *** Dumping AST Record Layout
425// CHECK-X64: *** Dumping AST Record Layout
426// CHECK-X64-NEXT:    0 | struct RZ4
427// CHECK-X64-NEXT:    0 |   struct RX4 (base)
428// CHECK-X64-NEXT:    0 |     struct RA a (empty)
429// CHECK-X64-NEXT:      |     [sizeof=1, align=1
430// CHECK-X64-NEXT:      |      nvsize=0, nvalign=1]
431// CHECK-X64-NEXT:    1 |     char b
432// CHECK-X64-NEXT:    3 |   struct RY (base) (empty)
433// CHECK-X64-NEXT:      | [sizeof=3, align=1
434// CHECK-X64-NEXT:      |  nvsize=3, nvalign=1]
435
436struct RZ5 : RX5, RY {};
437// CHECK: *** Dumping AST Record Layout
438// CHECK: *** Dumping AST Record Layout
439// CHECK-NEXT:    0 | struct RZ5
440// CHECK-NEXT:    0 |   struct RX5 (base)
441// CHECK-NEXT:    0 |     struct RA a (empty)
442// CHECK-NEXT:      |     [sizeof=1, align=1
443// CHECK-NEXT:      |      nvsize=0, nvalign=1]
444// CHECK-NEXT:    1 |     struct RB b
445// CHECK-NEXT:    1 |       char c
446// CHECK-NEXT:      |     [sizeof=1, align=1
447// CHECK-NEXT:      |      nvsize=1, nvalign=1]
448// CHECK-NEXT:    2 |   struct RY (base) (empty)
449// CHECK-NEXT:      | [sizeof=2, align=1
450// CHECK-NEXT:      |  nvsize=2, nvalign=1]
451// CHECK-X64: *** Dumping AST Record Layout
452// CHECK-X64: *** Dumping AST Record Layout
453// CHECK-X64-NEXT:    0 | struct RZ5
454// CHECK-X64-NEXT:    0 |   struct RX5 (base)
455// CHECK-X64-NEXT:    0 |     struct RA a (empty)
456// CHECK-X64-NEXT:      |     [sizeof=1, align=1
457// CHECK-X64-NEXT:      |      nvsize=0, nvalign=1]
458// CHECK-X64-NEXT:    1 |     struct RB b
459// CHECK-X64-NEXT:    1 |       char c
460// CHECK-X64-NEXT:      |     [sizeof=1, align=1
461// CHECK-X64-NEXT:      |      nvsize=1, nvalign=1]
462// CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
463// CHECK-X64-NEXT:      | [sizeof=2, align=1
464// CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
465
466struct RZ6 : RX6, RY {};
467// CHECK: *** Dumping AST Record Layout
468// CHECK: *** Dumping AST Record Layout
469// CHECK: *** Dumping AST Record Layout
470// CHECK-NEXT:    0 | struct RZ6
471// CHECK-NEXT:    0 |   struct RX6 (base)
472// CHECK-NEXT:    0 |     (RX6 vbtable pointer)
473// CHECK-NEXT:    4 |     struct RB a
474// CHECK-NEXT:    4 |       char c
475// CHECK-NEXT:      |     [sizeof=1, align=1
476// CHECK-NEXT:      |      nvsize=1, nvalign=1]
477// CHECK-NEXT:    9 |   struct RY (base) (empty)
478// CHECK-NEXT:   12 |   struct RV (virtual base) (empty)
479// CHECK-NEXT:      | [sizeof=12, align=4
480// CHECK-NEXT:      |  nvsize=12, nvalign=4]
481// CHECK-X64: *** Dumping AST Record Layout
482// CHECK-X64: *** Dumping AST Record Layout
483// CHECK-X64: *** Dumping AST Record Layout
484// CHECK-X64-NEXT:    0 | struct RZ6
485// CHECK-X64-NEXT:    0 |   struct RX6 (base)
486// CHECK-X64-NEXT:    0 |     (RX6 vbtable pointer)
487// CHECK-X64-NEXT:    8 |     struct RB a
488// CHECK-X64-NEXT:    8 |       char c
489// CHECK-X64-NEXT:      |     [sizeof=1, align=1
490// CHECK-X64-NEXT:      |      nvsize=1, nvalign=1]
491// CHECK-X64-NEXT:   17 |   struct RY (base) (empty)
492// CHECK-X64-NEXT:   24 |   struct RV (virtual base) (empty)
493// CHECK-X64-NEXT:      | [sizeof=24, align=8
494// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
495
496struct RZ7 : RX7, RY {};
497// CHECK: *** Dumping AST Record Layout
498// CHECK: *** Dumping AST Record Layout
499// CHECK: *** Dumping AST Record Layout
500// CHECK-NEXT:    0 | struct RZ7
501// CHECK-NEXT:    0 |   struct RX7 (base)
502// CHECK-NEXT:    0 |     (RX7 vbtable pointer)
503// CHECK-NEXT:    4 |     struct RA a (empty)
504// CHECK-NEXT:      |     [sizeof=1, align=1
505// CHECK-NEXT:      |      nvsize=0, nvalign=1]
506// CHECK-NEXT:    8 |   struct RY (base) (empty)
507// CHECK-NEXT:    8 |   struct RW (virtual base)
508// CHECK-NEXT:    8 |     char c
509// CHECK-NEXT:      | [sizeof=9, align=4
510// CHECK-NEXT:      |  nvsize=8, nvalign=4]
511// CHECK-X64: *** Dumping AST Record Layout
512// CHECK-X64: *** Dumping AST Record Layout
513// CHECK-X64: *** Dumping AST Record Layout
514// CHECK-X64-NEXT:    0 | struct RZ7
515// CHECK-X64-NEXT:    0 |   struct RX7 (base)
516// CHECK-X64-NEXT:    0 |     (RX7 vbtable pointer)
517// CHECK-X64-NEXT:    8 |     struct RA a (empty)
518// CHECK-X64-NEXT:      |     [sizeof=1, align=1
519// CHECK-X64-NEXT:      |      nvsize=0, nvalign=1]
520// CHECK-X64-NEXT:   16 |   struct RY (base) (empty)
521// CHECK-X64-NEXT:   16 |   struct RW (virtual base)
522// CHECK-X64-NEXT:   16 |     char c
523// CHECK-X64-NEXT:      | [sizeof=24, align=8
524// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
525
526struct RZ8 : RX8, RY {};
527// CHECK: *** Dumping AST Record Layout
528// CHECK: *** Dumping AST Record Layout
529// CHECK-NEXT:    0 | struct RZ8
530// CHECK-NEXT:    0 |   struct RX8 (base)
531// CHECK-NEXT:    4 |     struct RA (base) (empty)
532// CHECK-NEXT:    0 |     (RX8 vbtable pointer)
533// CHECK-NEXT:    4 |   struct RY (base) (empty)
534// CHECK-NEXT:    4 |   struct RW (virtual base)
535// CHECK-NEXT:    4 |     char c
536// CHECK-NEXT:      | [sizeof=5, align=4
537// CHECK-NEXT:      |  nvsize=4, nvalign=4]
538// CHECK-X64: *** Dumping AST Record Layout
539// CHECK-X64: *** Dumping AST Record Layout
540// CHECK-X64-NEXT:    0 | struct RZ8
541// CHECK-X64-NEXT:    0 |   struct RX8 (base)
542// CHECK-X64-NEXT:    8 |     struct RA (base) (empty)
543// CHECK-X64-NEXT:    0 |     (RX8 vbtable pointer)
544// CHECK-X64-NEXT:    8 |   struct RY (base) (empty)
545// CHECK-X64-NEXT:    8 |   struct RW (virtual base)
546// CHECK-X64-NEXT:    8 |     char c
547// CHECK-X64-NEXT:      | [sizeof=16, align=8
548// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
549
550struct JA {};
551struct JB {};
552struct JC : JA { virtual void f() {} };
553struct JD : virtual JB, virtual JC { virtual void f() {} JD() {} };
554
555// CHECK: *** Dumping AST Record Layout
556// CHECK: *** Dumping AST Record Layout
557// CHECK: *** Dumping AST Record Layout
558// CHECK: *** Dumping AST Record Layout
559// CHECK-NEXT:    0 | struct JD
560// CHECK-NEXT:    0 |   (JD vbtable pointer)
561// CHECK-NEXT:    4 |   struct JB (virtual base) (empty)
562// CHECK-NEXT:    4 |   (vtordisp for vbase JC)
563// CHECK-NEXT:    8 |   struct JC (virtual base)
564// CHECK-NEXT:    8 |     (JC vftable pointer)
565// CHECK-NEXT:   12 |     struct JA (base) (empty)
566// CHECK-NEXT:      | [sizeof=12, align=4
567// CHECK-NEXT:      |  nvsize=4, nvalign=4]
568// CHECK-X64: *** Dumping AST Record Layout
569// CHECK-X64: *** Dumping AST Record Layout
570// CHECK-X64: *** Dumping AST Record Layout
571// CHECK-X64: *** Dumping AST Record Layout
572// CHECK-X64-NEXT:    0 | struct JD
573// CHECK-X64-NEXT:    0 |   (JD vbtable pointer)
574// CHECK-X64-NEXT:    8 |   struct JB (virtual base) (empty)
575// CHECK-X64-NEXT:   12 |   (vtordisp for vbase JC)
576// CHECK-X64-NEXT:   16 |   struct JC (virtual base)
577// CHECK-X64-NEXT:   16 |     (JC vftable pointer)
578// CHECK-X64-NEXT:   24 |     struct JA (base) (empty)
579// CHECK-X64-NEXT:      | [sizeof=24, align=8
580// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
581
582int a[
583sizeof(AT3) +
584sizeof(BT3) +
585sizeof(T3) +
586sizeof(E) +
587sizeof(F) +
588sizeof(JC4) +
589sizeof(RZ0) +
590sizeof(RZ1) +
591sizeof(RZ2) +
592sizeof(RZ3) +
593sizeof(RZ4) +
594sizeof(RZ5) +
595sizeof(RZ6) +
596sizeof(RZ7) +
597sizeof(RZ8) +
598sizeof(JD) +
5990];
600