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