Home | History | Annotate | Download | only in Layout
      1 // RUN: %clang_cc1 -fno-rtti -fms-extensions -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>&1 \
      2 // RUN:            | FileCheck %s
      3 // RUN: %clang_cc1 -fno-rtti -fms-extensions -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
      4 // RUN:            | FileCheck %s -check-prefix CHECK-X64
      5 
      6 extern "C" int printf(const char *fmt, ...);
      7 
      8 struct B0 {
      9 	int a;
     10 	B0() : a(0xf00000B0) {}
     11 	virtual void f() { printf("B0"); }
     12 };
     13 
     14 struct __declspec(align(16)) B1 {
     15 	int a;
     16 	B1() : a(0xf00000B1) {}
     17 	virtual void f() { printf("B1"); }
     18 };
     19 
     20 struct __declspec(align(16)) Align16 {};
     21 struct __declspec(align(32)) Align32 {};
     22 struct VAlign16 : virtual Align16 {};
     23 struct VAlign32 : virtual Align32 {};
     24 
     25 struct A : virtual B0, virtual B1 {
     26 	int a;
     27 	A() : a(0xf000000A) {}
     28 	virtual void f() { printf("A"); }
     29 	virtual void g() { printf("A"); }
     30 };
     31 
     32 // CHECK: *** Dumping AST Record Layout
     33 // CHECK: *** Dumping AST Record Layout
     34 // CHECK: *** Dumping AST Record Layout
     35 // CHECK-NEXT:    0 | struct A
     36 // CHECK-NEXT:    0 |   (A vftable pointer)
     37 // CHECK-NEXT:    4 |   (A vbtable pointer)
     38 // CHECK-NEXT:    8 |   int a
     39 // CHECK-NEXT:   16 |   (vtordisp for vbase B0)
     40 // CHECK-NEXT:   20 |   struct B0 (virtual base)
     41 // CHECK-NEXT:   20 |     (B0 vftable pointer)
     42 // CHECK-NEXT:   24 |     int a
     43 // CHECK-NEXT:   44 |   (vtordisp for vbase B1)
     44 // CHECK-NEXT:   48 |   struct B1 (virtual base)
     45 // CHECK-NEXT:   48 |     (B1 vftable pointer)
     46 // CHECK-NEXT:   52 |     int a
     47 // CHECK-NEXT:      | [sizeof=64, align=16
     48 // CHECK-NEXT:      |  nvsize=12, nvalign=16]
     49 // CHECK-X64: *** Dumping AST Record Layout
     50 // CHECK-X64: *** Dumping AST Record Layout
     51 // CHECK-X64: *** Dumping AST Record Layout
     52 // CHECK-X64-NEXT:    0 | struct A
     53 // CHECK-X64-NEXT:    0 |   (A vftable pointer)
     54 // CHECK-X64-NEXT:    8 |   (A vbtable pointer)
     55 // CHECK-X64-NEXT:   16 |   int a
     56 // CHECK-X64-NEXT:   36 |   (vtordisp for vbase B0)
     57 // CHECK-X64-NEXT:   40 |   struct B0 (virtual base)
     58 // CHECK-X64-NEXT:   40 |     (B0 vftable pointer)
     59 // CHECK-X64-NEXT:   48 |     int a
     60 // CHECK-X64-NEXT:   76 |   (vtordisp for vbase B1)
     61 // CHECK-X64-NEXT:   80 |   struct B1 (virtual base)
     62 // CHECK-X64-NEXT:   80 |     (B1 vftable pointer)
     63 // CHECK-X64-NEXT:   88 |     int a
     64 // CHECK-X64-NEXT:      | [sizeof=96, align=16
     65 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=16]
     66 
     67 struct C : virtual B0, virtual B1, VAlign32 {
     68 	int a;
     69 	C() : a(0xf000000C) {}
     70 	virtual void f() { printf("C"); }
     71 	virtual void g() { printf("C"); }
     72 };
     73 
     74 // CHECK: *** Dumping AST Record Layout
     75 // CHECK: *** Dumping AST Record Layout
     76 // CHECK: *** Dumping AST Record Layout
     77 // CHECK-NEXT:    0 | struct C
     78 // CHECK-NEXT:    0 |   (C vftable pointer)
     79 // CHECK-NEXT:   32 |   struct VAlign32 (base)
     80 // CHECK-NEXT:   32 |     (VAlign32 vbtable pointer)
     81 // CHECK-NEXT:   36 |   int a
     82 // CHECK-NEXT:   64 |   (vtordisp for vbase B0)
     83 // CHECK-NEXT:   68 |   struct B0 (virtual base)
     84 // CHECK-NEXT:   68 |     (B0 vftable pointer)
     85 // CHECK-NEXT:   72 |     int a
     86 // CHECK-NEXT:  108 |   (vtordisp for vbase B1)
     87 // CHECK-NEXT:  112 |   struct B1 (virtual base)
     88 // CHECK-NEXT:  112 |     (B1 vftable pointer)
     89 // CHECK-NEXT:  116 |     int a
     90 // CHECK-NEXT:  128 |   struct Align32 (virtual base) (empty)
     91 // CHECK-NEXT:      | [sizeof=128, align=32
     92 // CHECK-NEXT:      |  nvsize=64, nvalign=32]
     93 // CHECK-X64: *** Dumping AST Record Layout
     94 // CHECK-X64: *** Dumping AST Record Layout
     95 // CHECK-X64: *** Dumping AST Record Layout
     96 // CHECK-X64-NEXT:    0 | struct C
     97 // CHECK-X64-NEXT:    0 |   (C vftable pointer)
     98 // CHECK-X64-NEXT:   32 |   struct VAlign32 (base)
     99 // CHECK-X64-NEXT:   32 |     (VAlign32 vbtable pointer)
    100 // CHECK-X64-NEXT:   40 |   int a
    101 // CHECK-X64-NEXT:   68 |   (vtordisp for vbase B0)
    102 // CHECK-X64-NEXT:   72 |   struct B0 (virtual base)
    103 // CHECK-X64-NEXT:   72 |     (B0 vftable pointer)
    104 // CHECK-X64-NEXT:   80 |     int a
    105 // CHECK-X64-NEXT:  108 |   (vtordisp for vbase B1)
    106 // CHECK-X64-NEXT:  112 |   struct B1 (virtual base)
    107 // CHECK-X64-NEXT:  112 |     (B1 vftable pointer)
    108 // CHECK-X64-NEXT:  120 |     int a
    109 // CHECK-X64-NEXT:  128 |   struct Align32 (virtual base) (empty)
    110 // CHECK-X64-NEXT:      | [sizeof=128, align=32
    111 // CHECK-X64-NEXT:      |  nvsize=64, nvalign=32]
    112 
    113 struct __declspec(align(32)) D : virtual B0, virtual B1  {
    114 	int a;
    115 	D() : a(0xf000000D) {}
    116 	virtual void f() { printf("D"); }
    117 	virtual void g() { printf("D"); }
    118 };
    119 
    120 // CHECK: *** Dumping AST Record Layout
    121 // CHECK-NEXT:    0 | struct D
    122 // CHECK-NEXT:    0 |   (D vftable pointer)
    123 // CHECK-NEXT:    4 |   (D vbtable pointer)
    124 // CHECK-NEXT:    8 |   int a
    125 // CHECK-NEXT:   32 |   (vtordisp for vbase B0)
    126 // CHECK-NEXT:   36 |   struct B0 (virtual base)
    127 // CHECK-NEXT:   36 |     (B0 vftable pointer)
    128 // CHECK-NEXT:   40 |     int a
    129 // CHECK-NEXT:   76 |   (vtordisp for vbase B1)
    130 // CHECK-NEXT:   80 |   struct B1 (virtual base)
    131 // CHECK-NEXT:   80 |     (B1 vftable pointer)
    132 // CHECK-NEXT:   84 |     int a
    133 // CHECK-NEXT:      | [sizeof=96, align=32
    134 // CHECK-NEXT:      |  nvsize=12, nvalign=32]
    135 // CHECK-X64: *** Dumping AST Record Layout
    136 // CHECK-X64-NEXT:    0 | struct D
    137 // CHECK-X64-NEXT:    0 |   (D vftable pointer)
    138 // CHECK-X64-NEXT:    8 |   (D vbtable pointer)
    139 // CHECK-X64-NEXT:   16 |   int a
    140 // CHECK-X64-NEXT:   36 |   (vtordisp for vbase B0)
    141 // CHECK-X64-NEXT:   40 |   struct B0 (virtual base)
    142 // CHECK-X64-NEXT:   40 |     (B0 vftable pointer)
    143 // CHECK-X64-NEXT:   48 |     int a
    144 // CHECK-X64-NEXT:   76 |   (vtordisp for vbase B1)
    145 // CHECK-X64-NEXT:   80 |   struct B1 (virtual base)
    146 // CHECK-X64-NEXT:   80 |     (B1 vftable pointer)
    147 // CHECK-X64-NEXT:   88 |     int a
    148 // CHECK-X64-NEXT:      | [sizeof=96, align=32
    149 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=32]
    150 
    151 struct AT {
    152 	virtual ~AT(){}
    153 };
    154 struct CT : virtual AT {
    155 	virtual ~CT();
    156 };
    157 CT::~CT(){}
    158 
    159 // CHECK: *** Dumping AST Record Layout
    160 // CHECK: *** Dumping AST Record Layout
    161 // CHECK-NEXT:    0 | struct CT
    162 // CHECK-NEXT:    0 |   (CT vbtable pointer)
    163 // CHECK-NEXT:    4 |   struct AT (virtual base)
    164 // CHECK-NEXT:    4 |     (AT vftable pointer)
    165 // CHECK-NEXT:      | [sizeof=8, align=4
    166 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
    167 // CHECK-X64: *** Dumping AST Record Layout
    168 // CHECK-X64: *** Dumping AST Record Layout
    169 // CHECK-X64-NEXT:    0 | struct CT
    170 // CHECK-X64-NEXT:    0 |   (CT vbtable pointer)
    171 // CHECK-X64-NEXT:    8 |   struct AT (virtual base)
    172 // CHECK-X64-NEXT:    8 |     (AT vftable pointer)
    173 // CHECK-X64-NEXT:      | [sizeof=16, align=8
    174 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
    175 
    176 struct XA {
    177 	XA() { printf("XA"); }
    178 	long long ll;
    179 };
    180 struct XB : XA {
    181 	XB() { printf("XB"); }
    182 	virtual void foo() {}
    183 	int b;
    184 };
    185 struct XC : virtual XB {
    186 	XC() { printf("XC"); }
    187 	virtual void foo() {}
    188 };
    189 
    190 // CHECK: *** Dumping AST Record Layout
    191 // CHECK: *** Dumping AST Record Layout
    192 // CHECK: *** Dumping AST Record Layout
    193 // CHECK-NEXT:    0 | struct XC
    194 // CHECK-NEXT:    0 |   (XC vbtable pointer)
    195 // CHECK-NEXT:    4 |   (vtordisp for vbase XB)
    196 // CHECK-NEXT:    8 |   struct XB (virtual base)
    197 // CHECK-NEXT:    8 |     (XB vftable pointer)
    198 // CHECK-NEXT:   16 |     struct XA (base)
    199 // CHECK-NEXT:   16 |       long long ll
    200 // CHECK-NEXT:   24 |     int b
    201 // CHECK-NEXT:      | [sizeof=32, align=8
    202 // CHECK-NEXT:      |  nvsize=4, nvalign=8]
    203 // CHECK-X64: *** Dumping AST Record Layout
    204 // CHECK-X64: *** Dumping AST Record Layout
    205 // CHECK-X64: *** Dumping AST Record Layout
    206 // CHECK-X64-NEXT:    0 | struct XC
    207 // CHECK-X64-NEXT:    0 |   (XC vbtable pointer)
    208 // CHECK-X64-NEXT:   12 |   (vtordisp for vbase XB)
    209 // CHECK-X64-NEXT:   16 |   struct XB (virtual base)
    210 // CHECK-X64-NEXT:   16 |     (XB vftable pointer)
    211 // CHECK-X64-NEXT:   24 |     struct XA (base)
    212 // CHECK-X64-NEXT:   24 |       long long ll
    213 // CHECK-X64-NEXT:   32 |     int b
    214 // CHECK-X64-NEXT:      | [sizeof=40, align=8
    215 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
    216 
    217 namespace pragma_test1 {
    218 // No overrides means no vtordisps by default.
    219 struct A { virtual ~A(); virtual void foo(); int a; };
    220 struct B : virtual A { virtual ~B(); virtual void bar(); int b; };
    221 struct C : virtual B { int c; };
    222 // CHECK: *** Dumping AST Record Layout
    223 // CHECK: *** Dumping AST Record Layout
    224 // CHECK: *** Dumping AST Record Layout
    225 // CHECK-NEXT:    0 | struct pragma_test1::C
    226 // CHECK-NEXT:    0 |   (C vbtable pointer)
    227 // CHECK-NEXT:    4 |   int c
    228 // CHECK-NEXT:    8 |   struct pragma_test1::A (virtual base)
    229 // CHECK-NEXT:    8 |     (A vftable pointer)
    230 // CHECK-NEXT:   12 |     int a
    231 // CHECK-NEXT:   16 |   struct pragma_test1::B (virtual base)
    232 // CHECK-NEXT:   16 |     (B vftable pointer)
    233 // CHECK-NEXT:   20 |     (B vbtable pointer)
    234 // CHECK-NEXT:   24 |     int b
    235 // CHECK-NEXT:      | [sizeof=28, align=4
    236 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
    237 // CHECK-X64: *** Dumping AST Record Layout
    238 // CHECK-X64: *** Dumping AST Record Layout
    239 // CHECK-X64: *** Dumping AST Record Layout
    240 }
    241 
    242 namespace pragma_test2 {
    243 struct A { virtual ~A(); virtual void foo(); int a; };
    244 #pragma vtordisp(push,2)
    245 struct B : virtual A { virtual ~B(); virtual void bar(); int b; };
    246 struct C : virtual B { int c; };
    247 #pragma vtordisp(pop)
    248 // CHECK: *** Dumping AST Record Layout
    249 // CHECK: *** Dumping AST Record Layout
    250 // CHECK: *** Dumping AST Record Layout
    251 // CHECK-NEXT:    0 | struct pragma_test2::C
    252 // CHECK-NEXT:    0 |   (C vbtable pointer)
    253 // CHECK-NEXT:    4 |   int c
    254 // CHECK-NEXT:    8 |   (vtordisp for vbase A)
    255 // CHECK-NEXT:   12 |   struct pragma_test2::A (virtual base)
    256 // CHECK-NEXT:   12 |     (A vftable pointer)
    257 // CHECK-NEXT:   16 |     int a
    258 //   By adding a virtual method and vftable to B, now we need a vtordisp.
    259 // CHECK-NEXT:   20 |   (vtordisp for vbase B)
    260 // CHECK-NEXT:   24 |   struct pragma_test2::B (virtual base)
    261 // CHECK-NEXT:   24 |     (B vftable pointer)
    262 // CHECK-NEXT:   28 |     (B vbtable pointer)
    263 // CHECK-NEXT:   32 |     int b
    264 // CHECK-NEXT:      | [sizeof=36, align=4
    265 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
    266 // CHECK-X64: *** Dumping AST Record Layout
    267 // CHECK-X64: *** Dumping AST Record Layout
    268 // CHECK-X64: *** Dumping AST Record Layout
    269 }
    270 
    271 namespace pragma_test3 {
    272 struct A { virtual ~A(); virtual void foo(); int a; };
    273 #pragma vtordisp(push,2)
    274 struct B : virtual A { virtual ~B(); virtual void foo(); int b; };
    275 struct C : virtual B { int c; };
    276 #pragma vtordisp(pop)
    277 // CHECK: *** Dumping AST Record Layout
    278 // CHECK: *** Dumping AST Record Layout
    279 // CHECK: *** Dumping AST Record Layout
    280 // CHECK-NEXT:    0 | struct pragma_test3::C
    281 // CHECK-NEXT:    0 |   (C vbtable pointer)
    282 // CHECK-NEXT:    4 |   int c
    283 // CHECK-NEXT:    8 |   (vtordisp for vbase A)
    284 // CHECK-NEXT:   12 |   struct pragma_test3::A (virtual base)
    285 // CHECK-NEXT:   12 |     (A vftable pointer)
    286 // CHECK-NEXT:   16 |     int a
    287 //   No vtordisp before B!  It doesn't have its own vftable.
    288 // CHECK-NEXT:   20 |   struct pragma_test3::B (virtual base)
    289 // CHECK-NEXT:   20 |     (B vbtable pointer)
    290 // CHECK-NEXT:   24 |     int b
    291 // CHECK-NEXT:      | [sizeof=28, align=4
    292 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
    293 // CHECK-X64: *** Dumping AST Record Layout
    294 // CHECK-X64: *** Dumping AST Record Layout
    295 // CHECK-X64: *** Dumping AST Record Layout
    296 }
    297 
    298 namespace pragma_test4 {
    299 struct A {
    300   A();
    301   virtual void foo();
    302   int a;
    303 };
    304 
    305 // Make sure the pragma applies to class template decls before they've been
    306 // instantiated.
    307 #pragma vtordisp(push,2)
    308 template <typename T>
    309 struct B : virtual A {
    310   B();
    311   virtual ~B();
    312   virtual void bar();
    313   T b;
    314 };
    315 #pragma vtordisp(pop)
    316 
    317 struct C : virtual B<int> { int c; };
    318 // CHECK: *** Dumping AST Record Layout
    319 // CHECK: *** Dumping AST Record Layout
    320 // CHECK: *** Dumping AST Record Layout
    321 // CHECK-NEXT:    0 | struct pragma_test4::C
    322 // CHECK-NEXT:    0 |   (C vbtable pointer)
    323 // CHECK-NEXT:    4 |   int c
    324 //   Pragma applies to B, which has vbase A.
    325 // CHECK-NEXT:    8 |   (vtordisp for vbase A)
    326 // CHECK-NEXT:   12 |   struct pragma_test4::A (virtual base)
    327 // CHECK-NEXT:   12 |     (A vftable pointer)
    328 // CHECK-NEXT:   16 |     int a
    329 //   Pragma does not apply to C, and B doesn't usually need a vtordisp in C.
    330 // CHECK-NEXT:   20 |   struct pragma_test4::B<int> (virtual base)
    331 // CHECK-NEXT:   20 |     (B vftable pointer)
    332 // CHECK-NEXT:   24 |     (B vbtable pointer)
    333 // CHECK-NEXT:   28 |     int b
    334 // CHECK-NEXT:      | [sizeof=32, align=4
    335 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
    336 // CHECK-X64: *** Dumping AST Record Layout
    337 // CHECK-X64: *** Dumping AST Record Layout
    338 // CHECK-X64: *** Dumping AST Record Layout
    339 }
    340 
    341 struct GA {
    342 	virtual void fun() {}
    343 };
    344 struct GB: public GA {};
    345 struct GC: public virtual GA {
    346 	virtual void fun() {}
    347 	GC() {}
    348 };
    349 struct GD: public virtual GC, public virtual GB {};
    350 
    351 // CHECK: *** Dumping AST Record Layout
    352 // CHECK: *** Dumping AST Record Layout
    353 // CHECK: *** Dumping AST Record Layout
    354 // CHECK: *** Dumping AST Record Layout
    355 // CHECK-NEXT:    0 | struct GD
    356 // CHECK-NEXT:    0 |   (GD vbtable pointer)
    357 // CHECK-NEXT:    4 |   (vtordisp for vbase GA)
    358 // CHECK-NEXT:    8 |   struct GA (virtual base)
    359 // CHECK-NEXT:    8 |     (GA vftable pointer)
    360 // CHECK-NEXT:   12 |   struct GC (virtual base)
    361 // CHECK-NEXT:   12 |     (GC vbtable pointer)
    362 // CHECK-NEXT:   16 |   struct GB (virtual base)
    363 // CHECK-NEXT:   16 |     struct GA (primary base)
    364 // CHECK-NEXT:   16 |       (GA vftable pointer)
    365 // CHECK-NEXT:      | [sizeof=20, align=4
    366 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
    367 // CHECK-X64: *** Dumping AST Record Layout
    368 // CHECK-X64: *** Dumping AST Record Layout
    369 // CHECK-X64: *** Dumping AST Record Layout
    370 // CHECK-X64: *** Dumping AST Record Layout
    371 // CHECK-X64-NEXT:    0 | struct GD
    372 // CHECK-X64-NEXT:    0 |   (GD vbtable pointer)
    373 // CHECK-X64-NEXT:   12 |   (vtordisp for vbase GA)
    374 // CHECK-X64-NEXT:   16 |   struct GA (virtual base)
    375 // CHECK-X64-NEXT:   16 |     (GA vftable pointer)
    376 // CHECK-X64-NEXT:   24 |   struct GC (virtual base)
    377 // CHECK-X64-NEXT:   24 |     (GC vbtable pointer)
    378 // CHECK-X64-NEXT:   32 |   struct GB (virtual base)
    379 // CHECK-X64-NEXT:   32 |     struct GA (primary base)
    380 // CHECK-X64-NEXT:   32 |       (GA vftable pointer)
    381 // CHECK-X64-NEXT:      | [sizeof=40, align=8
    382 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
    383 
    384 struct HA {
    385   virtual void fun() {}
    386 };
    387 #pragma vtordisp(push, 2)
    388 struct HB : virtual HA {};
    389 #pragma vtordisp(pop)
    390 #pragma vtordisp(push, 0)
    391 struct HC : virtual HB {};
    392 #pragma vtordisp(pop)
    393 
    394 // CHECK: *** Dumping AST Record Layout
    395 // CHECK: *** Dumping AST Record Layout
    396 // CHECK: *** Dumping AST Record Layout
    397 // CHECK-NEXT:    0 | struct HC
    398 // CHECK-NEXT:    0 |   (HC vbtable pointer)
    399 // CHECK-NEXT:    4 |   (vtordisp for vbase HA)
    400 // CHECK-NEXT:    8 |   struct HA (virtual base)
    401 // CHECK-NEXT:    8 |     (HA vftable pointer)
    402 // CHECK-NEXT:   12 |   struct HB (virtual base)
    403 // CHECK-NEXT:   12 |     (HB vbtable pointer)
    404 // CHECK-NEXT:      | [sizeof=16, align=4
    405 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
    406 // CHECK-X64: *** Dumping AST Record Layout
    407 // CHECK-X64: *** Dumping AST Record Layout
    408 // CHECK-X64: *** Dumping AST Record Layout
    409 // CHECK-X64-NEXT:    0 | struct HC
    410 // CHECK-X64-NEXT:    0 |   (HC vbtable pointer)
    411 // CHECK-X64-NEXT:   12 |   (vtordisp for vbase HA)
    412 // CHECK-X64-NEXT:   16 |   struct HA (virtual base)
    413 // CHECK-X64-NEXT:   16 |     (HA vftable pointer)
    414 // CHECK-X64-NEXT:   24 |   struct HB (virtual base)
    415 // CHECK-X64-NEXT:   24 |     (HB vbtable pointer)
    416 // CHECK-X64-NEXT:      | [sizeof=32, align=8
    417 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
    418 
    419 int a[
    420 sizeof(A)+
    421 sizeof(C)+
    422 sizeof(D)+
    423 sizeof(CT)+
    424 sizeof(XC)+
    425 sizeof(pragma_test1::C)+
    426 sizeof(pragma_test2::C)+
    427 sizeof(pragma_test3::C)+
    428 sizeof(pragma_test4::C)+
    429 sizeof(GD)+
    430 sizeof(HC)+
    431 0];
    432