1 // RUN: %clang_cc1 -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -cxx-abi microsoft %s 2>&1 \
2 // RUN: | FileCheck %s
3
4 #pragma pack(push, 8)
5
6 class B {
7 public:
b()8 virtual void b(){}
9 int b_field;
10 protected:
11 private:
12 };
13
14 class A : public B {
15 public:
16 int a_field;
a()17 virtual void a(){}
18 char one;
19 protected:
20 private:
21 };
22
23 class D {
24 public:
b()25 virtual void b(){}
26 double a;
27 };
28
29 class C : public virtual A,
30 public D, public B {
31 public:
32 double c1_field;
33 int c2_field;
34 double c3_field;
35 int c4_field;
foo()36 virtual void foo(){}
bar()37 virtual void bar(){}
38 protected:
39 private:
40 };
41
42 struct BaseStruct
43 {
BaseStructBaseStruct44 BaseStruct(){}
45 double v0;
46 float v1;
47 C fg;
48 };
49
50 struct DerivedStruct : public BaseStruct {
51 int x;
52 };
53
54 struct G
55 {
56 int g_field;
57 };
58
59 struct H : public G,
60 public virtual D
61 {
62 };
63
64 struct I : public virtual D
65 {
~II66 virtual ~I(){}
67 double q;
68 };
69
70 struct K
71 {
72 int k;
73 };
74
75 struct L
76 {
77 int l;
78 };
79
80 struct M : public virtual K
81 {
82 int m;
83 };
84
85 struct N : public L, public M
86 {
fN87 virtual void f(){}
88 };
89
90 struct O : public H, public G {
foO91 virtual void fo(){}
92 };
93
94 struct P : public M, public virtual L {
95 int p;
96 };
97
98 struct R {};
99
100 #pragma pack(pop)
101
102 // This needs only for building layouts.
103 // Without this clang doesn`t dump record layouts.
main()104 int main() {
105 // This avoid "Can't yet mangle constructors!" for MS ABI.
106 C* c;
107 c->foo();
108 DerivedStruct* v;
109 H* g;
110 BaseStruct* u;
111 I* i;
112 N* n;
113 O* o;
114 P* p;
115 R* r;
116 return 0;
117 }
118
119 // CHECK: 0 | class D
120 // CHECK-NEXT: 0 | (D vftable pointer)
121 // CHECK-NEXT: 8 | double a
122
123 // CHECK-NEXT: sizeof=16, dsize=16, align=8
124 // CHECK-NEXT: nvsize=16, nvalign=8
125
126 // CHECK: %class.D = type { i32 (...)**, double }
127
128 // CHECK: 0 | class B
129 // CHECK-NEXT: 0 | (B vftable pointer)
130 // CHECK-NEXT: 4 | int b_field
131
132 // CHECK-NEXT: sizeof=8, dsize=8, align=4
133 // CHECK-NEXT: nvsize=8, nvalign=4
134
135 // CHECK: %class.B = type { i32 (...)**, i32 }
136
137 // CHECK: 0 | class A
138 // CHECK-NEXT: 0 | class B (primary base)
139 // CHECK-NEXT: 0 | (B vftable pointer)
140 // CHECK-NEXT: 4 | int b_field
141 // CHECK-NEXT: 8 | int a_field
142 // CHECK-NEXT: 12 | char one
143
144 // CHECK-NEXT: sizeof=16, dsize=16, align=4
145 // CHECK-NEXT: nvsize=16, nvalign=4
146
147 // CHECK: 0 | class C
148 // CHECK-NEXT: 0 | class D (primary base)
149 // CHECK-NEXT: 0 | (D vftable pointer)
150 // CHECK-NEXT: 8 | double a
151 // CHECK-NEXT: 16 | class B (base)
152 // CHECK-NEXT: 16 | (B vftable pointer)
153 // CHECK-NEXT: 20 | int b_field
154 // CHECK-NEXT: 24 | (C vbtable pointer)
155 // CHECK-NEXT: 32 | double c1_field
156 // CHECK-NEXT: 40 | int c2_field
157 // CHECK-NEXT: 48 | double c3_field
158 // CHECK-NEXT: 56 | int c4_field
159 // CHECK-NEXT: 64 | class A (virtual base)
160 // CHECK-NEXT: 64 | class B (primary base)
161 // CHECK-NEXT: 64 | (B vftable pointer)
162 // CHECK-NEXT: 68 | int b_field
163 // CHECK-NEXT: 72 | int a_field
164 // CHECK-NEXT: 76 | char one
165
166 // CHECK-NEXT: sizeof=80, dsize=80, align=8
167 // CHECK-NEXT: nvsize=64, nvalign=8
168
169 // CHECK: %class.A = type { %class.B, i32, i8 }
170
171 // CHECK: %class.C = type { %class.D, %class.B, i32*, double, i32, double, i32, [4 x i8], %class.A }
172 // CHECK: %class.C.base = type { %class.D, %class.B, i32*, double, i32, double, i32 }
173
174 // CHECK: 0 | struct BaseStruct
175 // CHECK-NEXT: 0 | double v0
176 // CHECK-NEXT: 8 | float v1
177 // CHECK-NEXT: 16 | class C fg
178 // CHECK-NEXT: 16 | class D (primary base)
179 // CHECK-NEXT: 16 | (D vftable pointer)
180 // CHECK-NEXT: 24 | double a
181 // CHECK-NEXT: 32 | class B (base)
182 // CHECK-NEXT: 32 | (B vftable pointer)
183 // CHECK-NEXT: 36 | int b_field
184 // CHECK-NEXT: 40 | (C vbtable pointer)
185 // CHECK-NEXT: 48 | double c1_field
186 // CHECK-NEXT: 56 | int c2_field
187 // CHECK-NEXT: 64 | double c3_field
188 // CHECK-NEXT: 72 | int c4_field
189 // CHECK-NEXT: 80 | class A (virtual base)
190 // CHECK-NEXT: 80 | class B (primary base)
191 // CHECK-NEXT: 80 | (B vftable pointer)
192 // CHECK-NEXT: 84 | int b_field
193 // CHECK-NEXT: 88 | int a_field
194 // CHECK-NEXT: 92 | char one
195
196 // CHECK-NEXT: sizeof=80, dsize=80, align=8
197 // CHECK-NEXT: nvsize=64, nvalign=8
198
199 // CHECK: sizeof=96, dsize=96, align=8
200 // CHECK-NEXT: nvsize=96, nvalign=8
201
202 // CHECK: %struct.BaseStruct = type { double, float, %class.C }
203
204 // CHECK: 0 | struct DerivedStruct
205 // CHECK-NEXT: 0 | struct BaseStruct (base)
206 // CHECK-NEXT: 0 | double v0
207 // CHECK-NEXT: 8 | float v1
208 // CHECK-NEXT: 16 | class C fg
209 // CHECK-NEXT: 16 | class D (primary base)
210 // CHECK-NEXT: 16 | (D vftable pointer)
211 // CHECK-NEXT: 24 | double a
212 // CHECK-NEXT: 32 | class B (base)
213 // CHECK-NEXT: 32 | (B vftable pointer)
214 // CHECK-NEXT: 36 | int b_field
215 // CHECK-NEXT: 40 | (C vbtable pointer)
216 // CHECK-NEXT: 48 | double c1_field
217 // CHECK-NEXT: 56 | int c2_field
218 // CHECK-NEXT: 64 | double c3_field
219 // CHECK-NEXT: 72 | int c4_field
220 // CHECK-NEXT: 80 | class A (virtual base)
221 // CHECK-NEXT: 80 | class B (primary base)
222 // CHECK-NEXT: 80 | (B vftable pointer)
223 // CHECK-NEXT: 84 | int b_field
224 // CHECK-NEXT: 88 | int a_field
225 // CHECK-NEXT: 92 | char one
226 // CHECK-NEXT: sizeof=80, dsize=80, align=8
227 // CHECK-NEXT: nvsize=64, nvalign=8
228
229 // CHECK: 96 | int x
230 // CHECK-NEXT: sizeof=104, dsize=104, align=8
231 // CHECK-NEXT: nvsize=104, nvalign=8
232
233 // CHECK: %struct.DerivedStruct = type { %struct.BaseStruct, i32 }
234
235 // CHECK: 0 | struct G
236 // CHECK-NEXT: 0 | int g_field
237 // CHECK-NEXT: sizeof=4, dsize=4, align=4
238 // CHECK-NEXT: nvsize=4, nvalign=4
239
240 // CHECK: 0 | struct H
241 // CHECK-NEXT: 0 | struct G (base)
242 // CHECK-NEXT: 0 | int g_field
243 // CHECK-NEXT: 4 | (H vbtable pointer)
244 // CHECK-NEXT: 8 | class D (virtual base)
245 // CHECK-NEXT: 8 | (D vftable pointer)
246 // CHECK-NEXT: 16 | double a
247 // CHECK-NEXT: sizeof=24, dsize=24, align=8
248 // CHECK-NEXT: nvsize=8, nvalign=4
249
250 // CHECK: %struct.H = type { %struct.G, i32*, %class.D }
251
252 // CHECK: 0 | struct I
253 // CHECK-NEXT: 0 | (I vftable pointer)
254 // CHECK-NEXT: 8 | (I vbtable pointer)
255 // CHECK-NEXT: 16 | double q
256 // CHECK-NEXT: 24 | class D (virtual base)
257 // CHECK-NEXT: 24 | (D vftable pointer)
258 // CHECK-NEXT: 32 | double a
259 // CHECK-NEXT: sizeof=40, dsize=40, align=8
260 // CHECK-NEXT: nvsize=24, nvalign=8
261
262 // CHECK: %struct.I = type { i32 (...)**, [4 x i8], i32*, double, %class.D }
263 // CHECK: %struct.I.base = type { i32 (...)**, [4 x i8], i32*, double }
264
265 // CHECK: 0 | struct L
266 // CHECK-NEXT: 0 | int l
267 // CHECK-NEXT: sizeof=4, dsize=4, align=4
268 // CHECK-NEXT: nvsize=4, nvalign=4
269
270 // CHECK: 0 | struct K
271 // CHECK-NEXT: 0 | int k
272 // CHECK-NEXT: sizeof=4, dsize=4, align=4
273 // CHECK-NEXT: nvsize=4, nvalign=4
274
275 // CHECK: 0 | struct M
276 // CHECK-NEXT: 0 | (M vbtable pointer)
277 // CHECK-NEXT: 4 | int m
278 // CHECK-NEXT: 8 | struct K (virtual base)
279 // CHECK-NEXT: 8 | int k
280 // CHECK-NEXT: sizeof=12, dsize=12, align=4
281
282 //CHECK: %struct.M = type { i32*, i32, %struct.K }
283 //CHECK: %struct.M.base = type { i32*, i32 }
284
285 // CHECK: 0 | struct N
286 // CHECK-NEXT: 4 | struct L (base)
287 // CHECK-NEXT: 4 | int l
288 // CHECK-NEXT: 8 | struct M (base)
289 // CHECK-NEXT: 8 | (M vbtable pointer)
290 // CHECK-NEXT: 12 | int m
291 // CHECK-NEXT: 0 | (N vftable pointer)
292 // CHECK-NEXT: 16 | struct K (virtual base)
293 // CHECK-NEXT: 16 | int k
294 // CHECK-NEXT: sizeof=20, dsize=20, align=4
295 // CHECK-NEXT: nvsize=16, nvalign=4
296
297 //CHECK: %struct.N = type { i32 (...)**, %struct.L, %struct.M.base, %struct.K }
298
299 // FIXME: MSVC place struct H at offset 8.
300 // CHECK: 0 | struct O
301 // CHECK-NEXT: 4 | struct H (base)
302 // CHECK-NEXT: 4 | struct G (base)
303 // CHECK-NEXT: 4 | int g_field
304 // CHECK-NEXT: 8 | (H vbtable pointer)
305 // CHECK-NEXT: 12 | struct G (base)
306 // CHECK-NEXT: 12 | int g_field
307 // CHECK-NEXT: 0 | (O vftable pointer)
308 // CHECK-NEXT: 16 | class D (virtual base)
309 // CHECK-NEXT: 16 | (D vftable pointer)
310 // CHECK-NEXT: 24 | double a
311 // CHECK-NEXT: sizeof=32, dsize=32, align=8
312 // CHECK-NEXT: nvsize=16, nvalign=4
313
314 //CHECK: %struct.O = type { i32 (...)**, %struct.H.base, %struct.G, %class.D }
315 //CHECK: %struct.O.base = type { i32 (...)**, %struct.H.base, %struct.G }
316
317 // CHECK: 0 | struct P
318 // CHECK-NEXT: 0 | struct M (base)
319 // CHECK-NEXT: 0 | (M vbtable pointer)
320 // CHECK-NEXT: 4 | int m
321 // CHECK-NEXT: 8 | int p
322 // CHECK-NEXT: 12 | struct K (virtual base)
323 // CHECK-NEXT: 12 | int k
324 // CHECK-NEXT: 16 | struct L (virtual base)
325 // CHECK-NEXT: 16 | int l
326 // CHECK-NEXT: sizeof=20, dsize=20, align=4
327 // CHECK-NEXT: nvsize=12, nvalign=4
328
329 //CHECK: %struct.P = type { %struct.M.base, i32, %struct.K, %struct.L }
330
331 // CHECK: 0 | struct R (empty)
332 // CHECK-NEXT: sizeof=1, dsize=0, align=1
333 // CHECK-NEXT: nvsize=0, nvalign=1
334
335 //CHECK: %struct.R = type { i8 }
336