blob: ad4902e05f9838909ecc3c4967d8c0912e56585c [file] [log] [blame]
Reid Klecknerc0dca6d2014-02-12 23:50:26 +00001// RUN: %clang_cc1 -fno-rtti -fms-extensions -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>&1 \
Warren Huntbd1b0c62013-10-14 19:08:58 +00002// RUN: | FileCheck %s
Hans Wennborgc9bd88e2014-01-14 19:35:09 +00003// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
Warren Hunt55d8e822013-10-23 23:53:07 +00004// RUN: | FileCheck %s -check-prefix CHECK-X64
Warren Huntbd1b0c62013-10-14 19:08:58 +00005
6extern "C" int printf(const char *fmt, ...);
7
8struct B0 {
9 int a;
10 B0() : a(0xf00000B0) {}
11 virtual void f() { printf("B0"); }
12};
13
14struct __declspec(align(16)) B1 {
15 int a;
16 B1() : a(0xf00000B1) {}
17 virtual void f() { printf("B1"); }
18};
19
20struct __declspec(align(16)) Align16 {};
21struct __declspec(align(32)) Align32 {};
22struct VAlign16 : virtual Align16 {};
23struct VAlign32 : virtual Align32 {};
24
25struct 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
Warren Huntd640d7d2014-01-09 00:30:56 +000033// 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]
Warren Hunt55d8e822013-10-23 23:53:07 +000049// CHECK-X64: *** Dumping AST Record Layout
Warren Huntd640d7d2014-01-09 00:30:56 +000050// 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]
Warren Huntbd1b0c62013-10-14 19:08:58 +000066
67struct 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
Warren Huntd640d7d2014-01-09 00:30:56 +000075// 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]
Warren Hunt55d8e822013-10-23 23:53:07 +000093// CHECK-X64: *** Dumping AST Record Layout
Warren Huntd640d7d2014-01-09 00:30:56 +000094// 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]
Warren Huntbd1b0c62013-10-14 19:08:58 +0000112
113struct __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
Warren Huntd640d7d2014-01-09 00:30:56 +0000121// 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]
Warren Hunt55d8e822013-10-23 23:53:07 +0000135// CHECK-X64: *** Dumping AST Record Layout
Warren Huntd640d7d2014-01-09 00:30:56 +0000136// 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]
Warren Huntbd1b0c62013-10-14 19:08:58 +0000150
Warren Hunt55d8e822013-10-23 23:53:07 +0000151struct AT {
152 virtual ~AT(){}
153};
154struct CT : virtual AT {
155 virtual ~CT();
156};
Warren Hunt42be7762013-10-14 20:14:09 +0000157CT::~CT(){}
158
Warren Hunt55d8e822013-10-23 23:53:07 +0000159// CHECK: *** Dumping AST Record Layout
Warren Huntd640d7d2014-01-09 00:30:56 +0000160// 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]
Warren Hunt55d8e822013-10-23 23:53:07 +0000167// CHECK-X64: *** Dumping AST Record Layout
Warren Huntd640d7d2014-01-09 00:30:56 +0000168// 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]
Warren Hunt42be7762013-10-14 20:14:09 +0000175
Warren Huntf037bd12013-12-19 00:43:59 +0000176struct XA {
177 XA() { printf("XA"); }
178 long long ll;
179};
180struct XB : XA {
181 XB() { printf("XB"); }
182 virtual void foo() {}
183 int b;
184};
185struct XC : virtual XB {
186 XC() { printf("XC"); }
187 virtual void foo() {}
188};
189
190// CHECK: *** Dumping AST Record Layout
Warren Huntd640d7d2014-01-09 00:30:56 +0000191// 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]
Warren Huntf037bd12013-12-19 00:43:59 +0000203// CHECK-X64: *** Dumping AST Record Layout
Warren Huntd640d7d2014-01-09 00:30:56 +0000204// 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]
Warren Huntf037bd12013-12-19 00:43:59 +0000216
Reid Klecknerc0dca6d2014-02-12 23:50:26 +0000217namespace pragma_test1 {
218// No overrides means no vtordisps by default.
219struct A { virtual ~A(); virtual void foo(); int a; };
220struct B : virtual A { virtual ~B(); virtual void bar(); int b; };
221struct 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}
238
239namespace pragma_test2 {
240struct A { virtual ~A(); virtual void foo(); int a; };
241#pragma vtordisp(push,2)
242struct B : virtual A { virtual ~B(); virtual void bar(); int b; };
243struct C : virtual B { int c; };
244#pragma vtordisp(pop)
245// CHECK: *** Dumping AST Record Layout
246// CHECK: *** Dumping AST Record Layout
247// CHECK: *** Dumping AST Record Layout
248// CHECK-NEXT: 0 | struct pragma_test2::C
249// CHECK-NEXT: 0 | (C vbtable pointer)
250// CHECK-NEXT: 4 | int c
251// CHECK-NEXT: 8 | (vtordisp for vbase A)
252// CHECK-NEXT: 12 | struct pragma_test2::A (virtual base)
253// CHECK-NEXT: 12 | (A vftable pointer)
254// CHECK-NEXT: 16 | int a
255// By adding a virtual method and vftable to B, now we need a vtordisp.
256// CHECK-NEXT: 20 | (vtordisp for vbase B)
257// CHECK-NEXT: 24 | struct pragma_test2::B (virtual base)
258// CHECK-NEXT: 24 | (B vftable pointer)
259// CHECK-NEXT: 28 | (B vbtable pointer)
260// CHECK-NEXT: 32 | int b
261// CHECK-NEXT: | [sizeof=36, align=4
262// CHECK-NEXT: | nvsize=8, nvalign=4]
263}
264
265namespace pragma_test3 {
266struct A { virtual ~A(); virtual void foo(); int a; };
267#pragma vtordisp(push,2)
268struct B : virtual A { virtual ~B(); virtual void foo(); int b; };
269struct C : virtual B { int c; };
270#pragma vtordisp(pop)
271// CHECK: *** Dumping AST Record Layout
272// CHECK: *** Dumping AST Record Layout
273// CHECK: *** Dumping AST Record Layout
274// CHECK-NEXT: 0 | struct pragma_test3::C
275// CHECK-NEXT: 0 | (C vbtable pointer)
276// CHECK-NEXT: 4 | int c
277// CHECK-NEXT: 8 | (vtordisp for vbase A)
278// CHECK-NEXT: 12 | struct pragma_test3::A (virtual base)
279// CHECK-NEXT: 12 | (A vftable pointer)
280// CHECK-NEXT: 16 | int a
281// No vtordisp before B! It doesn't have its own vftable.
282// CHECK-NEXT: 20 | struct pragma_test3::B (virtual base)
283// CHECK-NEXT: 20 | (B vbtable pointer)
284// CHECK-NEXT: 24 | int b
285// CHECK-NEXT: | [sizeof=28, align=4
286// CHECK-NEXT: | nvsize=8, nvalign=4]
287}
288
289namespace pragma_test4 {
290struct A {
291 A();
292 virtual void foo();
293 int a;
294};
295
296// Make sure the pragma applies to class template decls before they've been
297// instantiated.
298#pragma vtordisp(push,2)
299template <typename T>
300struct B : virtual A {
301 B();
302 virtual ~B();
303 virtual void bar();
304 T b;
305};
306#pragma vtordisp(pop)
307
308struct C : virtual B<int> { int c; };
309// CHECK: *** Dumping AST Record Layout
310// CHECK: *** Dumping AST Record Layout
311// CHECK: *** Dumping AST Record Layout
312// CHECK-NEXT: 0 | struct pragma_test4::C
313// CHECK-NEXT: 0 | (C vbtable pointer)
314// CHECK-NEXT: 4 | int c
315// Pragma applies to B, which has vbase A.
316// CHECK-NEXT: 8 | (vtordisp for vbase A)
317// CHECK-NEXT: 12 | struct pragma_test4::A (virtual base)
318// CHECK-NEXT: 12 | (A vftable pointer)
319// CHECK-NEXT: 16 | int a
320// Pragma does not apply to C, and B doesn't usually need a vtordisp in C.
321// CHECK-NEXT: 20 | struct pragma_test4::B<int> (virtual base)
322// CHECK-NEXT: 20 | (B vftable pointer)
323// CHECK-NEXT: 24 | (B vbtable pointer)
324// CHECK-NEXT: 28 | int b
325// CHECK-NEXT: | [sizeof=32, align=4
326// CHECK-NEXT: | nvsize=8, nvalign=4]
327}
328
Warren Huntbd1b0c62013-10-14 19:08:58 +0000329int a[
330sizeof(A)+
331sizeof(C)+
Warren Hunt42be7762013-10-14 20:14:09 +0000332sizeof(D)+
Warren Huntf037bd12013-12-19 00:43:59 +0000333sizeof(CT)+
Reid Klecknerc0dca6d2014-02-12 23:50:26 +0000334sizeof(XC)+
335sizeof(pragma_test1::C)+
336sizeof(pragma_test2::C)+
337sizeof(pragma_test3::C)+
338sizeof(pragma_test4::C)];