Home | History | Annotate | Download | only in Sema
      1 // RUN: %clang_cc1 -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts %s 2>/dev/null \
      2 // RUN:            | FileCheck %s
      3 
      4 #pragma pack(push, 8)
      5 
      6 class B {
      7 public:
      8   virtual void b(){}
      9   int b_field;
     10 protected:
     11 private:
     12 };
     13 
     14 class A : public B {
     15 public:
     16   int a_field;
     17   virtual void a(){}
     18   char one;
     19 protected:
     20 private:
     21 };
     22 
     23 class D {
     24 public:
     25   virtual void b(){}
     26   double a;
     27 };
     28 
     29 class C : public virtual A,
     30           public D, public B {
     31 public:
     32   double c1_field;
     33   int c2_field;
     34   double c3_field;
     35   int c4_field;
     36   virtual void foo(){}
     37   virtual void bar(){}
     38 protected:
     39 private:
     40 };
     41 
     42 struct BaseStruct
     43 {
     44     BaseStruct(){}
     45     double v0;
     46     float v1;
     47     C fg;
     48 };
     49 
     50 struct DerivedStruct : public BaseStruct {
     51   int x;
     52 };
     53 
     54 struct G
     55 {
     56     int g_field;
     57 };
     58 
     59 struct H : public G,
     60            public virtual D
     61 {
     62 };
     63 
     64 struct I : public virtual D
     65 {
     66   virtual ~I(){}
     67   double q;
     68 };
     69 
     70 struct K
     71 {
     72   int k;
     73 };
     74 
     75 struct L
     76 {
     77   int l;
     78 };
     79 
     80 struct M : public virtual K
     81 {
     82   int m;
     83 };
     84 
     85 struct N : public L, public M
     86 {
     87   virtual void f(){}
     88 };
     89 
     90 struct O : public H, public G {
     91   virtual void fo(){}
     92 };
     93 
     94 struct P : public M, public virtual L {
     95   int p;
     96 };
     97 
     98 struct R {};
     99 
    100 class IA {
    101 public:
    102   virtual ~IA(){}
    103   virtual void ia() = 0;
    104 };
    105 
    106 class ICh : public virtual IA {
    107 public:
    108   virtual ~ICh(){}
    109   virtual void ia(){}
    110   virtual void iCh(){}
    111 };
    112 
    113 struct f {
    114   virtual int asd() {return -90;}
    115 };
    116 
    117 struct s : public virtual f {
    118   virtual ~s(){}
    119   int r;
    120   virtual int asd() {return -9;}
    121 };
    122 
    123 struct sd : virtual s, virtual ICh {
    124   virtual ~sd(){}
    125   int q;
    126   char y;
    127   virtual int asd() {return -1;}
    128 };
    129 struct AV {
    130   virtual void foo();
    131 };
    132 struct BV : AV {
    133 };
    134 struct CV : virtual BV {
    135   CV();
    136   virtual void foo();
    137 };
    138 struct DV : BV {
    139 };
    140 struct EV : CV, DV {
    141 };
    142 #pragma pack(pop)
    143 
    144 // This needs only for building layouts.
    145 // Without this clang doesn`t dump record layouts.
    146 int main() {
    147   // This avoid "Can't yet mangle constructors!" for MS ABI.
    148   C* c;
    149   c->foo();
    150   DerivedStruct* v;
    151   H* g;
    152   BaseStruct* u;
    153   I* i;
    154   N* n;
    155   O* o;
    156   P* p;
    157   R* r;
    158   sd *h;
    159   EV *j;
    160   return 0;
    161 }
    162 
    163 // CHECK:       0 | class D
    164 // CHECK-NEXT:  0 |   (D vftable pointer)
    165 // CHECK-NEXT:  8 |   double a
    166 
    167 // CHECK-NEXT: sizeof=16, align=8
    168 // CHECK-NEXT: nvsize=16, nvalign=8
    169 
    170 // CHECK: %class.D = type { i32 (...)**, double }
    171 
    172 // CHECK:       0 | class B
    173 // CHECK-NEXT:  0 |   (B vftable pointer)
    174 // CHECK-NEXT:  4 |   int b_field
    175 
    176 // CHECK-NEXT: sizeof=8, align=4
    177 // CHECK-NEXT: nvsize=8, nvalign=4
    178 
    179 // CHECK: %class.B = type { i32 (...)**, i32 }
    180 
    181 // CHECK:       0 | class A
    182 // CHECK-NEXT:  0 |   class B (primary base)
    183 // CHECK-NEXT:  0 |     (B vftable pointer)
    184 // CHECK-NEXT:  4 |     int b_field
    185 // CHECK-NEXT:  8 |   int a_field
    186 // CHECK-NEXT: 12 |   char one
    187 
    188 // CHECK-NEXT: sizeof=16, align=4
    189 // CHECK-NEXT: nvsize=16, nvalign=4
    190 
    191 // CHECK:       0 | class C
    192 // CHECK-NEXT:  0 |   class D (primary base)
    193 // CHECK-NEXT:  0 |     (D vftable pointer)
    194 // CHECK-NEXT:  8 |     double a
    195 // CHECK-NEXT: 16 |   class B (base)
    196 // CHECK-NEXT: 16 |     (B vftable pointer)
    197 // CHECK-NEXT: 20 |     int b_field
    198 // CHECK-NEXT: 24 |   (C vbtable pointer)
    199 // CHECK-NEXT: 32 |   double c1_field
    200 // CHECK-NEXT: 40 |   int c2_field
    201 // CHECK-NEXT: 48 |   double c3_field
    202 // CHECK-NEXT: 56 |   int c4_field
    203 // CHECK-NEXT: 64 |   class A (virtual base)
    204 // CHECK-NEXT: 64 |     class B (primary base)
    205 // CHECK-NEXT: 64 |       (B vftable pointer)
    206 // CHECK-NEXT: 68 |       int b_field
    207 // CHECK-NEXT: 72 |     int a_field
    208 // CHECK-NEXT: 76 |     char one
    209 
    210 // CHECK-NEXT: sizeof=80, align=8
    211 // CHECK-NEXT: nvsize=64, nvalign=8
    212 
    213 // CHECK: %class.A = type { %class.B, i32, i8 }
    214 
    215 // CHECK: %class.C = type { %class.D, %class.B, i32*, double, i32, double, i32, [4 x i8], %class.A }
    216 // CHECK: %class.C.base = type { %class.D, %class.B, i32*, double, i32, double, i32 }
    217 
    218 // CHECK:       0 | struct BaseStruct
    219 // CHECK-NEXT:  0 |   double v0
    220 // CHECK-NEXT:  8 |   float v1
    221 // CHECK-NEXT: 16 |   class C fg
    222 // CHECK-NEXT: 16 |     class D (primary base)
    223 // CHECK-NEXT: 16 |       (D vftable pointer)
    224 // CHECK-NEXT: 24 |       double a
    225 // CHECK-NEXT: 32 |     class B (base)
    226 // CHECK-NEXT: 32 |       (B vftable pointer)
    227 // CHECK-NEXT: 36 |       int b_field
    228 // CHECK-NEXT: 40 |     (C vbtable pointer)
    229 // CHECK-NEXT: 48 |     double c1_field
    230 // CHECK-NEXT: 56 |     int c2_field
    231 // CHECK-NEXT: 64 |     double c3_field
    232 // CHECK-NEXT: 72 |     int c4_field
    233 // CHECK-NEXT: 80 |     class A (virtual base)
    234 // CHECK-NEXT: 80 |       class B (primary base)
    235 // CHECK-NEXT: 80 |         (B vftable pointer)
    236 // CHECK-NEXT: 84 |         int b_field
    237 // CHECK-NEXT: 88 |       int a_field
    238 // CHECK-NEXT: 92 |       char one
    239 // CHECK-NEXT: sizeof=96, align=8
    240 // CHECK-NEXT: nvsize=96, nvalign=8
    241 
    242 // CHECK: %struct.BaseStruct = type { double, float, %class.C }
    243 
    244 // CHECK:       0 | struct DerivedStruct
    245 // CHECK-NEXT:  0 |   struct BaseStruct (base)
    246 // CHECK-NEXT:  0 |     double v0
    247 // CHECK-NEXT:  8 |     float v1
    248 // CHECK-NEXT: 16 |     class C fg
    249 // CHECK-NEXT: 16 |       class D (primary base)
    250 // CHECK-NEXT: 16 |         (D vftable pointer)
    251 // CHECK-NEXT: 24 |         double a
    252 // CHECK-NEXT: 32 |       class B (base)
    253 // CHECK-NEXT: 32 |         (B vftable pointer)
    254 // CHECK-NEXT: 36 |         int b_field
    255 // CHECK-NEXT: 40 |       (C vbtable pointer)
    256 // CHECK-NEXT: 48 |       double c1_field
    257 // CHECK-NEXT: 56 |       int c2_field
    258 // CHECK-NEXT: 64 |       double c3_field
    259 // CHECK-NEXT: 72 |       int c4_field
    260 // CHECK-NEXT: 80 |       class A (virtual base)
    261 // CHECK-NEXT: 80 |         class B (primary base)
    262 // CHECK-NEXT: 80 |           (B vftable pointer)
    263 // CHECK-NEXT: 84 |           int b_field
    264 // CHECK-NEXT: 88 |         int a_field
    265 // CHECK-NEXT: 92 |         char one
    266 // CHECK-NEXT: 96 |   int x
    267 // CHECK-NEXT: sizeof=104, align=8
    268 // CHECK-NEXT: nvsize=104, nvalign=8
    269 
    270 // CHECK: %struct.DerivedStruct = type { %struct.BaseStruct, i32 }
    271 
    272 // CHECK:      0 | struct G
    273 // CHECK-NEXT: 0 |   int g_field
    274 // CHECK-NEXT: sizeof=4, align=4
    275 // CHECK-NEXT: nvsize=4, nvalign=4
    276 
    277 // CHECK:       0 | struct H
    278 // CHECK-NEXT:  0 |   struct G (base)
    279 // CHECK-NEXT:  0 |     int g_field
    280 // CHECK-NEXT:  4 |   (H vbtable pointer)
    281 // CHECK-NEXT:  8 |   class D (virtual base)
    282 // CHECK-NEXT:  8 |     (D vftable pointer)
    283 // CHECK-NEXT: 16 |     double a
    284 // CHECK-NEXT: sizeof=24, align=8
    285 // CHECK-NEXT: nvsize=8, nvalign=8
    286 
    287 // CHECK: %struct.H = type { %struct.G, i32*, %class.D }
    288 
    289 // CHECK:       0 | struct I
    290 // CHECK-NEXT:  0 |   (I vftable pointer)
    291 // CHECK-NEXT:  8 |   (I vbtable pointer)
    292 // CHECK-NEXT: 16 |   double q
    293 // CHECK-NEXT: 24 |   class D (virtual base)
    294 // CHECK-NEXT: 24 |     (D vftable pointer)
    295 // CHECK-NEXT: 32 |     double a
    296 // CHECK-NEXT: sizeof=40, align=8
    297 // CHECK-NEXT: nvsize=24, nvalign=8
    298 
    299 // CHECK: %struct.I = type { i32 (...)**, [4 x i8], i32*, double, %class.D }
    300 // CHECK: %struct.I.base = type { i32 (...)**, [4 x i8], i32*, double }
    301 
    302 // CHECK:       0 | struct L
    303 // CHECK-NEXT:  0 |   int l
    304 // CHECK-NEXT: sizeof=4, align=4
    305 // CHECK-NEXT: nvsize=4, nvalign=4
    306 
    307 // CHECK:       0 | struct K
    308 // CHECK-NEXT:  0 |   int k
    309 // CHECK-NEXT: sizeof=4, align=4
    310 // CHECK-NEXT: nvsize=4, nvalign=4
    311 
    312 // CHECK:       0 | struct M
    313 // CHECK-NEXT:  0 |   (M vbtable pointer)
    314 // CHECK-NEXT:  4 |   int m
    315 // CHECK-NEXT:  8 |   struct K (virtual base)
    316 // CHECK-NEXT:  8 |     int k
    317 // CHECK-NEXT: sizeof=12, align=4
    318 
    319 //CHECK: %struct.M = type { i32*, i32, %struct.K }
    320 //CHECK: %struct.M.base = type { i32*, i32 }
    321 
    322 // CHECK:       0 | struct N
    323 // CHECK-NEXT:  0 |   (N vftable pointer)
    324 // CHECK-NEXT:  4 |   struct L (base)
    325 // CHECK-NEXT:  4 |     int l
    326 // CHECK-NEXT:  8 |   struct M (base)
    327 // CHECK-NEXT:  8 |     (M vbtable pointer)
    328 // CHECK-NEXT: 12 |     int m
    329 // CHECK-NEXT: 16 |   struct K (virtual base)
    330 // CHECK-NEXT: 16 |     int k
    331 // CHECK-NEXT: sizeof=20, align=4
    332 // CHECK-NEXT: nvsize=16, nvalign=4
    333 
    334 //CHECK: %struct.N = type { i32 (...)**, %struct.L, %struct.M.base, %struct.K }
    335 
    336 // CHECK:       0 | struct O
    337 // CHECK-NEXT:  0 |   (O vftable pointer)
    338 // CHECK-NEXT:  8 |   struct H (base)
    339 // CHECK-NEXT:  8 |     struct G (base)
    340 // CHECK-NEXT:  8 |       int g_field
    341 // CHECK-NEXT: 12 |     (H vbtable pointer)
    342 // CHECK-NEXT: 16 |   struct G (base)
    343 // CHECK-NEXT: 16 |     int g_field
    344 // CHECK-NEXT: 24 |   class D (virtual base)
    345 // CHECK-NEXT: 24 |     (D vftable pointer)
    346 // CHECK-NEXT: 32 |     double a
    347 // CHECK-NEXT:    | [sizeof=40, align=8
    348 // CHECK-NEXT:    |  nvsize=24, nvalign=8]
    349 
    350 // CHECK: struct.O = type { i32 (...)**, [4 x i8], %struct.H.base, %struct.G, %class.D }
    351 // CHECK: struct.O.base = type { i32 (...)**, [4 x i8], %struct.H.base, %struct.G, [4 x i8] }
    352 
    353 
    354 // CHECK:       0 | struct P
    355 // CHECK-NEXT:  0 |   struct M (base)
    356 // CHECK-NEXT:  0 |     (M vbtable pointer)
    357 // CHECK-NEXT:  4 |     int m
    358 // CHECK-NEXT:  8 |   int p
    359 // CHECK-NEXT: 12 |   struct K (virtual base)
    360 // CHECK-NEXT: 12 |     int k
    361 // CHECK-NEXT: 16 |   struct L (virtual base)
    362 // CHECK-NEXT: 16 |     int l
    363 // CHECK-NEXT: sizeof=20, align=4
    364 // CHECK-NEXT: nvsize=12, nvalign=4
    365 
    366 //CHECK: %struct.P = type { %struct.M.base, i32, %struct.K, %struct.L }
    367 
    368 // CHECK:       0 | struct R (empty)
    369 // CHECK-NEXT:  sizeof=1, align=1
    370 // CHECK-NEXT:  nvsize=0, nvalign=1
    371 
    372 //CHECK: %struct.R = type { i8 }
    373 
    374 // CHECK:       0 | struct f
    375 // CHECK-NEXT:  0 |   (f vftable pointer)
    376 // CHECK-NEXT: sizeof=4, align=4
    377 // CHECK-NEXT: nvsize=4, nvalign=4
    378 
    379 // CHECK:       0 | struct s
    380 // CHECK-NEXT:  0 |   (s vftable pointer)
    381 // CHECK-NEXT:  4 |   (s vbtable pointer)
    382 // CHECK-NEXT:  8 |   int r
    383 // CHECK-NEXT: 12 |   (vtordisp for vbase f)
    384 // CHECK-NEXT: 16 |   struct f (virtual base)
    385 // CHECK-NEXT: 16 |     (f vftable pointer)
    386 // CHECK-NEXT: sizeof=20, align=4
    387 // CHECK-NEXT: nvsize=12, nvalign=4
    388 
    389 // CHECK:       0 | class IA
    390 // CHECK-NEXT:  0 |   (IA vftable pointer)
    391 // CHECK-NEXT:  sizeof=4, align=4
    392 // CHECK-NEXT:  nvsize=4, nvalign=4
    393 
    394 // CHECK:       0 | class ICh
    395 // CHECK-NEXT:  0 |   (ICh vftable pointer)
    396 // CHECK-NEXT:  4 |   (ICh vbtable pointer)
    397 // CHECK-NEXT:  8 |   (vtordisp for vbase IA)
    398 // CHECK-NEXT: 12 |   class IA (virtual base)
    399 // CHECK-NEXT: 12 |     (IA vftable pointer)
    400 // CHECK-NEXT: sizeof=16, align=4
    401 // CHECK-NEXT: nvsize=8, nvalign=4
    402 
    403 // CHECK:       0 | struct sd
    404 // CHECK-NEXT:  0 |   (sd vbtable pointer)
    405 // CHECK-NEXT:  4 |   int q
    406 // CHECK-NEXT:  8 |   char y
    407 // CHECK-NEXT: 12 |   (vtordisp for vbase f)
    408 // CHECK-NEXT: 16 |   struct f (virtual base)
    409 // CHECK-NEXT: 16 |     (f vftable pointer)
    410 // CHECK-NEXT: 20 |   struct s (virtual base)
    411 // CHECK-NEXT: 20 |     (s vftable pointer)
    412 // CHECK-NEXT: 24 |     (s vbtable pointer)
    413 // CHECK-NEXT: 28 |     int r
    414 // CHECK-NEXT: 32 |   (vtordisp for vbase IA)
    415 // CHECK-NEXT: 36 |   class IA (virtual base)
    416 // CHECK-NEXT: 36 |     (IA vftable pointer)
    417 // CHECK-NEXT: 40 |   class ICh (virtual base)
    418 // CHECK-NEXT: 40 |     (ICh vftable pointer)
    419 // CHECK-NEXT: 44 |     (ICh vbtable pointer)
    420 // CHECK-NEXT: sizeof=48, align=4
    421 // CHECK-NEXT: nvsize=12, nvalign=4
    422 
    423 // CHECK: %struct.f = type { i32 (...)** }
    424 // CHECK: %struct.s = type { i32 (...)**, i32*, i32, i32, %struct.f }
    425 // CHECK: %class.IA = type { i32 (...)** }
    426 // CHECK: %class.ICh = type { i32 (...)**, i32*, i32, %class.IA }
    427 // CHECK: %struct.sd = type { i32*, i32, i8, i32, %struct.f, %struct.s.base, i32, %class.IA, %class.ICh.base }
    428 
    429 // CHECK:       0 | struct AV
    430 // CHECK-NEXT:  0 |   (AV vftable pointer)
    431 // CHECK-NEXT: sizeof=4, align=4
    432 // CHECK-NEXT: nvsize=4, nvalign=4
    433 
    434 
    435 // CHECK:       0 | struct BV
    436 // CHECK-NEXT:  0 |   struct AV (primary base)
    437 // CHECK-NEXT:  0 |     (AV vftable pointer)
    438 // CHECK-NEXT: sizeof=4, align=4
    439 // CHECK-NEXT: nvsize=4, nvalign=4
    440 
    441 
    442 // CHECK:       0 | struct CV
    443 // CHECK-NEXT:  0 |   (CV vbtable pointer)
    444 // CHECK-NEXT:  4 |   (vtordisp for vbase BV)
    445 // CHECK-NEXT:  8 |   struct BV (virtual base)
    446 // CHECK-NEXT:  8 |     struct AV (primary base)
    447 // CHECK-NEXT:  8 |       (AV vftable pointer)
    448 // CHECK-NEXT: sizeof=12, align=4
    449 // CHECK-NEXT: nvsize=4, nvalign=4
    450 
    451 // CHECK: %struct.AV = type { i32 (...)** }
    452 // CHECK: %struct.BV = type { %struct.AV }
    453 // CHECK: %struct.CV = type { i32*, i32, %struct.BV }
    454 // CHECK: %struct.CV.base = type { i32* }
    455 
    456 // CHECK:       0 | struct DV
    457 // CHECK-NEXT:  0 |   struct BV (primary base)
    458 // CHECK-NEXT:  0 |     struct AV (primary base)
    459 // CHECK-NEXT:  0 |       (AV vftable pointer)
    460 // CHECK-NEXT: sizeof=4, align=4
    461 // CHECK-NEXT: nvsize=4, nvalign=4
    462 
    463 // CHECK: %struct.DV = type { %struct.BV }
    464 
    465 // CHECK:       0 | struct EV
    466 // CHECK-NEXT:  0 |   struct DV (primary base)
    467 // CHECK-NEXT:  0 |     struct BV (primary base)
    468 // CHECK-NEXT:  0 |       struct AV (primary base)
    469 // CHECK-NEXT:  0 |         (AV vftable pointer)
    470 // CHECK-NEXT:  4 |   struct CV (base)
    471 // CHECK-NEXT:  4 |     (CV vbtable pointer)
    472 // CHECK-NEXT:  8 |   (vtordisp for vbase BV)
    473 // CHECK-NEXT: 12 |   struct BV (virtual base)
    474 // CHECK-NEXT: 12 |     struct AV (primary base)
    475 // CHECK-NEXT: 12 |       (AV vftable pointer)
    476 // CHECK-NEXT: sizeof=16, align=4
    477 // CHECK-NEXT: nvsize=8, nvalign=4
    478 
    479 // CHECK: %struct.EV = type { %struct.DV, %struct.CV.base, i32, %struct.BV }
    480 // CHECK: %struct.EV.base = type { %struct.DV, %struct.CV.base }
    481 
    482 // Overriding a method means that all the vbases containing that
    483 // method need a vtordisp.  Note: this code will cause an error in cl.exe.
    484 namespace test1 {
    485   struct A { virtual void foo(); };
    486   struct B : A {};
    487   struct C : virtual A, virtual B { C(); virtual void foo(); };
    488   void test() { C *c; }
    489 
    490 // CHECK:        0 | struct test1::C
    491 // CHECK-NEXT:   0 |   (C vbtable pointer)
    492 // CHECK-NEXT:   4 |   (vtordisp for vbase A)
    493 // CHECK-NEXT:   8 |   struct test1::A (virtual base)
    494 // CHECK-NEXT:   8 |     (A vftable pointer)
    495 // CHECK-NEXT:  12 |   (vtordisp for vbase B)
    496 // CHECK-NEXT:  16 |   struct test1::B (virtual base)
    497 // CHECK-NEXT:  16 |     struct test1::A (primary base)
    498 // CHECK-NEXT:  16 |       (A vftable pointer)
    499 // CHECK-NEXT:  sizeof=20, align=4
    500 // CHECK-NEXT:  nvsize=4, nvalign=4
    501 }
    502