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/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.
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//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
174struct 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
191struct 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]
200struct As;
201
202// undefined class. Should not crash
203// CHECK64: ClassDecl=A:[[@LINE+1]]:7 [type=Incomplete::A] [typekind=Record]
204class A;
205class B {
206  A* a1;
207  A& a2;
208};
209
210}
211
212namespace 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]
216struct 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]
223struct 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]
229struct C {
230// Make fields private so C won't be a POD type.
231private:
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]
238struct 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]
244struct __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]
251struct __attribute__((packed)) F : E {
252  char d;
253};
254
255struct 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]
258struct 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]
262struct I {
263  char b;
264  int a;
265} __attribute__((packed));
266
267}
268
269namespace Test1 {
270
271// Test complex class hierarchy
272struct A { };
273struct B : A { virtual void b(); };
274class C : virtual A { int c; };
275struct D : virtual B { };
276struct E : C, virtual D { };
277class 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]
280struct G : virtual E, F { };
281
282}
283
284namespace Test2 {
285
286// Test that this somewhat complex class structure is laid out correctly.
287struct A { };
288struct B : A { virtual void b(); };
289struct C : virtual B { };
290struct D : virtual A { };
291struct E : virtual B, D { };
292struct F : E, virtual C { };
293struct 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]
296struct H { G g; };
297
298}
299
300namespace 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]
303class B {
304public:
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;
309protected:
310private:
311};
312
313// CHECK32: ClassDecl=A:[[@LINE+1]]:7 (Definition) [type=Test3::A] [typekind=Record] [sizeof=16] [alignof=4]
314class A : public B {
315public:
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;
323protected:
324private:
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]
329class D {
330public:
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]
339class C : public virtual A,
340          public D, public B {
341public:
342  double c1_field;
343  int c2_field;
344  double c3_field;
345  int c4_field;
346  virtual void foo(){}
347  virtual void bar(){}
348protected:
349private:
350};
351
352struct 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
368namespace NotConstantSize {
369
370void 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
383namespace CrashTest {
384// test crash scenarios on dependent types.
385template<typename T>
386struct Foo {
387  T t;
388  int a;
389};
390
391Foo<Sizes::A> t1;
392Foo<Sizes::I> t2;
393
394void c;
395
396plopplop;
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]
400struct lastValid {
401};
402
403}
404