xref: /llvm-project/clang/test/Layout/ms-x86-primary-bases.cpp (revision 7c1d9b15eee3a34678addab2bab66f3020ac0753)
1 // RUN: %clang_cc1 -fno-rtti -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
2 // RUN:            | FileCheck %s --strict-whitespace
3 // RUN: %clang_cc1 -fno-rtti -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
4 // RUN:            | FileCheck %s -check-prefix CHECK-X64 --strict-whitespace
5 
6 extern "C" int printf(const char *fmt, ...);
7 
fB08 struct B0 { int a; B0() : a(0xf00000B0) { printf("B0 = %p\n", this); } virtual void f() { printf("B0"); } };
gB19 struct B1 { int a; B1() : a(0xf00000B1) { printf("B1 = %p\n", this); } virtual void g() { printf("B1"); } };
B2B210 struct B2 { int a; B2() : a(0xf00000B2) { printf("B1 = %p\n", this); } };
B0XB0X11 struct B0X { int a; B0X() : a(0xf00000B0) {} };
fB1X12 struct B1X { int a; B1X() : a(0xf00000B1) {} virtual void f() { printf("B0"); } };
B2XB2X13 struct B2X : virtual B1X { int a; B2X() : a(0xf00000B2) {} };
14 
15 struct A : virtual B0 {
16 };
17 
18 // CHECK-LABEL:   0 | struct A
19 // CHECK-NEXT:    0 |   (A vbtable pointer)
20 // CHECK-NEXT:    4 |   struct B0 (virtual base)
21 // CHECK-NEXT:    4 |     (B0 vftable pointer)
22 // CHECK-NEXT:    8 |     int a
23 // CHECK-NEXT:      | [sizeof=12, align=4
24 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
25 // CHECK-X64-LABEL:   0 | struct A
26 // CHECK-X64-NEXT:    0 |   (A vbtable pointer)
27 // CHECK-X64-NEXT:    8 |   struct B0 (virtual base)
28 // CHECK-X64-NEXT:    8 |     (B0 vftable pointer)
29 // CHECK-X64-NEXT:   16 |     int a
30 // CHECK-X64-NEXT:      | [sizeof=24, align=8
31 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
32 
33 struct B : virtual B0 {
fB34 	virtual void f() { printf("B"); }
35 };
36 
37 // CHECK-LABEL:   0 | struct B
38 // CHECK-NEXT:    0 |   (B vbtable pointer)
39 // CHECK-NEXT:    4 |   struct B0 (virtual base)
40 // CHECK-NEXT:    4 |     (B0 vftable pointer)
41 // CHECK-NEXT:    8 |     int a
42 // CHECK-NEXT:      | [sizeof=12, align=4
43 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
44 // CHECK-X64-LABEL:   0 | struct B
45 // CHECK-X64-NEXT:    0 |   (B vbtable pointer)
46 // CHECK-X64-NEXT:    8 |   struct B0 (virtual base)
47 // CHECK-X64-NEXT:    8 |     (B0 vftable pointer)
48 // CHECK-X64-NEXT:   16 |     int a
49 // CHECK-X64-NEXT:      | [sizeof=24, align=8
50 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
51 
52 struct C : virtual B0 {
gC53 	virtual void g() { printf("A"); }
54 };
55 
56 // CHECK-LABEL:   0 | struct C
57 // CHECK-NEXT:    0 |   (C vftable pointer)
58 // CHECK-NEXT:    4 |   (C vbtable pointer)
59 // CHECK-NEXT:    8 |   struct B0 (virtual base)
60 // CHECK-NEXT:    8 |     (B0 vftable pointer)
61 // CHECK-NEXT:   12 |     int a
62 // CHECK-NEXT:      | [sizeof=16, align=4
63 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
64 // CHECK-X64-LABEL:   0 | struct C
65 // CHECK-X64-NEXT:    0 |   (C vftable pointer)
66 // CHECK-X64-NEXT:    8 |   (C vbtable pointer)
67 // CHECK-X64-NEXT:   16 |   struct B0 (virtual base)
68 // CHECK-X64-NEXT:   16 |     (B0 vftable pointer)
69 // CHECK-X64-NEXT:   24 |     int a
70 // CHECK-X64-NEXT:      | [sizeof=32, align=8
71 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
72 
73 struct D : virtual B2, virtual B0 {
fD74 	virtual void f() { printf("D"); }
gD75 	virtual void g() { printf("D"); }
76 };
77 
78 // CHECK-LABEL:   0 | struct D
79 // CHECK-NEXT:    0 |   (D vftable pointer)
80 // CHECK-NEXT:    4 |   (D vbtable pointer)
81 // CHECK-NEXT:    8 |   struct B2 (virtual base)
82 // CHECK-NEXT:    8 |     int a
83 // CHECK-NEXT:   12 |   struct B0 (virtual base)
84 // CHECK-NEXT:   12 |     (B0 vftable pointer)
85 // CHECK-NEXT:   16 |     int a
86 // CHECK-NEXT:      | [sizeof=20, align=4
87 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
88 // CHECK-X64-LABEL:   0 | struct D
89 // CHECK-X64-NEXT:    0 |   (D vftable pointer)
90 // CHECK-X64-NEXT:    8 |   (D vbtable pointer)
91 // CHECK-X64-NEXT:   16 |   struct B2 (virtual base)
92 // CHECK-X64-NEXT:   16 |     int a
93 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base)
94 // CHECK-X64-NEXT:   24 |     (B0 vftable pointer)
95 // CHECK-X64-NEXT:   32 |     int a
96 // CHECK-X64-NEXT:      | [sizeof=40, align=8
97 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
98 
99 struct E : B0, virtual B1 {
fE100 	virtual void f() { printf("E"); }
gE101 	virtual void g() { printf("E"); }
102 };
103 
104 // CHECK-LABEL:   0 | struct E
105 // CHECK-NEXT:    0 |   struct B0 (primary base)
106 // CHECK-NEXT:    0 |     (B0 vftable pointer)
107 // CHECK-NEXT:    4 |     int a
108 // CHECK-NEXT:    8 |   (E vbtable pointer)
109 // CHECK-NEXT:   12 |   struct B1 (virtual base)
110 // CHECK-NEXT:   12 |     (B1 vftable pointer)
111 // CHECK-NEXT:   16 |     int a
112 // CHECK-NEXT:      | [sizeof=20, align=4
113 // CHECK-NEXT:      |  nvsize=12, nvalign=4]
114 // CHECK-X64-LABEL:   0 | struct E
115 // CHECK-X64-NEXT:    0 |   struct B0 (primary base)
116 // CHECK-X64-NEXT:    0 |     (B0 vftable pointer)
117 // CHECK-X64-NEXT:    8 |     int a
118 // CHECK-X64-NEXT:   16 |   (E vbtable pointer)
119 // CHECK-X64-NEXT:   24 |   struct B1 (virtual base)
120 // CHECK-X64-NEXT:   24 |     (B1 vftable pointer)
121 // CHECK-X64-NEXT:   32 |     int a
122 // CHECK-X64-NEXT:      | [sizeof=40, align=8
123 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
124 
125 struct F : virtual B0, virtual B1 {
126 };
127 
128 // CHECK-LABEL:   0 | struct F
129 // CHECK-NEXT:    0 |   (F vbtable pointer)
130 // CHECK-NEXT:    4 |   struct B0 (virtual base)
131 // CHECK-NEXT:    4 |     (B0 vftable pointer)
132 // CHECK-NEXT:    8 |     int a
133 // CHECK-NEXT:   12 |   struct B1 (virtual base)
134 // CHECK-NEXT:   12 |     (B1 vftable pointer)
135 // CHECK-NEXT:   16 |     int a
136 // CHECK-NEXT:      | [sizeof=20, align=4
137 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
138 // CHECK-X64-LABEL:   0 | struct F
139 // CHECK-X64-NEXT:    0 |   (F vbtable pointer)
140 // CHECK-X64-NEXT:    8 |   struct B0 (virtual base)
141 // CHECK-X64-NEXT:    8 |     (B0 vftable pointer)
142 // CHECK-X64-NEXT:   16 |     int a
143 // CHECK-X64-NEXT:   24 |   struct B1 (virtual base)
144 // CHECK-X64-NEXT:   24 |     (B1 vftable pointer)
145 // CHECK-X64-NEXT:   32 |     int a
146 // CHECK-X64-NEXT:      | [sizeof=40, align=8
147 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
148 
fAX149 struct AX : B0X, B1X { int a; AX() : a(0xf000000A) {} virtual void f() { printf("A"); } };
150 
151 // CHECK-LABEL:   0 | struct AX
152 // CHECK-NEXT:    0 |   struct B1X (primary base)
153 // CHECK-NEXT:    0 |     (B1X vftable pointer)
154 // CHECK-NEXT:    4 |     int a
155 // CHECK-NEXT:    8 |   struct B0X (base)
156 // CHECK-NEXT:    8 |     int a
157 // CHECK-NEXT:   12 |   int a
158 // CHECK-NEXT:      | [sizeof=16, align=4
159 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
160 // CHECK-X64-LABEL:   0 | struct AX
161 // CHECK-X64-NEXT:    0 |   struct B1X (primary base)
162 // CHECK-X64-NEXT:    0 |     (B1X vftable pointer)
163 // CHECK-X64-NEXT:    8 |     int a
164 // CHECK-X64-NEXT:   16 |   struct B0X (base)
165 // CHECK-X64-NEXT:   16 |     int a
166 // CHECK-X64-NEXT:   20 |   int a
167 // CHECK-X64-NEXT:      | [sizeof=24, align=8
168 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
169 
BXBX170 struct BX : B0X, B1X { int a; BX() : a(0xf000000B) {} virtual void g() { printf("B"); } };
171 
172 // CHECK-LABEL:   0 | struct BX
173 // CHECK-NEXT:    0 |   struct B1X (primary base)
174 // CHECK-NEXT:    0 |     (B1X vftable pointer)
175 // CHECK-NEXT:    4 |     int a
176 // CHECK-NEXT:    8 |   struct B0X (base)
177 // CHECK-NEXT:    8 |     int a
178 // CHECK-NEXT:   12 |   int a
179 // CHECK-NEXT:      | [sizeof=16, align=4
180 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
181 // CHECK-X64-LABEL:   0 | struct BX
182 // CHECK-X64-NEXT:    0 |   struct B1X (primary base)
183 // CHECK-X64-NEXT:    0 |     (B1X vftable pointer)
184 // CHECK-X64-NEXT:    8 |     int a
185 // CHECK-X64-NEXT:   16 |   struct B0X (base)
186 // CHECK-X64-NEXT:   16 |     int a
187 // CHECK-X64-NEXT:   20 |   int a
188 // CHECK-X64-NEXT:      | [sizeof=24, align=8
189 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
190 
CXCX191 struct CX : B0X, B2X { int a; CX() : a(0xf000000C) {} virtual void g() { printf("C"); } };
192 
193 // CHECK-LABEL:   0 | struct CX
194 // CHECK-NEXT:    0 |   (CX vftable pointer)
195 // CHECK-NEXT:    4 |   struct B0X (base)
196 // CHECK-NEXT:    4 |     int a
197 // CHECK-NEXT:    8 |   struct B2X (base)
198 // CHECK-NEXT:    8 |     (B2X vbtable pointer)
199 // CHECK-NEXT:   12 |     int a
200 // CHECK-NEXT:   16 |   int a
201 // CHECK-NEXT:   20 |   struct B1X (virtual base)
202 // CHECK-NEXT:   20 |     (B1X vftable pointer)
203 // CHECK-NEXT:   24 |     int a
204 // CHECK-NEXT:      | [sizeof=28, align=4
205 // CHECK-NEXT:      |  nvsize=20, nvalign=4]
206 // CHECK-X64-LABEL:   0 | struct CX
207 // CHECK-X64-NEXT:    0 |   (CX vftable pointer)
208 // CHECK-X64-NEXT:    8 |   struct B0X (base)
209 // CHECK-X64-NEXT:    8 |     int a
210 // CHECK-X64-NEXT:   16 |   struct B2X (base)
211 // CHECK-X64-NEXT:   16 |     (B2X vbtable pointer)
212 // CHECK-X64-NEXT:   24 |     int a
213 // CHECK-X64-NEXT:   32 |   int a
214 // CHECK-X64-NEXT:   40 |   struct B1X (virtual base)
215 // CHECK-X64-NEXT:   40 |     (B1X vftable pointer)
216 // CHECK-X64-NEXT:   48 |     int a
217 // CHECK-X64-NEXT:      | [sizeof=56, align=8
218 // CHECK-X64-NEXT:      |  nvsize=40, nvalign=8]
219 
DXDX220 struct DX : virtual B1X { int a; DX() : a(0xf000000D) {} virtual void f() { printf("D"); } };
221 
222 // CHECK-LABEL:   0 | struct DX
223 // CHECK-NEXT:    0 |   (DX vbtable pointer)
224 // CHECK-NEXT:    4 |   int a
225 // CHECK-NEXT:    8 |   (vtordisp for vbase B1X)
226 // CHECK-NEXT:   12 |   struct B1X (virtual base)
227 // CHECK-NEXT:   12 |     (B1X vftable pointer)
228 // CHECK-NEXT:   16 |     int a
229 // CHECK-NEXT:      | [sizeof=20, align=4
230 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
231 // CHECK-X64-LABEL:   0 | struct DX
232 // CHECK-X64-NEXT:    0 |   (DX vbtable pointer)
233 // CHECK-X64-NEXT:    8 |   int a
234 // CHECK-X64-NEXT:   20 |   (vtordisp for vbase B1X)
235 // CHECK-X64-NEXT:   24 |   struct B1X (virtual base)
236 // CHECK-X64-NEXT:   24 |     (B1X vftable pointer)
237 // CHECK-X64-NEXT:   32 |     int a
238 // CHECK-X64-NEXT:      | [sizeof=40, align=8
239 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
240 
EXEX241 struct EX : virtual B1X { int a; EX() : a(0xf000000E) {} virtual void g() { printf("E"); } };
242 
243 // CHECK-LABEL:   0 | struct EX
244 // CHECK-NEXT:    0 |   (EX vftable pointer)
245 // CHECK-NEXT:    4 |   (EX vbtable pointer)
246 // CHECK-NEXT:    8 |   int a
247 // CHECK-NEXT:   12 |   struct B1X (virtual base)
248 // CHECK-NEXT:   12 |     (B1X vftable pointer)
249 // CHECK-NEXT:   16 |     int a
250 // CHECK-NEXT:      | [sizeof=20, align=4
251 // CHECK-NEXT:      |  nvsize=12, nvalign=4]
252 // CHECK-X64-LABEL:   0 | struct EX
253 // CHECK-X64-NEXT:    0 |   (EX vftable pointer)
254 // CHECK-X64-NEXT:    8 |   (EX vbtable pointer)
255 // CHECK-X64-NEXT:   16 |   int a
256 // CHECK-X64-NEXT:   24 |   struct B1X (virtual base)
257 // CHECK-X64-NEXT:   24 |     (B1X vftable pointer)
258 // CHECK-X64-NEXT:   32 |     int a
259 // CHECK-X64-NEXT:      | [sizeof=40, align=8
260 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
261 
FXFX262 struct FX : virtual B1X { int a; FX() : a(0xf000000F) {} };
263 
264 // CHECK-LABEL:   0 | struct FX
265 // CHECK-NEXT:    0 |   (FX vbtable pointer)
266 // CHECK-NEXT:    4 |   int a
267 // CHECK-NEXT:    8 |   struct B1X (virtual base)
268 // CHECK-NEXT:    8 |     (B1X vftable pointer)
269 // CHECK-NEXT:   12 |     int a
270 // CHECK-NEXT:      | [sizeof=16, align=4
271 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
272 // CHECK-X64-LABEL:   0 | struct FX
273 // CHECK-X64-NEXT:    0 |   (FX vbtable pointer)
274 // CHECK-X64-NEXT:    8 |   int a
275 // CHECK-X64-NEXT:   16 |   struct B1X (virtual base)
276 // CHECK-X64-NEXT:   16 |     (B1X vftable pointer)
277 // CHECK-X64-NEXT:   24 |     int a
278 // CHECK-X64-NEXT:      | [sizeof=32, align=8
279 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
280 
281 int a[
282 sizeof(A)+
283 sizeof(B)+
284 sizeof(C)+
285 sizeof(D)+
286 sizeof(E)+
287 sizeof(F)+
288 sizeof(AX)+
289 sizeof(BX)+
290 sizeof(CX)+
291 sizeof(DX)+
292 sizeof(EX)+
293 sizeof(FX)];
294