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