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] 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. 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 int s4_e1; 164 }; 165 }; 166 }; 167 }; 168 int s4_e3; 169 }; 170 }; 171 172 //deep anonymous with sub-first-level incomplete 173 struct 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 190 struct 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] 199 struct As; 200 201 // undefined class. Should not crash 202 // CHECK64: ClassDecl=A:[[@LINE+1]]:7 [type=Incomplete::A] [typekind=Record] 203 class A; 204 class B { 205 A* a1; 206 A& a2; 207 }; 208 209 } 210 211 namespace 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] 215 struct 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] 222 struct 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] 228 struct C { 229 // Make fields private so C won't be a POD type. 230 private: 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] 237 struct 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] 243 struct __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] 250 struct __attribute__((packed)) F : E { 251 char d; 252 }; 253 254 struct 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] 257 struct 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] 261 struct I { 262 char b; 263 int a; 264 } __attribute__((packed)); 265 266 } 267 268 namespace Test1 { 269 270 // Test complex class hierarchy 271 struct A { }; 272 struct B : A { virtual void b(); }; 273 class C : virtual A { int c; }; 274 struct D : virtual B { }; 275 struct E : C, virtual D { }; 276 class 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] 279 struct G : virtual E, F { }; 280 281 } 282 283 namespace Test2 { 284 285 // Test that this somewhat complex class structure is laid out correctly. 286 struct A { }; 287 struct B : A { virtual void b(); }; 288 struct C : virtual B { }; 289 struct D : virtual A { }; 290 struct E : virtual B, D { }; 291 struct F : E, virtual C { }; 292 struct 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] 295 struct H { G g; }; 296 297 } 298 299 namespace 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] 302 class B { 303 public: 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; 308 protected: 309 private: 310 }; 311 312 // CHECK32: ClassDecl=A:[[@LINE+1]]:7 (Definition) [type=Test3::A] [typekind=Record] [sizeof=16] [alignof=4] 313 class A : public B { 314 public: 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; 322 protected: 323 private: 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] 328 class D { 329 public: 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] 338 class C : public virtual A, 339 public D, public B { 340 public: 341 double c1_field; 342 int c2_field; 343 double c3_field; 344 int c4_field; 345 virtual void foo(){} 346 virtual void bar(){} 347 protected: 348 private: 349 }; 350 351 struct 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 367 namespace NotConstantSize { 368 369 void 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 382 namespace CrashTest { 383 // test crash scenarios on dependent types. 384 template<typename T> 385 struct Foo { 386 T t; 387 int a; 388 }; 389 390 Foo<Sizes::A> t1; 391 Foo<Sizes::I> t2; 392 393 void c; 394 395 plopplop; 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] 399 struct lastValid { 400 }; 401 402 } 403