1 // RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>&1 \
2 // RUN:            | FileCheck %s
3 
4 extern "C" int printf(const char *fmt, ...);
5 
6 struct __declspec(align(8)) B0 { B0() {printf("B0 : %3d\n", ((int)this)&0xfff);} };
7 struct __declspec(align(8)) B1 { B1() {printf("B1 : %3d\n", ((int)this)&0xfff);} };
8 struct __declspec(align(8)) B2 { B2() {printf("B2 : %3d\n", ((int)this)&0xfff);} };
9 struct __declspec(align(8)) B3 { B3() {printf("B3 : %3d\n", ((int)this)&0xfff);} };
10 struct __declspec(align(8)) B4 { B4() {printf("B4 : %3d\n", ((int)this)&0xfff);} };
11 
12 struct C0 { int a; C0() : a(0xf00000C0) {printf("C0 : %3d\n", ((int)this)&0xfff);} };
13 struct C1 { int a; C1() : a(0xf00000C1) {printf("C1 : %3d\n", ((int)this)&0xfff);} };
14 struct C2 { int a; C2() : a(0xf00000C2) {printf("C2 : %3d\n", ((int)this)&0xfff);} };
15 struct C3 { int a; C3() : a(0xf00000C3) {printf("C3 : %3d\n", ((int)this)&0xfff);} };
16 struct C4 { int a; C4() : a(0xf00000C4) {printf("C4 : %3d\n", ((int)this)&0xfff);} };
17 
18 struct __declspec(align(16)) D0 { D0() {printf("D0 : %3d\n", ((int)this)&0xfff);} virtual void f() {} };
19 struct D1 { D1() {printf("D1 : %3d\n", ((int)this)&0xfff);} };
20 struct D2 { int a[8]; D2() {printf("D2 : %3d\n", ((int)this)&0xfff);} };
21 
22 struct A : virtual B0 {
23 	int a;
24 	A() : a(0xf000000A) {printf("X : %3d\n", ((int)this)&0xfff);}
25 };
26 
27 // CHECK: *** Dumping AST Record Layout
28 // CHECK:    0 | struct A
29 // CHECK:    0 |   (A vbtable pointer)
30 // CHECK:    4 |   int a
31 // CHECK:    8 |   struct B0 (virtual base) (empty)
32 // CHECK:      | [sizeof=8, align=8
33 // CHECK:      |  nvsize=8, nvalign=4]
34 
35 struct B : virtual B0 {
36 	B0 b0;
37 	int a;
38 	B() : a(0xf000000B) {printf("X : %3d\n", ((int)this)&0xfff);}
39 };
40 
41 // CHECK: *** Dumping AST Record Layout
42 // CHECK:    0 | struct B
43 // CHECK:    0 |   (B vbtable pointer)
44 // CHECK:    8 |   struct B0 b0 (empty)
45 // CHECK:      |   [sizeof=8, align=8
46 // CHECK:      |    nvsize=0, nvalign=1]
47 // CHECK:   16 |   int a
48 // CHECK:   24 |   struct B0 (virtual base) (empty)
49 // CHECK:      | [sizeof=24, align=8
50 // CHECK:      |  nvsize=24, nvalign=8]
51 
52 struct C : virtual B0, virtual B1, virtual B2, virtual B3, virtual B4 {
53 	int a;
54 	C() : a(0xf000000C) {printf("X : %3d\n", ((int)this)&0xfff);}
55 };
56 
57 // CHECK: *** Dumping AST Record Layout
58 // CHECK:    0 | struct C
59 // CHECK:    0 |   (C vbtable pointer)
60 // CHECK:    4 |   int a
61 // CHECK:    8 |   struct B0 (virtual base) (empty)
62 // CHECK:   16 |   struct B1 (virtual base) (empty)
63 // CHECK:   24 |   struct B2 (virtual base) (empty)
64 // CHECK:   32 |   struct B3 (virtual base) (empty)
65 // CHECK:   40 |   struct B4 (virtual base) (empty)
66 // CHECK:      | [sizeof=40, align=8
67 // CHECK:      |  nvsize=8, nvalign=4]
68 
69 struct D {
70 	B0 b0;
71 	C0 c0;
72 	C1 c1;
73 	C2 c2;
74 	B1 b1;
75 	int a;
76 	D() : a(0xf000000D) {printf("X : %3d\n", ((int)this)&0xfff);}
77 };
78 
79 // CHECK: *** Dumping AST Record Layout
80 // CHECK:    0 | struct D
81 // CHECK:    0 |   struct B0 b0 (empty)
82 // CHECK:      |   [sizeof=8, align=8
83 // CHECK:      |    nvsize=0, nvalign=1]
84 // CHECK:    8 |   struct C0 c0
85 // CHECK:    8 |     int a
86 // CHECK:      |   [sizeof=4, align=4
87 // CHECK:      |    nvsize=4, nvalign=4]
88 // CHECK:   12 |   struct C1 c1
89 // CHECK:   12 |     int a
90 // CHECK:      |   [sizeof=4, align=4
91 // CHECK:      |    nvsize=4, nvalign=4]
92 // CHECK:   16 |   struct C2 c2
93 // CHECK:   16 |     int a
94 // CHECK:      |   [sizeof=4, align=4
95 // CHECK:      |    nvsize=4, nvalign=4]
96 // CHECK:   24 |   struct B1 b1 (empty)
97 // CHECK:      |   [sizeof=8, align=8
98 // CHECK:      |    nvsize=0, nvalign=1]
99 // CHECK:   32 |   int a
100 // CHECK:      | [sizeof=40, align=8
101 // CHECK:      |  nvsize=40, nvalign=8]
102 
103 struct E : virtual B0, virtual C0, virtual C1, virtual C2, virtual B1 {
104 	int a;
105 	E() : a(0xf000000E) {printf("X : %3d\n", ((int)this)&0xfff);}
106 };
107 
108 // CHECK: *** Dumping AST Record Layout
109 // CHECK:    0 | struct E
110 // CHECK:    0 |   (E vbtable pointer)
111 // CHECK:    4 |   int a
112 // CHECK:    8 |   struct B0 (virtual base) (empty)
113 // CHECK:    8 |   struct C0 (virtual base)
114 // CHECK:    8 |     int a
115 // CHECK:   12 |   struct C1 (virtual base)
116 // CHECK:   12 |     int a
117 // CHECK:   16 |   struct C2 (virtual base)
118 // CHECK:   16 |     int a
119 // CHECK:   24 |   struct B1 (virtual base) (empty)
120 // CHECK:      | [sizeof=24, align=8
121 // CHECK:      |  nvsize=8, nvalign=4]
122 
123 struct F : virtual C0, virtual B0, virtual B1, virtual C1 {
124 	int a;
125 	F() : a(0xf000000F) {printf("X : %3d\n", ((int)this)&0xfff);}
126 };
127 
128 // CHECK: *** Dumping AST Record Layout
129 // CHECK:    0 | struct F
130 // CHECK:    0 |   (F vbtable pointer)
131 // CHECK:    4 |   int a
132 // CHECK:    8 |   struct C0 (virtual base)
133 // CHECK:    8 |     int a
134 // CHECK:   16 |   struct B0 (virtual base) (empty)
135 // CHECK:   24 |   struct B1 (virtual base) (empty)
136 // CHECK:   24 |   struct C1 (virtual base)
137 // CHECK:   24 |     int a
138 // CHECK:      | [sizeof=32, align=8
139 // CHECK:      |  nvsize=8, nvalign=4]
140 
141 struct G : virtual C0, virtual B0, virtual B1, D0, virtual C1 {
142 	int a;
143 	G() : a(0xf0000010) {printf("X : %3d\n", ((int)this)&0xfff);}
144 	virtual void f() {}
145 };
146 
147 // CHECK: *** Dumping AST Record Layout
148 // CHECK:    0 | struct G
149 // CHECK:    0 |   struct D0 (primary base)
150 // CHECK:    0 |     (D0 vftable pointer)
151 // CHECK:    4 |   (G vbtable pointer)
152 // CHECK:   20 |   int a
153 // CHECK:   32 |   struct C0 (virtual base)
154 // CHECK:   32 |     int a
155 // CHECK:   40 |   struct B0 (virtual base) (empty)
156 // CHECK:   56 |   struct B1 (virtual base) (empty)
157 // CHECK:   56 |   struct C1 (virtual base)
158 // CHECK:   56 |     int a
159 // CHECK:      | [sizeof=64, align=16
160 // CHECK:      |  nvsize=32, nvalign=16]
161 
162 struct H : virtual C0, virtual B0, virtual B1, virtual D0, virtual C1 {
163 	int a;
164 	H() : a(0xf0000011) {printf("X : %3d\n", ((int)this)&0xfff);}
165 	virtual void f() {}
166 };
167 
168 // CHECK: *** Dumping AST Record Layout
169 // CHECK:    0 | struct H
170 // CHECK:    0 |   (H vbtable pointer)
171 // CHECK:    4 |   int a
172 // CHECK:    8 |   struct C0 (virtual base)
173 // CHECK:    8 |     int a
174 // CHECK:   16 |   struct B0 (virtual base) (empty)
175 // CHECK:   24 |   struct B1 (virtual base) (empty)
176 // CHECK:   44 |   (vtordisp for vbase D0)
177 // CHECK:   48 |   struct D0 (virtual base)
178 // CHECK:   48 |     (D0 vftable pointer)
179 // CHECK:   52 |   struct C1 (virtual base)
180 // CHECK:   52 |     int a
181 // CHECK:      | [sizeof=64, align=16
182 // CHECK:      |  nvsize=8, nvalign=4]
183 
184 struct I : virtual B0, virtual B1, virtual B2, virtual B3, virtual B4 {
185 	__declspec(align(32)) int a;
186 	I() : a(0xf0000012) {printf("X : %3d\n", ((int)this)&0xfff);}
187 };
188 
189 // CHECK: *** Dumping AST Record Layout
190 // CHECK:    0 | struct I
191 // CHECK:    0 |   (I vbtable pointer)
192 // CHECK:   32 |   int a
193 // CHECK:   64 |   struct B0 (virtual base) (empty)
194 // CHECK:   72 |   struct B1 (virtual base) (empty)
195 // CHECK:  104 |   struct B2 (virtual base) (empty)
196 // CHECK:  136 |   struct B3 (virtual base) (empty)
197 // CHECK:  168 |   struct B4 (virtual base) (empty)
198 // CHECK:      | [sizeof=192, align=32
199 // CHECK:      |  nvsize=64, nvalign=32]
200 
201 struct __declspec(align(32)) J : virtual B0, virtual B1, virtual B2, virtual B3, virtual B4 {
202 	int a;
203 	J() : a(0xf0000012) {printf("X : %3d\n", ((int)this)&0xfff);}
204 };
205 
206 // CHECK: *** Dumping AST Record Layout
207 // CHECK:    0 | struct J
208 // CHECK:    0 |   (J vbtable pointer)
209 // CHECK:    4 |   int a
210 // CHECK:    8 |   struct B0 (virtual base) (empty)
211 // CHECK:   40 |   struct B1 (virtual base) (empty)
212 // CHECK:   72 |   struct B2 (virtual base) (empty)
213 // CHECK:  104 |   struct B3 (virtual base) (empty)
214 // CHECK:  136 |   struct B4 (virtual base) (empty)
215 // CHECK:      | [sizeof=160, align=32
216 // CHECK:      |  nvsize=8, nvalign=4]
217 
218 struct K : virtual D1, virtual B1, virtual B2, virtual B3, virtual B4 {
219 	__declspec(align(32)) int a;
220 	K() : a(0xf0000013) {printf("X : %3d\n", ((int)this)&0xfff);}
221 };
222 
223 // CHECK: *** Dumping AST Record Layout
224 // CHECK:    0 | struct K
225 // CHECK:    0 |   (K vbtable pointer)
226 // CHECK:   32 |   int a
227 // CHECK:   64 |   struct D1 (virtual base) (empty)
228 // CHECK:   72 |   struct B1 (virtual base) (empty)
229 // CHECK:  104 |   struct B2 (virtual base) (empty)
230 // CHECK:  136 |   struct B3 (virtual base) (empty)
231 // CHECK:  168 |   struct B4 (virtual base) (empty)
232 // CHECK:      | [sizeof=192, align=32
233 // CHECK:      |  nvsize=64, nvalign=32]
234 
235 struct L : virtual B1, virtual D1, virtual B2, virtual B3, virtual B4 {
236 	__declspec(align(32)) int a;
237 	L() : a(0xf0000014) {printf("X : %3d\n", ((int)this)&0xfff);}
238 };
239 
240 // CHECK: *** Dumping AST Record Layout
241 // CHECK:    0 | struct L
242 // CHECK:    0 |   (L vbtable pointer)
243 // CHECK:   32 |   int a
244 // CHECK:   64 |   struct B1 (virtual base) (empty)
245 // CHECK:   68 |   struct D1 (virtual base) (empty)
246 // CHECK:  104 |   struct B2 (virtual base) (empty)
247 // CHECK:  136 |   struct B3 (virtual base) (empty)
248 // CHECK:  168 |   struct B4 (virtual base) (empty)
249 // CHECK:      | [sizeof=192, align=32
250 // CHECK:      |  nvsize=64, nvalign=32]
251 
252 struct M : virtual B1, virtual B2, virtual D1, virtual B3, virtual B4 {
253 	__declspec(align(32)) int a;
254 	M() : a(0xf0000015) {printf("X : %3d\n", ((int)this)&0xfff);}
255 };
256 
257 // CHECK: *** Dumping AST Record Layout
258 // CHECK:    0 | struct M
259 // CHECK:    0 |   (M vbtable pointer)
260 // CHECK:   32 |   int a
261 // CHECK:   64 |   struct B1 (virtual base) (empty)
262 // CHECK:   72 |   struct B2 (virtual base) (empty)
263 // CHECK:  100 |   struct D1 (virtual base) (empty)
264 // CHECK:  136 |   struct B3 (virtual base) (empty)
265 // CHECK:  168 |   struct B4 (virtual base) (empty)
266 // CHECK:      | [sizeof=192, align=32
267 // CHECK:      |  nvsize=64, nvalign=32]
268 
269 struct N : virtual C0, virtual B1, virtual D1, virtual B2, virtual B3, virtual B4 {
270 	__declspec(align(32)) int a;
271 	N() : a(0xf0000016) {printf("X : %3d\n", ((int)this)&0xfff);}
272 };
273 
274 // CHECK: *** Dumping AST Record Layout
275 // CHECK:    0 | struct N
276 // CHECK:    0 |   (N vbtable pointer)
277 // CHECK:   32 |   int a
278 // CHECK:   64 |   struct C0 (virtual base)
279 // CHECK:   64 |     int a
280 // CHECK:   72 |   struct B1 (virtual base) (empty)
281 // CHECK:  100 |   struct D1 (virtual base) (empty)
282 // CHECK:  136 |   struct B2 (virtual base) (empty)
283 // CHECK:  168 |   struct B3 (virtual base) (empty)
284 // CHECK:  200 |   struct B4 (virtual base) (empty)
285 // CHECK:      | [sizeof=224, align=32
286 // CHECK:      |  nvsize=64, nvalign=32]
287 
288 struct O : virtual C0, virtual B1, virtual B2, virtual D1, virtual B3, virtual B4 {
289 	__declspec(align(32)) int a;
290 	O() : a(0xf0000017) {printf("X : %3d\n", ((int)this)&0xfff);}
291 };
292 
293 // CHECK: *** Dumping AST Record Layout
294 // CHECK:    0 | struct O
295 // CHECK:    0 |   (O vbtable pointer)
296 // CHECK:   32 |   int a
297 // CHECK:   64 |   struct C0 (virtual base)
298 // CHECK:   64 |     int a
299 // CHECK:   72 |   struct B1 (virtual base) (empty)
300 // CHECK:  104 |   struct B2 (virtual base) (empty)
301 // CHECK:  132 |   struct D1 (virtual base) (empty)
302 // CHECK:  168 |   struct B3 (virtual base) (empty)
303 // CHECK:  200 |   struct B4 (virtual base) (empty)
304 // CHECK:      | [sizeof=224, align=32
305 // CHECK:      |  nvsize=64, nvalign=32]
306 
307 struct P : virtual B1, virtual C0, virtual D1, virtual B2, virtual B3, virtual B4 {
308 	__declspec(align(32)) int a;
309 	P() : a(0xf0000018) {printf("X : %3d\n", ((int)this)&0xfff);}
310 };
311 
312 // CHECK: *** Dumping AST Record Layout
313 // CHECK:    0 | struct P
314 // CHECK:    0 |   (P vbtable pointer)
315 // CHECK:   32 |   int a
316 // CHECK:   64 |   struct B1 (virtual base) (empty)
317 // CHECK:   64 |   struct C0 (virtual base)
318 // CHECK:   64 |     int a
319 // CHECK:   68 |   struct D1 (virtual base) (empty)
320 // CHECK:  104 |   struct B2 (virtual base) (empty)
321 // CHECK:  136 |   struct B3 (virtual base) (empty)
322 // CHECK:  168 |   struct B4 (virtual base) (empty)
323 // CHECK:      | [sizeof=192, align=32
324 // CHECK:      |  nvsize=64, nvalign=32]
325 
326 struct Q : virtual B1, virtual C0, virtual B2, virtual D1, virtual B3, virtual B4 {
327 	__declspec(align(32)) int a;
328 	Q() : a(0xf0000019) {printf("X : %3d\n", ((int)this)&0xfff);}
329 };
330 
331 // CHECK: *** Dumping AST Record Layout
332 // CHECK:    0 | struct Q
333 // CHECK:    0 |   (Q vbtable pointer)
334 // CHECK:   32 |   int a
335 // CHECK:   64 |   struct B1 (virtual base) (empty)
336 // CHECK:   64 |   struct C0 (virtual base)
337 // CHECK:   64 |     int a
338 // CHECK:   72 |   struct B2 (virtual base) (empty)
339 // CHECK:  100 |   struct D1 (virtual base) (empty)
340 // CHECK:  136 |   struct B3 (virtual base) (empty)
341 // CHECK:  168 |   struct B4 (virtual base) (empty)
342 // CHECK:      | [sizeof=192, align=32
343 // CHECK:      |  nvsize=64, nvalign=32]
344 
345 struct R : virtual B0, virtual B1, virtual B2, virtual C0, virtual B3, virtual B4 {
346 	__declspec(align(32)) int a;
347 	R() : a(0xf0000020) {printf("X : %3d\n", ((int)this)&0xfff);}
348 };
349 
350 // CHECK: *** Dumping AST Record Layout
351 // CHECK:    0 | struct R
352 // CHECK:    0 |   (R vbtable pointer)
353 // CHECK:   32 |   int a
354 // CHECK:   64 |   struct B0 (virtual base) (empty)
355 // CHECK:   72 |   struct B1 (virtual base) (empty)
356 // CHECK:  104 |   struct B2 (virtual base) (empty)
357 // CHECK:  104 |   struct C0 (virtual base)
358 // CHECK:  104 |     int a
359 // CHECK:  112 |   struct B3 (virtual base) (empty)
360 // CHECK:  136 |   struct B4 (virtual base) (empty)
361 // CHECK:      | [sizeof=160, align=32
362 // CHECK:      |  nvsize=64, nvalign=32]
363 
364 struct S : virtual B0, virtual B1, virtual C0, virtual B2, virtual B3, virtual B4 {
365 	__declspec(align(32)) int a;
366 	S() : a(0xf0000021) {printf("X : %3d\n", ((int)this)&0xfff);}
367 };
368 
369 // CHECK: *** Dumping AST Record Layout
370 // CHECK:    0 | struct S
371 // CHECK:    0 |   (S vbtable pointer)
372 // CHECK:   32 |   int a
373 // CHECK:   64 |   struct B0 (virtual base) (empty)
374 // CHECK:   72 |   struct B1 (virtual base) (empty)
375 // CHECK:   72 |   struct C0 (virtual base)
376 // CHECK:   72 |     int a
377 // CHECK:   80 |   struct B2 (virtual base) (empty)
378 // CHECK:  104 |   struct B3 (virtual base) (empty)
379 // CHECK:  136 |   struct B4 (virtual base) (empty)
380 // CHECK:      | [sizeof=160, align=32
381 // CHECK:      |  nvsize=64, nvalign=32]
382 
383 struct T : virtual B0, virtual B1, virtual C0, virtual D2, virtual B2, virtual B3, virtual B4 {
384 	__declspec(align(16)) int a;
385 	T() : a(0xf0000022) {printf("X : %3d\n", ((int)this)&0xfff);}
386 };
387 
388 // CHECK: *** Dumping AST Record Layout
389 // CHECK:    0 | struct T
390 // CHECK:    0 |   (T vbtable pointer)
391 // CHECK:   16 |   int a
392 // CHECK:   32 |   struct B0 (virtual base) (empty)
393 // CHECK:   40 |   struct B1 (virtual base) (empty)
394 // CHECK:   40 |   struct C0 (virtual base)
395 // CHECK:   40 |     int a
396 // CHECK:   44 |   struct D2 (virtual base)
397 // CHECK:   44 |     int [8] a
398 // CHECK:   80 |   struct B2 (virtual base) (empty)
399 // CHECK:   88 |   struct B3 (virtual base) (empty)
400 // CHECK:  104 |   struct B4 (virtual base) (empty)
401 // CHECK:      | [sizeof=112, align=16
402 // CHECK:      |  nvsize=32, nvalign=16]
403 
404 struct __declspec(align(32)) U : virtual B0, virtual B1 {
405 	int a;
406 	U() : a(0xf0000023) {printf("X : %3d\n", ((int)this)&0xfff);}
407 };
408 
409 // CHECK: *** Dumping AST Record Layout
410 // CHECK:    0 | struct U
411 // CHECK:    0 |   (U vbtable pointer)
412 // CHECK:    4 |   int a
413 // CHECK:    8 |   struct B0 (virtual base) (empty)
414 // CHECK:   40 |   struct B1 (virtual base) (empty)
415 // CHECK:      | [sizeof=64, align=32
416 // CHECK:      |  nvsize=8, nvalign=4]
417 
418 struct __declspec(align(32)) V : virtual D1 {
419 	int a;
420 	V() : a(0xf0000024) {printf("X : %3d\n", ((int)this)&0xfff);}
421 };
422 
423 // CHECK: *** Dumping AST Record Layout
424 // CHECK:    0 | struct V
425 // CHECK:    0 |   (V vbtable pointer)
426 // CHECK:    4 |   int a
427 // CHECK:    8 |   struct D1 (virtual base) (empty)
428 // CHECK:      | [sizeof=32, align=32
429 // CHECK:      |  nvsize=8, nvalign=4]
430 
431 int a[
432 sizeof(A)+
433 sizeof(B)+
434 sizeof(C)+
435 sizeof(D)+
436 sizeof(E)+
437 sizeof(F)+
438 sizeof(G)+
439 sizeof(H)+
440 sizeof(I)+
441 sizeof(J)+
442 sizeof(K)+
443 sizeof(L)+
444 sizeof(M)+
445 sizeof(N)+
446 sizeof(O)+
447 sizeof(P)+
448 sizeof(Q)+
449 sizeof(R)+
450 sizeof(S)+
451 sizeof(T)+
452 sizeof(U)+
453 sizeof(V)];