1 // from SemaCXX/class-layout.cpp
2 // RUN: c-index-test -test-print-type-size %s -target x86_64-pc-linux-gnu | FileCheck -check-prefix=CHECK64 %s
3 // RUN: c-index-test -test-print-type-size %s -target i386-apple-darwin9 | FileCheck -check-prefix=CHECK32 %s
4
5 namespace basic {
6
7 // CHECK64: VarDecl=v:[[@LINE+2]]:6 (Definition) [type=void] [typekind=Void]
8 // CHECK32: VarDecl=v:[[@LINE+1]]:6 (Definition) [type=void] [typekind=Void]
9 void v;
10
11 // CHECK64: VarDecl=v1:[[@LINE+2]]:7 (Definition) [type=void *] [typekind=Pointer] [sizeof=8] [alignof=8]
12 // CHECK32: VarDecl=v1:[[@LINE+1]]:7 (Definition) [type=void *] [typekind=Pointer] [sizeof=4] [alignof=4]
13 void *v1;
14
15 // offsetof
16 // CHECK64: StructDecl=simple:[[@LINE+2]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=48] [alignof=8]
17 // CHECK32: StructDecl=simple:[[@LINE+1]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=36] [alignof=4]
18 struct simple {
19 int a;
20 char b;
21 // CHECK64: FieldDecl=c:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=40] [BitFieldSize=3]
22 int c:3;
23 long d;
24 int e:5;
25 // CHECK64: FieldDecl=f:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=133] [BitFieldSize=4]
26 int f:4;
27 // CHECK64: FieldDecl=g:[[@LINE+2]]:13 (Definition) [type=long long] [typekind=LongLong] [sizeof=8] [alignof=8] [offsetof=192]
28 // CHECK32: FieldDecl=g:[[@LINE+1]]:13 (Definition) [type=long long] [typekind=LongLong] [sizeof=8] [alignof=4] [offsetof=128]
29 long long g;
30 // CHECK64: FieldDecl=h:[[@LINE+1]]:8 (Definition) [type=char] [typekind=Char_S] [sizeof=1] [alignof=1] [offsetof=256] [BitFieldSize=3]
31 char h:3;
32 char i:3;
33 float j;
34 // CHECK64: FieldDecl=k:[[@LINE+2]]:10 (Definition) [type=char *] [typekind=Pointer] [sizeof=8] [alignof=8] [offsetof=320]
35 // CHECK32: FieldDecl=k:[[@LINE+1]]:10 (Definition) [type=char *] [typekind=Pointer] [sizeof=4] [alignof=4] [offsetof=256]
36 char * k;
37 };
38
39
40 // CHECK64: UnionDecl=u:[[@LINE+2]]:7 (Definition) [type=basic::u] [typekind=Record] [sizeof=48] [alignof=8]
41 // CHECK32: UnionDecl=u:[[@LINE+1]]:7 (Definition) [type=basic::u] [typekind=Record] [sizeof=36] [alignof=4]
42 union u {
43 int u1;
44 long long u2;
45 struct simple s1;
46 };
47
48 // CHECK64: VarDecl=s1:[[@LINE+2]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=48] [alignof=8]
49 // CHECK32: VarDecl=s1:[[@LINE+1]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=36] [alignof=4]
50 simple s1;
51
52 struct Test {
53 struct {
54 union {
55 //CHECK64: FieldDecl=foo:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
56 int foo;
57 };
58 };
59 };
60
61 struct Test2 {
62 struct {
63 struct {
64 //CHECK64: FieldDecl=foo:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
65 int foo;
66 };
67 struct {
68 //CHECK64: FieldDecl=bar:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=32/0]
69 int bar;
70 };
71 struct {
72 struct {
73 //CHECK64: FieldDecl=foobar:[[@LINE+1]]:15 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64/0]
74 int foobar;
75 };
76 };
77 };
78 };
79
80 }
81
82 // these are test crash. Offsetof return values are not important.
83 namespace Incomplete {
84 // test that fields in incomplete named record do not crash
85 union named {
86 struct forward_decl f1;
87 int f2;
88 struct x {
89 int g1;
90 } f3;
91 struct forward_decl f4;
92 struct x2{
93 int g2;
94 struct forward_decl g3;
95 } f5;
96 };
97
98 // test that fields in incomplete anonymous record do not crash
99 union f {
100 struct forward_decl f1;
101 int f2;
102 struct {
103 int e1;
104 struct {
105 struct forward_decl2 g1;
106 };
107 int e3;
108 };
109 };
110
111
112 // incomplete not in root level, in named record
113 struct s1 {
114 struct {
115 struct forward_decl2 s1_g1;
116 int s1_e1;
117 } s1_x; // named record shows in s1->field_iterator
118 int s1_e3;
119 };
120
121 // incomplete not in root level, in anonymous record
122 struct s1b {
123 struct {
124 struct forward_decl2 s1b_g1;
125 }; // erroneous anonymous record does not show in s1b->field_iterator
126 int s1b_e2;
127 };
128
129 struct s2 {
130 struct {
131 struct forward_decl2 s2_g1;
132 int s2_e1;
133 }; // erroneous anonymous record does not show in s1b->field_iterator
134 int s2_e3;
135 };
136
137 //deep anonymous with deep level incomplete
138 struct s3 {
139 struct {
140 int s3_e1;
141 struct {
142 struct {
143 struct {
144 struct {
145 struct forward_decl2 s3_g1;
146 };
147 };
148 };
149 };
150 int s3_e3;
151 };
152 };
153
154 //deep anonymous with first level incomplete
155 struct s4a {
156 struct forward_decl2 g1;
157 struct {
158 struct forward_decl2 g2;
159 struct {
160 struct {
161 struct {
162 struct {
163 //CHECK64: FieldDecl=s4_e1:[[@LINE+1]]:17 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-1/0]
164 int s4_e1;
165 };
166 };
167 };
168 };
169 int s4_e3;
170 };
171 };
172
173 //deep anonymous with sub-first-level incomplete
174 struct s4b {
175 struct {
176 struct forward_decl2 g1;
177 struct {
178 struct {
179 struct {
180 struct {
181 int s4b_e1;
182 };
183 };
184 };
185 };
186 int s4b_e3;
187 };
188 };
189
190 //named struct within anonymous struct
191 struct s5 {
192 struct {
193 struct x {
194 int i;
195 };
196 };
197 };
198
199 // CHECK64: StructDecl=As:[[@LINE+1]]:8 [type=Incomplete::As] [typekind=Record]
200 struct As;
201
202 // undefined class. Should not crash
203 // CHECK64: ClassDecl=A:[[@LINE+1]]:7 [type=Incomplete::A] [typekind=Record]
204 class A;
205 class B {
206 A* a1;
207 A& a2;
208 };
209
210 }
211
212 namespace Sizes {
213
214 // CHECK64: StructDecl=A:[[@LINE+2]]:8 (Definition) [type=Sizes::A] [typekind=Record] [sizeof=8] [alignof=4]
215 // CHECK32: StructDecl=A:[[@LINE+1]]:8 (Definition) [type=Sizes::A] [typekind=Record] [sizeof=8] [alignof=4]
216 struct A {
217 int a;
218 char b;
219 };
220
221 // CHECK64: StructDecl=B:[[@LINE+2]]:8 (Definition) [type=Sizes::B] [typekind=Record] [sizeof=12] [alignof=4]
222 // CHECK32: StructDecl=B:[[@LINE+1]]:8 (Definition) [type=Sizes::B] [typekind=Record] [sizeof=12] [alignof=4]
223 struct B : A {
224 char c;
225 };
226
227 // CHECK64: StructDecl=C:[[@LINE+2]]:8 (Definition) [type=Sizes::C] [typekind=Record] [sizeof=8] [alignof=4]
228 // CHECK32: StructDecl=C:[[@LINE+1]]:8 (Definition) [type=Sizes::C] [typekind=Record] [sizeof=8] [alignof=4]
229 struct C {
230 // Make fields private so C won't be a POD type.
231 private:
232 int a;
233 char b;
234 };
235
236 // CHECK64: StructDecl=D:[[@LINE+2]]:8 (Definition) [type=Sizes::D] [typekind=Record] [sizeof=8] [alignof=4]
237 // CHECK32: StructDecl=D:[[@LINE+1]]:8 (Definition) [type=Sizes::D] [typekind=Record] [sizeof=8] [alignof=4]
238 struct D : C {
239 char c;
240 };
241
242 // CHECK64: StructDecl=E:[[@LINE+2]]:32 (Definition) [type=Sizes::E] [typekind=Record] [sizeof=5] [alignof=1]
243 // CHECK32: StructDecl=E:[[@LINE+1]]:32 (Definition) [type=Sizes::E] [typekind=Record] [sizeof=5] [alignof=1]
244 struct __attribute__((packed)) E {
245 char b;
246 int a;
247 };
248
249 // CHECK64: StructDecl=F:[[@LINE+2]]:32 (Definition) [type=Sizes::F] [typekind=Record] [sizeof=6] [alignof=1]
250 // CHECK32: StructDecl=F:[[@LINE+1]]:32 (Definition) [type=Sizes::F] [typekind=Record] [sizeof=6] [alignof=1]
251 struct __attribute__((packed)) F : E {
252 char d;
253 };
254
255 struct G { G(); };
256 // CHECK64: StructDecl=H:[[@LINE+2]]:8 (Definition) [type=Sizes::H] [typekind=Record] [sizeof=1] [alignof=1]
257 // CHECK32: StructDecl=H:[[@LINE+1]]:8 (Definition) [type=Sizes::H] [typekind=Record] [sizeof=1] [alignof=1]
258 struct H : G { };
259
260 // CHECK64: StructDecl=I:[[@LINE+2]]:8 (Definition) [type=Sizes::I] [typekind=Record] [sizeof=5] [alignof=1]
261 // CHECK32: StructDecl=I:[[@LINE+1]]:8 (Definition) [type=Sizes::I] [typekind=Record] [sizeof=5] [alignof=1]
262 struct I {
263 char b;
264 int a;
265 } __attribute__((packed));
266
267 }
268
269 namespace Test1 {
270
271 // Test complex class hierarchy
272 struct A { };
273 struct B : A { virtual void b(); };
274 class C : virtual A { int c; };
275 struct D : virtual B { };
276 struct E : C, virtual D { };
277 class F : virtual E { };
278 // CHECK64: StructDecl=G:[[@LINE+2]]:8 (Definition) [type=Test1::G] [typekind=Record] [sizeof=24] [alignof=8]
279 // CHECK32: StructDecl=G:[[@LINE+1]]:8 (Definition) [type=Test1::G] [typekind=Record] [sizeof=16] [alignof=4]
280 struct G : virtual E, F { };
281
282 }
283
284 namespace Test2 {
285
286 // Test that this somewhat complex class structure is laid out correctly.
287 struct A { };
288 struct B : A { virtual void b(); };
289 struct C : virtual B { };
290 struct D : virtual A { };
291 struct E : virtual B, D { };
292 struct F : E, virtual C { };
293 struct G : virtual F, A { };
294 // CHECK64: StructDecl=H:[[@LINE+2]]:8 (Definition) [type=Test2::H] [typekind=Record] [sizeof=24] [alignof=8]
295 // CHECK32: StructDecl=H:[[@LINE+1]]:8 (Definition) [type=Test2::H] [typekind=Record] [sizeof=12] [alignof=4]
296 struct H { G g; };
297
298 }
299
300 namespace Test3 {
301 // CHECK64: ClassDecl=B:[[@LINE+2]]:7 (Definition) [type=Test3::B] [typekind=Record] [sizeof=16] [alignof=8]
302 // CHECK32: ClassDecl=B:[[@LINE+1]]:7 (Definition) [type=Test3::B] [typekind=Record] [sizeof=8] [alignof=4]
303 class B {
304 public:
b()305 virtual void b(){}
306 // CHECK64: FieldDecl=b_field:[[@LINE+2]]:8 (Definition) [type=long] [typekind=Long] [sizeof=8] [alignof=8] [offsetof=64]
307 // CHECK32: FieldDecl=b_field:[[@LINE+1]]:8 (Definition) [type=long] [typekind=Long] [sizeof=4] [alignof=4] [offsetof=32]
308 long b_field;
309 protected:
310 private:
311 };
312
313 // CHECK32: ClassDecl=A:[[@LINE+1]]:7 (Definition) [type=Test3::A] [typekind=Record] [sizeof=16] [alignof=4]
314 class A : public B {
315 public:
316 // CHECK64: FieldDecl=a_field:[[@LINE+2]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=128]
317 // CHECK32: FieldDecl=a_field:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64]
318 int a_field;
a()319 virtual void a(){}
320 // CHECK64: FieldDecl=one:[[@LINE+2]]:8 (Definition) [type=char] [typekind=Char_S] [sizeof=1] [alignof=1] [offsetof=160]
321 // CHECK32: FieldDecl=one:[[@LINE+1]]:8 (Definition) [type=char] [typekind=Char_S] [sizeof=1] [alignof=1] [offsetof=96]
322 char one;
323 protected:
324 private:
325 };
326
327 // CHECK64: ClassDecl=D:[[@LINE+2]]:7 (Definition) [type=Test3::D] [typekind=Record] [sizeof=16] [alignof=8]
328 // CHECK32: ClassDecl=D:[[@LINE+1]]:7 (Definition) [type=Test3::D] [typekind=Record] [sizeof=12] [alignof=4]
329 class D {
330 public:
b()331 virtual void b(){}
332 // CHECK64: FieldDecl=a:[[@LINE+2]]:10 (Definition) [type=double] [typekind=Double] [sizeof=8] [alignof=8] [offsetof=64]
333 // CHECK32: FieldDecl=a:[[@LINE+1]]:10 (Definition) [type=double] [typekind=Double] [sizeof=8] [alignof=4] [offsetof=32]
334 double a;
335 };
336
337 // CHECK64: ClassDecl=C:[[@LINE+2]]:7 (Definition) [type=Test3::C] [typekind=Record] [sizeof=88] [alignof=8]
338 // CHECK32: ClassDecl=C:[[@LINE+1]]:7 (Definition) [type=Test3::C] [typekind=Record] [sizeof=60] [alignof=4]
339 class C : public virtual A,
340 public D, public B {
341 public:
342 double c1_field;
343 int c2_field;
344 double c3_field;
345 int c4_field;
foo()346 virtual void foo(){}
bar()347 virtual void bar(){}
348 protected:
349 private:
350 };
351
352 struct BaseStruct
353 {
BaseStructTest3::BaseStruct354 BaseStruct(){}
355 double v0;
356 float v1;
357 // CHECK64: FieldDecl=fg:[[@LINE+2]]:7 (Definition) [type=Test3::C] [typekind=Record] [sizeof=88] [alignof=8] [offsetof=128]
358 // CHECK32: FieldDecl=fg:[[@LINE+1]]:7 (Definition) [type=Test3::C] [typekind=Record] [sizeof=60] [alignof=4] [offsetof=96]
359 C fg;
360 // CHECK64: FieldDecl=rg:[[@LINE+2]]:8 (Definition) [type=Test3::C &] [typekind=LValueReference] [sizeof=88] [alignof=8] [offsetof=832]
361 // CHECK32: FieldDecl=rg:[[@LINE+1]]:8 (Definition) [type=Test3::C &] [typekind=LValueReference] [sizeof=60] [alignof=4] [offsetof=576]
362 C &rg;
363 int x;
364 };
365
366 }
367
368 namespace NotConstantSize {
369
f(int i)370 void f(int i) {
371 // CHECK32: VarDecl=v2:[[@LINE+1]]:8 (Definition) [type=int [i]] [typekind=VariableArray] [sizeof=-4] [alignof=4]
372 int v2[i];
373 {
374 struct CS1 {
375 int f1[i];
376 float f2;
377 };
378 }
379 }
380
381 }
382
383 namespace CrashTest {
384 // test crash scenarios on dependent types.
385 template<typename T>
386 struct Foo {
387 T t;
388 int a;
389 };
390
391 Foo<Sizes::A> t1;
392 Foo<Sizes::I> t2;
393
394 void c;
395
396 plopplop;
397
398 // CHECK64: StructDecl=lastValid:[[@LINE+2]]:8 (Definition) [type=CrashTest::lastValid] [typekind=Record] [sizeof=1] [alignof=1]
399 // CHECK32: StructDecl=lastValid:[[@LINE+1]]:8 (Definition) [type=CrashTest::lastValid] [typekind=Record] [sizeof=1] [alignof=1]
400 struct lastValid {
401 };
402
403 }
404