1// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fms-extensions -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 -fms-extensions -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:    1 |   struct RY (base) (empty)
395// CHECK-NEXT:      | [sizeof=1, align=1
396// CHECK-NEXT:      |  nvsize=1, nvalign=1]
397// CHECK-X64: *** Dumping AST Record Layout
398// CHECK-X64: *** Dumping AST Record Layout
399// CHECK-X64-NEXT:    0 | struct RZ3
400// CHECK-X64-NEXT:    0 |   struct RX3 (base)
401// CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
402// CHECK-X64-NEXT:    0 |     struct RB a
403// CHECK-X64-NEXT:    0 |       char c
404// CHECK-X64-NEXT:    1 |   struct RY (base) (empty)
405// CHECK-X64-NEXT:      | [sizeof=1, align=1
406// CHECK-X64-NEXT:      |  nvsize=1, nvalign=1]
407
408struct RZ4 : RX4, RY {};
409// CHECK: *** Dumping AST Record Layout
410// CHECK: *** Dumping AST Record Layout
411// CHECK-NEXT:    0 | struct RZ4
412// CHECK-NEXT:    0 |   struct RX4 (base)
413// CHECK-NEXT:    0 |     struct RA a (empty)
414// CHECK-NEXT:    1 |     char b
415// CHECK-NEXT:    3 |   struct RY (base) (empty)
416// CHECK-NEXT:      | [sizeof=3, align=1
417// CHECK-NEXT:      |  nvsize=3, nvalign=1]
418// CHECK-X64: *** Dumping AST Record Layout
419// CHECK-X64: *** Dumping AST Record Layout
420// CHECK-X64-NEXT:    0 | struct RZ4
421// CHECK-X64-NEXT:    0 |   struct RX4 (base)
422// CHECK-X64-NEXT:    0 |     struct RA a (empty)
423// CHECK-X64-NEXT:    1 |     char b
424// CHECK-X64-NEXT:    3 |   struct RY (base) (empty)
425// CHECK-X64-NEXT:      | [sizeof=3, align=1
426// CHECK-X64-NEXT:      |  nvsize=3, nvalign=1]
427
428struct RZ5 : RX5, RY {};
429// CHECK: *** Dumping AST Record Layout
430// CHECK: *** Dumping AST Record Layout
431// CHECK-NEXT:    0 | struct RZ5
432// CHECK-NEXT:    0 |   struct RX5 (base)
433// CHECK-NEXT:    0 |     struct RA a (empty)
434// CHECK-NEXT:    1 |     struct RB b
435// CHECK-NEXT:    1 |       char c
436// CHECK-NEXT:    2 |   struct RY (base) (empty)
437// CHECK-NEXT:      | [sizeof=2, align=1
438// CHECK-NEXT:      |  nvsize=2, nvalign=1]
439// CHECK-X64: *** Dumping AST Record Layout
440// CHECK-X64: *** Dumping AST Record Layout
441// CHECK-X64-NEXT:    0 | struct RZ5
442// CHECK-X64-NEXT:    0 |   struct RX5 (base)
443// CHECK-X64-NEXT:    0 |     struct RA a (empty)
444// CHECK-X64-NEXT:    1 |     struct RB b
445// CHECK-X64-NEXT:    1 |       char c
446// CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
447// CHECK-X64-NEXT:      | [sizeof=2, align=1
448// CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
449
450struct RZ6 : RX6, RY {};
451// CHECK: *** Dumping AST Record Layout
452// CHECK: *** Dumping AST Record Layout
453// CHECK: *** Dumping AST Record Layout
454// CHECK-NEXT:    0 | struct RZ6
455// CHECK-NEXT:    0 |   struct RX6 (base)
456// CHECK-NEXT:    0 |     (RX6 vbtable pointer)
457// CHECK-NEXT:    4 |     struct RB a
458// CHECK-NEXT:    4 |       char c
459// CHECK-NEXT:    9 |   struct RY (base) (empty)
460// CHECK-NEXT:   12 |   struct RV (virtual base) (empty)
461// CHECK-NEXT:      | [sizeof=12, align=4
462// CHECK-NEXT:      |  nvsize=12, nvalign=4]
463// CHECK-X64: *** Dumping AST Record Layout
464// CHECK-X64: *** Dumping AST Record Layout
465// CHECK-X64: *** Dumping AST Record Layout
466// CHECK-X64-NEXT:    0 | struct RZ6
467// CHECK-X64-NEXT:    0 |   struct RX6 (base)
468// CHECK-X64-NEXT:    0 |     (RX6 vbtable pointer)
469// CHECK-X64-NEXT:    8 |     struct RB a
470// CHECK-X64-NEXT:    8 |       char c
471// CHECK-X64-NEXT:   17 |   struct RY (base) (empty)
472// CHECK-X64-NEXT:   24 |   struct RV (virtual base) (empty)
473// CHECK-X64-NEXT:      | [sizeof=24, align=8
474// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
475
476struct RZ7 : RX7, RY {};
477// CHECK: *** Dumping AST Record Layout
478// CHECK: *** Dumping AST Record Layout
479// CHECK: *** Dumping AST Record Layout
480// CHECK-NEXT:    0 | struct RZ7
481// CHECK-NEXT:    0 |   struct RX7 (base)
482// CHECK-NEXT:    0 |     (RX7 vbtable pointer)
483// CHECK-NEXT:    4 |     struct RA a (empty)
484// CHECK-NEXT:    8 |   struct RY (base) (empty)
485// CHECK-NEXT:    8 |   struct RW (virtual base)
486// CHECK-NEXT:    8 |     char c
487// CHECK-NEXT:      | [sizeof=9, align=4
488// CHECK-NEXT:      |  nvsize=8, nvalign=4]
489// CHECK-X64: *** Dumping AST Record Layout
490// CHECK-X64: *** Dumping AST Record Layout
491// CHECK-X64: *** Dumping AST Record Layout
492// CHECK-X64-NEXT:    0 | struct RZ7
493// CHECK-X64-NEXT:    0 |   struct RX7 (base)
494// CHECK-X64-NEXT:    0 |     (RX7 vbtable pointer)
495// CHECK-X64-NEXT:    8 |     struct RA a (empty)
496// CHECK-X64-NEXT:   16 |   struct RY (base) (empty)
497// CHECK-X64-NEXT:   16 |   struct RW (virtual base)
498// CHECK-X64-NEXT:   16 |     char c
499// CHECK-X64-NEXT:      | [sizeof=24, align=8
500// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
501
502struct RZ8 : RX8, RY {};
503// CHECK: *** Dumping AST Record Layout
504// CHECK: *** Dumping AST Record Layout
505// CHECK-NEXT:    0 | struct RZ8
506// CHECK-NEXT:    0 |   struct RX8 (base)
507// CHECK-NEXT:    4 |     struct RA (base) (empty)
508// CHECK-NEXT:    0 |     (RX8 vbtable pointer)
509// CHECK-NEXT:    4 |   struct RY (base) (empty)
510// CHECK-NEXT:    4 |   struct RW (virtual base)
511// CHECK-NEXT:    4 |     char c
512// CHECK-NEXT:      | [sizeof=5, align=4
513// CHECK-NEXT:      |  nvsize=4, nvalign=4]
514// CHECK-X64: *** Dumping AST Record Layout
515// CHECK-X64: *** Dumping AST Record Layout
516// CHECK-X64-NEXT:    0 | struct RZ8
517// CHECK-X64-NEXT:    0 |   struct RX8 (base)
518// CHECK-X64-NEXT:    8 |     struct RA (base) (empty)
519// CHECK-X64-NEXT:    0 |     (RX8 vbtable pointer)
520// CHECK-X64-NEXT:    8 |   struct RY (base) (empty)
521// CHECK-X64-NEXT:    8 |   struct RW (virtual base)
522// CHECK-X64-NEXT:    8 |     char c
523// CHECK-X64-NEXT:      | [sizeof=16, align=8
524// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
525
526struct JA {};
527struct JB {};
528struct JC : JA { virtual void f() {} };
529struct JD : virtual JB, virtual JC { virtual void f() {} JD() {} };
530
531// CHECK: *** Dumping AST Record Layout
532// CHECK: *** Dumping AST Record Layout
533// CHECK: *** Dumping AST Record Layout
534// CHECK: *** Dumping AST Record Layout
535// CHECK-NEXT:    0 | struct JD
536// CHECK-NEXT:    0 |   (JD vbtable pointer)
537// CHECK-NEXT:    4 |   struct JB (virtual base) (empty)
538// CHECK-NEXT:    4 |   (vtordisp for vbase JC)
539// CHECK-NEXT:    8 |   struct JC (virtual base)
540// CHECK-NEXT:    8 |     (JC vftable pointer)
541// CHECK-NEXT:   12 |     struct JA (base) (empty)
542// CHECK-NEXT:      | [sizeof=12, align=4
543// CHECK-NEXT:      |  nvsize=4, nvalign=4]
544// CHECK-X64: *** Dumping AST Record Layout
545// CHECK-X64: *** Dumping AST Record Layout
546// CHECK-X64: *** Dumping AST Record Layout
547// CHECK-X64: *** Dumping AST Record Layout
548// CHECK-X64-NEXT:    0 | struct JD
549// CHECK-X64-NEXT:    0 |   (JD vbtable pointer)
550// CHECK-X64-NEXT:    8 |   struct JB (virtual base) (empty)
551// CHECK-X64-NEXT:   12 |   (vtordisp for vbase JC)
552// CHECK-X64-NEXT:   16 |   struct JC (virtual base)
553// CHECK-X64-NEXT:   16 |     (JC vftable pointer)
554// CHECK-X64-NEXT:   24 |     struct JA (base) (empty)
555// CHECK-X64-NEXT:      | [sizeof=24, align=8
556// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
557
558int a[
559sizeof(AT3) +
560sizeof(BT3) +
561sizeof(T3) +
562sizeof(E) +
563sizeof(F) +
564sizeof(JC4) +
565sizeof(RZ0) +
566sizeof(RZ1) +
567sizeof(RZ2) +
568sizeof(RZ3) +
569sizeof(RZ4) +
570sizeof(RZ5) +
571sizeof(RZ6) +
572sizeof(RZ7) +
573sizeof(RZ8) +
574sizeof(JD) +
5750];
576