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