xref: /llvm-project/clang/test/Sema/ms_class_layout.cpp (revision 84d2d3a90eaeed9397ded468d7cce1cefd30f578)
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:
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;
17   virtual void a(){}
18   char one;
19 protected:
20 private:
21 };
22 
23 class D {
24 public:
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;
36   virtual void foo(){}
37   virtual void bar(){}
38 protected:
39 private:
40 };
41 
42 struct BaseStruct
43 {
44     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     virtual ~G(){}
57     int a;
58     double b;
59 };
60 
61 #pragma pack(pop)
62 
63 // This needs only for building layouts.
64 // Without this clang doesn`t dump record layouts.
65 int main() {
66   // This avoid "Can't yet mangle constructors!" for MS ABI.
67   C* c;
68   c->foo();
69   DerivedStruct* v;
70   G* g;
71   BaseStruct* u;
72   return 0;
73 }
74 
75 // CHECK:       0 | class D
76 // CHECK-NEXT:  0 |   (D vtable pointer)
77 // CHECK-NEXT:  8 |   double a
78 
79 // CHECK-NEXT: sizeof=16, dsize=16, align=8
80 // CHECK-NEXT: nvsize=16, nvalign=8
81 
82 // CHECK:       0 | class B
83 // CHECK-NEXT:  0 |   (B vtable pointer)
84 // CHECK-NEXT:  4 |   int b_field
85 
86 // CHECK-NEXT: sizeof=8, dsize=8, align=4
87 // CHECK-NEXT: nvsize=8, nvalign=4
88 
89 // CHECK:       0 | class A
90 // CHECK-NEXT:  0 |   class B (primary base)
91 // CHECK-NEXT:  0 |     (B vtable pointer)
92 // CHECK-NEXT:  4 |     int b_field
93 // CHECK-NEXT:  8 |   int a_field
94 // CHECK-NEXT: 12 |   char one
95 
96 // CHECK-NEXT: sizeof=16, dsize=16, align=4
97 // CHECK-NEXT: nvsize=16, nvalign=4
98 
99 // CHECK:       0 | class C
100 // CHECK-NEXT:  0 |   class D (primary base)
101 // CHECK-NEXT:  0 |     (D vtable pointer)
102 // CHECK-NEXT:  8 |     double a
103 // CHECK-NEXT: 16 |   class B (base)
104 // CHECK-NEXT: 16 |     (B vtable pointer)
105 // CHECK-NEXT: 20 |     int b_field
106 // CHECK-NEXT: 24 |   (C vbtable pointer)
107 // CHECK-NEXT: 32 |   double c1_field
108 // CHECK-NEXT: 40 |   int c2_field
109 // CHECK-NEXT: 48 |   double c3_field
110 // CHECK-NEXT: 56 |   int c4_field
111 // CHECK-NEXT: 64 |   class A (virtual base)
112 // CHECK-NEXT: 64 |     class B (primary base)
113 // CHECK-NEXT: 64 |       (B vtable pointer)
114 // CHECK-NEXT: 68 |       int b_field
115 // CHECK-NEXT: 72 |     int a_field
116 // CHECK-NEXT: 76 |     char one
117 
118 // CHECK-NEXT: sizeof=80, dsize=80, align=8
119 // CHECK-NEXT: nvsize=80, nvalign=8
120 
121 // CHECK:       0 | struct BaseStruct
122 // CHECK-NEXT:  0 |   double v0
123 // CHECK-NEXT:  8 |   float v1
124 // CHECK-NEXT: 16 |   class C fg
125 // CHECK-NEXT: 16 |     class D (primary base)
126 // CHECK-NEXT: 16 |       (D vtable pointer)
127 // CHECK-NEXT: 24 |       double a
128 // CHECK-NEXT: 32 |     class B (base)
129 // CHECK-NEXT: 32 |       (B vtable pointer)
130 // CHECK-NEXT: 36 |       int b_field
131 // CHECK-NEXT: 40 |     (C vbtable pointer)
132 // CHECK-NEXT: 48 |     double c1_field
133 // CHECK-NEXT: 56 |     int c2_field
134 // CHECK-NEXT: 64 |     double c3_field
135 // CHECK-NEXT: 72 |     int c4_field
136 // CHECK-NEXT: 80 |     class A (virtual base)
137 // CHECK-NEXT: 80 |       class B (primary base)
138 // CHECK-NEXT: 80 |         (B vtable pointer)
139 // CHECK-NEXT: 84 |         int b_field
140 // CHECK-NEXT: 88 |       int a_field
141 // CHECK-NEXT: 92 |       char one
142 
143 // CHECK-NEXT: sizeof=80, dsize=80, align=8
144 // CHECK-NEXT: nvsize=80, nvalign=8
145 
146 // CHECK: sizeof=96, dsize=96, align=8
147 // CHECK-NEXT: nvsize=96, nvalign=8
148 
149 // CHECK:       0 | struct DerivedStruct
150 // CHECK-NEXT:  0 |   struct BaseStruct (base)
151 // CHECK-NEXT:  0 |     double v0
152 // CHECK-NEXT:  8 |     float v1
153 // CHECK-NEXT: 16 |     class C fg
154 // CHECK-NEXT: 16 |       class D (primary base)
155 // CHECK-NEXT: 16 |         (D vtable pointer)
156 // CHECK-NEXT: 24 |         double a
157 // CHECK-NEXT: 32 |       class B (base)
158 // CHECK-NEXT: 32 |         (B vtable pointer)
159 // CHECK-NEXT: 36 |         int b_field
160 // CHECK-NEXT: 40 |       (C vbtable pointer)
161 // CHECK-NEXT: 48 |       double c1_field
162 // CHECK-NEXT: 56 |       int c2_field
163 // CHECK-NEXT: 64 |       double c3_field
164 // CHECK-NEXT: 72 |       int c4_field
165 // CHECK-NEXT: 80 |       class A (virtual base)
166 // CHECK-NEXT: 80 |         class B (primary base)
167 // CHECK-NEXT: 80 |           (B vtable pointer)
168 // CHECK-NEXT: 84 |           int b_field
169 // CHECK-NEXT: 88 |         int a_field
170 // CHECK-NEXT: 92 |         char one
171 // CHECK-NEXT: sizeof=80, dsize=80, align=8
172 // CHECK-NEXT: nvsize=80, nvalign=8
173 
174 // CHECK: 96 |   int x
175 // CHECK-NEXT: sizeof=104, dsize=104, align=8
176 // CHECK-NEXT: nvsize=104, nvalign=8
177