1 | // RUN: %clang_cc1 -fno-rtti -fms-extensions -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>&1 \ |
2 | // RUN: | FileCheck %s |
3 | // RUN: %clang_cc1 -fno-rtti -fms-extensions -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 | |
6 | extern "C" int printf(const char *fmt, ...); |
7 | |
8 | struct B0 { |
9 | int a; |
10 | B0() : a(0xf00000B0) {} |
11 | virtual void f() { printf("B0"); } |
12 | }; |
13 | |
14 | struct __declspec(align(16)) B1 { |
15 | int a; |
16 | B1() : a(0xf00000B1) {} |
17 | virtual void f() { printf("B1"); } |
18 | }; |
19 | |
20 | struct __declspec(align(16)) Align16 {}; |
21 | struct __declspec(align(32)) Align32 {}; |
22 | struct VAlign16 : virtual Align16 {}; |
23 | struct VAlign32 : virtual Align32 {}; |
24 | |
25 | struct A : virtual B0, virtual B1 { |
26 | int a; |
27 | A() : a(0xf000000A) {} |
28 | virtual void f() { printf("A"); } |
29 | virtual void g() { printf("A"); } |
30 | }; |
31 | |
32 | // CHECK: *** Dumping AST Record Layout |
33 | // CHECK: *** Dumping AST Record Layout |
34 | // CHECK: *** Dumping AST Record Layout |
35 | // CHECK-NEXT: 0 | struct A |
36 | // CHECK-NEXT: 0 | (A vftable pointer) |
37 | // CHECK-NEXT: 4 | (A vbtable pointer) |
38 | // CHECK-NEXT: 8 | int a |
39 | // CHECK-NEXT: 16 | (vtordisp for vbase B0) |
40 | // CHECK-NEXT: 20 | struct B0 (virtual base) |
41 | // CHECK-NEXT: 20 | (B0 vftable pointer) |
42 | // CHECK-NEXT: 24 | int a |
43 | // CHECK-NEXT: 44 | (vtordisp for vbase B1) |
44 | // CHECK-NEXT: 48 | struct B1 (virtual base) |
45 | // CHECK-NEXT: 48 | (B1 vftable pointer) |
46 | // CHECK-NEXT: 52 | int a |
47 | // CHECK-NEXT: | [sizeof=64, align=16 |
48 | // CHECK-NEXT: | nvsize=12, nvalign=16] |
49 | // CHECK-X64: *** Dumping AST Record Layout |
50 | // CHECK-X64: *** Dumping AST Record Layout |
51 | // CHECK-X64: *** Dumping AST Record Layout |
52 | // CHECK-X64-NEXT: 0 | struct A |
53 | // CHECK-X64-NEXT: 0 | (A vftable pointer) |
54 | // CHECK-X64-NEXT: 8 | (A vbtable pointer) |
55 | // CHECK-X64-NEXT: 16 | int a |
56 | // CHECK-X64-NEXT: 36 | (vtordisp for vbase B0) |
57 | // CHECK-X64-NEXT: 40 | struct B0 (virtual base) |
58 | // CHECK-X64-NEXT: 40 | (B0 vftable pointer) |
59 | // CHECK-X64-NEXT: 48 | int a |
60 | // CHECK-X64-NEXT: 76 | (vtordisp for vbase B1) |
61 | // CHECK-X64-NEXT: 80 | struct B1 (virtual base) |
62 | // CHECK-X64-NEXT: 80 | (B1 vftable pointer) |
63 | // CHECK-X64-NEXT: 88 | int a |
64 | // CHECK-X64-NEXT: | [sizeof=96, align=16 |
65 | // CHECK-X64-NEXT: | nvsize=24, nvalign=16] |
66 | |
67 | struct C : virtual B0, virtual B1, VAlign32 { |
68 | int a; |
69 | C() : a(0xf000000C) {} |
70 | virtual void f() { printf("C"); } |
71 | virtual void g() { printf("C"); } |
72 | }; |
73 | |
74 | // CHECK: *** Dumping AST Record Layout |
75 | // CHECK: *** Dumping AST Record Layout |
76 | // CHECK: *** Dumping AST Record Layout |
77 | // CHECK-NEXT: 0 | struct C |
78 | // CHECK-NEXT: 0 | (C vftable pointer) |
79 | // CHECK-NEXT: 32 | struct VAlign32 (base) |
80 | // CHECK-NEXT: 32 | (VAlign32 vbtable pointer) |
81 | // CHECK-NEXT: 36 | int a |
82 | // CHECK-NEXT: 64 | (vtordisp for vbase B0) |
83 | // CHECK-NEXT: 68 | struct B0 (virtual base) |
84 | // CHECK-NEXT: 68 | (B0 vftable pointer) |
85 | // CHECK-NEXT: 72 | int a |
86 | // CHECK-NEXT: 108 | (vtordisp for vbase B1) |
87 | // CHECK-NEXT: 112 | struct B1 (virtual base) |
88 | // CHECK-NEXT: 112 | (B1 vftable pointer) |
89 | // CHECK-NEXT: 116 | int a |
90 | // CHECK-NEXT: 128 | struct Align32 (virtual base) (empty) |
91 | // CHECK-NEXT: | [sizeof=128, align=32 |
92 | // CHECK-NEXT: | nvsize=64, nvalign=32] |
93 | // CHECK-X64: *** Dumping AST Record Layout |
94 | // CHECK-X64: *** Dumping AST Record Layout |
95 | // CHECK-X64: *** Dumping AST Record Layout |
96 | // CHECK-X64-NEXT: 0 | struct C |
97 | // CHECK-X64-NEXT: 0 | (C vftable pointer) |
98 | // CHECK-X64-NEXT: 32 | struct VAlign32 (base) |
99 | // CHECK-X64-NEXT: 32 | (VAlign32 vbtable pointer) |
100 | // CHECK-X64-NEXT: 40 | int a |
101 | // CHECK-X64-NEXT: 68 | (vtordisp for vbase B0) |
102 | // CHECK-X64-NEXT: 72 | struct B0 (virtual base) |
103 | // CHECK-X64-NEXT: 72 | (B0 vftable pointer) |
104 | // CHECK-X64-NEXT: 80 | int a |
105 | // CHECK-X64-NEXT: 108 | (vtordisp for vbase B1) |
106 | // CHECK-X64-NEXT: 112 | struct B1 (virtual base) |
107 | // CHECK-X64-NEXT: 112 | (B1 vftable pointer) |
108 | // CHECK-X64-NEXT: 120 | int a |
109 | // CHECK-X64-NEXT: 128 | struct Align32 (virtual base) (empty) |
110 | // CHECK-X64-NEXT: | [sizeof=128, align=32 |
111 | // CHECK-X64-NEXT: | nvsize=64, nvalign=32] |
112 | |
113 | struct __declspec(align(32)) D : virtual B0, virtual B1 { |
114 | int a; |
115 | D() : a(0xf000000D) {} |
116 | virtual void f() { printf("D"); } |
117 | virtual void g() { printf("D"); } |
118 | }; |
119 | |
120 | // CHECK: *** Dumping AST Record Layout |
121 | // CHECK-NEXT: 0 | struct D |
122 | // CHECK-NEXT: 0 | (D vftable pointer) |
123 | // CHECK-NEXT: 4 | (D vbtable pointer) |
124 | // CHECK-NEXT: 8 | int a |
125 | // CHECK-NEXT: 32 | (vtordisp for vbase B0) |
126 | // CHECK-NEXT: 36 | struct B0 (virtual base) |
127 | // CHECK-NEXT: 36 | (B0 vftable pointer) |
128 | // CHECK-NEXT: 40 | int a |
129 | // CHECK-NEXT: 76 | (vtordisp for vbase B1) |
130 | // CHECK-NEXT: 80 | struct B1 (virtual base) |
131 | // CHECK-NEXT: 80 | (B1 vftable pointer) |
132 | // CHECK-NEXT: 84 | int a |
133 | // CHECK-NEXT: | [sizeof=96, align=32 |
134 | // CHECK-NEXT: | nvsize=12, nvalign=32] |
135 | // CHECK-X64: *** Dumping AST Record Layout |
136 | // CHECK-X64-NEXT: 0 | struct D |
137 | // CHECK-X64-NEXT: 0 | (D vftable pointer) |
138 | // CHECK-X64-NEXT: 8 | (D vbtable pointer) |
139 | // CHECK-X64-NEXT: 16 | int a |
140 | // CHECK-X64-NEXT: 36 | (vtordisp for vbase B0) |
141 | // CHECK-X64-NEXT: 40 | struct B0 (virtual base) |
142 | // CHECK-X64-NEXT: 40 | (B0 vftable pointer) |
143 | // CHECK-X64-NEXT: 48 | int a |
144 | // CHECK-X64-NEXT: 76 | (vtordisp for vbase B1) |
145 | // CHECK-X64-NEXT: 80 | struct B1 (virtual base) |
146 | // CHECK-X64-NEXT: 80 | (B1 vftable pointer) |
147 | // CHECK-X64-NEXT: 88 | int a |
148 | // CHECK-X64-NEXT: | [sizeof=96, align=32 |
149 | // CHECK-X64-NEXT: | nvsize=24, nvalign=32] |
150 | |
151 | struct AT { |
152 | virtual ~AT(){} |
153 | }; |
154 | struct CT : virtual AT { |
155 | virtual ~CT(); |
156 | }; |
157 | CT::~CT(){} |
158 | |
159 | // CHECK: *** Dumping AST Record Layout |
160 | // CHECK: *** Dumping AST Record Layout |
161 | // CHECK-NEXT: 0 | struct CT |
162 | // CHECK-NEXT: 0 | (CT vbtable pointer) |
163 | // CHECK-NEXT: 4 | struct AT (virtual base) |
164 | // CHECK-NEXT: 4 | (AT vftable pointer) |
165 | // CHECK-NEXT: | [sizeof=8, align=4 |
166 | // CHECK-NEXT: | nvsize=4, nvalign=4] |
167 | // CHECK-X64: *** Dumping AST Record Layout |
168 | // CHECK-X64: *** Dumping AST Record Layout |
169 | // CHECK-X64-NEXT: 0 | struct CT |
170 | // CHECK-X64-NEXT: 0 | (CT vbtable pointer) |
171 | // CHECK-X64-NEXT: 8 | struct AT (virtual base) |
172 | // CHECK-X64-NEXT: 8 | (AT vftable pointer) |
173 | // CHECK-X64-NEXT: | [sizeof=16, align=8 |
174 | // CHECK-X64-NEXT: | nvsize=8, nvalign=8] |
175 | |
176 | struct XA { |
177 | XA() { printf("XA"); } |
178 | long long ll; |
179 | }; |
180 | struct XB : XA { |
181 | XB() { printf("XB"); } |
182 | virtual void foo() {} |
183 | int b; |
184 | }; |
185 | struct XC : virtual XB { |
186 | XC() { printf("XC"); } |
187 | virtual void foo() {} |
188 | }; |
189 | |
190 | // CHECK: *** Dumping AST Record Layout |
191 | // CHECK: *** Dumping AST Record Layout |
192 | // CHECK: *** Dumping AST Record Layout |
193 | // CHECK-NEXT: 0 | struct XC |
194 | // CHECK-NEXT: 0 | (XC vbtable pointer) |
195 | // CHECK-NEXT: 4 | (vtordisp for vbase XB) |
196 | // CHECK-NEXT: 8 | struct XB (virtual base) |
197 | // CHECK-NEXT: 8 | (XB vftable pointer) |
198 | // CHECK-NEXT: 16 | struct XA (base) |
199 | // CHECK-NEXT: 16 | long long ll |
200 | // CHECK-NEXT: 24 | int b |
201 | // CHECK-NEXT: | [sizeof=32, align=8 |
202 | // CHECK-NEXT: | nvsize=4, nvalign=8] |
203 | // CHECK-X64: *** Dumping AST Record Layout |
204 | // CHECK-X64: *** Dumping AST Record Layout |
205 | // CHECK-X64: *** Dumping AST Record Layout |
206 | // CHECK-X64-NEXT: 0 | struct XC |
207 | // CHECK-X64-NEXT: 0 | (XC vbtable pointer) |
208 | // CHECK-X64-NEXT: 12 | (vtordisp for vbase XB) |
209 | // CHECK-X64-NEXT: 16 | struct XB (virtual base) |
210 | // CHECK-X64-NEXT: 16 | (XB vftable pointer) |
211 | // CHECK-X64-NEXT: 24 | struct XA (base) |
212 | // CHECK-X64-NEXT: 24 | long long ll |
213 | // CHECK-X64-NEXT: 32 | int b |
214 | // CHECK-X64-NEXT: | [sizeof=40, align=8 |
215 | // CHECK-X64-NEXT: | nvsize=8, nvalign=8] |
216 | |
217 | namespace pragma_test1 { |
218 | // No overrides means no vtordisps by default. |
219 | struct A { virtual ~A(); virtual void foo(); int a; }; |
220 | struct B : virtual A { virtual ~B(); virtual void bar(); int b; }; |
221 | struct C : virtual B { int c; }; |
222 | // CHECK: *** Dumping AST Record Layout |
223 | // CHECK: *** Dumping AST Record Layout |
224 | // CHECK: *** Dumping AST Record Layout |
225 | // CHECK-NEXT: 0 | struct pragma_test1::C |
226 | // CHECK-NEXT: 0 | (C vbtable pointer) |
227 | // CHECK-NEXT: 4 | int c |
228 | // CHECK-NEXT: 8 | struct pragma_test1::A (virtual base) |
229 | // CHECK-NEXT: 8 | (A vftable pointer) |
230 | // CHECK-NEXT: 12 | int a |
231 | // CHECK-NEXT: 16 | struct pragma_test1::B (virtual base) |
232 | // CHECK-NEXT: 16 | (B vftable pointer) |
233 | // CHECK-NEXT: 20 | (B vbtable pointer) |
234 | // CHECK-NEXT: 24 | int b |
235 | // CHECK-NEXT: | [sizeof=28, align=4 |
236 | // CHECK-NEXT: | nvsize=8, nvalign=4] |
237 | // CHECK-X64: *** Dumping AST Record Layout |
238 | // CHECK-X64: *** Dumping AST Record Layout |
239 | // CHECK-X64: *** Dumping AST Record Layout |
240 | } |
241 | |
242 | namespace pragma_test2 { |
243 | struct A { virtual ~A(); virtual void foo(); int a; }; |
244 | #pragma vtordisp(push,2) |
245 | struct B : virtual A { virtual ~B(); virtual void bar(); int b; }; |
246 | struct C : virtual B { int c; }; |
247 | #pragma vtordisp(pop) |
248 | // CHECK: *** Dumping AST Record Layout |
249 | // CHECK: *** Dumping AST Record Layout |
250 | // CHECK: *** Dumping AST Record Layout |
251 | // CHECK-NEXT: 0 | struct pragma_test2::C |
252 | // CHECK-NEXT: 0 | (C vbtable pointer) |
253 | // CHECK-NEXT: 4 | int c |
254 | // CHECK-NEXT: 8 | (vtordisp for vbase A) |
255 | // CHECK-NEXT: 12 | struct pragma_test2::A (virtual base) |
256 | // CHECK-NEXT: 12 | (A vftable pointer) |
257 | // CHECK-NEXT: 16 | int a |
258 | // By adding a virtual method and vftable to B, now we need a vtordisp. |
259 | // CHECK-NEXT: 20 | (vtordisp for vbase B) |
260 | // CHECK-NEXT: 24 | struct pragma_test2::B (virtual base) |
261 | // CHECK-NEXT: 24 | (B vftable pointer) |
262 | // CHECK-NEXT: 28 | (B vbtable pointer) |
263 | // CHECK-NEXT: 32 | int b |
264 | // CHECK-NEXT: | [sizeof=36, align=4 |
265 | // CHECK-NEXT: | nvsize=8, nvalign=4] |
266 | // CHECK-X64: *** Dumping AST Record Layout |
267 | // CHECK-X64: *** Dumping AST Record Layout |
268 | // CHECK-X64: *** Dumping AST Record Layout |
269 | } |
270 | |
271 | namespace pragma_test3 { |
272 | struct A { virtual ~A(); virtual void foo(); int a; }; |
273 | #pragma vtordisp(push,2) |
274 | struct B : virtual A { virtual ~B(); virtual void foo(); int b; }; |
275 | struct C : virtual B { int c; }; |
276 | #pragma vtordisp(pop) |
277 | // CHECK: *** Dumping AST Record Layout |
278 | // CHECK: *** Dumping AST Record Layout |
279 | // CHECK: *** Dumping AST Record Layout |
280 | // CHECK-NEXT: 0 | struct pragma_test3::C |
281 | // CHECK-NEXT: 0 | (C vbtable pointer) |
282 | // CHECK-NEXT: 4 | int c |
283 | // CHECK-NEXT: 8 | (vtordisp for vbase A) |
284 | // CHECK-NEXT: 12 | struct pragma_test3::A (virtual base) |
285 | // CHECK-NEXT: 12 | (A vftable pointer) |
286 | // CHECK-NEXT: 16 | int a |
287 | // No vtordisp before B! It doesn't have its own vftable. |
288 | // CHECK-NEXT: 20 | struct pragma_test3::B (virtual base) |
289 | // CHECK-NEXT: 20 | (B vbtable pointer) |
290 | // CHECK-NEXT: 24 | int b |
291 | // CHECK-NEXT: | [sizeof=28, align=4 |
292 | // CHECK-NEXT: | nvsize=8, nvalign=4] |
293 | // CHECK-X64: *** Dumping AST Record Layout |
294 | // CHECK-X64: *** Dumping AST Record Layout |
295 | // CHECK-X64: *** Dumping AST Record Layout |
296 | } |
297 | |
298 | namespace pragma_test4 { |
299 | struct A { |
300 | A(); |
301 | virtual void foo(); |
302 | int a; |
303 | }; |
304 | |
305 | // Make sure the pragma applies to class template decls before they've been |
306 | // instantiated. |
307 | #pragma vtordisp(push,2) |
308 | template <typename T> |
309 | struct B : virtual A { |
310 | B(); |
311 | virtual ~B(); |
312 | virtual void bar(); |
313 | T b; |
314 | }; |
315 | #pragma vtordisp(pop) |
316 | |
317 | struct C : virtual B<int> { int c; }; |
318 | // CHECK: *** Dumping AST Record Layout |
319 | // CHECK: *** Dumping AST Record Layout |
320 | // CHECK: *** Dumping AST Record Layout |
321 | // CHECK-NEXT: 0 | struct pragma_test4::C |
322 | // CHECK-NEXT: 0 | (C vbtable pointer) |
323 | // CHECK-NEXT: 4 | int c |
324 | // Pragma applies to B, which has vbase A. |
325 | // CHECK-NEXT: 8 | (vtordisp for vbase A) |
326 | // CHECK-NEXT: 12 | struct pragma_test4::A (virtual base) |
327 | // CHECK-NEXT: 12 | (A vftable pointer) |
328 | // CHECK-NEXT: 16 | int a |
329 | // Pragma does not apply to C, and B doesn't usually need a vtordisp in C. |
330 | // CHECK-NEXT: 20 | struct pragma_test4::B<int> (virtual base) |
331 | // CHECK-NEXT: 20 | (B vftable pointer) |
332 | // CHECK-NEXT: 24 | (B vbtable pointer) |
333 | // CHECK-NEXT: 28 | int b |
334 | // CHECK-NEXT: | [sizeof=32, align=4 |
335 | // CHECK-NEXT: | nvsize=8, nvalign=4] |
336 | // CHECK-X64: *** Dumping AST Record Layout |
337 | // CHECK-X64: *** Dumping AST Record Layout |
338 | // CHECK-X64: *** Dumping AST Record Layout |
339 | } |
340 | |
341 | struct GA { |
342 | virtual void fun() {} |
343 | }; |
344 | struct GB: public GA {}; |
345 | struct GC: public virtual GA { |
346 | virtual void fun() {} |
347 | GC() {} |
348 | }; |
349 | struct GD: public virtual GC, public virtual GB {}; |
350 | |
351 | // CHECK: *** Dumping AST Record Layout |
352 | // CHECK: *** Dumping AST Record Layout |
353 | // CHECK: *** Dumping AST Record Layout |
354 | // CHECK: *** Dumping AST Record Layout |
355 | // CHECK-NEXT: 0 | struct GD |
356 | // CHECK-NEXT: 0 | (GD vbtable pointer) |
357 | // CHECK-NEXT: 4 | (vtordisp for vbase GA) |
358 | // CHECK-NEXT: 8 | struct GA (virtual base) |
359 | // CHECK-NEXT: 8 | (GA vftable pointer) |
360 | // CHECK-NEXT: 12 | struct GC (virtual base) |
361 | // CHECK-NEXT: 12 | (GC vbtable pointer) |
362 | // CHECK-NEXT: 16 | struct GB (virtual base) |
363 | // CHECK-NEXT: 16 | struct GA (primary base) |
364 | // CHECK-NEXT: 16 | (GA vftable pointer) |
365 | // CHECK-NEXT: | [sizeof=20, align=4 |
366 | // CHECK-NEXT: | nvsize=4, nvalign=4] |
367 | // CHECK-X64: *** Dumping AST Record Layout |
368 | // CHECK-X64: *** Dumping AST Record Layout |
369 | // CHECK-X64: *** Dumping AST Record Layout |
370 | // CHECK-X64: *** Dumping AST Record Layout |
371 | // CHECK-X64-NEXT: 0 | struct GD |
372 | // CHECK-X64-NEXT: 0 | (GD vbtable pointer) |
373 | // CHECK-X64-NEXT: 12 | (vtordisp for vbase GA) |
374 | // CHECK-X64-NEXT: 16 | struct GA (virtual base) |
375 | // CHECK-X64-NEXT: 16 | (GA vftable pointer) |
376 | // CHECK-X64-NEXT: 24 | struct GC (virtual base) |
377 | // CHECK-X64-NEXT: 24 | (GC vbtable pointer) |
378 | // CHECK-X64-NEXT: 32 | struct GB (virtual base) |
379 | // CHECK-X64-NEXT: 32 | struct GA (primary base) |
380 | // CHECK-X64-NEXT: 32 | (GA vftable pointer) |
381 | // CHECK-X64-NEXT: | [sizeof=40, align=8 |
382 | // CHECK-X64-NEXT: | nvsize=8, nvalign=8] |
383 | |
384 | struct HA { |
385 | virtual void fun() {} |
386 | }; |
387 | #pragma vtordisp(push, 2) |
388 | struct HB : virtual HA {}; |
389 | #pragma vtordisp(pop) |
390 | #pragma vtordisp(push, 0) |
391 | struct HC : virtual HB {}; |
392 | #pragma vtordisp(pop) |
393 | |
394 | // CHECK: *** Dumping AST Record Layout |
395 | // CHECK: *** Dumping AST Record Layout |
396 | // CHECK: *** Dumping AST Record Layout |
397 | // CHECK-NEXT: 0 | struct HC |
398 | // CHECK-NEXT: 0 | (HC vbtable pointer) |
399 | // CHECK-NEXT: 4 | (vtordisp for vbase HA) |
400 | // CHECK-NEXT: 8 | struct HA (virtual base) |
401 | // CHECK-NEXT: 8 | (HA vftable pointer) |
402 | // CHECK-NEXT: 12 | struct HB (virtual base) |
403 | // CHECK-NEXT: 12 | (HB vbtable pointer) |
404 | // CHECK-NEXT: | [sizeof=16, align=4 |
405 | // CHECK-NEXT: | nvsize=4, nvalign=4] |
406 | // CHECK-X64: *** Dumping AST Record Layout |
407 | // CHECK-X64: *** Dumping AST Record Layout |
408 | // CHECK-X64: *** Dumping AST Record Layout |
409 | // CHECK-X64-NEXT: 0 | struct HC |
410 | // CHECK-X64-NEXT: 0 | (HC vbtable pointer) |
411 | // CHECK-X64-NEXT: 12 | (vtordisp for vbase HA) |
412 | // CHECK-X64-NEXT: 16 | struct HA (virtual base) |
413 | // CHECK-X64-NEXT: 16 | (HA vftable pointer) |
414 | // CHECK-X64-NEXT: 24 | struct HB (virtual base) |
415 | // CHECK-X64-NEXT: 24 | (HB vbtable pointer) |
416 | // CHECK-X64-NEXT: | [sizeof=32, align=8 |
417 | // CHECK-X64-NEXT: | nvsize=8, nvalign=8] |
418 | |
419 | struct IA { |
420 | virtual void f(); |
421 | }; |
422 | struct __declspec(dllexport) IB : virtual IA { |
423 | virtual void f() = 0; |
424 | IB() {} |
425 | }; |
426 | |
427 | // CHECK: *** Dumping AST Record Layout |
428 | // CHECK: *** Dumping AST Record Layout |
429 | // CHECK-NEXT: 0 | struct IB |
430 | // CHECK-NEXT: 0 | (IB vbtable pointer) |
431 | // CHECK-NEXT: 4 | struct IA (virtual base) |
432 | // CHECK-NEXT: 4 | (IA vftable pointer) |
433 | // CHECK-NEXT: | [sizeof=8, align=4 |
434 | // CHECK-NEXT: | nvsize=4, nvalign=4] |
435 | // CHECK-X64: *** Dumping AST Record Layout |
436 | // CHECK-X64: *** Dumping AST Record Layout |
437 | // CHECK-X64-NEXT: 0 | struct IB |
438 | // CHECK-X64-NEXT: 0 | (IB vbtable pointer) |
439 | // CHECK-X64-NEXT: 8 | struct IA (virtual base) |
440 | // CHECK-X64-NEXT: 8 | (IA vftable pointer) |
441 | // CHECK-X64-NEXT: | [sizeof=16, align=8 |
442 | // CHECK-X64-NEXT: | nvsize=8, nvalign=8] |
443 | |
444 | int a[ |
445 | sizeof(A)+ |
446 | sizeof(C)+ |
447 | sizeof(D)+ |
448 | sizeof(CT)+ |
449 | sizeof(XC)+ |
450 | sizeof(pragma_test1::C)+ |
451 | sizeof(pragma_test2::C)+ |
452 | sizeof(pragma_test3::C)+ |
453 | sizeof(pragma_test4::C)+ |
454 | sizeof(GD)+ |
455 | sizeof(HC)+ |
456 | sizeof(IB)+ |
457 | 0]; |
458 | |