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
5namespace 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]
9void 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]
13void *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]
18struct 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]
42union 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]
50simple s1;
51
52struct 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
61struct 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]
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]
74          int foobar;
75        };
76    };
77  };
78};
79
80}
81
82// these are test crash. Offsetof return values are not important.
83namespace Incomplete {
84// test that fields in incomplete named record do not crash
85union 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
99union 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
113struct 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
122struct 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
129struct 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
138struct 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
155struct s4a {
156  struct forward_decl2 g1;
157  struct {
158   struct forward_decl2 g2;
159    struct {
160      struct {
161        struct {
162          struct {
163            int s4_e1;
164          };
165        };
166      };
167    };
168    int s4_e3;
169  };
170};
171
172//deep anonymous with sub-first-level incomplete
173struct s4b {
174  struct {
175    struct forward_decl2 g1;
176    struct {
177      struct {
178        struct {
179          struct {
180            int s4b_e1;
181          };
182        };
183      };
184    };
185    int s4b_e3;
186  };
187};
188
189//named struct within anonymous struct
190struct s5 {
191  struct {
192    struct x {
193      int i;
194    };
195  };
196};
197
198// CHECK64: StructDecl=As:[[@LINE+1]]:8 [type=Incomplete::As] [typekind=Record]
199struct As;
200
201// undefined class. Should not crash
202// CHECK64: ClassDecl=A:[[@LINE+1]]:7 [type=Incomplete::A] [typekind=Record]
203class A;
204class B {
205  A* a1;
206  A& a2;
207};
208
209}
210
211namespace Sizes {
212
213// CHECK64: StructDecl=A:[[@LINE+2]]:8 (Definition) [type=Sizes::A] [typekind=Record] [sizeof=8] [alignof=4]
214// CHECK32: StructDecl=A:[[@LINE+1]]:8 (Definition) [type=Sizes::A] [typekind=Record] [sizeof=8] [alignof=4]
215struct A {
216  int a;
217  char b;
218};
219
220// CHECK64: StructDecl=B:[[@LINE+2]]:8 (Definition) [type=Sizes::B] [typekind=Record] [sizeof=12] [alignof=4]
221// CHECK32: StructDecl=B:[[@LINE+1]]:8 (Definition) [type=Sizes::B] [typekind=Record] [sizeof=12] [alignof=4]
222struct B : A {
223  char c;
224};
225
226// CHECK64: StructDecl=C:[[@LINE+2]]:8 (Definition) [type=Sizes::C] [typekind=Record] [sizeof=8] [alignof=4]
227// CHECK32: StructDecl=C:[[@LINE+1]]:8 (Definition) [type=Sizes::C] [typekind=Record] [sizeof=8] [alignof=4]
228struct C {
229// Make fields private so C won't be a POD type.
230private:
231  int a;
232  char b;
233};
234
235// CHECK64: StructDecl=D:[[@LINE+2]]:8 (Definition) [type=Sizes::D] [typekind=Record] [sizeof=8] [alignof=4]
236// CHECK32: StructDecl=D:[[@LINE+1]]:8 (Definition) [type=Sizes::D] [typekind=Record] [sizeof=8] [alignof=4]
237struct D : C {
238  char c;
239};
240
241// CHECK64: StructDecl=E:[[@LINE+2]]:32 (Definition) [type=Sizes::E] [typekind=Record] [sizeof=5] [alignof=1]
242// CHECK32: StructDecl=E:[[@LINE+1]]:32 (Definition) [type=Sizes::E] [typekind=Record] [sizeof=5] [alignof=1]
243struct __attribute__((packed)) E {
244  char b;
245  int a;
246};
247
248// CHECK64: StructDecl=F:[[@LINE+2]]:32 (Definition) [type=Sizes::F] [typekind=Record] [sizeof=6] [alignof=1]
249// CHECK32: StructDecl=F:[[@LINE+1]]:32 (Definition) [type=Sizes::F] [typekind=Record] [sizeof=6] [alignof=1]
250struct __attribute__((packed)) F : E {
251  char d;
252};
253
254struct G { G(); };
255// CHECK64: StructDecl=H:[[@LINE+2]]:8 (Definition) [type=Sizes::H] [typekind=Record] [sizeof=1] [alignof=1]
256// CHECK32: StructDecl=H:[[@LINE+1]]:8 (Definition) [type=Sizes::H] [typekind=Record] [sizeof=1] [alignof=1]
257struct H : G { };
258
259// CHECK64: StructDecl=I:[[@LINE+2]]:8 (Definition) [type=Sizes::I] [typekind=Record] [sizeof=5] [alignof=1]
260// CHECK32: StructDecl=I:[[@LINE+1]]:8 (Definition) [type=Sizes::I] [typekind=Record] [sizeof=5] [alignof=1]
261struct I {
262  char b;
263  int a;
264} __attribute__((packed));
265
266}
267
268namespace Test1 {
269
270// Test complex class hierarchy
271struct A { };
272struct B : A { virtual void b(); };
273class C : virtual A { int c; };
274struct D : virtual B { };
275struct E : C, virtual D { };
276class F : virtual E { };
277// CHECK64: StructDecl=G:[[@LINE+2]]:8 (Definition) [type=Test1::G] [typekind=Record] [sizeof=24] [alignof=8]
278// CHECK32: StructDecl=G:[[@LINE+1]]:8 (Definition) [type=Test1::G] [typekind=Record] [sizeof=16] [alignof=4]
279struct G : virtual E, F { };
280
281}
282
283namespace Test2 {
284
285// Test that this somewhat complex class structure is laid out correctly.
286struct A { };
287struct B : A { virtual void b(); };
288struct C : virtual B { };
289struct D : virtual A { };
290struct E : virtual B, D { };
291struct F : E, virtual C { };
292struct G : virtual F, A { };
293// CHECK64: StructDecl=H:[[@LINE+2]]:8 (Definition) [type=Test2::H] [typekind=Record] [sizeof=24] [alignof=8]
294// CHECK32: StructDecl=H:[[@LINE+1]]:8 (Definition) [type=Test2::H] [typekind=Record] [sizeof=12] [alignof=4]
295struct H { G g; };
296
297}
298
299namespace Test3 {
300// CHECK64: ClassDecl=B:[[@LINE+2]]:7 (Definition) [type=Test3::B] [typekind=Record] [sizeof=16] [alignof=8]
301// CHECK32: ClassDecl=B:[[@LINE+1]]:7 (Definition) [type=Test3::B] [typekind=Record] [sizeof=8] [alignof=4]
302class B {
303public:
304  virtual void b(){}
305// CHECK64: FieldDecl=b_field:[[@LINE+2]]:8 (Definition) [type=long] [typekind=Long] [sizeof=8] [alignof=8] [offsetof=64]
306// CHECK32: FieldDecl=b_field:[[@LINE+1]]:8 (Definition) [type=long] [typekind=Long] [sizeof=4] [alignof=4] [offsetof=32]
307  long b_field;
308protected:
309private:
310};
311
312// CHECK32: ClassDecl=A:[[@LINE+1]]:7 (Definition) [type=Test3::A] [typekind=Record] [sizeof=16] [alignof=4]
313class A : public B {
314public:
315// CHECK64: FieldDecl=a_field:[[@LINE+2]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=128]
316// CHECK32: FieldDecl=a_field:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64]
317  int a_field;
318  virtual void a(){}
319// CHECK64: FieldDecl=one:[[@LINE+2]]:8 (Definition) [type=char] [typekind=Char_S] [sizeof=1] [alignof=1] [offsetof=160]
320// CHECK32: FieldDecl=one:[[@LINE+1]]:8 (Definition) [type=char] [typekind=Char_S] [sizeof=1] [alignof=1] [offsetof=96]
321  char one;
322protected:
323private:
324};
325
326// CHECK64: ClassDecl=D:[[@LINE+2]]:7 (Definition) [type=Test3::D] [typekind=Record] [sizeof=16] [alignof=8]
327// CHECK32: ClassDecl=D:[[@LINE+1]]:7 (Definition) [type=Test3::D] [typekind=Record] [sizeof=12] [alignof=4]
328class D {
329public:
330  virtual void b(){}
331// CHECK64: FieldDecl=a:[[@LINE+2]]:10 (Definition) [type=double] [typekind=Double] [sizeof=8] [alignof=8] [offsetof=64]
332// CHECK32: FieldDecl=a:[[@LINE+1]]:10 (Definition) [type=double] [typekind=Double] [sizeof=8] [alignof=4] [offsetof=32]
333  double a;
334};
335
336// CHECK64: ClassDecl=C:[[@LINE+2]]:7 (Definition) [type=Test3::C] [typekind=Record] [sizeof=88] [alignof=8]
337// CHECK32: ClassDecl=C:[[@LINE+1]]:7 (Definition) [type=Test3::C] [typekind=Record] [sizeof=60] [alignof=4]
338class C : public virtual A,
339          public D, public B {
340public:
341  double c1_field;
342  int c2_field;
343  double c3_field;
344  int c4_field;
345  virtual void foo(){}
346  virtual void bar(){}
347protected:
348private:
349};
350
351struct BaseStruct
352{
353    BaseStruct(){}
354    double v0;
355    float v1;
356// CHECK64: FieldDecl=fg:[[@LINE+2]]:7 (Definition) [type=Test3::C] [typekind=Record] [sizeof=88] [alignof=8] [offsetof=128]
357// CHECK32: FieldDecl=fg:[[@LINE+1]]:7 (Definition) [type=Test3::C] [typekind=Record] [sizeof=60] [alignof=4] [offsetof=96]
358    C fg;
359// CHECK64: FieldDecl=rg:[[@LINE+2]]:8 (Definition) [type=Test3::C &] [typekind=LValueReference] [sizeof=88] [alignof=8] [offsetof=832]
360// CHECK32: FieldDecl=rg:[[@LINE+1]]:8 (Definition) [type=Test3::C &] [typekind=LValueReference] [sizeof=60] [alignof=4] [offsetof=576]
361    C &rg;
362    int x;
363};
364
365}
366
367namespace NotConstantSize {
368
369void f(int i) {
370// CHECK32: VarDecl=v2:[[@LINE+1]]:8 (Definition) [type=int [i]] [typekind=VariableArray] [sizeof=-4] [alignof=4]
371   int v2[i];
372   {
373   struct CS1 {
374     int f1[i];
375     float f2;
376   };
377   }
378}
379
380}
381
382namespace CrashTest {
383// test crash scenarios on dependent types.
384template<typename T>
385struct Foo {
386  T t;
387  int a;
388};
389
390Foo<Sizes::A> t1;
391Foo<Sizes::I> t2;
392
393void c;
394
395plopplop;
396
397// CHECK64: StructDecl=lastValid:[[@LINE+2]]:8 (Definition) [type=CrashTest::lastValid] [typekind=Record] [sizeof=1] [alignof=1]
398// CHECK32: StructDecl=lastValid:[[@LINE+1]]:8 (Definition) [type=CrashTest::lastValid] [typekind=Record] [sizeof=1] [alignof=1]
399struct lastValid {
400};
401
402}
403