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
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, dsize=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, dsize=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, dsize=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, dsize=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
240// CHECK-NEXT: sizeof=80, dsize=80, align=8
241// CHECK-NEXT: nvsize=64, nvalign=8
242
243// CHECK: sizeof=96, dsize=96, align=8
244// CHECK-NEXT: nvsize=96, nvalign=8
245
246// CHECK: %struct.BaseStruct = type { double, float, %class.C }
247
248// CHECK:       0 | struct DerivedStruct
249// CHECK-NEXT:  0 |   struct BaseStruct (base)
250// CHECK-NEXT:  0 |     double v0
251// CHECK-NEXT:  8 |     float v1
252// CHECK-NEXT: 16 |     class C fg
253// CHECK-NEXT: 16 |       class D (primary base)
254// CHECK-NEXT: 16 |         (D vftable pointer)
255// CHECK-NEXT: 24 |         double a
256// CHECK-NEXT: 32 |       class B (base)
257// CHECK-NEXT: 32 |         (B vftable pointer)
258// CHECK-NEXT: 36 |         int b_field
259// CHECK-NEXT: 40 |       (C vbtable pointer)
260// CHECK-NEXT: 48 |       double c1_field
261// CHECK-NEXT: 56 |       int c2_field
262// CHECK-NEXT: 64 |       double c3_field
263// CHECK-NEXT: 72 |       int c4_field
264// CHECK-NEXT: 80 |       class A (virtual base)
265// CHECK-NEXT: 80 |         class B (primary base)
266// CHECK-NEXT: 80 |           (B vftable pointer)
267// CHECK-NEXT: 84 |           int b_field
268// CHECK-NEXT: 88 |         int a_field
269// CHECK-NEXT: 92 |         char one
270// CHECK-NEXT: sizeof=80, dsize=80, align=8
271// CHECK-NEXT: nvsize=64, nvalign=8
272
273// CHECK: 96 |   int x
274// CHECK-NEXT: sizeof=104, dsize=104, align=8
275// CHECK-NEXT: nvsize=104, nvalign=8
276
277// CHECK: %struct.DerivedStruct = type { %struct.BaseStruct, i32 }
278
279// CHECK:      0 | struct G
280// CHECK-NEXT: 0 |   int g_field
281// CHECK-NEXT: sizeof=4, dsize=4, align=4
282// CHECK-NEXT: nvsize=4, nvalign=4
283
284// CHECK:       0 | struct H
285// CHECK-NEXT:  0 |   struct G (base)
286// CHECK-NEXT:  0 |     int g_field
287// CHECK-NEXT:  4 |   (H vbtable pointer)
288// CHECK-NEXT:  8 |   class D (virtual base)
289// CHECK-NEXT:  8 |     (D vftable pointer)
290// CHECK-NEXT: 16 |     double a
291// CHECK-NEXT: sizeof=24, dsize=24, align=8
292// CHECK-NEXT: nvsize=8, nvalign=4
293
294// CHECK: %struct.H = type { %struct.G, i32*, %class.D }
295
296// CHECK:       0 | struct I
297// CHECK-NEXT:  0 |   (I vftable pointer)
298// CHECK-NEXT:  8 |   (I vbtable pointer)
299// CHECK-NEXT: 16 |   double q
300// CHECK-NEXT: 24 |   class D (virtual base)
301// CHECK-NEXT: 24 |     (D vftable pointer)
302// CHECK-NEXT: 32 |     double a
303// CHECK-NEXT: sizeof=40, dsize=40, align=8
304// CHECK-NEXT: nvsize=24, nvalign=8
305
306// CHECK: %struct.I = type { i32 (...)**, [4 x i8], i32*, double, %class.D }
307// CHECK: %struct.I.base = type { i32 (...)**, [4 x i8], i32*, double }
308
309// CHECK:       0 | struct L
310// CHECK-NEXT:  0 |   int l
311// CHECK-NEXT: sizeof=4, dsize=4, align=4
312// CHECK-NEXT: nvsize=4, nvalign=4
313
314// CHECK:       0 | struct K
315// CHECK-NEXT:  0 |   int k
316// CHECK-NEXT: sizeof=4, dsize=4, align=4
317// CHECK-NEXT: nvsize=4, nvalign=4
318
319// CHECK:       0 | struct M
320// CHECK-NEXT:  0 |   (M vbtable pointer)
321// CHECK-NEXT:  4 |   int m
322// CHECK-NEXT:  8 |   struct K (virtual base)
323// CHECK-NEXT:  8 |     int k
324// CHECK-NEXT: sizeof=12, dsize=12, align=4
325
326//CHECK: %struct.M = type { i32*, i32, %struct.K }
327//CHECK: %struct.M.base = type { i32*, i32 }
328
329// CHECK:       0 | struct N
330// CHECK-NEXT:  4 |   struct L (base)
331// CHECK-NEXT:  4 |     int l
332// CHECK-NEXT:  8 |   struct M (base)
333// CHECK-NEXT:  8 |     (M vbtable pointer)
334// CHECK-NEXT: 12 |     int m
335// CHECK-NEXT:  0 |   (N vftable pointer)
336// CHECK-NEXT: 16 |   struct K (virtual base)
337// CHECK-NEXT: 16 |     int k
338// CHECK-NEXT: sizeof=20, dsize=20, align=4
339// CHECK-NEXT: nvsize=16, nvalign=4
340
341//CHECK: %struct.N = type { i32 (...)**, %struct.L, %struct.M.base, %struct.K }
342
343// FIXME: MSVC place struct H at offset 8.
344// CHECK:       0 | struct O
345// CHECK-NEXT:  4 |   struct H (base)
346// CHECK-NEXT:  4 |     struct G (base)
347// CHECK-NEXT:  4 |       int g_field
348// CHECK-NEXT:  8 |     (H vbtable pointer)
349// CHECK-NEXT: 12 |   struct G (base)
350// CHECK-NEXT: 12 |     int g_field
351// CHECK-NEXT:  0 |   (O vftable pointer)
352// CHECK-NEXT: 16 |   class D (virtual base)
353// CHECK-NEXT: 16 |     (D vftable pointer)
354// CHECK-NEXT: 24 |     double a
355// CHECK-NEXT: sizeof=32, dsize=32, align=8
356// CHECK-NEXT: nvsize=16, nvalign=4
357
358//CHECK: %struct.O = type { i32 (...)**, %struct.H.base, %struct.G, %class.D }
359//CHECK: %struct.O.base = type { i32 (...)**, %struct.H.base, %struct.G }
360
361// CHECK:       0 | struct P
362// CHECK-NEXT:  0 |   struct M (base)
363// CHECK-NEXT:  0 |     (M vbtable pointer)
364// CHECK-NEXT:  4 |     int m
365// CHECK-NEXT:  8 |   int p
366// CHECK-NEXT: 12 |   struct K (virtual base)
367// CHECK-NEXT: 12 |     int k
368// CHECK-NEXT: 16 |   struct L (virtual base)
369// CHECK-NEXT: 16 |     int l
370// CHECK-NEXT: sizeof=20, dsize=20, align=4
371// CHECK-NEXT: nvsize=12, nvalign=4
372
373//CHECK: %struct.P = type { %struct.M.base, i32, %struct.K, %struct.L }
374
375// CHECK:       0 | struct R (empty)
376// CHECK-NEXT:  sizeof=1, dsize=0, align=1
377// CHECK-NEXT:  nvsize=0, nvalign=1
378
379//CHECK: %struct.R = type { i8 }
380
381// CHECK:       0 | struct f
382// CHECK-NEXT:  0 |   (f vftable pointer)
383// CHECK-NEXT: sizeof=4, dsize=4, align=4
384// CHECK-NEXT: nvsize=4, nvalign=4
385
386// CHECK:       0 | struct s
387// CHECK-NEXT:  0 |   (s vftable pointer)
388// CHECK-NEXT:  4 |   (s vbtable pointer)
389// CHECK-NEXT:  8 |   int r
390// CHECK-NEXT: 12 |   (vtordisp for vbase f)
391// CHECK-NEXT: 16 |   struct f (virtual base)
392// CHECK-NEXT: 16 |     (f vftable pointer)
393// CHECK-NEXT: sizeof=20, dsize=20, align=4
394// CHECK-NEXT: nvsize=12, nvalign=4
395
396// CHECK:       0 | class IA
397// CHECK-NEXT:  0 |   (IA vftable pointer)
398// CHECK-NEXT:  sizeof=4, dsize=4, align=4
399// CHECK-NEXT:  nvsize=4, nvalign=4
400
401// CHECK:       0 | class ICh
402// CHECK-NEXT:  0 |   (ICh vftable pointer)
403// CHECK-NEXT:  4 |   (ICh vbtable pointer)
404// CHECK-NEXT:  8 |   (vtordisp for vbase IA)
405// CHECK-NEXT: 12 |   class IA (virtual base)
406// CHECK-NEXT: 12 |     (IA vftable pointer)
407// CHECK-NEXT: sizeof=16, dsize=16, align=4
408// CHECK-NEXT: nvsize=8, nvalign=4
409
410// CHECK:       0 | struct sd
411// CHECK-NEXT:  0 |   (sd vbtable pointer)
412// CHECK-NEXT:  4 |   int q
413// CHECK-NEXT:  8 |   char y
414// CHECK-NEXT: 12 |   (vtordisp for vbase f)
415// CHECK-NEXT: 16 |   struct f (virtual base)
416// CHECK-NEXT: 16 |     (f vftable pointer)
417// CHECK-NEXT: 20 |   struct s (virtual base)
418// CHECK-NEXT: 20 |     (s vftable pointer)
419// CHECK-NEXT: 24 |     (s vbtable pointer)
420// CHECK-NEXT: 28 |     int r
421// CHECK-NEXT: 32 |   (vtordisp for vbase IA)
422// CHECK-NEXT: 36 |   class IA (virtual base)
423// CHECK-NEXT: 36 |     (IA vftable pointer)
424// CHECK-NEXT: 40 |   class ICh (virtual base)
425// CHECK-NEXT: 40 |     (ICh vftable pointer)
426// CHECK-NEXT: 44 |     (ICh vbtable pointer)
427// CHECK-NEXT: sizeof=48, dsize=48, align=4
428// CHECK-NEXT: nvsize=12, nvalign=4
429
430// CHECK: %struct.f = type { i32 (...)** }
431// CHECK: %struct.s = type { i32 (...)**, i32*, i32, [4 x i8], %struct.f }
432// CHECK: %class.IA = type { i32 (...)** }
433// CHECK: %class.ICh = type { i32 (...)**, i32*, [4 x i8], %class.IA }
434// CHECK: %struct.sd = type { i32*, i32, i8, [7 x i8], %struct.f, %struct.s.base, [4 x i8], %class.IA, %class.ICh.base }
435
436// CHECK:       0 | struct AV
437// CHECK-NEXT:  0 |   (AV vftable pointer)
438// CHECK-NEXT: sizeof=4, dsize=4, align=4
439// CHECK-NEXT: nvsize=4, nvalign=4
440
441
442// CHECK:       0 | struct BV
443// CHECK-NEXT:  0 |   struct AV (primary base)
444// CHECK-NEXT:  0 |     (AV vftable pointer)
445// CHECK-NEXT: sizeof=4, dsize=4, align=4
446// CHECK-NEXT: nvsize=4, nvalign=4
447
448
449// CHECK:       0 | struct CV
450// CHECK-NEXT:  0 |   (CV vbtable pointer)
451// CHECK-NEXT:  4 |   (vtordisp for vbase BV)
452// CHECK-NEXT:  8 |   struct BV (virtual base)
453// CHECK-NEXT:  8 |     struct AV (primary base)
454// CHECK-NEXT:  8 |       (AV vftable pointer)
455// CHECK-NEXT: sizeof=12, dsize=12, align=4
456// CHECK-NEXT: nvsize=4, nvalign=4
457
458// CHECK: %struct.AV = type { i32 (...)** }
459// CHECK: %struct.BV = type { %struct.AV }
460// CHECK: %struct.CV = type { i32*, [4 x i8], %struct.BV }
461// CHECK: %struct.CV.base = type { i32* }
462
463// CHECK:       0 | struct DV
464// CHECK-NEXT:  0 |   struct BV (primary base)
465// CHECK-NEXT:  0 |     struct AV (primary base)
466// CHECK-NEXT:  0 |       (AV vftable pointer)
467// CHECK-NEXT: sizeof=4, dsize=4, align=4
468// CHECK-NEXT: nvsize=4, nvalign=4
469
470// CHECK: %struct.DV = type { %struct.BV }
471
472// CHECK:       0 | struct EV
473// CHECK-NEXT:  4 |   struct CV (base)
474// CHECK-NEXT:  4 |     (CV vbtable pointer)
475// CHECK-NEXT:  0 |   struct DV (primary base)
476// CHECK-NEXT:  0 |     struct BV (primary base)
477// CHECK-NEXT:  0 |       struct AV (primary base)
478// CHECK-NEXT:  0 |         (AV vftable pointer)
479// CHECK-NEXT:  8 |   (vtordisp for vbase BV)
480// CHECK-NEXT: 12 |   struct BV (virtual base)
481// CHECK-NEXT: 12 |     struct AV (primary base)
482// CHECK-NEXT: 12 |       (AV vftable pointer)
483// CHECK-NEXT: sizeof=16, dsize=16, align=4
484// CHECK-NEXT: nvsize=8, nvalign=4
485
486// CHECK: %struct.EV = type { %struct.DV, %struct.CV.base, [4 x i8], %struct.BV }
487// CHECK: %struct.EV.base = type { %struct.DV, %struct.CV.base }
488
489// Overriding a method means that all the vbases containing that
490// method need a vtordisp.
491namespace test1 {
492  struct A { virtual void foo(); };
493  struct B : A {};
494  struct C : virtual A, virtual B { C(); virtual void foo(); };
495  void test() { C *c; }
496
497// CHECK:        0 | struct test1::C
498// CHECK-NEXT:   0 |   (C vbtable pointer)
499// CHECK-NEXT:   4 |   (vtordisp for vbase A)
500// CHECK-NEXT:   8 |   struct test1::A (virtual base)
501// CHECK-NEXT:   8 |     (A vftable pointer)
502// CHECK-NEXT:  12 |   (vtordisp for vbase B)
503// CHECK-NEXT:  16 |   struct test1::B (virtual base)
504// CHECK-NEXT:  16 |     struct test1::A (primary base)
505// CHECK-NEXT:  16 |       (A vftable pointer)
506// CHECK-NEXT:  sizeof=20, dsize=20, align=4
507// CHECK-NEXT:  nvsize=4, nvalign=4
508}
509