xref: /aosp_15_r20/external/clang/test/Index/print-type-size.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
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