xref: /llvm-project/clang/test/Layout/ms-x86-alias-avoidance-padding.cpp (revision 7c1d9b15eee3a34678addab2bab66f3020ac0753)
1 // RUN: %clang_cc1 -fno-rtti -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 -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 __declspec(align(4096)) char buffer[4096];
8 
9 struct AT {};
10 
11 struct V : AT {
12 	char c;
VV13 	V() {
14 		printf("V   - this: %d\n", (int)((char*)this - buffer));
15 	}
16 };
17 
18 struct AT0 {
19 	union { struct { int a; AT t; } y; int b; } x;
20 	char c;
AT0AT021 	AT0() {
22 		printf("AT0 - this: %d\n", (int)((char*)this - buffer));
23 	}
24 };
25 
26 struct AT1 : V {
27 	int a;
AT1AT128 	AT1() {
29 		printf("AT1 - this: %d\n", (int)((char*)this - buffer));
30 	}
31 };
32 
33 struct AT2 {
34 	AT0 t;
35 	char AT2FieldName0;
AT2AT236 	AT2() {
37 		printf("AT2 - this: %d\n", (int)((char*)this - buffer));
38 		printf("AT2 - Fiel: %d\n", (int)((char*)&AT2FieldName0 - buffer));
39 	}
40 };
41 
42 struct AT3 : AT2, AT1 {
AT3AT343 	AT3() {
44 		printf("AT3 - this: %d\n", (int)((char*)this - buffer));
45 	}
46 };
47 
48 // CHECK-LABEL:   0 | struct AT3{{$}}
49 // CHECK-NEXT:    0 |   struct AT2 (base)
50 // CHECK-NEXT:    0 |     struct AT0 t
51 // CHECK-NEXT:    0 |       union AT0::(unnamed at {{.*}} x
52 // CHECK-NEXT:    0 |         struct AT0::(unnamed at {{.*}} y
53 // CHECK-NEXT:    0 |           int a
54 // CHECK-NEXT:    4 |           struct AT t (empty)
55 // CHECK:         0 |         int b
56 // CHECK:         8 |       char c
57 // CHECK:        12 |     char AT2FieldName0
58 // CHECK-NEXT:   20 |   struct AT1 (base)
59 // CHECK-NEXT:   20 |     struct V (base)
60 // CHECK-NEXT:   20 |       struct AT (base) (empty)
61 // CHECK-NEXT:   20 |       char c
62 // CHECK-NEXT:   24 |     int a
63 // CHECK-NEXT:      | [sizeof=28, align=4
64 // CHECK-NEXT:      |  nvsize=28, nvalign=4]
65 // CHECK-X64-LABEL:   0 | struct AT3{{$}}
66 // CHECK-X64-NEXT:    0 |   struct AT2 (base)
67 // CHECK-X64-NEXT:    0 |     struct AT0 t
68 // CHECK-X64-NEXT:    0 |       union AT0::(unnamed at {{.*}} x
69 // CHECK-X64-NEXT:    0 |         struct AT0::(unnamed at {{.*}} y
70 // CHECK-X64-NEXT:    0 |           int a
71 // CHECK-X64-NEXT:    4 |           struct AT t (empty)
72 // CHECK-X64:         0 |         int b
73 // CHECK-X64:         8 |       char c
74 // CHECK-X64:        12 |     char AT2FieldName0
75 // CHECK-X64-NEXT:   20 |   struct AT1 (base)
76 // CHECK-X64-NEXT:   20 |     struct V (base)
77 // CHECK-X64-NEXT:   20 |       struct AT (base) (empty)
78 // CHECK-X64-NEXT:   20 |       char c
79 // CHECK-X64-NEXT:   24 |     int a
80 // CHECK-X64-NEXT:      | [sizeof=28, align=4
81 // CHECK-X64-NEXT:      |  nvsize=28, nvalign=4]
82 
83 struct BT0 {
BT0BT084 	BT0() {
85 		printf("BT0 - this: %d\n", (int)((char*)this - buffer));
86 	}
87 };
88 
89 struct BT2 : BT0 {
90 	char BT2FieldName0;
BT2BT291 	BT2() {
92 		printf("BT2 - this: %d\n", (int)((char*)this - buffer));
93 		printf("BT2 - Fiel: %d\n", (int)((char*)&BT2FieldName0 - buffer));
94 	}
95 };
96 
97 struct BT3 : BT0, BT2 {
BT3BT398 	BT3() {
99 		printf("BT3 - this: %d\n", (int)((char*)this - buffer));
100 	}
101 };
102 
103 // CHECK-LABEL:   0 | struct BT3{{$}}
104 // CHECK-NEXT:    0 |   struct BT0 (base) (empty)
105 // CHECK-NEXT:    1 |   struct BT2 (base)
106 // CHECK-NEXT:    1 |     struct BT0 (base) (empty)
107 // CHECK-NEXT:    1 |     char BT2FieldName0
108 // CHECK-NEXT:      | [sizeof=2, align=1
109 // CHECK-NEXT:      |  nvsize=2, nvalign=1]
110 // CHECK-X64-LABEL:   0 | struct BT3{{$}}
111 // CHECK-X64-NEXT:    0 |   struct BT0 (base) (empty)
112 // CHECK-X64-NEXT:    1 |   struct BT2 (base)
113 // CHECK-X64-NEXT:    1 |     struct BT0 (base) (empty)
114 // CHECK-X64-NEXT:    1 |     char BT2FieldName0
115 // CHECK-X64-NEXT:      | [sizeof=2, align=1
116 // CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
117 
118 struct T0 : AT {
T0T0119 	T0() {
120 		printf("T0 (this) : %d\n", (int)((char*)this - buffer));
121 	}
122 };
123 
124 struct T1 : T0 {
125 	char a;
T1T1126 	T1() {
127 		printf("T1 (this) : %d\n", (int)((char*)this - buffer));
128 		printf("T1 (fiel) : %d\n", (int)((char*)&a - buffer));
129 	}
130 };
131 
132 struct T2 : AT {
133 	char a;
T2T2134 	T2() {
135 		printf("T2 (this) : %d\n", (int)((char*)this - buffer));
136 		printf("T2 (fiel) : %d\n", (int)((char*)&a - buffer));
137 	}
138 };
139 
140 struct __declspec(align(1)) T3 : virtual T1, virtual T2 {
T3T3141 	T3() {
142 		printf("T3 (this) : %d\n", (int)((char*)this - buffer));
143 	}
144 };
145 
146 // CHECK-LABEL:   0 | struct T3{{$}}
147 // CHECK-NEXT:    0 |   (T3 vbtable pointer)
148 // CHECK-NEXT:    4 |   struct T1 (virtual base)
149 // CHECK-NEXT:    4 |     struct T0 (base) (empty)
150 // CHECK-NEXT:    4 |       struct AT (base) (empty)
151 // CHECK-NEXT:    4 |     char a
152 // CHECK-NEXT:   12 |   struct T2 (virtual base)
153 // CHECK-NEXT:   12 |     struct AT (base) (empty)
154 // CHECK-NEXT:   12 |     char a
155 // CHECK-NEXT:      | [sizeof=16, align=4
156 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
157 // CHECK-X64-LABEL:   0 | struct T3{{$}}
158 // CHECK-X64-NEXT:    0 |   (T3 vbtable pointer)
159 // CHECK-X64-NEXT:    8 |   struct T1 (virtual base)
160 // CHECK-X64-NEXT:    8 |     struct T0 (base) (empty)
161 // CHECK-X64-NEXT:    8 |       struct AT (base) (empty)
162 // CHECK-X64-NEXT:    8 |     char a
163 // CHECK-X64-NEXT:   16 |   struct T2 (virtual base)
164 // CHECK-X64-NEXT:   16 |     struct AT (base) (empty)
165 // CHECK-X64-NEXT:   16 |     char a
166 // CHECK-X64-NEXT:      | [sizeof=24, align=8
167 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
168 
169 struct B {};
170 struct C { int a; };
171 struct D : B, virtual C { B b; };
172 struct E : D, B {};
173 // CHECK-LABEL:   0 | struct E{{$}}
174 // CHECK-NEXT:    0 |   struct D (base)
175 // CHECK-NEXT:    4 |     struct B (base) (empty)
176 // CHECK-NEXT:    0 |     (D vbtable pointer)
177 // CHECK-NEXT:    4 |     struct B b (empty)
178 // CHECK:         8 |   struct B (base) (empty)
179 // CHECK-NEXT:    8 |   struct C (virtual base)
180 // CHECK-NEXT:    8 |     int a
181 // CHECK-NEXT:      | [sizeof=12, align=4
182 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
183 // CHECK-X64-LABEL:  0 | struct E{{$}}
184 // CHECK-X64-NEXT:   0 |   struct D (base)
185 // CHECK-X64-NEXT:   8 |     struct B (base) (empty)
186 // CHECK-X64-NEXT:   0 |     (D vbtable pointer)
187 // CHECK-X64-NEXT:   8 |     struct B b (empty)
188 // CHECK-X64:       16 |   struct B (base) (empty)
189 // CHECK-X64-NEXT:  16 |   struct C (virtual base)
190 // CHECK-X64-NEXT:  16 |     int a
191 // CHECK-X64-NEXT:     | [sizeof=24, align=8
192 // CHECK-X64-NEXT:     |  nvsize=16, nvalign=8]
193 
194 struct F : virtual D, virtual B {};
195 // CHECK-LABEL:   0 | struct F{{$}}
196 // CHECK-NEXT:    0 |   (F vbtable pointer)
197 // CHECK-NEXT:    4 |   struct C (virtual base)
198 // CHECK-NEXT:    4 |     int a
199 // CHECK-NEXT:    8 |   struct D (virtual base)
200 // CHECK-NEXT:   12 |     struct B (base) (empty)
201 // CHECK-NEXT:    8 |     (D vbtable pointer)
202 // CHECK-NEXT:   12 |     struct B b (empty)
203 // CHECK:        16 |   struct B (virtual base) (empty)
204 // CHECK-NEXT:      | [sizeof=16, align=4
205 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
206 // CHECK-X64-LABEL:   0 | struct F{{$}}
207 // CHECK-X64-NEXT:    0 |   (F vbtable pointer)
208 // CHECK-X64-NEXT:    8 |   struct C (virtual base)
209 // CHECK-X64-NEXT:    8 |     int a
210 // CHECK-X64-NEXT:   16 |   struct D (virtual base)
211 // CHECK-X64-NEXT:   24 |     struct B (base) (empty)
212 // CHECK-X64-NEXT:   16 |     (D vbtable pointer)
213 // CHECK-X64-NEXT:   24 |     struct B b (empty)
214 // CHECK-X64:        32 |   struct B (virtual base) (empty)
215 // CHECK-X64-NEXT:      | [sizeof=32, align=8
216 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
217 
218 struct JC0 {
JC0JC0219 	JC0() { printf("JC0 : %d\n", (int)((char*)this - buffer)); }
220 };
221 struct JC1 : JC0 {
fJC1222 	virtual void f() {}
JC1JC1223 	JC1() { printf("JC1 : %d\n", (int)((char*)this - buffer)); }
224 };
225 struct JC2 : JC1 {
JC2JC2226 	JC2() { printf("JC2 : %d\n", (int)((char*)this - buffer)); }
227 };
228 struct JC4 : JC1, JC2 {
JC4JC4229 	JC4() { printf("JC4 : %d\n", (int)((char*)this - buffer)); }
230 };
231 
232 // CHECK-LABEL:   0 | struct JC4{{$}}
233 // CHECK-NEXT:    0 |   struct JC1 (primary base)
234 // CHECK-NEXT:    0 |     (JC1 vftable pointer)
235 // CHECK-NEXT:    4 |     struct JC0 (base) (empty)
236 // CHECK-NEXT:    8 |   struct JC2 (base)
237 // CHECK-NEXT:    8 |     struct JC1 (primary base)
238 // CHECK-NEXT:    8 |       (JC1 vftable pointer)
239 // CHECK-NEXT:   12 |       struct JC0 (base) (empty)
240 // CHECK-NEXT:      | [sizeof=12, align=4
241 // CHECK-NEXT:      |  nvsize=12, nvalign=4]
242 // CHECK-X64-LABEL:   0 | struct JC4{{$}}
243 // CHECK-X64-NEXT:    0 |   struct JC1 (primary base)
244 // CHECK-X64-NEXT:    0 |     (JC1 vftable pointer)
245 // CHECK-X64-NEXT:    8 |     struct JC0 (base) (empty)
246 // CHECK-X64-NEXT:   16 |   struct JC2 (base)
247 // CHECK-X64-NEXT:   16 |     struct JC1 (primary base)
248 // CHECK-X64-NEXT:   16 |       (JC1 vftable pointer)
249 // CHECK-X64-NEXT:   24 |       struct JC0 (base) (empty)
250 // CHECK-X64-NEXT:      | [sizeof=24, align=8
251 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
252 
253 struct RA {};
254 struct RB { char c; };
255 struct RV {};
256 struct RW { char c; };
RYRY257 struct RY { RY() { printf("%Id\n", (char*)this - buffer); } };
258 struct RX0 : RB, RA {};
259 struct RX1 : RA, RB {};
260 struct RX2 : RA { char a; };
261 struct RX3 : RA { RB a; };
262 struct RX4 { RA a; char b; };
263 struct RX5 { RA a; RB b; };
264 struct RX6 : virtual RV { RB a; };
265 struct RX7 : virtual RW { RA a; };
266 struct RX8 : RA, virtual RW {};
267 
268 struct RZ0 : RX0, RY {};
269 // CHECK-LABEL:   0 | struct RZ0{{$}}
270 // CHECK-NEXT:    0 |   struct RX0 (base)
271 // CHECK-NEXT:    0 |     struct RB (base)
272 // CHECK-NEXT:    0 |       char c
273 // CHECK-NEXT:    1 |     struct RA (base) (empty)
274 // CHECK-NEXT:    2 |   struct RY (base) (empty)
275 // CHECK-NEXT:      | [sizeof=2, align=1
276 // CHECK-NEXT:      |  nvsize=2, nvalign=1]
277 // CHECK-X64-LABEL:   0 | struct RZ0{{$}}
278 // CHECK-X64-NEXT:    0 |   struct RX0 (base)
279 // CHECK-X64-NEXT:    0 |     struct RB (base)
280 // CHECK-X64-NEXT:    0 |       char c
281 // CHECK-X64-NEXT:    1 |     struct RA (base) (empty)
282 // CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
283 // CHECK-X64-NEXT:      | [sizeof=2, align=1
284 // CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
285 
286 struct RZ1 : RX1, RY {};
287 // CHECK-LABEL:   0 | struct RZ1{{$}}
288 // CHECK-NEXT:    0 |   struct RX1 (base)
289 // CHECK-NEXT:    0 |     struct RA (base) (empty)
290 // CHECK-NEXT:    0 |     struct RB (base)
291 // CHECK-NEXT:    0 |       char c
292 // CHECK-NEXT:    1 |   struct RY (base) (empty)
293 // CHECK-NEXT:      | [sizeof=1, align=1
294 // CHECK-NEXT:      |  nvsize=1, nvalign=1]
295 // CHECK-X64-LABEL:   0 | struct RZ1{{$}}
296 // CHECK-X64-NEXT:    0 |   struct RX1 (base)
297 // CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
298 // CHECK-X64-NEXT:    0 |     struct RB (base)
299 // CHECK-X64-NEXT:    0 |       char c
300 // CHECK-X64-NEXT:    1 |   struct RY (base) (empty)
301 // CHECK-X64-NEXT:      | [sizeof=1, align=1
302 // CHECK-X64-NEXT:      |  nvsize=1, nvalign=1]
303 
304 struct RZ2 : RX2, RY {};
305 // CHECK-LABEL:   0 | struct RZ2{{$}}
306 // CHECK-NEXT:    0 |   struct RX2 (base)
307 // CHECK-NEXT:    0 |     struct RA (base) (empty)
308 // CHECK-NEXT:    0 |     char a
309 // CHECK-NEXT:    2 |   struct RY (base) (empty)
310 // CHECK-NEXT:      | [sizeof=2, align=1
311 // CHECK-NEXT:      |  nvsize=2, nvalign=1]
312 // CHECK-X64-LABEL:   0 | struct RZ2{{$}}
313 // CHECK-X64-NEXT:    0 |   struct RX2 (base)
314 // CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
315 // CHECK-X64-NEXT:    0 |     char a
316 // CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
317 // CHECK-X64-NEXT:      | [sizeof=2, align=1
318 // CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
319 
320 struct RZ3 : RX3, RY {};
321 // CHECK-LABEL:   0 | struct RZ3{{$}}
322 // CHECK-NEXT:    0 |   struct RX3 (base)
323 // CHECK-NEXT:    0 |     struct RA (base) (empty)
324 // CHECK-NEXT:    0 |     struct RB a
325 // CHECK-NEXT:    0 |       char c
326 // CHECK-NEXT:    1 |   struct RY (base) (empty)
327 // CHECK-NEXT:      | [sizeof=1, align=1
328 // CHECK-NEXT:      |  nvsize=1, nvalign=1]
329 // CHECK-X64-LABEL:   0 | struct RZ3{{$}}
330 // CHECK-X64-NEXT:    0 |   struct RX3 (base)
331 // CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
332 // CHECK-X64-NEXT:    0 |     struct RB a
333 // CHECK-X64-NEXT:    0 |       char c
334 // CHECK-X64-NEXT:    1 |   struct RY (base) (empty)
335 // CHECK-X64-NEXT:      | [sizeof=1, align=1
336 // CHECK-X64-NEXT:      |  nvsize=1, nvalign=1]
337 
338 struct RZ4 : RX4, RY {};
339 // CHECK-LABEL:   0 | struct RZ4{{$}}
340 // CHECK-NEXT:    0 |   struct RX4 (base)
341 // CHECK-NEXT:    0 |     struct RA a (empty)
342 // CHECK-NEXT:    1 |     char b
343 // CHECK-NEXT:    3 |   struct RY (base) (empty)
344 // CHECK-NEXT:      | [sizeof=3, align=1
345 // CHECK-NEXT:      |  nvsize=3, nvalign=1]
346 // CHECK-X64-LABEL:   0 | struct RZ4{{$}}
347 // CHECK-X64-NEXT:    0 |   struct RX4 (base)
348 // CHECK-X64-NEXT:    0 |     struct RA a (empty)
349 // CHECK-X64-NEXT:    1 |     char b
350 // CHECK-X64-NEXT:    3 |   struct RY (base) (empty)
351 // CHECK-X64-NEXT:      | [sizeof=3, align=1
352 // CHECK-X64-NEXT:      |  nvsize=3, nvalign=1]
353 
354 struct RZ5 : RX5, RY {};
355 // CHECK-LABEL:   0 | struct RZ5{{$}}
356 // CHECK-NEXT:    0 |   struct RX5 (base)
357 // CHECK-NEXT:    0 |     struct RA a (empty)
358 // CHECK-NEXT:    1 |     struct RB b
359 // CHECK-NEXT:    1 |       char c
360 // CHECK-NEXT:    2 |   struct RY (base) (empty)
361 // CHECK-NEXT:      | [sizeof=2, align=1
362 // CHECK-NEXT:      |  nvsize=2, nvalign=1]
363 // CHECK-X64-LABEL:   0 | struct RZ5{{$}}
364 // CHECK-X64-NEXT:    0 |   struct RX5 (base)
365 // CHECK-X64-NEXT:    0 |     struct RA a (empty)
366 // CHECK-X64-NEXT:    1 |     struct RB b
367 // CHECK-X64-NEXT:    1 |       char c
368 // CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
369 // CHECK-X64-NEXT:      | [sizeof=2, align=1
370 // CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
371 
372 struct RZ6 : RX6, RY {};
373 // CHECK-LABEL:   0 | struct RZ6{{$}}
374 // CHECK-NEXT:    0 |   struct RX6 (base)
375 // CHECK-NEXT:    0 |     (RX6 vbtable pointer)
376 // CHECK-NEXT:    4 |     struct RB a
377 // CHECK-NEXT:    4 |       char c
378 // CHECK-NEXT:    9 |   struct RY (base) (empty)
379 // CHECK-NEXT:   12 |   struct RV (virtual base) (empty)
380 // CHECK-NEXT:      | [sizeof=12, align=4
381 // CHECK-NEXT:      |  nvsize=12, nvalign=4]
382 // CHECK-X64-LABEL:   0 | struct RZ6{{$}}
383 // CHECK-X64-NEXT:    0 |   struct RX6 (base)
384 // CHECK-X64-NEXT:    0 |     (RX6 vbtable pointer)
385 // CHECK-X64-NEXT:    8 |     struct RB a
386 // CHECK-X64-NEXT:    8 |       char c
387 // CHECK-X64-NEXT:   17 |   struct RY (base) (empty)
388 // CHECK-X64-NEXT:   24 |   struct RV (virtual base) (empty)
389 // CHECK-X64-NEXT:      | [sizeof=24, align=8
390 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
391 
392 struct RZ7 : RX7, RY {};
393 // CHECK-LABEL:   0 | struct RZ7{{$}}
394 // CHECK-NEXT:    0 |   struct RX7 (base)
395 // CHECK-NEXT:    0 |     (RX7 vbtable pointer)
396 // CHECK-NEXT:    4 |     struct RA a (empty)
397 // CHECK-NEXT:    8 |   struct RY (base) (empty)
398 // CHECK-NEXT:    8 |   struct RW (virtual base)
399 // CHECK-NEXT:    8 |     char c
400 // CHECK-NEXT:      | [sizeof=9, align=4
401 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
402 // CHECK-X64-LABEL:   0 | struct RZ7{{$}}
403 // CHECK-X64-NEXT:    0 |   struct RX7 (base)
404 // CHECK-X64-NEXT:    0 |     (RX7 vbtable pointer)
405 // CHECK-X64-NEXT:    8 |     struct RA a (empty)
406 // CHECK-X64-NEXT:   16 |   struct RY (base) (empty)
407 // CHECK-X64-NEXT:   16 |   struct RW (virtual base)
408 // CHECK-X64-NEXT:   16 |     char c
409 // CHECK-X64-NEXT:      | [sizeof=24, align=8
410 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
411 
412 struct RZ8 : RX8, RY {};
413 // CHECK-LABEL:   0 | struct RZ8{{$}}
414 // CHECK-NEXT:    0 |   struct RX8 (base)
415 // CHECK-NEXT:    4 |     struct RA (base) (empty)
416 // CHECK-NEXT:    0 |     (RX8 vbtable pointer)
417 // CHECK-NEXT:    4 |   struct RY (base) (empty)
418 // CHECK-NEXT:    4 |   struct RW (virtual base)
419 // CHECK-NEXT:    4 |     char c
420 // CHECK-NEXT:      | [sizeof=5, align=4
421 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
422 // CHECK-X64-LABEL:   0 | struct RZ8{{$}}
423 // CHECK-X64-NEXT:    0 |   struct RX8 (base)
424 // CHECK-X64-NEXT:    8 |     struct RA (base) (empty)
425 // CHECK-X64-NEXT:    0 |     (RX8 vbtable pointer)
426 // CHECK-X64-NEXT:    8 |   struct RY (base) (empty)
427 // CHECK-X64-NEXT:    8 |   struct RW (virtual base)
428 // CHECK-X64-NEXT:    8 |     char c
429 // CHECK-X64-NEXT:      | [sizeof=16, align=8
430 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
431 
432 struct JA {};
433 struct JB {};
fJC434 struct JC : JA { virtual void f() {} };
fJD435 struct JD : virtual JB, virtual JC { virtual void f() {} JD() {} };
436 
437 // CHECK-LABEL:   0 | struct JD{{$}}
438 // CHECK-NEXT:    0 |   (JD vbtable pointer)
439 // CHECK-NEXT:    4 |   struct JB (virtual base) (empty)
440 // CHECK-NEXT:    4 |   (vtordisp for vbase JC)
441 // CHECK-NEXT:    8 |   struct JC (virtual base)
442 // CHECK-NEXT:    8 |     (JC vftable pointer)
443 // CHECK-NEXT:   12 |     struct JA (base) (empty)
444 // CHECK-NEXT:      | [sizeof=12, align=4
445 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
446 // CHECK-X64-LABEL:   0 | struct JD{{$}}
447 // CHECK-X64-NEXT:    0 |   (JD vbtable pointer)
448 // CHECK-X64-NEXT:    8 |   struct JB (virtual base) (empty)
449 // CHECK-X64-NEXT:   12 |   (vtordisp for vbase JC)
450 // CHECK-X64-NEXT:   16 |   struct JC (virtual base)
451 // CHECK-X64-NEXT:   16 |     (JC vftable pointer)
452 // CHECK-X64-NEXT:   24 |     struct JA (base) (empty)
453 // CHECK-X64-NEXT:      | [sizeof=24, align=8
454 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
455 
456 int a[
457 sizeof(AT3) +
458 sizeof(BT3) +
459 sizeof(T3) +
460 sizeof(E) +
461 sizeof(F) +
462 sizeof(JC4) +
463 sizeof(RZ0) +
464 sizeof(RZ1) +
465 sizeof(RZ2) +
466 sizeof(RZ3) +
467 sizeof(RZ4) +
468 sizeof(RZ5) +
469 sizeof(RZ6) +
470 sizeof(RZ7) +
471 sizeof(RZ8) +
472 sizeof(JD) +
473 0];
474