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) (invalid) [type=void] [typekind=Void] |
8 | // CHECK32: VarDecl=v:[[@LINE+1]]:6 (Definition) (invalid) [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: |
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; |
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: |
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; |
346 | virtual void foo(){} |
347 | virtual void bar(){} |
348 | protected: |
349 | private: |
350 | }; |
351 | |
352 | struct BaseStruct |
353 | { |
354 | 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 | |
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 | // CHECK64: CXXMethod=Tie:[[@LINE+3]]:8 (const) [type=auto (void *) const] [typekind=FunctionProto] [sizeof=1] [alignof=4] [resulttype=auto] [resulttypekind=Auto] [resultsizeof=-6] [resultalignof=-6] |
404 | // CHECK32: CXXMethod=Tie:[[@LINE+2]]:8 (const) [type=auto (void *) const] [typekind=FunctionProto] [sizeof=1] [alignof=4] [resulttype=auto] [resulttypekind=Auto] [resultsizeof=-6] [resultalignof=-6] |
405 | class BrowsingContext { |
406 | auto Tie(void*) const; |
407 | }; |
408 | |
409 | } |
410 | |