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