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