1 // RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fms-extensions -fdump-record-layouts -fsyntax-only %s 2>&1 \
2 // RUN:            | FileCheck %s
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
5 
6 extern "C" int printf(const char *fmt, ...);
7 
B0B08 struct B0 { int a; B0() : a(0xf00000B0) {} };
B1B19 struct B1 { char a; B1() : a(0xB1) {} };
B2B210 struct B2 : virtual B1 { int a; B2() : a(0xf00000B2) {} };
B3B311 struct B3 { __declspec(align(16)) int a; B3() : a(0xf00000B3) {} };
B4B412 struct B4 : virtual B3 { int a; B4() : a(0xf00000B4) {} };
B5B513 struct B5 { __declspec(align(32)) int a; B5() : a(0xf00000B5) {} };
B6B614 struct B6 { int a; B6() : a(0xf00000B6) {} virtual void f() { printf("B6"); } };
15 
AA16 struct A : B0, virtual B1 { __declspec(align(16)) int a; A() : a(0xf000000A) {} virtual void f() { printf("A"); } };
17 
18 // CHECK: *** Dumping AST Record Layout
19 // CHECK: *** Dumping AST Record Layout
20 // CHECK: *** Dumping AST Record Layout
21 // CHECK-NEXT:    0 | struct A
22 // CHECK-NEXT:    0 |   (A vftable pointer)
23 // CHECK-NEXT:   16 |   struct B0 (base)
24 // CHECK-NEXT:   16 |     int a
25 // CHECK-NEXT:   20 |   (A vbtable pointer)
26 // CHECK-NEXT:   48 |   int a
27 // CHECK-NEXT:   64 |   struct B1 (virtual base)
28 // CHECK-NEXT:   64 |     char a
29 // CHECK-NEXT:      | [sizeof=80, align=16
30 // CHECK-NEXT:      |  nvsize=64, nvalign=16]
31 // CHECK-X64: *** Dumping AST Record Layout
32 // CHECK-X64: *** Dumping AST Record Layout
33 // CHECK-X64: *** Dumping AST Record Layout
34 // CHECK-X64-NEXT:    0 | struct A
35 // CHECK-X64-NEXT:    0 |   (A vftable pointer)
36 // CHECK-X64-NEXT:   16 |   struct B0 (base)
37 // CHECK-X64-NEXT:   16 |     int a
38 // CHECK-X64-NEXT:   24 |   (A vbtable pointer)
39 // CHECK-X64-NEXT:   48 |   int a
40 // CHECK-X64-NEXT:   64 |   struct B1 (virtual base)
41 // CHECK-X64-NEXT:   64 |     char a
42 // CHECK-X64-NEXT:      | [sizeof=80, align=16
43 // CHECK-X64-NEXT:      |  nvsize=64, nvalign=16]
44 
BB45 struct B : A, B2 { int a; B() : a(0xf000000B) {} virtual void f() { printf("B"); } };
46 
47 // CHECK: *** Dumping AST Record Layout
48 // CHECK: *** Dumping AST Record Layout
49 // CHECK-NEXT:    0 | struct B
50 // CHECK-NEXT:    0 |   struct A (primary base)
51 // CHECK-NEXT:    0 |     (A vftable pointer)
52 // CHECK-NEXT:   16 |     struct B0 (base)
53 // CHECK-NEXT:   16 |       int a
54 // CHECK-NEXT:   20 |     (A vbtable pointer)
55 // CHECK-NEXT:   48 |     int a
56 // CHECK-NEXT:   64 |   struct B2 (base)
57 // CHECK-NEXT:   64 |     (B2 vbtable pointer)
58 // CHECK-NEXT:   68 |     int a
59 // CHECK-NEXT:   72 |   int a
60 // CHECK-NEXT:   80 |   struct B1 (virtual base)
61 // CHECK-NEXT:   80 |     char a
62 // CHECK-NEXT:      | [sizeof=96, align=16
63 // CHECK-NEXT:      |  nvsize=80, nvalign=16]
64 // CHECK-X64: *** Dumping AST Record Layout
65 // CHECK-X64: *** Dumping AST Record Layout
66 // CHECK-X64-NEXT:    0 | struct B
67 // CHECK-X64-NEXT:    0 |   struct A (primary base)
68 // CHECK-X64-NEXT:    0 |     (A vftable pointer)
69 // CHECK-X64-NEXT:   16 |     struct B0 (base)
70 // CHECK-X64-NEXT:   16 |       int a
71 // CHECK-X64-NEXT:   24 |     (A vbtable pointer)
72 // CHECK-X64-NEXT:   48 |     int a
73 // CHECK-X64-NEXT:   64 |   struct B2 (base)
74 // CHECK-X64-NEXT:   64 |     (B2 vbtable pointer)
75 // CHECK-X64-NEXT:   72 |     int a
76 // CHECK-X64-NEXT:   80 |   int a
77 // CHECK-X64-NEXT:   96 |   struct B1 (virtual base)
78 // CHECK-X64-NEXT:   96 |     char a
79 // CHECK-X64-NEXT:      | [sizeof=112, align=16
80 // CHECK-X64-NEXT:      |  nvsize=96, nvalign=16]
81 
CC82 struct C : B4 { int a; C() : a(0xf000000C) {} virtual void f() { printf("C"); } };
83 
84 // CHECK: *** Dumping AST Record Layout
85 // CHECK: *** Dumping AST Record Layout
86 // CHECK: *** Dumping AST Record Layout
87 // CHECK-NEXT:    0 | struct C
88 // CHECK-NEXT:    0 |   (C vftable pointer)
89 // CHECK-NEXT:   16 |   struct B4 (base)
90 // CHECK-NEXT:   16 |     (B4 vbtable pointer)
91 // CHECK-NEXT:   20 |     int a
92 // CHECK-NEXT:   24 |   int a
93 // CHECK-NEXT:   32 |   struct B3 (virtual base)
94 // CHECK-NEXT:   32 |     int a
95 // CHECK-NEXT:      | [sizeof=48, align=16
96 // CHECK-NEXT:      |  nvsize=32, nvalign=16]
97 // CHECK-X64: *** Dumping AST Record Layout
98 // CHECK-X64: *** Dumping AST Record Layout
99 // CHECK-X64: *** Dumping AST Record Layout
100 // CHECK-X64-NEXT:    0 | struct C
101 // CHECK-X64-NEXT:    0 |   (C vftable pointer)
102 // CHECK-X64-NEXT:   16 |   struct B4 (base)
103 // CHECK-X64-NEXT:   16 |     (B4 vbtable pointer)
104 // CHECK-X64-NEXT:   24 |     int a
105 // CHECK-X64-NEXT:   32 |   int a
106 // CHECK-X64-NEXT:   48 |   struct B3 (virtual base)
107 // CHECK-X64-NEXT:   48 |     int a
108 // CHECK-X64-NEXT:      | [sizeof=64, align=16
109 // CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
110 
DD111 struct D : C { int a; D() : a(0xf000000D) {} virtual void f() { printf("D"); } };
112 
113 // CHECK: *** Dumping AST Record Layout
114 // CHECK-NEXT:    0 | struct D
115 // CHECK-NEXT:    0 |   struct C (primary base)
116 // CHECK-NEXT:    0 |     (C vftable pointer)
117 // CHECK-NEXT:   16 |     struct B4 (base)
118 // CHECK-NEXT:   16 |       (B4 vbtable pointer)
119 // CHECK-NEXT:   20 |       int a
120 // CHECK-NEXT:   24 |     int a
121 // CHECK-NEXT:   32 |   int a
122 // CHECK-NEXT:   48 |   struct B3 (virtual base)
123 // CHECK-NEXT:   48 |     int a
124 // CHECK-NEXT:      | [sizeof=64, align=16
125 // CHECK-NEXT:      |  nvsize=48, nvalign=16]
126 // CHECK-X64: *** Dumping AST Record Layout
127 // CHECK-X64-NEXT:    0 | struct D
128 // CHECK-X64-NEXT:    0 |   struct C (primary base)
129 // CHECK-X64-NEXT:    0 |     (C vftable pointer)
130 // CHECK-X64-NEXT:   16 |     struct B4 (base)
131 // CHECK-X64-NEXT:   16 |       (B4 vbtable pointer)
132 // CHECK-X64-NEXT:   24 |       int a
133 // CHECK-X64-NEXT:   32 |     int a
134 // CHECK-X64-NEXT:   48 |   int a
135 // CHECK-X64-NEXT:   64 |   struct B3 (virtual base)
136 // CHECK-X64-NEXT:   64 |     int a
137 // CHECK-X64-NEXT:      | [sizeof=80, align=16
138 // CHECK-X64-NEXT:      |  nvsize=64, nvalign=16]
139 
EE140 struct E : virtual C { int a; E() : a(0xf000000E) {} virtual void f() { printf("E"); } };
141 
142 // CHECK: *** Dumping AST Record Layout
143 // CHECK-NEXT:    0 | struct E
144 // CHECK-NEXT:    0 |   (E vbtable pointer)
145 // CHECK-NEXT:    4 |   int a
146 // CHECK-NEXT:   16 |   struct B3 (virtual base)
147 // CHECK-NEXT:   16 |     int a
148 // CHECK-NEXT:   44 |   (vtordisp for vbase C)
149 // CHECK-NEXT:   48 |   struct C (virtual base)
150 // CHECK-NEXT:   48 |     (C vftable pointer)
151 // CHECK-NEXT:   64 |     struct B4 (base)
152 // CHECK-NEXT:   64 |       (B4 vbtable pointer)
153 // CHECK-NEXT:   68 |       int a
154 // CHECK-NEXT:   72 |     int a
155 // CHECK-NEXT:      | [sizeof=80, align=16
156 // CHECK-NEXT:      |  nvsize=8, nvalign=16]
157 // CHECK-X64: *** Dumping AST Record Layout
158 // CHECK-X64-NEXT:    0 | struct E
159 // CHECK-X64-NEXT:    0 |   (E vbtable pointer)
160 // CHECK-X64-NEXT:    8 |   int a
161 // CHECK-X64-NEXT:   16 |   struct B3 (virtual base)
162 // CHECK-X64-NEXT:   16 |     int a
163 // CHECK-X64-NEXT:   44 |   (vtordisp for vbase C)
164 // CHECK-X64-NEXT:   48 |   struct C (virtual base)
165 // CHECK-X64-NEXT:   48 |     (C vftable pointer)
166 // CHECK-X64-NEXT:   64 |     struct B4 (base)
167 // CHECK-X64-NEXT:   64 |       (B4 vbtable pointer)
168 // CHECK-X64-NEXT:   72 |       int a
169 // CHECK-X64-NEXT:   80 |     int a
170 // CHECK-X64-NEXT:      | [sizeof=96, align=16
171 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=16]
172 
FF173 struct F : B3, virtual B0 { int a; F() : a(0xf000000F) {} virtual void f() { printf("F"); } };
174 
175 // CHECK: *** Dumping AST Record Layout
176 // CHECK-NEXT:    0 | struct F
177 // CHECK-NEXT:    0 |   (F vftable pointer)
178 // CHECK-NEXT:   16 |   struct B3 (base)
179 // CHECK-NEXT:   16 |     int a
180 // CHECK-NEXT:   32 |   (F vbtable pointer)
181 // CHECK-NEXT:   48 |   int a
182 // CHECK-NEXT:   64 |   struct B0 (virtual base)
183 // CHECK-NEXT:   64 |     int a
184 // CHECK-NEXT:      | [sizeof=80, align=16
185 // CHECK-NEXT:      |  nvsize=64, nvalign=16]
186 // CHECK-X64: *** Dumping AST Record Layout
187 // CHECK-X64-NEXT:    0 | struct F
188 // CHECK-X64-NEXT:    0 |   (F vftable pointer)
189 // CHECK-X64-NEXT:   16 |   struct B3 (base)
190 // CHECK-X64-NEXT:   16 |     int a
191 // CHECK-X64-NEXT:   32 |   (F vbtable pointer)
192 // CHECK-X64-NEXT:   48 |   int a
193 // CHECK-X64-NEXT:   64 |   struct B0 (virtual base)
194 // CHECK-X64-NEXT:   64 |     int a
195 // CHECK-X64-NEXT:      | [sizeof=80, align=16
196 // CHECK-X64-NEXT:      |  nvsize=64, nvalign=16]
197 
GG198 struct G : B2, B6, virtual B1 { int a; G() : a(0xf0000010) {} };
199 
200 // CHECK: *** Dumping AST Record Layout
201 // CHECK: *** Dumping AST Record Layout
202 // CHECK-NEXT:    0 | struct G
203 // CHECK-NEXT:    0 |   struct B6 (primary base)
204 // CHECK-NEXT:    0 |     (B6 vftable pointer)
205 // CHECK-NEXT:    4 |     int a
206 // CHECK-NEXT:    8 |   struct B2 (base)
207 // CHECK-NEXT:    8 |     (B2 vbtable pointer)
208 // CHECK-NEXT:   12 |     int a
209 // CHECK-NEXT:   16 |   int a
210 // CHECK-NEXT:   20 |   struct B1 (virtual base)
211 // CHECK-NEXT:   20 |     char a
212 // CHECK-NEXT:      | [sizeof=21, align=4
213 // CHECK-NEXT:      |  nvsize=20, nvalign=4]
214 // CHECK-X64: *** Dumping AST Record Layout
215 // CHECK-X64: *** Dumping AST Record Layout
216 // CHECK-X64-NEXT:    0 | struct G
217 // CHECK-X64-NEXT:    0 |   struct B6 (primary base)
218 // CHECK-X64-NEXT:    0 |     (B6 vftable pointer)
219 // CHECK-X64-NEXT:    8 |     int a
220 // CHECK-X64-NEXT:   16 |   struct B2 (base)
221 // CHECK-X64-NEXT:   16 |     (B2 vbtable pointer)
222 // CHECK-X64-NEXT:   24 |     int a
223 // CHECK-X64-NEXT:   32 |   int a
224 // CHECK-X64-NEXT:   40 |   struct B1 (virtual base)
225 // CHECK-X64-NEXT:   40 |     char a
226 // CHECK-X64-NEXT:      | [sizeof=48, align=8
227 // CHECK-X64-NEXT:      |  nvsize=40, nvalign=8]
228 
HH229 struct H : B6, B2, virtual B1 { int a; H() : a(0xf0000011) {} };
230 
231 // CHECK: *** Dumping AST Record Layout
232 // CHECK-NEXT:    0 | struct H
233 // CHECK-NEXT:    0 |   struct B6 (primary base)
234 // CHECK-NEXT:    0 |     (B6 vftable pointer)
235 // CHECK-NEXT:    4 |     int a
236 // CHECK-NEXT:    8 |   struct B2 (base)
237 // CHECK-NEXT:    8 |     (B2 vbtable pointer)
238 // CHECK-NEXT:   12 |     int a
239 // CHECK-NEXT:   16 |   int a
240 // CHECK-NEXT:   20 |   struct B1 (virtual base)
241 // CHECK-NEXT:   20 |     char a
242 // CHECK-NEXT:      | [sizeof=21, align=4
243 // CHECK-NEXT:      |  nvsize=20, nvalign=4]
244 // CHECK-X64: *** Dumping AST Record Layout
245 // CHECK-X64-NEXT:    0 | struct H
246 // CHECK-X64-NEXT:    0 |   struct B6 (primary base)
247 // CHECK-X64-NEXT:    0 |     (B6 vftable pointer)
248 // CHECK-X64-NEXT:    8 |     int a
249 // CHECK-X64-NEXT:   16 |   struct B2 (base)
250 // CHECK-X64-NEXT:   16 |     (B2 vbtable pointer)
251 // CHECK-X64-NEXT:   24 |     int a
252 // CHECK-X64-NEXT:   32 |   int a
253 // CHECK-X64-NEXT:   40 |   struct B1 (virtual base)
254 // CHECK-X64-NEXT:   40 |     char a
255 // CHECK-X64-NEXT:      | [sizeof=48, align=8
256 // CHECK-X64-NEXT:      |  nvsize=40, nvalign=8]
257 
II258 struct I : B0, virtual B1 { int a; int a1; __declspec(align(16)) int a2; I() : a(0xf0000011), a1(0xf0000011), a2(0xf0000011) {} };
259 
260 // CHECK: *** Dumping AST Record Layout
261 // CHECK-NEXT:    0 | struct I
262 // CHECK-NEXT:    0 |   struct B0 (base)
263 // CHECK-NEXT:    0 |     int a
264 // CHECK-NEXT:    4 |   (I vbtable pointer)
265 // CHECK-NEXT:   20 |   int a
266 // CHECK-NEXT:   24 |   int a1
267 // CHECK-NEXT:   32 |   int a2
268 // CHECK-NEXT:   48 |   struct B1 (virtual base)
269 // CHECK-NEXT:   48 |     char a
270 // CHECK-NEXT:      | [sizeof=64, align=16
271 // CHECK-NEXT:      |  nvsize=48, nvalign=16]
272 // CHECK-X64: *** Dumping AST Record Layout
273 // CHECK-X64-NEXT:    0 | struct I
274 // CHECK-X64-NEXT:    0 |   struct B0 (base)
275 // CHECK-X64-NEXT:    0 |     int a
276 // CHECK-X64-NEXT:    8 |   (I vbtable pointer)
277 // CHECK-X64-NEXT:   20 |   int a
278 // CHECK-X64-NEXT:   24 |   int a1
279 // CHECK-X64-NEXT:   32 |   int a2
280 // CHECK-X64-NEXT:   48 |   struct B1 (virtual base)
281 // CHECK-X64-NEXT:   48 |     char a
282 // CHECK-X64-NEXT:      | [sizeof=64, align=16
283 // CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
284 
JJ285 struct J : B0, B3, virtual B1 { int a; int a1; J() : a(0xf0000012), a1(0xf0000012) {} };
286 
287 // CHECK: *** Dumping AST Record Layout
288 // CHECK-NEXT:    0 | struct J
289 // CHECK-NEXT:    0 |   struct B0 (base)
290 // CHECK-NEXT:    0 |     int a
291 // CHECK-NEXT:   16 |   struct B3 (base)
292 // CHECK-NEXT:   16 |     int a
293 // CHECK-NEXT:   32 |   (J vbtable pointer)
294 // CHECK-NEXT:   48 |   int a
295 // CHECK-NEXT:   52 |   int a1
296 // CHECK-NEXT:   64 |   struct B1 (virtual base)
297 // CHECK-NEXT:   64 |     char a
298 // CHECK-NEXT:      | [sizeof=80, align=16
299 // CHECK-NEXT:      |  nvsize=64, nvalign=16]
300 // CHECK-X64: *** Dumping AST Record Layout
301 // CHECK-X64-NEXT:    0 | struct J
302 // CHECK-X64-NEXT:    0 |   struct B0 (base)
303 // CHECK-X64-NEXT:    0 |     int a
304 // CHECK-X64-NEXT:   16 |   struct B3 (base)
305 // CHECK-X64-NEXT:   16 |     int a
306 // CHECK-X64-NEXT:   32 |   (J vbtable pointer)
307 // CHECK-X64-NEXT:   48 |   int a
308 // CHECK-X64-NEXT:   52 |   int a1
309 // CHECK-X64-NEXT:   64 |   struct B1 (virtual base)
310 // CHECK-X64-NEXT:   64 |     char a
311 // CHECK-X64-NEXT:      | [sizeof=80, align=16
312 // CHECK-X64-NEXT:      |  nvsize=64, nvalign=16]
313 
fK314 struct K { int a; K() : a(0xf0000013) {} virtual void f() { printf("K"); } };
315 
316 // CHECK: *** Dumping AST Record Layout
317 // CHECK-NEXT:    0 | struct K
318 // CHECK-NEXT:    0 |   (K vftable pointer)
319 // CHECK-NEXT:    4 |   int a
320 // CHECK-NEXT:      | [sizeof=8, align=4
321 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
322 // CHECK-X64: *** Dumping AST Record Layout
323 // CHECK-X64-NEXT:    0 | struct K
324 // CHECK-X64-NEXT:    0 |   (K vftable pointer)
325 // CHECK-X64-NEXT:    8 |   int a
326 // CHECK-X64-NEXT:      | [sizeof=16, align=8
327 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
328 
gL329 struct L : virtual K { int a; L() : a(0xf0000014) {} virtual void g() { printf("L"); } };
330 
331 // CHECK: *** Dumping AST Record Layout
332 // CHECK-NEXT:    0 | struct L
333 // CHECK-NEXT:    0 |   (L vftable pointer)
334 // CHECK-NEXT:    4 |   (L vbtable pointer)
335 // CHECK-NEXT:    8 |   int a
336 // CHECK-NEXT:   12 |   struct K (virtual base)
337 // CHECK-NEXT:   12 |     (K vftable pointer)
338 // CHECK-NEXT:   16 |     int a
339 // CHECK-NEXT:      | [sizeof=20, align=4
340 // CHECK-NEXT:      |  nvsize=12, nvalign=4]
341 // CHECK-X64: *** Dumping AST Record Layout
342 // CHECK-X64-NEXT:    0 | struct L
343 // CHECK-X64-NEXT:    0 |   (L vftable pointer)
344 // CHECK-X64-NEXT:    8 |   (L vbtable pointer)
345 // CHECK-X64-NEXT:   16 |   int a
346 // CHECK-X64-NEXT:   24 |   struct K (virtual base)
347 // CHECK-X64-NEXT:   24 |     (K vftable pointer)
348 // CHECK-X64-NEXT:   32 |     int a
349 // CHECK-X64-NEXT:      | [sizeof=40, align=8
350 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
351 
fM352 struct M : virtual K { int a; M() : a(0xf0000015) {} virtual void f() { printf("M"); } };
353 
354 // CHECK: *** Dumping AST Record Layout
355 // CHECK-NEXT:    0 | struct M
356 // CHECK-NEXT:    0 |   (M vbtable pointer)
357 // CHECK-NEXT:    4 |   int a
358 // CHECK-NEXT:    8 |   (vtordisp for vbase K)
359 // CHECK-NEXT:   12 |   struct K (virtual base)
360 // CHECK-NEXT:   12 |     (K vftable pointer)
361 // CHECK-NEXT:   16 |     int a
362 // CHECK-NEXT:      | [sizeof=20, align=4
363 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
364 // CHECK-X64: *** Dumping AST Record Layout
365 // CHECK-X64-NEXT:    0 | struct M
366 // CHECK-X64-NEXT:    0 |   (M vbtable pointer)
367 // CHECK-X64-NEXT:    8 |   int a
368 // CHECK-X64-NEXT:   20 |   (vtordisp for vbase K)
369 // CHECK-X64-NEXT:   24 |   struct K (virtual base)
370 // CHECK-X64-NEXT:   24 |     (K vftable pointer)
371 // CHECK-X64-NEXT:   32 |     int a
372 // CHECK-X64-NEXT:      | [sizeof=40, align=8
373 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
374 
375 int a[
376 sizeof(A)+
377 sizeof(B)+
378 sizeof(C)+
379 sizeof(D)+
380 sizeof(E)+
381 sizeof(F)+
382 sizeof(G)+
383 sizeof(H)+
384 sizeof(I)+
385 sizeof(J)+
386 sizeof(K)+
387 sizeof(L)+
388 sizeof(M)];
389