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