Home | History | Annotate | Download | only in Sema
      1 // RUN: %clang_cc1 -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -cxx-abi microsoft %s 2>&1 \
      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, dsize=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, dsize=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, dsize=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, dsize=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 
    240 // CHECK-NEXT: sizeof=80, dsize=80, align=8
    241 // CHECK-NEXT: nvsize=64, nvalign=8
    242 
    243 // CHECK: sizeof=96, dsize=96, align=8
    244 // CHECK-NEXT: nvsize=96, nvalign=8
    245 
    246 // CHECK: %struct.BaseStruct = type { double, float, %class.C }
    247 
    248 // CHECK:       0 | struct DerivedStruct
    249 // CHECK-NEXT:  0 |   struct BaseStruct (base)
    250 // CHECK-NEXT:  0 |     double v0
    251 // CHECK-NEXT:  8 |     float v1
    252 // CHECK-NEXT: 16 |     class C fg
    253 // CHECK-NEXT: 16 |       class D (primary base)
    254 // CHECK-NEXT: 16 |         (D vftable pointer)
    255 // CHECK-NEXT: 24 |         double a
    256 // CHECK-NEXT: 32 |       class B (base)
    257 // CHECK-NEXT: 32 |         (B vftable pointer)
    258 // CHECK-NEXT: 36 |         int b_field
    259 // CHECK-NEXT: 40 |       (C vbtable pointer)
    260 // CHECK-NEXT: 48 |       double c1_field
    261 // CHECK-NEXT: 56 |       int c2_field
    262 // CHECK-NEXT: 64 |       double c3_field
    263 // CHECK-NEXT: 72 |       int c4_field
    264 // CHECK-NEXT: 80 |       class A (virtual base)
    265 // CHECK-NEXT: 80 |         class B (primary base)
    266 // CHECK-NEXT: 80 |           (B vftable pointer)
    267 // CHECK-NEXT: 84 |           int b_field
    268 // CHECK-NEXT: 88 |         int a_field
    269 // CHECK-NEXT: 92 |         char one
    270 // CHECK-NEXT: sizeof=80, dsize=80, align=8
    271 // CHECK-NEXT: nvsize=64, nvalign=8
    272 
    273 // CHECK: 96 |   int x
    274 // CHECK-NEXT: sizeof=104, dsize=104, align=8
    275 // CHECK-NEXT: nvsize=104, nvalign=8
    276 
    277 // CHECK: %struct.DerivedStruct = type { %struct.BaseStruct, i32 }
    278 
    279 // CHECK:      0 | struct G
    280 // CHECK-NEXT: 0 |   int g_field
    281 // CHECK-NEXT: sizeof=4, dsize=4, align=4
    282 // CHECK-NEXT: nvsize=4, nvalign=4
    283 
    284 // CHECK:       0 | struct H
    285 // CHECK-NEXT:  0 |   struct G (base)
    286 // CHECK-NEXT:  0 |     int g_field
    287 // CHECK-NEXT:  4 |   (H vbtable pointer)
    288 // CHECK-NEXT:  8 |   class D (virtual base)
    289 // CHECK-NEXT:  8 |     (D vftable pointer)
    290 // CHECK-NEXT: 16 |     double a
    291 // CHECK-NEXT: sizeof=24, dsize=24, align=8
    292 // CHECK-NEXT: nvsize=8, nvalign=4
    293 
    294 // CHECK: %struct.H = type { %struct.G, i32*, %class.D }
    295 
    296 // CHECK:       0 | struct I
    297 // CHECK-NEXT:  0 |   (I vftable pointer)
    298 // CHECK-NEXT:  8 |   (I vbtable pointer)
    299 // CHECK-NEXT: 16 |   double q
    300 // CHECK-NEXT: 24 |   class D (virtual base)
    301 // CHECK-NEXT: 24 |     (D vftable pointer)
    302 // CHECK-NEXT: 32 |     double a
    303 // CHECK-NEXT: sizeof=40, dsize=40, align=8
    304 // CHECK-NEXT: nvsize=24, nvalign=8
    305 
    306 // CHECK: %struct.I = type { i32 (...)**, [4 x i8], i32*, double, %class.D }
    307 // CHECK: %struct.I.base = type { i32 (...)**, [4 x i8], i32*, double }
    308 
    309 // CHECK:       0 | struct L
    310 // CHECK-NEXT:  0 |   int l
    311 // CHECK-NEXT: sizeof=4, dsize=4, align=4
    312 // CHECK-NEXT: nvsize=4, nvalign=4
    313 
    314 // CHECK:       0 | struct K
    315 // CHECK-NEXT:  0 |   int k
    316 // CHECK-NEXT: sizeof=4, dsize=4, align=4
    317 // CHECK-NEXT: nvsize=4, nvalign=4
    318 
    319 // CHECK:       0 | struct M
    320 // CHECK-NEXT:  0 |   (M vbtable pointer)
    321 // CHECK-NEXT:  4 |   int m
    322 // CHECK-NEXT:  8 |   struct K (virtual base)
    323 // CHECK-NEXT:  8 |     int k
    324 // CHECK-NEXT: sizeof=12, dsize=12, align=4
    325 
    326 //CHECK: %struct.M = type { i32*, i32, %struct.K }
    327 //CHECK: %struct.M.base = type { i32*, i32 }
    328 
    329 // CHECK:       0 | struct N
    330 // CHECK-NEXT:  4 |   struct L (base)
    331 // CHECK-NEXT:  4 |     int l
    332 // CHECK-NEXT:  8 |   struct M (base)
    333 // CHECK-NEXT:  8 |     (M vbtable pointer)
    334 // CHECK-NEXT: 12 |     int m
    335 // CHECK-NEXT:  0 |   (N vftable pointer)
    336 // CHECK-NEXT: 16 |   struct K (virtual base)
    337 // CHECK-NEXT: 16 |     int k
    338 // CHECK-NEXT: sizeof=20, dsize=20, align=4
    339 // CHECK-NEXT: nvsize=16, nvalign=4
    340 
    341 //CHECK: %struct.N = type { i32 (...)**, %struct.L, %struct.M.base, %struct.K }
    342 
    343 // FIXME: MSVC place struct H at offset 8.
    344 // CHECK:       0 | struct O
    345 // CHECK-NEXT:  4 |   struct H (base)
    346 // CHECK-NEXT:  4 |     struct G (base)
    347 // CHECK-NEXT:  4 |       int g_field
    348 // CHECK-NEXT:  8 |     (H vbtable pointer)
    349 // CHECK-NEXT: 12 |   struct G (base)
    350 // CHECK-NEXT: 12 |     int g_field
    351 // CHECK-NEXT:  0 |   (O vftable pointer)
    352 // CHECK-NEXT: 16 |   class D (virtual base)
    353 // CHECK-NEXT: 16 |     (D vftable pointer)
    354 // CHECK-NEXT: 24 |     double a
    355 // CHECK-NEXT: sizeof=32, dsize=32, align=8
    356 // CHECK-NEXT: nvsize=16, nvalign=4
    357 
    358 //CHECK: %struct.O = type { i32 (...)**, %struct.H.base, %struct.G, %class.D }
    359 //CHECK: %struct.O.base = type { i32 (...)**, %struct.H.base, %struct.G }
    360 
    361 // CHECK:       0 | struct P
    362 // CHECK-NEXT:  0 |   struct M (base)
    363 // CHECK-NEXT:  0 |     (M vbtable pointer)
    364 // CHECK-NEXT:  4 |     int m
    365 // CHECK-NEXT:  8 |   int p
    366 // CHECK-NEXT: 12 |   struct K (virtual base)
    367 // CHECK-NEXT: 12 |     int k
    368 // CHECK-NEXT: 16 |   struct L (virtual base)
    369 // CHECK-NEXT: 16 |     int l
    370 // CHECK-NEXT: sizeof=20, dsize=20, align=4
    371 // CHECK-NEXT: nvsize=12, nvalign=4
    372 
    373 //CHECK: %struct.P = type { %struct.M.base, i32, %struct.K, %struct.L }
    374 
    375 // CHECK:       0 | struct R (empty)
    376 // CHECK-NEXT:  sizeof=1, dsize=0, align=1
    377 // CHECK-NEXT:  nvsize=0, nvalign=1
    378 
    379 //CHECK: %struct.R = type { i8 }
    380 
    381 // CHECK:       0 | struct f
    382 // CHECK-NEXT:  0 |   (f vftable pointer)
    383 // CHECK-NEXT: sizeof=4, dsize=4, align=4
    384 // CHECK-NEXT: nvsize=4, nvalign=4
    385 
    386 // CHECK:       0 | struct s
    387 // CHECK-NEXT:  0 |   (s vftable pointer)
    388 // CHECK-NEXT:  4 |   (s vbtable pointer)
    389 // CHECK-NEXT:  8 |   int r
    390 // CHECK-NEXT: 12 |   (vtordisp for vbase f)
    391 // CHECK-NEXT: 16 |   struct f (virtual base)
    392 // CHECK-NEXT: 16 |     (f vftable pointer)
    393 // CHECK-NEXT: sizeof=20, dsize=20, align=4
    394 // CHECK-NEXT: nvsize=12, nvalign=4
    395 
    396 // CHECK:       0 | class IA
    397 // CHECK-NEXT:  0 |   (IA vftable pointer)
    398 // CHECK-NEXT:  sizeof=4, dsize=4, align=4
    399 // CHECK-NEXT:  nvsize=4, nvalign=4
    400 
    401 // CHECK:       0 | class ICh
    402 // CHECK-NEXT:  0 |   (ICh vftable pointer)
    403 // CHECK-NEXT:  4 |   (ICh vbtable pointer)
    404 // CHECK-NEXT:  8 |   (vtordisp for vbase IA)
    405 // CHECK-NEXT: 12 |   class IA (virtual base)
    406 // CHECK-NEXT: 12 |     (IA vftable pointer)
    407 // CHECK-NEXT: sizeof=16, dsize=16, align=4
    408 // CHECK-NEXT: nvsize=8, nvalign=4
    409 
    410 // CHECK:       0 | struct sd
    411 // CHECK-NEXT:  0 |   (sd vbtable pointer)
    412 // CHECK-NEXT:  4 |   int q
    413 // CHECK-NEXT:  8 |   char y
    414 // CHECK-NEXT: 12 |   (vtordisp for vbase f)
    415 // CHECK-NEXT: 16 |   struct f (virtual base)
    416 // CHECK-NEXT: 16 |     (f vftable pointer)
    417 // CHECK-NEXT: 20 |   struct s (virtual base)
    418 // CHECK-NEXT: 20 |     (s vftable pointer)
    419 // CHECK-NEXT: 24 |     (s vbtable pointer)
    420 // CHECK-NEXT: 28 |     int r
    421 // CHECK-NEXT: 32 |   (vtordisp for vbase IA)
    422 // CHECK-NEXT: 36 |   class IA (virtual base)
    423 // CHECK-NEXT: 36 |     (IA vftable pointer)
    424 // CHECK-NEXT: 40 |   class ICh (virtual base)
    425 // CHECK-NEXT: 40 |     (ICh vftable pointer)
    426 // CHECK-NEXT: 44 |     (ICh vbtable pointer)
    427 // CHECK-NEXT: sizeof=48, dsize=48, align=4
    428 // CHECK-NEXT: nvsize=12, nvalign=4
    429 
    430 // CHECK: %struct.f = type { i32 (...)** }
    431 // CHECK: %struct.s = type { i32 (...)**, i32*, i32, [4 x i8], %struct.f }
    432 // CHECK: %class.IA = type { i32 (...)** }
    433 // CHECK: %class.ICh = type { i32 (...)**, i32*, [4 x i8], %class.IA }
    434 // CHECK: %struct.sd = type { i32*, i32, i8, [7 x i8], %struct.f, %struct.s.base, [4 x i8], %class.IA, %class.ICh.base }
    435 
    436 // CHECK:       0 | struct AV
    437 // CHECK-NEXT:  0 |   (AV vftable pointer)
    438 // CHECK-NEXT: sizeof=4, dsize=4, align=4
    439 // CHECK-NEXT: nvsize=4, nvalign=4
    440 
    441 
    442 // CHECK:       0 | struct BV
    443 // CHECK-NEXT:  0 |   struct AV (primary base)
    444 // CHECK-NEXT:  0 |     (AV vftable pointer)
    445 // CHECK-NEXT: sizeof=4, dsize=4, align=4
    446 // CHECK-NEXT: nvsize=4, nvalign=4
    447 
    448 
    449 // CHECK:       0 | struct CV
    450 // CHECK-NEXT:  0 |   (CV vbtable pointer)
    451 // CHECK-NEXT:  4 |   (vtordisp for vbase BV)
    452 // CHECK-NEXT:  8 |   struct BV (virtual base)
    453 // CHECK-NEXT:  8 |     struct AV (primary base)
    454 // CHECK-NEXT:  8 |       (AV vftable pointer)
    455 // CHECK-NEXT: sizeof=12, dsize=12, align=4
    456 // CHECK-NEXT: nvsize=4, nvalign=4
    457 
    458 // CHECK: %struct.AV = type { i32 (...)** }
    459 // CHECK: %struct.BV = type { %struct.AV }
    460 // CHECK: %struct.CV = type { i32*, [4 x i8], %struct.BV }
    461 // CHECK: %struct.CV.base = type { i32* }
    462 
    463 // CHECK:       0 | struct DV
    464 // CHECK-NEXT:  0 |   struct BV (primary base)
    465 // CHECK-NEXT:  0 |     struct AV (primary base)
    466 // CHECK-NEXT:  0 |       (AV vftable pointer)
    467 // CHECK-NEXT: sizeof=4, dsize=4, align=4
    468 // CHECK-NEXT: nvsize=4, nvalign=4
    469 
    470 // CHECK: %struct.DV = type { %struct.BV }
    471 
    472 // CHECK:       0 | struct EV
    473 // CHECK-NEXT:  4 |   struct CV (base)
    474 // CHECK-NEXT:  4 |     (CV vbtable pointer)
    475 // CHECK-NEXT:  0 |   struct DV (primary base)
    476 // CHECK-NEXT:  0 |     struct BV (primary base)
    477 // CHECK-NEXT:  0 |       struct AV (primary base)
    478 // CHECK-NEXT:  0 |         (AV vftable pointer)
    479 // CHECK-NEXT:  8 |   (vtordisp for vbase BV)
    480 // CHECK-NEXT: 12 |   struct BV (virtual base)
    481 // CHECK-NEXT: 12 |     struct AV (primary base)
    482 // CHECK-NEXT: 12 |       (AV vftable pointer)
    483 // CHECK-NEXT: sizeof=16, dsize=16, align=4
    484 // CHECK-NEXT: nvsize=8, nvalign=4
    485 
    486 // CHECK: %struct.EV = type { %struct.DV, %struct.CV.base, [4 x i8], %struct.BV }
    487 // CHECK: %struct.EV.base = type { %struct.DV, %struct.CV.base }
    488 
    489 // Overriding a method means that all the vbases containing that
    490 // method need a vtordisp.
    491 namespace test1 {
    492   struct A { virtual void foo(); };
    493   struct B : A {};
    494   struct C : virtual A, virtual B { C(); virtual void foo(); };
    495   void test() { C *c; }
    496 
    497 // CHECK:        0 | struct test1::C
    498 // CHECK-NEXT:   0 |   (C vbtable pointer)
    499 // CHECK-NEXT:   4 |   (vtordisp for vbase A)
    500 // CHECK-NEXT:   8 |   struct test1::A (virtual base)
    501 // CHECK-NEXT:   8 |     (A vftable pointer)
    502 // CHECK-NEXT:  12 |   (vtordisp for vbase B)
    503 // CHECK-NEXT:  16 |   struct test1::B (virtual base)
    504 // CHECK-NEXT:  16 |     struct test1::A (primary base)
    505 // CHECK-NEXT:  16 |       (A vftable pointer)
    506 // CHECK-NEXT:  sizeof=20, dsize=20, align=4
    507 // CHECK-NEXT:  nvsize=4, nvalign=4
    508 }
    509