Clang Project

clang_source_code/test/Sema/ms_class_layout.cpp
1// RUN: %clang_cc1 -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts %s 2>/dev/null \
2// RUN:            | FileCheck %s
3
4#pragma pack(push, 8)
5
6class B {
7public:
8  virtual void b(){}
9  int b_field;
10protected:
11private:
12};
13
14class A : public B {
15public:
16  int a_field;
17  virtual void a(){}
18  char one;
19protected:
20private:
21};
22
23class D {
24public:
25  virtual void b(){}
26  double a;
27};
28
29class C : public virtual A, 
30          public D, public B {
31public:
32  double c1_field;
33  int c2_field;
34  double c3_field;
35  int c4_field;
36  virtual void foo(){}
37  virtual void bar(){}
38protected:
39private:
40};
41
42struct BaseStruct
43{
44    BaseStruct(){}
45    double v0;
46    float v1;
47    C fg;
48};
49
50struct DerivedStruct : public BaseStruct {
51  int x;
52};
53
54struct G
55{
56    int g_field;
57};
58
59struct H : public G, 
60           public virtual D
61{
62};
63
64struct I : public virtual D
65{
66  virtual ~I(){}
67  double q;
68};
69
70struct K
71{
72  int k;
73};
74
75struct L
76{
77  int l;
78};
79
80struct M : public virtual K
81{
82  int m;
83};
84
85struct N : public L, public M
86{
87  virtual void f(){}
88};
89
90struct O : public H, public G {
91  virtual void fo(){}
92};
93
94struct P : public M, public virtual L {
95  int p;
96};
97
98struct R {};
99
100class IA {
101public:
102  virtual ~IA(){}
103  virtual void ia() = 0;
104};
105
106class ICh : public virtual IA {
107public:
108  virtual ~ICh(){}
109  virtual void ia(){}
110  virtual void iCh(){}
111};
112
113struct f {
114  virtual int asd() {return -90;}
115};
116
117struct s : public virtual f {
118  virtual ~s(){}
119  int r;
120  virtual int asd() {return -9;}
121};
122
123struct sd : virtual s, virtual ICh {
124  virtual ~sd(){}
125  int q;
126  char y;
127  virtual int asd() {return -1;}
128};
129struct AV { 
130  virtual void foo(); 
131};
132struct BV : AV { 
133};
134struct CV : virtual BV { 
135  CV(); 
136  virtual void foo(); 
137};
138struct DV : BV {
139};
140struct EV : CV, DV {
141};
142#pragma pack(pop)
143
144// This needs only for building layouts. 
145// Without this clang doesn`t dump record layouts.
146int main() {
147  // This avoid "Can't yet mangle constructors!" for MS ABI.
148  C* c;
149  c->foo();
150  DerivedStruct* v;
151  H* g;
152  BaseStruct* u;
153  I* i;
154  N* n;
155  O* o;
156  P* p;
157  R* r;
158  sd *h;
159  EV *j;
160  return 0;
161}
162
163// CHECK:       0 | class D
164// CHECK-NEXT:  0 |   (D vftable pointer)
165// CHECK-NEXT:  8 |   double a
166
167// CHECK-NEXT: sizeof=16, align=8
168// CHECK-NEXT: nvsize=16, nvalign=8
169
170// CHECK: %class.D = type { i32 (...)**, double }
171
172// CHECK:       0 | class B
173// CHECK-NEXT:  0 |   (B vftable pointer)
174// CHECK-NEXT:  4 |   int b_field
175
176// CHECK-NEXT: sizeof=8, align=4
177// CHECK-NEXT: nvsize=8, nvalign=4
178
179// CHECK: %class.B = type { i32 (...)**, i32 }
180
181// CHECK:       0 | class A
182// CHECK-NEXT:  0 |   class B (primary base)
183// CHECK-NEXT:  0 |     (B vftable pointer)
184// CHECK-NEXT:  4 |     int b_field
185// CHECK-NEXT:  8 |   int a_field
186// CHECK-NEXT: 12 |   char one
187
188// CHECK-NEXT: sizeof=16, align=4
189// CHECK-NEXT: nvsize=16, nvalign=4
190
191// CHECK:       0 | class C
192// CHECK-NEXT:  0 |   class D (primary base)
193// CHECK-NEXT:  0 |     (D vftable pointer)
194// CHECK-NEXT:  8 |     double a
195// CHECK-NEXT: 16 |   class B (base)
196// CHECK-NEXT: 16 |     (B vftable pointer)
197// CHECK-NEXT: 20 |     int b_field
198// CHECK-NEXT: 24 |   (C vbtable pointer)
199// CHECK-NEXT: 32 |   double c1_field
200// CHECK-NEXT: 40 |   int c2_field
201// CHECK-NEXT: 48 |   double c3_field
202// CHECK-NEXT: 56 |   int c4_field
203// CHECK-NEXT: 64 |   class A (virtual base)
204// CHECK-NEXT: 64 |     class B (primary base)
205// CHECK-NEXT: 64 |       (B vftable pointer)
206// CHECK-NEXT: 68 |       int b_field
207// CHECK-NEXT: 72 |     int a_field
208// CHECK-NEXT: 76 |     char one
209
210// CHECK-NEXT: sizeof=80, align=8
211// CHECK-NEXT: nvsize=64, nvalign=8
212
213// CHECK: %class.A = type { %class.B, i32, i8 }
214
215// CHECK: %class.C = type { %class.D, %class.B, i32*, double, i32, double, i32, [4 x i8], %class.A }
216// CHECK: %class.C.base = type { %class.D, %class.B, i32*, double, i32, double, i32 }
217
218// CHECK:       0 | struct BaseStruct
219// CHECK-NEXT:  0 |   double v0
220// CHECK-NEXT:  8 |   float v1
221// CHECK-NEXT: 16 |   class C fg
222// CHECK-NEXT: 16 |     class D (primary base)
223// CHECK-NEXT: 16 |       (D vftable pointer)
224// CHECK-NEXT: 24 |       double a
225// CHECK-NEXT: 32 |     class B (base)
226// CHECK-NEXT: 32 |       (B vftable pointer)
227// CHECK-NEXT: 36 |       int b_field
228// CHECK-NEXT: 40 |     (C vbtable pointer)
229// CHECK-NEXT: 48 |     double c1_field
230// CHECK-NEXT: 56 |     int c2_field
231// CHECK-NEXT: 64 |     double c3_field
232// CHECK-NEXT: 72 |     int c4_field
233// CHECK-NEXT: 80 |     class A (virtual base)
234// CHECK-NEXT: 80 |       class B (primary base)
235// CHECK-NEXT: 80 |         (B vftable pointer)
236// CHECK-NEXT: 84 |         int b_field
237// CHECK-NEXT: 88 |       int a_field
238// CHECK-NEXT: 92 |       char one
239// CHECK-NEXT: sizeof=96, align=8
240// CHECK-NEXT: nvsize=96, nvalign=8
241
242// CHECK: %struct.BaseStruct = type { double, float, %class.C }
243
244// CHECK:       0 | struct DerivedStruct
245// CHECK-NEXT:  0 |   struct BaseStruct (base)
246// CHECK-NEXT:  0 |     double v0
247// CHECK-NEXT:  8 |     float v1
248// CHECK-NEXT: 16 |     class C fg
249// CHECK-NEXT: 16 |       class D (primary base)
250// CHECK-NEXT: 16 |         (D vftable pointer)
251// CHECK-NEXT: 24 |         double a
252// CHECK-NEXT: 32 |       class B (base)
253// CHECK-NEXT: 32 |         (B vftable pointer)
254// CHECK-NEXT: 36 |         int b_field
255// CHECK-NEXT: 40 |       (C vbtable pointer)
256// CHECK-NEXT: 48 |       double c1_field
257// CHECK-NEXT: 56 |       int c2_field
258// CHECK-NEXT: 64 |       double c3_field
259// CHECK-NEXT: 72 |       int c4_field
260// CHECK-NEXT: 80 |       class A (virtual base)
261// CHECK-NEXT: 80 |         class B (primary base)
262// CHECK-NEXT: 80 |           (B vftable pointer)
263// CHECK-NEXT: 84 |           int b_field
264// CHECK-NEXT: 88 |         int a_field
265// CHECK-NEXT: 92 |         char one
266// CHECK-NEXT: 96 |   int x
267// CHECK-NEXT: sizeof=104, align=8
268// CHECK-NEXT: nvsize=104, nvalign=8
269
270// CHECK: %struct.DerivedStruct = type { %struct.BaseStruct, i32 }
271
272// CHECK:      0 | struct G
273// CHECK-NEXT: 0 |   int g_field
274// CHECK-NEXT: sizeof=4, align=4
275// CHECK-NEXT: nvsize=4, nvalign=4
276
277// CHECK:       0 | struct H
278// CHECK-NEXT:  0 |   struct G (base)
279// CHECK-NEXT:  0 |     int g_field
280// CHECK-NEXT:  4 |   (H vbtable pointer)
281// CHECK-NEXT:  8 |   class D (virtual base)
282// CHECK-NEXT:  8 |     (D vftable pointer)
283// CHECK-NEXT: 16 |     double a
284// CHECK-NEXT: sizeof=24, align=8
285// CHECK-NEXT: nvsize=8, nvalign=8
286
287// CHECK: %struct.H = type { %struct.G, i32*, %class.D }
288
289// CHECK:       0 | struct I
290// CHECK-NEXT:  0 |   (I vftable pointer)
291// CHECK-NEXT:  8 |   (I vbtable pointer)
292// CHECK-NEXT: 16 |   double q
293// CHECK-NEXT: 24 |   class D (virtual base)
294// CHECK-NEXT: 24 |     (D vftable pointer)
295// CHECK-NEXT: 32 |     double a
296// CHECK-NEXT: sizeof=40, align=8
297// CHECK-NEXT: nvsize=24, nvalign=8
298
299// CHECK: %struct.I = type { i32 (...)**, [4 x i8], i32*, double, %class.D }
300// CHECK: %struct.I.base = type { i32 (...)**, [4 x i8], i32*, double }
301
302// CHECK:       0 | struct L
303// CHECK-NEXT:  0 |   int l
304// CHECK-NEXT: sizeof=4, align=4
305// CHECK-NEXT: nvsize=4, nvalign=4
306
307// CHECK:       0 | struct K
308// CHECK-NEXT:  0 |   int k
309// CHECK-NEXT: sizeof=4, align=4
310// CHECK-NEXT: nvsize=4, nvalign=4
311
312// CHECK:       0 | struct M
313// CHECK-NEXT:  0 |   (M vbtable pointer)
314// CHECK-NEXT:  4 |   int m
315// CHECK-NEXT:  8 |   struct K (virtual base)
316// CHECK-NEXT:  8 |     int k
317// CHECK-NEXT: sizeof=12, align=4
318
319//CHECK: %struct.M = type { i32*, i32, %struct.K }
320//CHECK: %struct.M.base = type { i32*, i32 }
321
322// CHECK:       0 | struct N
323// CHECK-NEXT:  0 |   (N vftable pointer)
324// CHECK-NEXT:  4 |   struct L (base)
325// CHECK-NEXT:  4 |     int l
326// CHECK-NEXT:  8 |   struct M (base)
327// CHECK-NEXT:  8 |     (M vbtable pointer)
328// CHECK-NEXT: 12 |     int m
329// CHECK-NEXT: 16 |   struct K (virtual base)
330// CHECK-NEXT: 16 |     int k
331// CHECK-NEXT: sizeof=20, align=4
332// CHECK-NEXT: nvsize=16, nvalign=4
333
334//CHECK: %struct.N = type { i32 (...)**, %struct.L, %struct.M.base, %struct.K }
335
336// CHECK:       0 | struct O
337// CHECK-NEXT:  0 |   (O vftable pointer)
338// CHECK-NEXT:  8 |   struct H (base)
339// CHECK-NEXT:  8 |     struct G (base)
340// CHECK-NEXT:  8 |       int g_field
341// CHECK-NEXT: 12 |     (H vbtable pointer)
342// CHECK-NEXT: 16 |   struct G (base)
343// CHECK-NEXT: 16 |     int g_field
344// CHECK-NEXT: 24 |   class D (virtual base)
345// CHECK-NEXT: 24 |     (D vftable pointer)
346// CHECK-NEXT: 32 |     double a
347// CHECK-NEXT:    | [sizeof=40, align=8
348// CHECK-NEXT:    |  nvsize=24, nvalign=8]
349
350// CHECK: struct.O = type { i32 (...)**, [4 x i8], %struct.H.base, %struct.G, %class.D }
351// CHECK: struct.O.base = type { i32 (...)**, [4 x i8], %struct.H.base, %struct.G, [4 x i8] }
352
353
354// CHECK:       0 | struct P
355// CHECK-NEXT:  0 |   struct M (base)
356// CHECK-NEXT:  0 |     (M vbtable pointer)
357// CHECK-NEXT:  4 |     int m
358// CHECK-NEXT:  8 |   int p
359// CHECK-NEXT: 12 |   struct K (virtual base)
360// CHECK-NEXT: 12 |     int k
361// CHECK-NEXT: 16 |   struct L (virtual base)
362// CHECK-NEXT: 16 |     int l
363// CHECK-NEXT: sizeof=20, align=4
364// CHECK-NEXT: nvsize=12, nvalign=4
365
366//CHECK: %struct.P = type { %struct.M.base, i32, %struct.K, %struct.L }
367
368// CHECK:       0 | struct R (empty)
369// CHECK-NEXT:  sizeof=1, align=1
370// CHECK-NEXT:  nvsize=0, nvalign=1
371
372//CHECK: %struct.R = type { i8 }
373
374// CHECK:       0 | struct f
375// CHECK-NEXT:  0 |   (f vftable pointer)
376// CHECK-NEXT: sizeof=4, align=4
377// CHECK-NEXT: nvsize=4, nvalign=4
378
379// CHECK:       0 | struct s
380// CHECK-NEXT:  0 |   (s vftable pointer)
381// CHECK-NEXT:  4 |   (s vbtable pointer)
382// CHECK-NEXT:  8 |   int r
383// CHECK-NEXT: 12 |   (vtordisp for vbase f)
384// CHECK-NEXT: 16 |   struct f (virtual base)
385// CHECK-NEXT: 16 |     (f vftable pointer)
386// CHECK-NEXT: sizeof=20, align=4
387// CHECK-NEXT: nvsize=12, nvalign=4
388
389// CHECK:       0 | class IA
390// CHECK-NEXT:  0 |   (IA vftable pointer)
391// CHECK-NEXT:  sizeof=4, align=4
392// CHECK-NEXT:  nvsize=4, nvalign=4
393
394// CHECK:       0 | class ICh
395// CHECK-NEXT:  0 |   (ICh vftable pointer)
396// CHECK-NEXT:  4 |   (ICh vbtable pointer)
397// CHECK-NEXT:  8 |   (vtordisp for vbase IA)
398// CHECK-NEXT: 12 |   class IA (virtual base)
399// CHECK-NEXT: 12 |     (IA vftable pointer)
400// CHECK-NEXT: sizeof=16, align=4
401// CHECK-NEXT: nvsize=8, nvalign=4
402
403// CHECK:       0 | struct sd
404// CHECK-NEXT:  0 |   (sd vbtable pointer)
405// CHECK-NEXT:  4 |   int q
406// CHECK-NEXT:  8 |   char y
407// CHECK-NEXT: 12 |   (vtordisp for vbase f)
408// CHECK-NEXT: 16 |   struct f (virtual base)
409// CHECK-NEXT: 16 |     (f vftable pointer)
410// CHECK-NEXT: 20 |   struct s (virtual base)
411// CHECK-NEXT: 20 |     (s vftable pointer)
412// CHECK-NEXT: 24 |     (s vbtable pointer)
413// CHECK-NEXT: 28 |     int r
414// CHECK-NEXT: 32 |   (vtordisp for vbase IA)
415// CHECK-NEXT: 36 |   class IA (virtual base)
416// CHECK-NEXT: 36 |     (IA vftable pointer)
417// CHECK-NEXT: 40 |   class ICh (virtual base)
418// CHECK-NEXT: 40 |     (ICh vftable pointer)
419// CHECK-NEXT: 44 |     (ICh vbtable pointer)
420// CHECK-NEXT: sizeof=48, align=4
421// CHECK-NEXT: nvsize=12, nvalign=4
422
423// CHECK: %struct.f = type { i32 (...)** }
424// CHECK: %struct.s = type { i32 (...)**, i32*, i32, i32, %struct.f }
425// CHECK: %class.IA = type { i32 (...)** }
426// CHECK: %class.ICh = type { i32 (...)**, i32*, i32, %class.IA }
427// CHECK: %struct.sd = type { i32*, i32, i8, i32, %struct.f, %struct.s.base, i32, %class.IA, %class.ICh.base }
428
429// CHECK:       0 | struct AV
430// CHECK-NEXT:  0 |   (AV vftable pointer)
431// CHECK-NEXT: sizeof=4, align=4
432// CHECK-NEXT: nvsize=4, nvalign=4
433
434
435// CHECK:       0 | struct BV
436// CHECK-NEXT:  0 |   struct AV (primary base)
437// CHECK-NEXT:  0 |     (AV vftable pointer)
438// CHECK-NEXT: sizeof=4, align=4
439// CHECK-NEXT: nvsize=4, nvalign=4
440
441
442// CHECK:       0 | struct CV
443// CHECK-NEXT:  0 |   (CV vbtable pointer)
444// CHECK-NEXT:  4 |   (vtordisp for vbase BV)
445// CHECK-NEXT:  8 |   struct BV (virtual base)
446// CHECK-NEXT:  8 |     struct AV (primary base)
447// CHECK-NEXT:  8 |       (AV vftable pointer)
448// CHECK-NEXT: sizeof=12, align=4
449// CHECK-NEXT: nvsize=4, nvalign=4
450
451// CHECK: %struct.AV = type { i32 (...)** }
452// CHECK: %struct.BV = type { %struct.AV }
453// CHECK: %struct.CV = type { i32*, i32, %struct.BV }
454// CHECK: %struct.CV.base = type { i32* }
455
456// CHECK:       0 | struct DV
457// CHECK-NEXT:  0 |   struct BV (primary base)
458// CHECK-NEXT:  0 |     struct AV (primary base)
459// CHECK-NEXT:  0 |       (AV vftable pointer)
460// CHECK-NEXT: sizeof=4, align=4
461// CHECK-NEXT: nvsize=4, nvalign=4
462
463// CHECK: %struct.DV = type { %struct.BV }
464
465// CHECK:       0 | struct EV
466// CHECK-NEXT:  0 |   struct DV (primary base)
467// CHECK-NEXT:  0 |     struct BV (primary base)
468// CHECK-NEXT:  0 |       struct AV (primary base)
469// CHECK-NEXT:  0 |         (AV vftable pointer)
470// CHECK-NEXT:  4 |   struct CV (base)
471// CHECK-NEXT:  4 |     (CV vbtable pointer)
472// CHECK-NEXT:  8 |   (vtordisp for vbase BV)
473// CHECK-NEXT: 12 |   struct BV (virtual base)
474// CHECK-NEXT: 12 |     struct AV (primary base)
475// CHECK-NEXT: 12 |       (AV vftable pointer)
476// CHECK-NEXT: sizeof=16, align=4
477// CHECK-NEXT: nvsize=8, nvalign=4
478
479// CHECK: %struct.EV = type { %struct.DV, %struct.CV.base, i32, %struct.BV }
480// CHECK: %struct.EV.base = type { %struct.DV, %struct.CV.base }
481
482// Overriding a method means that all the vbases containing that
483// method need a vtordisp.  Note: this code will cause an error in cl.exe.
484namespace test1 {
485  struct A { virtual void foo(); };
486  struct B : A {};
487  struct C : virtual A, virtual B { C(); virtual void foo(); };
488  void test() { C *c; }
489
490// CHECK:        0 | struct test1::C
491// CHECK-NEXT:   0 |   (C vbtable pointer)
492// CHECK-NEXT:   4 |   (vtordisp for vbase A)
493// CHECK-NEXT:   8 |   struct test1::A (virtual base)
494// CHECK-NEXT:   8 |     (A vftable pointer)
495// CHECK-NEXT:  12 |   (vtordisp for vbase B)
496// CHECK-NEXT:  16 |   struct test1::B (virtual base)
497// CHECK-NEXT:  16 |     struct test1::A (primary base)
498// CHECK-NEXT:  16 |       (A vftable pointer)
499// CHECK-NEXT:  sizeof=20, align=4
500// CHECK-NEXT:  nvsize=4, nvalign=4
501}
502