xref: /llvm-project/clang/test/Sema/ms_class_layout.cpp (revision faaf2731f60458b486345778a158c5b2ce56a74f)
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     int g_field;
57 };
58 
59 struct H : public G,
60            public virtual D
61 {
62 };
63 
64 struct I : public virtual D
65 {
66   virtual ~I(){}
67   double q;
68 };
69 
70 #pragma pack(pop)
71 
72 // This needs only for building layouts.
73 // Without this clang doesn`t dump record layouts.
74 int main() {
75   // This avoid "Can't yet mangle constructors!" for MS ABI.
76   C* c;
77   c->foo();
78   DerivedStruct* v;
79   H* g;
80   BaseStruct* u;
81   I* i;
82   return 0;
83 }
84 
85 // CHECK:       0 | class D
86 // CHECK-NEXT:  0 |   (D vftable pointer)
87 // CHECK-NEXT:  8 |   double a
88 
89 // CHECK-NEXT: sizeof=16, dsize=16, align=8
90 // CHECK-NEXT: nvsize=16, nvalign=8
91 
92 // CHECK: %class.D = type { [8 x i8], double }
93 
94 // CHECK:       0 | class B
95 // CHECK-NEXT:  0 |   (B vftable pointer)
96 // CHECK-NEXT:  4 |   int b_field
97 
98 // CHECK-NEXT: sizeof=8, dsize=8, align=4
99 // CHECK-NEXT: nvsize=8, nvalign=4
100 
101 // CHECK: %class.B = type { [4 x i8], i32 }
102 
103 // CHECK:       0 | class A
104 // CHECK-NEXT:  0 |   class B (primary base)
105 // CHECK-NEXT:  0 |     (B vftable pointer)
106 // CHECK-NEXT:  4 |     int b_field
107 // CHECK-NEXT:  8 |   int a_field
108 // CHECK-NEXT: 12 |   char one
109 
110 // CHECK-NEXT: sizeof=16, dsize=16, align=4
111 // CHECK-NEXT: nvsize=16, nvalign=4
112 
113 // CHECK:       0 | class C
114 // CHECK-NEXT:  0 |   class D (primary base)
115 // CHECK-NEXT:  0 |     (D vftable pointer)
116 // CHECK-NEXT:  8 |     double a
117 // CHECK-NEXT: 16 |   class B (base)
118 // CHECK-NEXT: 16 |     (B vftable pointer)
119 // CHECK-NEXT: 20 |     int b_field
120 // CHECK-NEXT: 24 |   (C vbtable pointer)
121 // CHECK-NEXT: 32 |   double c1_field
122 // CHECK-NEXT: 40 |   int c2_field
123 // CHECK-NEXT: 48 |   double c3_field
124 // CHECK-NEXT: 56 |   int c4_field
125 // CHECK-NEXT: 64 |   class A (virtual base)
126 // CHECK-NEXT: 64 |     class B (primary base)
127 // CHECK-NEXT: 64 |       (B vftable pointer)
128 // CHECK-NEXT: 68 |       int b_field
129 // CHECK-NEXT: 72 |     int a_field
130 // CHECK-NEXT: 76 |     char one
131 
132 // CHECK-NEXT: sizeof=80, dsize=80, align=8
133 // CHECK-NEXT: nvsize=64, nvalign=8
134 
135 // CHECK: %class.A = type { %class.B, i32, i8 }
136 
137 // CHECK: %class.C = type { %class.D, %class.B, [8 x i8], double, i32, double, i32, [4 x i8], %class.A }
138 // CHECK: %class.C.base = type { %class.D, %class.B, [8 x i8], double, i32, double, i32 }
139 
140 // CHECK:       0 | struct BaseStruct
141 // CHECK-NEXT:  0 |   double v0
142 // CHECK-NEXT:  8 |   float v1
143 // CHECK-NEXT: 16 |   class C fg
144 // CHECK-NEXT: 16 |     class D (primary base)
145 // CHECK-NEXT: 16 |       (D vftable pointer)
146 // CHECK-NEXT: 24 |       double a
147 // CHECK-NEXT: 32 |     class B (base)
148 // CHECK-NEXT: 32 |       (B vftable pointer)
149 // CHECK-NEXT: 36 |       int b_field
150 // CHECK-NEXT: 40 |     (C vbtable pointer)
151 // CHECK-NEXT: 48 |     double c1_field
152 // CHECK-NEXT: 56 |     int c2_field
153 // CHECK-NEXT: 64 |     double c3_field
154 // CHECK-NEXT: 72 |     int c4_field
155 // CHECK-NEXT: 80 |     class A (virtual base)
156 // CHECK-NEXT: 80 |       class B (primary base)
157 // CHECK-NEXT: 80 |         (B vftable pointer)
158 // CHECK-NEXT: 84 |         int b_field
159 // CHECK-NEXT: 88 |       int a_field
160 // CHECK-NEXT: 92 |       char one
161 
162 // CHECK-NEXT: sizeof=80, dsize=80, align=8
163 // CHECK-NEXT: nvsize=64, nvalign=8
164 
165 // CHECK: sizeof=96, dsize=96, align=8
166 // CHECK-NEXT: nvsize=96, nvalign=8
167 
168 // CHECK: %struct.BaseStruct = type { double, float, %class.C }
169 
170 // CHECK:       0 | struct DerivedStruct
171 // CHECK-NEXT:  0 |   struct BaseStruct (base)
172 // CHECK-NEXT:  0 |     double v0
173 // CHECK-NEXT:  8 |     float v1
174 // CHECK-NEXT: 16 |     class C fg
175 // CHECK-NEXT: 16 |       class D (primary base)
176 // CHECK-NEXT: 16 |         (D vftable pointer)
177 // CHECK-NEXT: 24 |         double a
178 // CHECK-NEXT: 32 |       class B (base)
179 // CHECK-NEXT: 32 |         (B vftable pointer)
180 // CHECK-NEXT: 36 |         int b_field
181 // CHECK-NEXT: 40 |       (C vbtable pointer)
182 // CHECK-NEXT: 48 |       double c1_field
183 // CHECK-NEXT: 56 |       int c2_field
184 // CHECK-NEXT: 64 |       double c3_field
185 // CHECK-NEXT: 72 |       int c4_field
186 // CHECK-NEXT: 80 |       class A (virtual base)
187 // CHECK-NEXT: 80 |         class B (primary base)
188 // CHECK-NEXT: 80 |           (B vftable pointer)
189 // CHECK-NEXT: 84 |           int b_field
190 // CHECK-NEXT: 88 |         int a_field
191 // CHECK-NEXT: 92 |         char one
192 // CHECK-NEXT: sizeof=80, dsize=80, align=8
193 // CHECK-NEXT: nvsize=64, nvalign=8
194 
195 // CHECK: 96 |   int x
196 // CHECK-NEXT: sizeof=104, dsize=104, align=8
197 // CHECK-NEXT: nvsize=104, nvalign=8
198 
199 // CHECK: %struct.DerivedStruct = type { %struct.BaseStruct, i32 }
200 
201 // CHECK:      0 | struct G
202 // CHECK-NEXT: 0 |   int g_field
203 // CHECK-NEXT: sizeof=4, dsize=4, align=4
204 // CHECK-NEXT: nvsize=4, nvalign=4
205 
206 // CHECK:       0 | struct H
207 // CHECK-NEXT:  0 |   struct G (base)
208 // CHECK-NEXT:  0 |     int g_field
209 // CHECK-NEXT:  4 |   (H vbtable pointer)
210 // CHECK-NEXT:  8 |   class D (virtual base)
211 // CHECK-NEXT:  8 |     (D vftable pointer)
212 // CHECK-NEXT: 16 |     double a
213 // CHECK-NEXT: sizeof=24, dsize=24, align=8
214 // CHECK-NEXT: nvsize=8, nvalign=4
215 
216 // CHECK: %struct.H = type { %struct.G, [4 x i8], %class.D }
217 
218 // CHECK:       0 | struct I
219 // CHECK-NEXT:  0 |   (I vftable pointer)
220 // CHECK-NEXT:  8 |   (I vbtable pointer)
221 // CHECK-NEXT: 16 |   double q
222 // CHECK-NEXT: 24 |   class D (virtual base)
223 // CHECK-NEXT: 24 |     (D vftable pointer)
224 // CHECK-NEXT: 32 |     double a
225 // CHECK-NEXT: sizeof=40, dsize=40, align=8
226 // CHECK-NEXT: nvsize=24, nvalign=8
227 
228 // CHECK: %struct.I = type { [16 x i8], double, %class.D }
229 // CHECK: %struct.I.base = type { [16 x i8], double }
230