1 // RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
2 // RUN:            | FileCheck %s
3 // RUN: %clang_cc1 -fno-rtti -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 
fB08 struct B0 { int a; B0() : a(0xf00000B0) { printf("B0 = %p\n", this); } virtual void f() { printf("B0"); } };
gB19 struct B1 { int a; B1() : a(0xf00000B1) { printf("B1 = %p\n", this); } virtual void g() { printf("B1"); } };
B2B210 struct B2 { int a; B2() : a(0xf00000B2) { printf("B1 = %p\n", this); } };
B0XB0X11 struct B0X { int a; B0X() : a(0xf00000B0) {} };
fB1X12 struct B1X { int a; B1X() : a(0xf00000B1) {} virtual void f() { printf("B0"); } };
B2XB2X13 struct B2X : virtual B1X { int a; B2X() : a(0xf00000B2) {} };
14 
15 struct A : virtual B0 {
16 };
17 
18 // CHECK: *** Dumping AST Record Layout
19 // CHECK: *** Dumping AST Record Layout
20 // CHECK-NEXT:    0 | struct A
21 // CHECK-NEXT:    0 |   (A vbtable pointer)
22 // CHECK-NEXT:    4 |   struct B0 (virtual base)
23 // CHECK-NEXT:    4 |     (B0 vftable pointer)
24 // CHECK-NEXT:    8 |     int a
25 // CHECK-NEXT:      | [sizeof=12, align=4
26 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
27 // CHECK-X64: *** Dumping AST Record Layout
28 // CHECK-X64: *** Dumping AST Record Layout
29 // CHECK-X64-NEXT:    0 | struct A
30 // CHECK-X64-NEXT:    0 |   (A vbtable pointer)
31 // CHECK-X64-NEXT:    8 |   struct B0 (virtual base)
32 // CHECK-X64-NEXT:    8 |     (B0 vftable pointer)
33 // CHECK-X64-NEXT:   16 |     int a
34 // CHECK-X64-NEXT:      | [sizeof=24, align=8
35 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
36 
37 struct B : virtual B0 {
fB38 	virtual void f() { printf("B"); }
39 };
40 
41 // CHECK: *** Dumping AST Record Layout
42 // CHECK-NEXT:    0 | struct B
43 // CHECK-NEXT:    0 |   (B vbtable pointer)
44 // CHECK-NEXT:    4 |   struct B0 (virtual base)
45 // CHECK-NEXT:    4 |     (B0 vftable pointer)
46 // CHECK-NEXT:    8 |     int a
47 // CHECK-NEXT:      | [sizeof=12, align=4
48 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
49 // CHECK-X64: *** Dumping AST Record Layout
50 // CHECK-X64-NEXT:    0 | struct B
51 // CHECK-X64-NEXT:    0 |   (B vbtable pointer)
52 // CHECK-X64-NEXT:    8 |   struct B0 (virtual base)
53 // CHECK-X64-NEXT:    8 |     (B0 vftable pointer)
54 // CHECK-X64-NEXT:   16 |     int a
55 // CHECK-X64-NEXT:      | [sizeof=24, align=8
56 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
57 
58 struct C : virtual B0 {
gC59 	virtual void g() { printf("A"); }
60 };
61 
62 // CHECK: *** Dumping AST Record Layout
63 // CHECK-NEXT:    0 | struct C
64 // CHECK-NEXT:    0 |   (C vftable pointer)
65 // CHECK-NEXT:    4 |   (C vbtable pointer)
66 // CHECK-NEXT:    8 |   struct B0 (virtual base)
67 // CHECK-NEXT:    8 |     (B0 vftable pointer)
68 // CHECK-NEXT:   12 |     int a
69 // CHECK-NEXT:      | [sizeof=16, align=4
70 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
71 // CHECK-X64: *** Dumping AST Record Layout
72 // CHECK-X64-NEXT:    0 | struct C
73 // CHECK-X64-NEXT:    0 |   (C vftable pointer)
74 // CHECK-X64-NEXT:    8 |   (C vbtable pointer)
75 // CHECK-X64-NEXT:   16 |   struct B0 (virtual base)
76 // CHECK-X64-NEXT:   16 |     (B0 vftable pointer)
77 // CHECK-X64-NEXT:   24 |     int a
78 // CHECK-X64-NEXT:      | [sizeof=32, align=8
79 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
80 
81 struct D : virtual B2, virtual B0 {
fD82 	virtual void f() { printf("D"); }
gD83 	virtual void g() { printf("D"); }
84 };
85 
86 // CHECK: *** Dumping AST Record Layout
87 // CHECK: *** Dumping AST Record Layout
88 // CHECK-NEXT:    0 | struct D
89 // CHECK-NEXT:    0 |   (D vftable pointer)
90 // CHECK-NEXT:    4 |   (D vbtable pointer)
91 // CHECK-NEXT:    8 |   struct B2 (virtual base)
92 // CHECK-NEXT:    8 |     int a
93 // CHECK-NEXT:   12 |   struct B0 (virtual base)
94 // CHECK-NEXT:   12 |     (B0 vftable pointer)
95 // CHECK-NEXT:   16 |     int a
96 // CHECK-NEXT:      | [sizeof=20, align=4
97 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
98 // CHECK-X64: *** Dumping AST Record Layout
99 // CHECK-X64: *** Dumping AST Record Layout
100 // CHECK-X64-NEXT:    0 | struct D
101 // CHECK-X64-NEXT:    0 |   (D vftable pointer)
102 // CHECK-X64-NEXT:    8 |   (D vbtable pointer)
103 // CHECK-X64-NEXT:   16 |   struct B2 (virtual base)
104 // CHECK-X64-NEXT:   16 |     int a
105 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base)
106 // CHECK-X64-NEXT:   24 |     (B0 vftable pointer)
107 // CHECK-X64-NEXT:   32 |     int a
108 // CHECK-X64-NEXT:      | [sizeof=40, align=8
109 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
110 
111 struct E : B0, virtual B1 {
fE112 	virtual void f() { printf("E"); }
gE113 	virtual void g() { printf("E"); }
114 };
115 
116 // CHECK: *** Dumping AST Record Layout
117 // CHECK: *** Dumping AST Record Layout
118 // CHECK-NEXT:    0 | struct E
119 // CHECK-NEXT:    0 |   struct B0 (primary base)
120 // CHECK-NEXT:    0 |     (B0 vftable pointer)
121 // CHECK-NEXT:    4 |     int a
122 // CHECK-NEXT:    8 |   (E vbtable pointer)
123 // CHECK-NEXT:   12 |   struct B1 (virtual base)
124 // CHECK-NEXT:   12 |     (B1 vftable pointer)
125 // CHECK-NEXT:   16 |     int a
126 // CHECK-NEXT:      | [sizeof=20, align=4
127 // CHECK-NEXT:      |  nvsize=12, nvalign=4]
128 // CHECK-X64: *** Dumping AST Record Layout
129 // CHECK-X64: *** Dumping AST Record Layout
130 // CHECK-X64-NEXT:    0 | struct E
131 // CHECK-X64-NEXT:    0 |   struct B0 (primary base)
132 // CHECK-X64-NEXT:    0 |     (B0 vftable pointer)
133 // CHECK-X64-NEXT:    8 |     int a
134 // CHECK-X64-NEXT:   16 |   (E vbtable pointer)
135 // CHECK-X64-NEXT:   24 |   struct B1 (virtual base)
136 // CHECK-X64-NEXT:   24 |     (B1 vftable pointer)
137 // CHECK-X64-NEXT:   32 |     int a
138 // CHECK-X64-NEXT:      | [sizeof=40, align=8
139 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
140 
141 struct F : virtual B0, virtual B1 {
142 };
143 
144 // CHECK: *** Dumping AST Record Layout
145 // CHECK-NEXT:    0 | struct F
146 // CHECK-NEXT:    0 |   (F vbtable pointer)
147 // CHECK-NEXT:    4 |   struct B0 (virtual base)
148 // CHECK-NEXT:    4 |     (B0 vftable pointer)
149 // CHECK-NEXT:    8 |     int a
150 // CHECK-NEXT:   12 |   struct B1 (virtual base)
151 // CHECK-NEXT:   12 |     (B1 vftable pointer)
152 // CHECK-NEXT:   16 |     int a
153 // CHECK-NEXT:      | [sizeof=20, align=4
154 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
155 // CHECK-X64: *** Dumping AST Record Layout
156 // CHECK-X64-NEXT:    0 | struct F
157 // CHECK-X64-NEXT:    0 |   (F vbtable pointer)
158 // CHECK-X64-NEXT:    8 |   struct B0 (virtual base)
159 // CHECK-X64-NEXT:    8 |     (B0 vftable pointer)
160 // CHECK-X64-NEXT:   16 |     int a
161 // CHECK-X64-NEXT:   24 |   struct B1 (virtual base)
162 // CHECK-X64-NEXT:   24 |     (B1 vftable pointer)
163 // CHECK-X64-NEXT:   32 |     int a
164 // CHECK-X64-NEXT:      | [sizeof=40, align=8
165 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
166 
fAX167 struct AX : B0X, B1X { int a; AX() : a(0xf000000A) {} virtual void f() { printf("A"); } };
168 
169 // CHECK: *** Dumping AST Record Layout
170 // CHECK: *** Dumping AST Record Layout
171 // CHECK: *** Dumping AST Record Layout
172 // CHECK-NEXT:    0 | struct AX
173 // CHECK-NEXT:    0 |   struct B1X (primary base)
174 // CHECK-NEXT:    0 |     (B1X vftable pointer)
175 // CHECK-NEXT:    4 |     int a
176 // CHECK-NEXT:    8 |   struct B0X (base)
177 // CHECK-NEXT:    8 |     int a
178 // CHECK-NEXT:   12 |   int a
179 // CHECK-NEXT:      | [sizeof=16, align=4
180 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
181 // CHECK-X64: *** Dumping AST Record Layout
182 // CHECK-X64: *** Dumping AST Record Layout
183 // CHECK-X64: *** Dumping AST Record Layout
184 // CHECK-X64-NEXT:    0 | struct AX
185 // CHECK-X64-NEXT:    0 |   struct B1X (primary base)
186 // CHECK-X64-NEXT:    0 |     (B1X vftable pointer)
187 // CHECK-X64-NEXT:    8 |     int a
188 // CHECK-X64-NEXT:   16 |   struct B0X (base)
189 // CHECK-X64-NEXT:   16 |     int a
190 // CHECK-X64-NEXT:   20 |   int a
191 // CHECK-X64-NEXT:      | [sizeof=24, align=8
192 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
193 
BXBX194 struct BX : B0X, B1X { int a; BX() : a(0xf000000B) {} virtual void g() { printf("B"); } };
195 
196 // CHECK: *** Dumping AST Record Layout
197 // CHECK-NEXT:    0 | struct BX
198 // CHECK-NEXT:    0 |   struct B1X (primary base)
199 // CHECK-NEXT:    0 |     (B1X vftable pointer)
200 // CHECK-NEXT:    4 |     int a
201 // CHECK-NEXT:    8 |   struct B0X (base)
202 // CHECK-NEXT:    8 |     int a
203 // CHECK-NEXT:   12 |   int a
204 // CHECK-NEXT:      | [sizeof=16, align=4
205 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
206 // CHECK-X64: *** Dumping AST Record Layout
207 // CHECK-X64-NEXT:    0 | struct BX
208 // CHECK-X64-NEXT:    0 |   struct B1X (primary base)
209 // CHECK-X64-NEXT:    0 |     (B1X vftable pointer)
210 // CHECK-X64-NEXT:    8 |     int a
211 // CHECK-X64-NEXT:   16 |   struct B0X (base)
212 // CHECK-X64-NEXT:   16 |     int a
213 // CHECK-X64-NEXT:   20 |   int a
214 // CHECK-X64-NEXT:      | [sizeof=24, align=8
215 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
216 
CXCX217 struct CX : B0X, B2X { int a; CX() : a(0xf000000C) {} virtual void g() { printf("C"); } };
218 
219 // CHECK: *** Dumping AST Record Layout
220 // CHECK: *** Dumping AST Record Layout
221 // CHECK-NEXT:    0 | struct CX
222 // CHECK-NEXT:    0 |   (CX vftable pointer)
223 // CHECK-NEXT:    4 |   struct B0X (base)
224 // CHECK-NEXT:    4 |     int a
225 // CHECK-NEXT:    8 |   struct B2X (base)
226 // CHECK-NEXT:    8 |     (B2X vbtable pointer)
227 // CHECK-NEXT:   12 |     int a
228 // CHECK-NEXT:   16 |   int a
229 // CHECK-NEXT:   20 |   struct B1X (virtual base)
230 // CHECK-NEXT:   20 |     (B1X vftable pointer)
231 // CHECK-NEXT:   24 |     int a
232 // CHECK-NEXT:      | [sizeof=28, align=4
233 // CHECK-NEXT:      |  nvsize=20, nvalign=4]
234 // CHECK-X64: *** Dumping AST Record Layout
235 // CHECK-X64: *** Dumping AST Record Layout
236 // CHECK-X64-NEXT:    0 | struct CX
237 // CHECK-X64-NEXT:    0 |   (CX vftable pointer)
238 // CHECK-X64-NEXT:    8 |   struct B0X (base)
239 // CHECK-X64-NEXT:    8 |     int a
240 // CHECK-X64-NEXT:   16 |   struct B2X (base)
241 // CHECK-X64-NEXT:   16 |     (B2X vbtable pointer)
242 // CHECK-X64-NEXT:   24 |     int a
243 // CHECK-X64-NEXT:   32 |   int a
244 // CHECK-X64-NEXT:   40 |   struct B1X (virtual base)
245 // CHECK-X64-NEXT:   40 |     (B1X vftable pointer)
246 // CHECK-X64-NEXT:   48 |     int a
247 // CHECK-X64-NEXT:      | [sizeof=56, align=8
248 // CHECK-X64-NEXT:      |  nvsize=40, nvalign=8]
249 
DXDX250 struct DX : virtual B1X { int a; DX() : a(0xf000000D) {} virtual void f() { printf("D"); } };
251 
252 // CHECK: *** Dumping AST Record Layout
253 // CHECK-NEXT:    0 | struct DX
254 // CHECK-NEXT:    0 |   (DX vbtable pointer)
255 // CHECK-NEXT:    4 |   int a
256 // CHECK-NEXT:    8 |   (vtordisp for vbase B1X)
257 // CHECK-NEXT:   12 |   struct B1X (virtual base)
258 // CHECK-NEXT:   12 |     (B1X vftable pointer)
259 // CHECK-NEXT:   16 |     int a
260 // CHECK-NEXT:      | [sizeof=20, align=4
261 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
262 // CHECK-X64: *** Dumping AST Record Layout
263 // CHECK-X64-NEXT:    0 | struct DX
264 // CHECK-X64-NEXT:    0 |   (DX vbtable pointer)
265 // CHECK-X64-NEXT:    8 |   int a
266 // CHECK-X64-NEXT:   20 |   (vtordisp for vbase B1X)
267 // CHECK-X64-NEXT:   24 |   struct B1X (virtual base)
268 // CHECK-X64-NEXT:   24 |     (B1X vftable pointer)
269 // CHECK-X64-NEXT:   32 |     int a
270 // CHECK-X64-NEXT:      | [sizeof=40, align=8
271 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
272 
EXEX273 struct EX : virtual B1X { int a; EX() : a(0xf000000E) {} virtual void g() { printf("E"); } };
274 
275 // CHECK: *** Dumping AST Record Layout
276 // CHECK-NEXT:    0 | struct EX
277 // CHECK-NEXT:    0 |   (EX vftable pointer)
278 // CHECK-NEXT:    4 |   (EX vbtable pointer)
279 // CHECK-NEXT:    8 |   int a
280 // CHECK-NEXT:   12 |   struct B1X (virtual base)
281 // CHECK-NEXT:   12 |     (B1X vftable pointer)
282 // CHECK-NEXT:   16 |     int a
283 // CHECK-NEXT:      | [sizeof=20, align=4
284 // CHECK-NEXT:      |  nvsize=12, nvalign=4]
285 // CHECK-X64: *** Dumping AST Record Layout
286 // CHECK-X64-NEXT:    0 | struct EX
287 // CHECK-X64-NEXT:    0 |   (EX vftable pointer)
288 // CHECK-X64-NEXT:    8 |   (EX vbtable pointer)
289 // CHECK-X64-NEXT:   16 |   int a
290 // CHECK-X64-NEXT:   24 |   struct B1X (virtual base)
291 // CHECK-X64-NEXT:   24 |     (B1X vftable pointer)
292 // CHECK-X64-NEXT:   32 |     int a
293 // CHECK-X64-NEXT:      | [sizeof=40, align=8
294 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
295 
FXFX296 struct FX : virtual B1X { int a; FX() : a(0xf000000F) {} };
297 
298 // CHECK: *** Dumping AST Record Layout
299 // CHECK-NEXT:    0 | struct FX
300 // CHECK-NEXT:    0 |   (FX vbtable pointer)
301 // CHECK-NEXT:    4 |   int a
302 // CHECK-NEXT:    8 |   struct B1X (virtual base)
303 // CHECK-NEXT:    8 |     (B1X vftable pointer)
304 // CHECK-NEXT:   12 |     int a
305 // CHECK-NEXT:      | [sizeof=16, align=4
306 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
307 // CHECK-X64: *** Dumping AST Record Layout
308 // CHECK-X64-NEXT:    0 | struct FX
309 // CHECK-X64-NEXT:    0 |   (FX vbtable pointer)
310 // CHECK-X64-NEXT:    8 |   int a
311 // CHECK-X64-NEXT:   16 |   struct B1X (virtual base)
312 // CHECK-X64-NEXT:   16 |     (B1X vftable pointer)
313 // CHECK-X64-NEXT:   24 |     int a
314 // CHECK-X64-NEXT:      | [sizeof=32, align=8
315 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
316 
317 int a[
318 sizeof(A)+
319 sizeof(B)+
320 sizeof(C)+
321 sizeof(D)+
322 sizeof(E)+
323 sizeof(F)+
324 sizeof(AX)+
325 sizeof(BX)+
326 sizeof(CX)+
327 sizeof(DX)+
328 sizeof(EX)+
329 sizeof(FX)];
330