Home | History | Annotate | Download | only in Layout
      1 // RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fms-extensions -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
      2 // RUN:            | FileCheck %s
      3 // RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fms-extensions -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 __declspec(align(4096)) char buffer[4096];
      8 
      9 struct AT {};
     10 
     11 struct V : AT {
     12 	char c;
     13 	V() {
     14 		printf("V   - this: %d\n", (int)((char*)this - buffer));
     15 	}
     16 };
     17 
     18 struct AT0 {
     19 	union { struct { int a; AT t; } y; int b; } x;
     20 	char c;
     21 	AT0() {
     22 		printf("AT0 - this: %d\n", (int)((char*)this - buffer));
     23 	}
     24 };
     25 
     26 struct AT1 : V {
     27 	int a;
     28 	AT1() {
     29 		printf("AT1 - this: %d\n", (int)((char*)this - buffer));
     30 	}
     31 };
     32 
     33 struct AT2 {
     34 	AT0 t;
     35 	char AT2FieldName0;
     36 	AT2() {
     37 		printf("AT2 - this: %d\n", (int)((char*)this - buffer));
     38 		printf("AT2 - Fiel: %d\n", (int)((char*)&AT2FieldName0 - buffer));
     39 	}
     40 };
     41 
     42 struct AT3 : AT2, AT1 {
     43 	AT3() {
     44 		printf("AT3 - this: %d\n", (int)((char*)this - buffer));
     45 	}
     46 };
     47 
     48 // CHECK: *** Dumping AST Record Layout
     49 // CHECK: *** Dumping AST Record Layout
     50 // CHECK: *** Dumping AST Record Layout
     51 // CHECK: *** Dumping AST Record Layout
     52 // CHECK: *** Dumping AST Record Layout
     53 // CHECK: *** Dumping AST Record Layout
     54 // CHECK: *** Dumping AST Record Layout
     55 // CHECK: *** Dumping AST Record Layout
     56 // CHECK-NEXT:    0 | struct AT3
     57 // CHECK-NEXT:    0 |   struct AT2 (base)
     58 // CHECK-NEXT:    0 |     struct AT0 t
     59 // CHECK-NEXT:    0 |       union AT0::(anonymous at {{.*}} x
     60 // CHECK-NEXT:    0 |         struct AT0::(anonymous at {{.*}} y
     61 // CHECK-NEXT:    0 |           int a
     62 // CHECK-NEXT:    4 |           struct AT t (empty)
     63 // CHECK:         0 |         int b
     64 // CHECK:         8 |       char c
     65 // CHECK:        12 |     char AT2FieldName0
     66 // CHECK-NEXT:   20 |   struct AT1 (base)
     67 // CHECK-NEXT:   20 |     struct V (base)
     68 // CHECK-NEXT:   20 |       struct AT (base) (empty)
     69 // CHECK-NEXT:   20 |       char c
     70 // CHECK-NEXT:   24 |     int a
     71 // CHECK-NEXT:      | [sizeof=28, align=4
     72 // CHECK-NEXT:      |  nvsize=28, nvalign=4]
     73 // CHECK-X64: *** Dumping AST Record Layout
     74 // CHECK-X64: *** Dumping AST Record Layout
     75 // CHECK-X64: *** Dumping AST Record Layout
     76 // CHECK-X64: *** Dumping AST Record Layout
     77 // CHECK-X64: *** Dumping AST Record Layout
     78 // CHECK-X64: *** Dumping AST Record Layout
     79 // CHECK-X64: *** Dumping AST Record Layout
     80 // CHECK-X64: *** Dumping AST Record Layout
     81 // CHECK-X64-NEXT:    0 | struct AT3
     82 // CHECK-X64-NEXT:    0 |   struct AT2 (base)
     83 // CHECK-X64-NEXT:    0 |     struct AT0 t
     84 // CHECK-X64-NEXT:    0 |       union AT0::(anonymous at {{.*}} x
     85 // CHECK-X64-NEXT:    0 |         struct AT0::(anonymous at {{.*}} y
     86 // CHECK-X64-NEXT:    0 |           int a
     87 // CHECK-X64-NEXT:    4 |           struct AT t (empty)
     88 // CHECK-X64:         0 |         int b
     89 // CHECK-X64:         8 |       char c
     90 // CHECK-X64:        12 |     char AT2FieldName0
     91 // CHECK-X64-NEXT:   20 |   struct AT1 (base)
     92 // CHECK-X64-NEXT:   20 |     struct V (base)
     93 // CHECK-X64-NEXT:   20 |       struct AT (base) (empty)
     94 // CHECK-X64-NEXT:   20 |       char c
     95 // CHECK-X64-NEXT:   24 |     int a
     96 // CHECK-X64-NEXT:      | [sizeof=28, align=4
     97 // CHECK-X64-NEXT:      |  nvsize=28, nvalign=4]
     98 
     99 struct BT0 {
    100 	BT0() {
    101 		printf("BT0 - this: %d\n", (int)((char*)this - buffer));
    102 	}
    103 };
    104 
    105 struct BT2 : BT0 {
    106 	char BT2FieldName0;
    107 	BT2() {
    108 		printf("BT2 - this: %d\n", (int)((char*)this - buffer));
    109 		printf("BT2 - Fiel: %d\n", (int)((char*)&BT2FieldName0 - buffer));
    110 	}
    111 };
    112 
    113 struct BT3 : BT0, BT2 {
    114 	BT3() {
    115 		printf("BT3 - this: %d\n", (int)((char*)this - buffer));
    116 	}
    117 };
    118 
    119 // CHECK: *** Dumping AST Record Layout
    120 // CHECK: *** Dumping AST Record Layout
    121 // CHECK: *** Dumping AST Record Layout
    122 // CHECK-NEXT:    0 | struct BT3
    123 // CHECK-NEXT:    0 |   struct BT0 (base) (empty)
    124 // CHECK-NEXT:    1 |   struct BT2 (base)
    125 // CHECK-NEXT:    1 |     struct BT0 (base) (empty)
    126 // CHECK-NEXT:    1 |     char BT2FieldName0
    127 // CHECK-NEXT:      | [sizeof=2, align=1
    128 // CHECK-NEXT:      |  nvsize=2, nvalign=1]
    129 // CHECK-X64: *** Dumping AST Record Layout
    130 // CHECK-X64: *** Dumping AST Record Layout
    131 // CHECK-X64: *** Dumping AST Record Layout
    132 // CHECK-X64-NEXT:    0 | struct BT3
    133 // CHECK-X64-NEXT:    0 |   struct BT0 (base) (empty)
    134 // CHECK-X64-NEXT:    1 |   struct BT2 (base)
    135 // CHECK-X64-NEXT:    1 |     struct BT0 (base) (empty)
    136 // CHECK-X64-NEXT:    1 |     char BT2FieldName0
    137 // CHECK-X64-NEXT:      | [sizeof=2, align=1
    138 // CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
    139 
    140 struct T0 : AT {
    141 	T0() {
    142 		printf("T0 (this) : %d\n", (int)((char*)this - buffer));
    143 	}
    144 };
    145 
    146 struct T1 : T0 {
    147 	char a;
    148 	T1() {
    149 		printf("T1 (this) : %d\n", (int)((char*)this - buffer));
    150 		printf("T1 (fiel) : %d\n", (int)((char*)&a - buffer));
    151 	}
    152 };
    153 
    154 struct T2 : AT {
    155 	char a;
    156 	T2() {
    157 		printf("T2 (this) : %d\n", (int)((char*)this - buffer));
    158 		printf("T2 (fiel) : %d\n", (int)((char*)&a - buffer));
    159 	}
    160 };
    161 
    162 struct __declspec(align(1)) T3 : virtual T1, virtual T2 {
    163 	T3() {
    164 		printf("T3 (this) : %d\n", (int)((char*)this - buffer));
    165 	}
    166 };
    167 
    168 // CHECK: *** Dumping AST Record Layout
    169 // CHECK: *** Dumping AST Record Layout
    170 // CHECK: *** Dumping AST Record Layout
    171 // CHECK: *** Dumping AST Record Layout
    172 // CHECK-NEXT:    0 | struct T3
    173 // CHECK-NEXT:    0 |   (T3 vbtable pointer)
    174 // CHECK-NEXT:    4 |   struct T1 (virtual base)
    175 // CHECK-NEXT:    4 |     struct T0 (base) (empty)
    176 // CHECK-NEXT:    4 |       struct AT (base) (empty)
    177 // CHECK-NEXT:    4 |     char a
    178 // CHECK-NEXT:   12 |   struct T2 (virtual base)
    179 // CHECK-NEXT:   12 |     struct AT (base) (empty)
    180 // CHECK-NEXT:   12 |     char a
    181 // CHECK-NEXT:      | [sizeof=16, align=4
    182 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
    183 // CHECK-X64: *** Dumping AST Record Layout
    184 // CHECK-X64: *** Dumping AST Record Layout
    185 // CHECK-X64: *** Dumping AST Record Layout
    186 // CHECK-X64: *** Dumping AST Record Layout
    187 // CHECK-X64-NEXT:    0 | struct T3
    188 // CHECK-X64-NEXT:    0 |   (T3 vbtable pointer)
    189 // CHECK-X64-NEXT:    8 |   struct T1 (virtual base)
    190 // CHECK-X64-NEXT:    8 |     struct T0 (base) (empty)
    191 // CHECK-X64-NEXT:    8 |       struct AT (base) (empty)
    192 // CHECK-X64-NEXT:    8 |     char a
    193 // CHECK-X64-NEXT:   16 |   struct T2 (virtual base)
    194 // CHECK-X64-NEXT:   16 |     struct AT (base) (empty)
    195 // CHECK-X64-NEXT:   16 |     char a
    196 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    197 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
    198 
    199 struct B {};
    200 struct C { int a; };
    201 struct D : B, virtual C { B b; };
    202 struct E : D, B {};
    203 // CHECK: *** Dumping AST Record Layout
    204 // CHECK: *** Dumping AST Record Layout
    205 // CHECK: *** Dumping AST Record Layout
    206 // CHECK: *** Dumping AST Record Layout
    207 // CHECK-NEXT:    0 | struct E
    208 // CHECK-NEXT:    0 |   struct D (base)
    209 // CHECK-NEXT:    4 |     struct B (base) (empty)
    210 // CHECK-NEXT:    0 |     (D vbtable pointer)
    211 // CHECK-NEXT:    4 |     struct B b (empty)
    212 // CHECK:         8 |   struct B (base) (empty)
    213 // CHECK-NEXT:    8 |   struct C (virtual base)
    214 // CHECK-NEXT:    8 |     int a
    215 // CHECK-NEXT:      | [sizeof=12, align=4
    216 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
    217 // CHECK-X64: *** Dumping AST Record Layout
    218 // CHECK-X64: *** Dumping AST Record Layout
    219 // CHECK-X64: *** Dumping AST Record Layout
    220 // CHECK-X64: *** Dumping AST Record Layout
    221 // CHECK-X64-NEXT:   0 | struct E
    222 // CHECK-X64-NEXT:   0 |   struct D (base)
    223 // CHECK-X64-NEXT:   8 |     struct B (base) (empty)
    224 // CHECK-X64-NEXT:   0 |     (D vbtable pointer)
    225 // CHECK-X64-NEXT:   8 |     struct B b (empty)
    226 // CHECK-X64:       16 |   struct B (base) (empty)
    227 // CHECK-X64-NEXT:  16 |   struct C (virtual base)
    228 // CHECK-X64-NEXT:  16 |     int a
    229 // CHECK-X64-NEXT:     | [sizeof=24, align=8
    230 // CHECK-X64-NEXT:     |  nvsize=16, nvalign=8]
    231 
    232 struct F : virtual D, virtual B {};
    233 // CHECK: *** Dumping AST Record Layout
    234 // CHECK-NEXT:    0 | struct F
    235 // CHECK-NEXT:    0 |   (F vbtable pointer)
    236 // CHECK-NEXT:    4 |   struct C (virtual base)
    237 // CHECK-NEXT:    4 |     int a
    238 // CHECK-NEXT:    8 |   struct D (virtual base)
    239 // CHECK-NEXT:   12 |     struct B (base) (empty)
    240 // CHECK-NEXT:    8 |     (D vbtable pointer)
    241 // CHECK-NEXT:   12 |     struct B b (empty)
    242 // CHECK:        16 |   struct B (virtual base) (empty)
    243 // CHECK-NEXT:      | [sizeof=16, align=4
    244 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
    245 // CHECK-X64: *** Dumping AST Record Layout
    246 // CHECK-X64-NEXT:    0 | struct F
    247 // CHECK-X64-NEXT:    0 |   (F vbtable pointer)
    248 // CHECK-X64-NEXT:    8 |   struct C (virtual base)
    249 // CHECK-X64-NEXT:    8 |     int a
    250 // CHECK-X64-NEXT:   16 |   struct D (virtual base)
    251 // CHECK-X64-NEXT:   24 |     struct B (base) (empty)
    252 // CHECK-X64-NEXT:   16 |     (D vbtable pointer)
    253 // CHECK-X64-NEXT:   24 |     struct B b (empty)
    254 // CHECK-X64:        32 |   struct B (virtual base) (empty)
    255 // CHECK-X64-NEXT:      | [sizeof=32, align=8
    256 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
    257 
    258 struct JC0 {
    259 	JC0() { printf("JC0 : %d\n", (int)((char*)this - buffer)); }
    260 };
    261 struct JC1 : JC0 {
    262 	virtual void f() {}
    263 	JC1() { printf("JC1 : %d\n", (int)((char*)this - buffer)); }
    264 };
    265 struct JC2 : JC1 {
    266 	JC2() { printf("JC2 : %d\n", (int)((char*)this - buffer)); }
    267 };
    268 struct JC4 : JC1, JC2 {
    269 	JC4() { printf("JC4 : %d\n", (int)((char*)this - buffer)); }
    270 };
    271 
    272 // CHECK: *** Dumping AST Record Layout
    273 // CHECK: *** Dumping AST Record Layout
    274 // CHECK: *** Dumping AST Record Layout
    275 // CHECK: *** Dumping AST Record Layout
    276 // CHECK-NEXT:    0 | struct JC4
    277 // CHECK-NEXT:    0 |   struct JC1 (primary base)
    278 // CHECK-NEXT:    0 |     (JC1 vftable pointer)
    279 // CHECK-NEXT:    4 |     struct JC0 (base) (empty)
    280 // CHECK-NEXT:    8 |   struct JC2 (base)
    281 // CHECK-NEXT:    8 |     struct JC1 (primary base)
    282 // CHECK-NEXT:    8 |       (JC1 vftable pointer)
    283 // CHECK-NEXT:   12 |       struct JC0 (base) (empty)
    284 // CHECK-NEXT:      | [sizeof=12, align=4
    285 // CHECK-NEXT:      |  nvsize=12, nvalign=4]
    286 // CHECK-X64: *** Dumping AST Record Layout
    287 // CHECK-X64: *** Dumping AST Record Layout
    288 // CHECK-X64: *** Dumping AST Record Layout
    289 // CHECK-X64: *** Dumping AST Record Layout
    290 // CHECK-X64-NEXT:    0 | struct JC4
    291 // CHECK-X64-NEXT:    0 |   struct JC1 (primary base)
    292 // CHECK-X64-NEXT:    0 |     (JC1 vftable pointer)
    293 // CHECK-X64-NEXT:    8 |     struct JC0 (base) (empty)
    294 // CHECK-X64-NEXT:   16 |   struct JC2 (base)
    295 // CHECK-X64-NEXT:   16 |     struct JC1 (primary base)
    296 // CHECK-X64-NEXT:   16 |       (JC1 vftable pointer)
    297 // CHECK-X64-NEXT:   24 |       struct JC0 (base) (empty)
    298 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    299 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    300 
    301 struct RA {};
    302 struct RB { char c; };
    303 struct RV {};
    304 struct RW { char c; };
    305 struct RY { RY() { printf("%Id\n", (char*)this - buffer); } };
    306 struct RX0 : RB, RA {};
    307 struct RX1 : RA, RB {};
    308 struct RX2 : RA { char a; };
    309 struct RX3 : RA { RB a; };
    310 struct RX4 { RA a; char b; };
    311 struct RX5 { RA a; RB b; };
    312 struct RX6 : virtual RV { RB a; };
    313 struct RX7 : virtual RW { RA a; };
    314 struct RX8 : RA, virtual RW {};
    315 
    316 struct RZ0 : RX0, RY {};
    317 // CHECK: *** Dumping AST Record Layout
    318 // CHECK: *** Dumping AST Record Layout
    319 // CHECK: *** Dumping AST Record Layout
    320 // CHECK: *** Dumping AST Record Layout
    321 // CHECK: *** Dumping AST Record Layout
    322 // CHECK-NEXT:    0 | struct RZ0
    323 // CHECK-NEXT:    0 |   struct RX0 (base)
    324 // CHECK-NEXT:    0 |     struct RB (base)
    325 // CHECK-NEXT:    0 |       char c
    326 // CHECK-NEXT:    1 |     struct RA (base) (empty)
    327 // CHECK-NEXT:    2 |   struct RY (base) (empty)
    328 // CHECK-NEXT:      | [sizeof=2, align=1
    329 // CHECK-NEXT:      |  nvsize=2, nvalign=1]
    330 // CHECK-X64: *** Dumping AST Record Layout
    331 // CHECK-X64: *** Dumping AST Record Layout
    332 // CHECK-X64: *** Dumping AST Record Layout
    333 // CHECK-X64: *** Dumping AST Record Layout
    334 // CHECK-X64: *** Dumping AST Record Layout
    335 // CHECK-X64-NEXT:    0 | struct RZ0
    336 // CHECK-X64-NEXT:    0 |   struct RX0 (base)
    337 // CHECK-X64-NEXT:    0 |     struct RB (base)
    338 // CHECK-X64-NEXT:    0 |       char c
    339 // CHECK-X64-NEXT:    1 |     struct RA (base) (empty)
    340 // CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
    341 // CHECK-X64-NEXT:      | [sizeof=2, align=1
    342 // CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
    343 
    344 struct RZ1 : RX1, RY {};
    345 // CHECK: *** Dumping AST Record Layout
    346 // CHECK: *** Dumping AST Record Layout
    347 // CHECK-NEXT:    0 | struct RZ1
    348 // CHECK-NEXT:    0 |   struct RX1 (base)
    349 // CHECK-NEXT:    0 |     struct RA (base) (empty)
    350 // CHECK-NEXT:    0 |     struct RB (base)
    351 // CHECK-NEXT:    0 |       char c
    352 // CHECK-NEXT:    1 |   struct RY (base) (empty)
    353 // CHECK-NEXT:      | [sizeof=1, align=1
    354 // CHECK-NEXT:      |  nvsize=1, nvalign=1]
    355 // CHECK-X64: *** Dumping AST Record Layout
    356 // CHECK-X64: *** Dumping AST Record Layout
    357 // CHECK-X64-NEXT:    0 | struct RZ1
    358 // CHECK-X64-NEXT:    0 |   struct RX1 (base)
    359 // CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
    360 // CHECK-X64-NEXT:    0 |     struct RB (base)
    361 // CHECK-X64-NEXT:    0 |       char c
    362 // CHECK-X64-NEXT:    1 |   struct RY (base) (empty)
    363 // CHECK-X64-NEXT:      | [sizeof=1, align=1
    364 // CHECK-X64-NEXT:      |  nvsize=1, nvalign=1]
    365 
    366 struct RZ2 : RX2, RY {};
    367 // CHECK: *** Dumping AST Record Layout
    368 // CHECK: *** Dumping AST Record Layout
    369 // CHECK-NEXT:    0 | struct RZ2
    370 // CHECK-NEXT:    0 |   struct RX2 (base)
    371 // CHECK-NEXT:    0 |     struct RA (base) (empty)
    372 // CHECK-NEXT:    0 |     char a
    373 // CHECK-NEXT:    2 |   struct RY (base) (empty)
    374 // CHECK-NEXT:      | [sizeof=2, align=1
    375 // CHECK-NEXT:      |  nvsize=2, nvalign=1]
    376 // CHECK-X64: *** Dumping AST Record Layout
    377 // CHECK-X64: *** Dumping AST Record Layout
    378 // CHECK-X64-NEXT:    0 | struct RZ2
    379 // CHECK-X64-NEXT:    0 |   struct RX2 (base)
    380 // CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
    381 // CHECK-X64-NEXT:    0 |     char a
    382 // CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
    383 // CHECK-X64-NEXT:      | [sizeof=2, align=1
    384 // CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
    385 
    386 struct RZ3 : RX3, RY {};
    387 // CHECK: *** Dumping AST Record Layout
    388 // CHECK: *** Dumping AST Record Layout
    389 // CHECK-NEXT:    0 | struct RZ3
    390 // CHECK-NEXT:    0 |   struct RX3 (base)
    391 // CHECK-NEXT:    0 |     struct RA (base) (empty)
    392 // CHECK-NEXT:    0 |     struct RB a
    393 // CHECK-NEXT:    0 |       char c
    394 // CHECK-NEXT:    1 |   struct RY (base) (empty)
    395 // CHECK-NEXT:      | [sizeof=1, align=1
    396 // CHECK-NEXT:      |  nvsize=1, nvalign=1]
    397 // CHECK-X64: *** Dumping AST Record Layout
    398 // CHECK-X64: *** Dumping AST Record Layout
    399 // CHECK-X64-NEXT:    0 | struct RZ3
    400 // CHECK-X64-NEXT:    0 |   struct RX3 (base)
    401 // CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
    402 // CHECK-X64-NEXT:    0 |     struct RB a
    403 // CHECK-X64-NEXT:    0 |       char c
    404 // CHECK-X64-NEXT:    1 |   struct RY (base) (empty)
    405 // CHECK-X64-NEXT:      | [sizeof=1, align=1
    406 // CHECK-X64-NEXT:      |  nvsize=1, nvalign=1]
    407 
    408 struct RZ4 : RX4, RY {};
    409 // CHECK: *** Dumping AST Record Layout
    410 // CHECK: *** Dumping AST Record Layout
    411 // CHECK-NEXT:    0 | struct RZ4
    412 // CHECK-NEXT:    0 |   struct RX4 (base)
    413 // CHECK-NEXT:    0 |     struct RA a (empty)
    414 // CHECK-NEXT:    1 |     char b
    415 // CHECK-NEXT:    3 |   struct RY (base) (empty)
    416 // CHECK-NEXT:      | [sizeof=3, align=1
    417 // CHECK-NEXT:      |  nvsize=3, nvalign=1]
    418 // CHECK-X64: *** Dumping AST Record Layout
    419 // CHECK-X64: *** Dumping AST Record Layout
    420 // CHECK-X64-NEXT:    0 | struct RZ4
    421 // CHECK-X64-NEXT:    0 |   struct RX4 (base)
    422 // CHECK-X64-NEXT:    0 |     struct RA a (empty)
    423 // CHECK-X64-NEXT:    1 |     char b
    424 // CHECK-X64-NEXT:    3 |   struct RY (base) (empty)
    425 // CHECK-X64-NEXT:      | [sizeof=3, align=1
    426 // CHECK-X64-NEXT:      |  nvsize=3, nvalign=1]
    427 
    428 struct RZ5 : RX5, RY {};
    429 // CHECK: *** Dumping AST Record Layout
    430 // CHECK: *** Dumping AST Record Layout
    431 // CHECK-NEXT:    0 | struct RZ5
    432 // CHECK-NEXT:    0 |   struct RX5 (base)
    433 // CHECK-NEXT:    0 |     struct RA a (empty)
    434 // CHECK-NEXT:    1 |     struct RB b
    435 // CHECK-NEXT:    1 |       char c
    436 // CHECK-NEXT:    2 |   struct RY (base) (empty)
    437 // CHECK-NEXT:      | [sizeof=2, align=1
    438 // CHECK-NEXT:      |  nvsize=2, nvalign=1]
    439 // CHECK-X64: *** Dumping AST Record Layout
    440 // CHECK-X64: *** Dumping AST Record Layout
    441 // CHECK-X64-NEXT:    0 | struct RZ5
    442 // CHECK-X64-NEXT:    0 |   struct RX5 (base)
    443 // CHECK-X64-NEXT:    0 |     struct RA a (empty)
    444 // CHECK-X64-NEXT:    1 |     struct RB b
    445 // CHECK-X64-NEXT:    1 |       char c
    446 // CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
    447 // CHECK-X64-NEXT:      | [sizeof=2, align=1
    448 // CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
    449 
    450 struct RZ6 : RX6, RY {};
    451 // CHECK: *** Dumping AST Record Layout
    452 // CHECK: *** Dumping AST Record Layout
    453 // CHECK: *** Dumping AST Record Layout
    454 // CHECK-NEXT:    0 | struct RZ6
    455 // CHECK-NEXT:    0 |   struct RX6 (base)
    456 // CHECK-NEXT:    0 |     (RX6 vbtable pointer)
    457 // CHECK-NEXT:    4 |     struct RB a
    458 // CHECK-NEXT:    4 |       char c
    459 // CHECK-NEXT:    9 |   struct RY (base) (empty)
    460 // CHECK-NEXT:   12 |   struct RV (virtual base) (empty)
    461 // CHECK-NEXT:      | [sizeof=12, align=4
    462 // CHECK-NEXT:      |  nvsize=12, nvalign=4]
    463 // CHECK-X64: *** Dumping AST Record Layout
    464 // CHECK-X64: *** Dumping AST Record Layout
    465 // CHECK-X64: *** Dumping AST Record Layout
    466 // CHECK-X64-NEXT:    0 | struct RZ6
    467 // CHECK-X64-NEXT:    0 |   struct RX6 (base)
    468 // CHECK-X64-NEXT:    0 |     (RX6 vbtable pointer)
    469 // CHECK-X64-NEXT:    8 |     struct RB a
    470 // CHECK-X64-NEXT:    8 |       char c
    471 // CHECK-X64-NEXT:   17 |   struct RY (base) (empty)
    472 // CHECK-X64-NEXT:   24 |   struct RV (virtual base) (empty)
    473 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    474 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    475 
    476 struct RZ7 : RX7, RY {};
    477 // CHECK: *** Dumping AST Record Layout
    478 // CHECK: *** Dumping AST Record Layout
    479 // CHECK: *** Dumping AST Record Layout
    480 // CHECK-NEXT:    0 | struct RZ7
    481 // CHECK-NEXT:    0 |   struct RX7 (base)
    482 // CHECK-NEXT:    0 |     (RX7 vbtable pointer)
    483 // CHECK-NEXT:    4 |     struct RA a (empty)
    484 // CHECK-NEXT:    8 |   struct RY (base) (empty)
    485 // CHECK-NEXT:    8 |   struct RW (virtual base)
    486 // CHECK-NEXT:    8 |     char c
    487 // CHECK-NEXT:      | [sizeof=9, align=4
    488 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
    489 // CHECK-X64: *** Dumping AST Record Layout
    490 // CHECK-X64: *** Dumping AST Record Layout
    491 // CHECK-X64: *** Dumping AST Record Layout
    492 // CHECK-X64-NEXT:    0 | struct RZ7
    493 // CHECK-X64-NEXT:    0 |   struct RX7 (base)
    494 // CHECK-X64-NEXT:    0 |     (RX7 vbtable pointer)
    495 // CHECK-X64-NEXT:    8 |     struct RA a (empty)
    496 // CHECK-X64-NEXT:   16 |   struct RY (base) (empty)
    497 // CHECK-X64-NEXT:   16 |   struct RW (virtual base)
    498 // CHECK-X64-NEXT:   16 |     char c
    499 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    500 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
    501 
    502 struct RZ8 : RX8, RY {};
    503 // CHECK: *** Dumping AST Record Layout
    504 // CHECK: *** Dumping AST Record Layout
    505 // CHECK-NEXT:    0 | struct RZ8
    506 // CHECK-NEXT:    0 |   struct RX8 (base)
    507 // CHECK-NEXT:    4 |     struct RA (base) (empty)
    508 // CHECK-NEXT:    0 |     (RX8 vbtable pointer)
    509 // CHECK-NEXT:    4 |   struct RY (base) (empty)
    510 // CHECK-NEXT:    4 |   struct RW (virtual base)
    511 // CHECK-NEXT:    4 |     char c
    512 // CHECK-NEXT:      | [sizeof=5, align=4
    513 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
    514 // CHECK-X64: *** Dumping AST Record Layout
    515 // CHECK-X64: *** Dumping AST Record Layout
    516 // CHECK-X64-NEXT:    0 | struct RZ8
    517 // CHECK-X64-NEXT:    0 |   struct RX8 (base)
    518 // CHECK-X64-NEXT:    8 |     struct RA (base) (empty)
    519 // CHECK-X64-NEXT:    0 |     (RX8 vbtable pointer)
    520 // CHECK-X64-NEXT:    8 |   struct RY (base) (empty)
    521 // CHECK-X64-NEXT:    8 |   struct RW (virtual base)
    522 // CHECK-X64-NEXT:    8 |     char c
    523 // CHECK-X64-NEXT:      | [sizeof=16, align=8
    524 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
    525 
    526 struct JA {};
    527 struct JB {};
    528 struct JC : JA { virtual void f() {} };
    529 struct JD : virtual JB, virtual JC { virtual void f() {} JD() {} };
    530 
    531 // CHECK: *** Dumping AST Record Layout
    532 // CHECK: *** Dumping AST Record Layout
    533 // CHECK: *** Dumping AST Record Layout
    534 // CHECK: *** Dumping AST Record Layout
    535 // CHECK-NEXT:    0 | struct JD
    536 // CHECK-NEXT:    0 |   (JD vbtable pointer)
    537 // CHECK-NEXT:    4 |   struct JB (virtual base) (empty)
    538 // CHECK-NEXT:    4 |   (vtordisp for vbase JC)
    539 // CHECK-NEXT:    8 |   struct JC (virtual base)
    540 // CHECK-NEXT:    8 |     (JC vftable pointer)
    541 // CHECK-NEXT:   12 |     struct JA (base) (empty)
    542 // CHECK-NEXT:      | [sizeof=12, align=4
    543 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
    544 // CHECK-X64: *** Dumping AST Record Layout
    545 // CHECK-X64: *** Dumping AST Record Layout
    546 // CHECK-X64: *** Dumping AST Record Layout
    547 // CHECK-X64: *** Dumping AST Record Layout
    548 // CHECK-X64-NEXT:    0 | struct JD
    549 // CHECK-X64-NEXT:    0 |   (JD vbtable pointer)
    550 // CHECK-X64-NEXT:    8 |   struct JB (virtual base) (empty)
    551 // CHECK-X64-NEXT:   12 |   (vtordisp for vbase JC)
    552 // CHECK-X64-NEXT:   16 |   struct JC (virtual base)
    553 // CHECK-X64-NEXT:   16 |     (JC vftable pointer)
    554 // CHECK-X64-NEXT:   24 |     struct JA (base) (empty)
    555 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    556 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
    557 
    558 int a[
    559 sizeof(AT3) +
    560 sizeof(BT3) +
    561 sizeof(T3) +
    562 sizeof(E) +
    563 sizeof(F) +
    564 sizeof(JC4) +
    565 sizeof(RZ0) +
    566 sizeof(RZ1) +
    567 sizeof(RZ2) +
    568 sizeof(RZ3) +
    569 sizeof(RZ4) +
    570 sizeof(RZ5) +
    571 sizeof(RZ6) +
    572 sizeof(RZ7) +
    573 sizeof(RZ8) +
    574 sizeof(JD) +
    575 0];
    576