Home | History | Annotate | Download | only in Layout
      1 // RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -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 -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 { B0() { printf("B0 = %p\n", this); } };
      9 struct B1 { B1() { printf("B1 = %p\n", this); } };
     10 struct B2 { B2() { printf("B2 = %p\n", this); } };
     11 struct B3 { B3() { printf("B3 = %p\n", this); } };
     12 struct B4 { B4() { printf("B4 = %p\n", this); } };
     13 struct B5 { B5() { printf("B5 = %p\n", this); } };
     14 struct __declspec(align(2)) B6 { B6() { printf("B6 = %p\n", this); } };
     15 struct __declspec(align(16)) B7 { B7() { printf("B7 = %p\n", this); } };
     16 struct B8 { char c[5]; B8() { printf("B8 = %p\n", this); } };
     17 struct B9 { char c[6]; B9() { printf("B9 = %p\n", this); } };
     18 struct B10 { char c[7]; B10() { printf("B10 = %p\n", this); } };
     19 struct B11 { char c[8]; B11() { printf("B11 = %p\n", this); } };
     20 struct B0X { B0X() { printf("B0 = %p\n", this); } };
     21 struct B1X { B1X() { printf("B1 = %p\n", this); } };
     22 struct __declspec(align(16)) B2X { B2X() { printf("B2 = %p\n", this); } };
     23 struct __declspec(align(2)) B3X { B3X() { printf("B3 = %p\n", this); } };
     24 struct B4X { B4X() { printf("B4 = %p\n", this); } };
     25 struct B5X { B5X() { printf("B5 = %p\n", this); } };
     26 struct B6X { B6X() { printf("B6 = %p\n", this); } };
     27 struct B8X { short a; B8X() : a(0x000000B8) { printf("B8 = %p\n", this); } };
     28 
     29 struct AA : B8, B1, virtual B0 {
     30 	int a;
     31 	AA() : a(0x000000AA) { printf("AA = %p\n", this); }
     32 };
     33 
     34 // CHECK: *** Dumping AST Record Layout
     35 // CHECK: *** Dumping AST Record Layout
     36 // CHECK: *** Dumping AST Record Layout
     37 // CHECK: *** Dumping AST Record Layout
     38 // CHECK-NEXT:    0 | struct AA
     39 // CHECK-NEXT:    0 |   struct B8 (base)
     40 // CHECK-NEXT:    0 |     char [5] c
     41 // CHECK-NEXT:   13 |   struct B1 (base) (empty)
     42 // CHECK-NEXT:    8 |   (AA vbtable pointer)
     43 // CHECK-NEXT:   16 |   int a
     44 // CHECK-NEXT:   20 |   struct B0 (virtual base) (empty)
     45 // CHECK-NEXT:      | [sizeof=20, align=4
     46 // CHECK-NEXT:      |  nvsize=20, nvalign=4]
     47 // CHECK-X64: *** Dumping AST Record Layout
     48 // CHECK-X64: *** Dumping AST Record Layout
     49 // CHECK-X64: *** Dumping AST Record Layout
     50 // CHECK-X64: *** Dumping AST Record Layout
     51 // CHECK-X64-NEXT:    0 | struct AA
     52 // CHECK-X64-NEXT:    0 |   struct B8 (base)
     53 // CHECK-X64-NEXT:    0 |     char [5] c
     54 // CHECK-X64-NEXT:   17 |   struct B1 (base) (empty)
     55 // CHECK-X64-NEXT:    8 |   (AA vbtable pointer)
     56 // CHECK-X64-NEXT:   20 |   int a
     57 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
     58 // CHECK-X64-NEXT:      | [sizeof=24, align=8
     59 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
     60 
     61 struct AB : B8, B1, virtual B0 {
     62 	short a;
     63 	AB() : a(0x000000AB) { printf("AB = %p\n", this); }
     64 };
     65 
     66 // CHECK: *** Dumping AST Record Layout
     67 // CHECK-NEXT:    0 | struct AB
     68 // CHECK-NEXT:    0 |   struct B8 (base)
     69 // CHECK-NEXT:    0 |     char [5] c
     70 // CHECK-NEXT:   13 |   struct B1 (base) (empty)
     71 // CHECK-NEXT:    8 |   (AB vbtable pointer)
     72 // CHECK-NEXT:   14 |   short a
     73 // CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
     74 // CHECK-NEXT:      | [sizeof=16, align=4
     75 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
     76 // CHECK-X64: *** Dumping AST Record Layout
     77 // CHECK-X64-NEXT:    0 | struct AB
     78 // CHECK-X64-NEXT:    0 |   struct B8 (base)
     79 // CHECK-X64-NEXT:    0 |     char [5] c
     80 // CHECK-X64-NEXT:   17 |   struct B1 (base) (empty)
     81 // CHECK-X64-NEXT:    8 |   (AB vbtable pointer)
     82 // CHECK-X64-NEXT:   18 |   short a
     83 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
     84 // CHECK-X64-NEXT:      | [sizeof=24, align=8
     85 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
     86 
     87 struct AC : B8, B1, virtual B0 {
     88 	char a;
     89 	AC() : a(0x000000AC) { printf("AC = %p\n", this); }
     90 };
     91 
     92 // CHECK: *** Dumping AST Record Layout
     93 // CHECK-NEXT:    0 | struct AC
     94 // CHECK-NEXT:    0 |   struct B8 (base)
     95 // CHECK-NEXT:    0 |     char [5] c
     96 // CHECK-NEXT:   12 |   struct B1 (base) (empty)
     97 // CHECK-NEXT:    8 |   (AC vbtable pointer)
     98 // CHECK-NEXT:   12 |   char a
     99 // CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
    100 // CHECK-NEXT:      | [sizeof=16, align=4
    101 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
    102 // CHECK-X64: *** Dumping AST Record Layout
    103 // CHECK-X64-NEXT:    0 | struct AC
    104 // CHECK-X64-NEXT:    0 |   struct B8 (base)
    105 // CHECK-X64-NEXT:    0 |     char [5] c
    106 // CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
    107 // CHECK-X64-NEXT:    8 |   (AC vbtable pointer)
    108 // CHECK-X64-NEXT:   16 |   char a
    109 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
    110 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    111 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    112 
    113 struct AD : B8, B1, virtual B0 {
    114 	AD() { printf("AD = %p\n", this); }
    115 };
    116 
    117 // CHECK: *** Dumping AST Record Layout
    118 // CHECK-NEXT:    0 | struct AD
    119 // CHECK-NEXT:    0 |   struct B8 (base)
    120 // CHECK-NEXT:    0 |     char [5] c
    121 // CHECK-NEXT:   12 |   struct B1 (base) (empty)
    122 // CHECK-NEXT:    8 |   (AD vbtable pointer)
    123 // CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
    124 // CHECK-NEXT:      | [sizeof=12, align=4
    125 // CHECK-NEXT:      |  nvsize=12, nvalign=4]
    126 // CHECK-X64: *** Dumping AST Record Layout
    127 // CHECK-X64-NEXT:    0 | struct AD
    128 // CHECK-X64-NEXT:    0 |   struct B8 (base)
    129 // CHECK-X64-NEXT:    0 |     char [5] c
    130 // CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
    131 // CHECK-X64-NEXT:    8 |   (AD vbtable pointer)
    132 // CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
    133 // CHECK-X64-NEXT:      | [sizeof=16, align=8
    134 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
    135 
    136 struct AA1 : B9, B1, virtual B0 {
    137 	int a;
    138 	AA1() : a(0x00000AA1) { printf("AA1 = %p\n", this); }
    139 };
    140 
    141 // CHECK: *** Dumping AST Record Layout
    142 // CHECK: *** Dumping AST Record Layout
    143 // CHECK-NEXT:    0 | struct AA1
    144 // CHECK-NEXT:    0 |   struct B9 (base)
    145 // CHECK-NEXT:    0 |     char [6] c
    146 // CHECK-NEXT:   14 |   struct B1 (base) (empty)
    147 // CHECK-NEXT:    8 |   (AA1 vbtable pointer)
    148 // CHECK-NEXT:   16 |   int a
    149 // CHECK-NEXT:   20 |   struct B0 (virtual base) (empty)
    150 // CHECK-NEXT:      | [sizeof=20, align=4
    151 // CHECK-NEXT:      |  nvsize=20, nvalign=4]
    152 // CHECK-X64: *** Dumping AST Record Layout
    153 // CHECK-X64: *** Dumping AST Record Layout
    154 // CHECK-X64-NEXT:    0 | struct AA1
    155 // CHECK-X64-NEXT:    0 |   struct B9 (base)
    156 // CHECK-X64-NEXT:    0 |     char [6] c
    157 // CHECK-X64-NEXT:   18 |   struct B1 (base) (empty)
    158 // CHECK-X64-NEXT:    8 |   (AA1 vbtable pointer)
    159 // CHECK-X64-NEXT:   20 |   int a
    160 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
    161 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    162 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    163 
    164 struct AB1 : B9, B1, virtual B0 {
    165 	short a;
    166 	AB1() : a(0x00000AB1) { printf("AB1 = %p\n", this); }
    167 };
    168 
    169 // CHECK: *** Dumping AST Record Layout
    170 // CHECK-NEXT:    0 | struct AB1
    171 // CHECK-NEXT:    0 |   struct B9 (base)
    172 // CHECK-NEXT:    0 |     char [6] c
    173 // CHECK-NEXT:   12 |   struct B1 (base) (empty)
    174 // CHECK-NEXT:    8 |   (AB1 vbtable pointer)
    175 // CHECK-NEXT:   12 |   short a
    176 // CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
    177 // CHECK-NEXT:      | [sizeof=16, align=4
    178 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
    179 // CHECK-X64: *** Dumping AST Record Layout
    180 // CHECK-X64-NEXT:    0 | struct AB1
    181 // CHECK-X64-NEXT:    0 |   struct B9 (base)
    182 // CHECK-X64-NEXT:    0 |     char [6] c
    183 // CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
    184 // CHECK-X64-NEXT:    8 |   (AB1 vbtable pointer)
    185 // CHECK-X64-NEXT:   16 |   short a
    186 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
    187 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    188 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    189 
    190 struct AC1 : B9, B1, virtual B0 {
    191 	char a;
    192 	AC1() : a(0x000000C1) { printf("AC1 = %p\n", this); }
    193 };
    194 
    195 // CHECK: *** Dumping AST Record Layout
    196 // CHECK-NEXT:    0 | struct AC1
    197 // CHECK-NEXT:    0 |   struct B9 (base)
    198 // CHECK-NEXT:    0 |     char [6] c
    199 // CHECK-NEXT:   12 |   struct B1 (base) (empty)
    200 // CHECK-NEXT:    8 |   (AC1 vbtable pointer)
    201 // CHECK-NEXT:   12 |   char a
    202 // CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
    203 // CHECK-NEXT:      | [sizeof=16, align=4
    204 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
    205 // CHECK-X64: *** Dumping AST Record Layout
    206 // CHECK-X64-NEXT:    0 | struct AC1
    207 // CHECK-X64-NEXT:    0 |   struct B9 (base)
    208 // CHECK-X64-NEXT:    0 |     char [6] c
    209 // CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
    210 // CHECK-X64-NEXT:    8 |   (AC1 vbtable pointer)
    211 // CHECK-X64-NEXT:   16 |   char a
    212 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
    213 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    214 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    215 
    216 struct AD1 : B9, B1, virtual B0 {
    217 	AD1() { printf("AD1 = %p\n", this); }
    218 };
    219 
    220 // CHECK: *** Dumping AST Record Layout
    221 // CHECK-NEXT:    0 | struct AD1
    222 // CHECK-NEXT:    0 |   struct B9 (base)
    223 // CHECK-NEXT:    0 |     char [6] c
    224 // CHECK-NEXT:   12 |   struct B1 (base) (empty)
    225 // CHECK-NEXT:    8 |   (AD1 vbtable pointer)
    226 // CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
    227 // CHECK-NEXT:      | [sizeof=12, align=4
    228 // CHECK-NEXT:      |  nvsize=12, nvalign=4]
    229 // CHECK-X64: *** Dumping AST Record Layout
    230 // CHECK-X64-NEXT:    0 | struct AD1
    231 // CHECK-X64-NEXT:    0 |   struct B9 (base)
    232 // CHECK-X64-NEXT:    0 |     char [6] c
    233 // CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
    234 // CHECK-X64-NEXT:    8 |   (AD1 vbtable pointer)
    235 // CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
    236 // CHECK-X64-NEXT:      | [sizeof=16, align=8
    237 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
    238 
    239 struct AA2 : B10, B1, virtual B0 {
    240 	int a;
    241 	AA2() : a(0x00000AA2) { printf("AA2 = %p\n", this); }
    242 };
    243 
    244 // CHECK: *** Dumping AST Record Layout
    245 // CHECK: *** Dumping AST Record Layout
    246 // CHECK-NEXT:    0 | struct AA2
    247 // CHECK-NEXT:    0 |   struct B10 (base)
    248 // CHECK-NEXT:    0 |     char [7] c
    249 // CHECK-NEXT:   15 |   struct B1 (base) (empty)
    250 // CHECK-NEXT:    8 |   (AA2 vbtable pointer)
    251 // CHECK-NEXT:   16 |   int a
    252 // CHECK-NEXT:   20 |   struct B0 (virtual base) (empty)
    253 // CHECK-NEXT:      | [sizeof=20, align=4
    254 // CHECK-NEXT:      |  nvsize=20, nvalign=4]
    255 // CHECK-X64: *** Dumping AST Record Layout
    256 // CHECK-X64: *** Dumping AST Record Layout
    257 // CHECK-X64-NEXT:    0 | struct AA2
    258 // CHECK-X64-NEXT:    0 |   struct B10 (base)
    259 // CHECK-X64-NEXT:    0 |     char [7] c
    260 // CHECK-X64-NEXT:   19 |   struct B1 (base) (empty)
    261 // CHECK-X64-NEXT:    8 |   (AA2 vbtable pointer)
    262 // CHECK-X64-NEXT:   20 |   int a
    263 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
    264 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    265 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    266 
    267 struct AB2 : B10, B1, virtual B0 {
    268 	short a;
    269 	AB2() : a(0x00000AB2) { printf("AB2 = %p\n", this); }
    270 };
    271 
    272 // CHECK: *** Dumping AST Record Layout
    273 // CHECK-NEXT:    0 | struct AB2
    274 // CHECK-NEXT:    0 |   struct B10 (base)
    275 // CHECK-NEXT:    0 |     char [7] c
    276 // CHECK-NEXT:   13 |   struct B1 (base) (empty)
    277 // CHECK-NEXT:    8 |   (AB2 vbtable pointer)
    278 // CHECK-NEXT:   14 |   short a
    279 // CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
    280 // CHECK-NEXT:      | [sizeof=16, align=4
    281 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
    282 // CHECK-X64: *** Dumping AST Record Layout
    283 // CHECK-X64-NEXT:    0 | struct AB2
    284 // CHECK-X64-NEXT:    0 |   struct B10 (base)
    285 // CHECK-X64-NEXT:    0 |     char [7] c
    286 // CHECK-X64-NEXT:   17 |   struct B1 (base) (empty)
    287 // CHECK-X64-NEXT:    8 |   (AB2 vbtable pointer)
    288 // CHECK-X64-NEXT:   18 |   short a
    289 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
    290 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    291 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    292 
    293 struct AC2 : B10, B1, virtual B0 {
    294 	char a;
    295 	AC2() : a(0x000000C2) { printf("AC2 = %p\n", this); }
    296 };
    297 
    298 // CHECK: *** Dumping AST Record Layout
    299 // CHECK-NEXT:    0 | struct AC2
    300 // CHECK-NEXT:    0 |   struct B10 (base)
    301 // CHECK-NEXT:    0 |     char [7] c
    302 // CHECK-NEXT:   12 |   struct B1 (base) (empty)
    303 // CHECK-NEXT:    8 |   (AC2 vbtable pointer)
    304 // CHECK-NEXT:   12 |   char a
    305 // CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
    306 // CHECK-NEXT:      | [sizeof=16, align=4
    307 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
    308 // CHECK-X64: *** Dumping AST Record Layout
    309 // CHECK-X64-NEXT:    0 | struct AC2
    310 // CHECK-X64-NEXT:    0 |   struct B10 (base)
    311 // CHECK-X64-NEXT:    0 |     char [7] c
    312 // CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
    313 // CHECK-X64-NEXT:    8 |   (AC2 vbtable pointer)
    314 // CHECK-X64-NEXT:   16 |   char a
    315 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
    316 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    317 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    318 
    319 struct AD2 : B10, B1, virtual B0 {
    320 	AD2() { printf("AD2 = %p\n", this); }
    321 };
    322 
    323 // CHECK: *** Dumping AST Record Layout
    324 // CHECK-NEXT:    0 | struct AD2
    325 // CHECK-NEXT:    0 |   struct B10 (base)
    326 // CHECK-NEXT:    0 |     char [7] c
    327 // CHECK-NEXT:   12 |   struct B1 (base) (empty)
    328 // CHECK-NEXT:    8 |   (AD2 vbtable pointer)
    329 // CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
    330 // CHECK-NEXT:      | [sizeof=12, align=4
    331 // CHECK-NEXT:      |  nvsize=12, nvalign=4]
    332 // CHECK-X64: *** Dumping AST Record Layout
    333 // CHECK-X64-NEXT:    0 | struct AD2
    334 // CHECK-X64-NEXT:    0 |   struct B10 (base)
    335 // CHECK-X64-NEXT:    0 |     char [7] c
    336 // CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
    337 // CHECK-X64-NEXT:    8 |   (AD2 vbtable pointer)
    338 // CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
    339 // CHECK-X64-NEXT:      | [sizeof=16, align=8
    340 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
    341 
    342 struct AA3 : B11, B1, virtual B0 {
    343 	int a;
    344 	AA3() : a(0x00000AA3) { printf("AA3 = %p\n", this); }
    345 };
    346 
    347 // CHECK: *** Dumping AST Record Layout
    348 // CHECK: *** Dumping AST Record Layout
    349 // CHECK-NEXT:    0 | struct AA3
    350 // CHECK-NEXT:    0 |   struct B11 (base)
    351 // CHECK-NEXT:    0 |     char [8] c
    352 // CHECK-NEXT:   12 |   struct B1 (base) (empty)
    353 // CHECK-NEXT:    8 |   (AA3 vbtable pointer)
    354 // CHECK-NEXT:   12 |   int a
    355 // CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
    356 // CHECK-NEXT:      | [sizeof=16, align=4
    357 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
    358 // CHECK-X64: *** Dumping AST Record Layout
    359 // CHECK-X64: *** Dumping AST Record Layout
    360 // CHECK-X64-NEXT:    0 | struct AA3
    361 // CHECK-X64-NEXT:    0 |   struct B11 (base)
    362 // CHECK-X64-NEXT:    0 |     char [8] c
    363 // CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
    364 // CHECK-X64-NEXT:    8 |   (AA3 vbtable pointer)
    365 // CHECK-X64-NEXT:   16 |   int a
    366 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
    367 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    368 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    369 
    370 struct AB3 : B11, B1, virtual B0 {
    371 	short a;
    372 	AB3() : a(0x00000AB3) { printf("AB3 = %p\n", this); }
    373 };
    374 
    375 // CHECK: *** Dumping AST Record Layout
    376 // CHECK-NEXT:    0 | struct AB3
    377 // CHECK-NEXT:    0 |   struct B11 (base)
    378 // CHECK-NEXT:    0 |     char [8] c
    379 // CHECK-NEXT:   12 |   struct B1 (base) (empty)
    380 // CHECK-NEXT:    8 |   (AB3 vbtable pointer)
    381 // CHECK-NEXT:   12 |   short a
    382 // CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
    383 // CHECK-NEXT:      | [sizeof=16, align=4
    384 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
    385 // CHECK-X64: *** Dumping AST Record Layout
    386 // CHECK-X64-NEXT:    0 | struct AB3
    387 // CHECK-X64-NEXT:    0 |   struct B11 (base)
    388 // CHECK-X64-NEXT:    0 |     char [8] c
    389 // CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
    390 // CHECK-X64-NEXT:    8 |   (AB3 vbtable pointer)
    391 // CHECK-X64-NEXT:   16 |   short a
    392 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
    393 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    394 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    395 
    396 struct AC3 : B11, B1, virtual B0 {
    397 	char a;
    398 	AC3() : a(0x000000C3) { printf("AC3 = %p\n", this); }
    399 };
    400 
    401 // CHECK: *** Dumping AST Record Layout
    402 // CHECK-NEXT:    0 | struct AC3
    403 // CHECK-NEXT:    0 |   struct B11 (base)
    404 // CHECK-NEXT:    0 |     char [8] c
    405 // CHECK-NEXT:   12 |   struct B1 (base) (empty)
    406 // CHECK-NEXT:    8 |   (AC3 vbtable pointer)
    407 // CHECK-NEXT:   12 |   char a
    408 // CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
    409 // CHECK-NEXT:      | [sizeof=16, align=4
    410 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
    411 // CHECK-X64: *** Dumping AST Record Layout
    412 // CHECK-X64-NEXT:    0 | struct AC3
    413 // CHECK-X64-NEXT:    0 |   struct B11 (base)
    414 // CHECK-X64-NEXT:    0 |     char [8] c
    415 // CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
    416 // CHECK-X64-NEXT:    8 |   (AC3 vbtable pointer)
    417 // CHECK-X64-NEXT:   16 |   char a
    418 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
    419 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    420 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    421 
    422 struct AD3 : B11, B1, virtual B0 {
    423 	AD3() { printf("AD3 = %p\n", this); }
    424 };
    425 
    426 // CHECK: *** Dumping AST Record Layout
    427 // CHECK-NEXT:    0 | struct AD3
    428 // CHECK-NEXT:    0 |   struct B11 (base)
    429 // CHECK-NEXT:    0 |     char [8] c
    430 // CHECK-NEXT:   12 |   struct B1 (base) (empty)
    431 // CHECK-NEXT:    8 |   (AD3 vbtable pointer)
    432 // CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
    433 // CHECK-NEXT:      | [sizeof=12, align=4
    434 // CHECK-NEXT:      |  nvsize=12, nvalign=4]
    435 // CHECK-X64: *** Dumping AST Record Layout
    436 // CHECK-X64-NEXT:    0 | struct AD3
    437 // CHECK-X64-NEXT:    0 |   struct B11 (base)
    438 // CHECK-X64-NEXT:    0 |     char [8] c
    439 // CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
    440 // CHECK-X64-NEXT:    8 |   (AD3 vbtable pointer)
    441 // CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
    442 // CHECK-X64-NEXT:      | [sizeof=16, align=8
    443 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
    444 
    445 struct B : B1, B2, virtual B0 {
    446 	B() { printf("B = %p\n", this); }
    447 };
    448 
    449 // CHECK: *** Dumping AST Record Layout
    450 // CHECK: *** Dumping AST Record Layout
    451 // CHECK-NEXT:    0 | struct B
    452 // CHECK-NEXT:    0 |   struct B1 (base) (empty)
    453 // CHECK-NEXT:    8 |   struct B2 (base) (empty)
    454 // CHECK-NEXT:    4 |   (B vbtable pointer)
    455 // CHECK-NEXT:    8 |   struct B0 (virtual base) (empty)
    456 // CHECK-NEXT:      | [sizeof=8, align=4
    457 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
    458 // CHECK-X64: *** Dumping AST Record Layout
    459 // CHECK-X64: *** Dumping AST Record Layout
    460 // CHECK-X64-NEXT:    0 | struct B
    461 // CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
    462 // CHECK-X64-NEXT:   16 |   struct B2 (base) (empty)
    463 // CHECK-X64-NEXT:    8 |   (B vbtable pointer)
    464 // CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
    465 // CHECK-X64-NEXT:      | [sizeof=16, align=8
    466 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
    467 
    468 struct C : B1, B2, B3, virtual B0 {
    469 	char a;
    470 	C() : a(0x0000000C) { printf("C = %p\n", this); }
    471 };
    472 
    473 // CHECK: *** Dumping AST Record Layout
    474 // CHECK: *** Dumping AST Record Layout
    475 // CHECK-NEXT:    0 | struct C
    476 // CHECK-NEXT:    0 |   struct B1 (base) (empty)
    477 // CHECK-NEXT:    1 |   struct B2 (base) (empty)
    478 // CHECK-NEXT:    8 |   struct B3 (base) (empty)
    479 // CHECK-NEXT:    4 |   (C vbtable pointer)
    480 // CHECK-NEXT:    8 |   char a
    481 // CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
    482 // CHECK-NEXT:      | [sizeof=12, align=4
    483 // CHECK-NEXT:      |  nvsize=12, nvalign=4]
    484 // CHECK-X64: *** Dumping AST Record Layout
    485 // CHECK-X64: *** Dumping AST Record Layout
    486 // CHECK-X64-NEXT:    0 | struct C
    487 // CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
    488 // CHECK-X64-NEXT:    1 |   struct B2 (base) (empty)
    489 // CHECK-X64-NEXT:   16 |   struct B3 (base) (empty)
    490 // CHECK-X64-NEXT:    8 |   (C vbtable pointer)
    491 // CHECK-X64-NEXT:   16 |   char a
    492 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
    493 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    494 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    495 
    496 struct D : B1, B2, B3, B4, B5, virtual B0 {
    497 	int a;
    498 	D() : a(0x0000000D) { printf("D = %p\n", this); }
    499 };
    500 
    501 // CHECK: *** Dumping AST Record Layout
    502 // CHECK: *** Dumping AST Record Layout
    503 // CHECK: *** Dumping AST Record Layout
    504 // CHECK-NEXT:    0 | struct D
    505 // CHECK-NEXT:    0 |   struct B1 (base) (empty)
    506 // CHECK-NEXT:    1 |   struct B2 (base) (empty)
    507 // CHECK-NEXT:    2 |   struct B3 (base) (empty)
    508 // CHECK-NEXT:    3 |   struct B4 (base) (empty)
    509 // CHECK-NEXT:    8 |   struct B5 (base) (empty)
    510 // CHECK-NEXT:    4 |   (D vbtable pointer)
    511 // CHECK-NEXT:    8 |   int a
    512 // CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
    513 // CHECK-NEXT:      | [sizeof=12, align=4
    514 // CHECK-NEXT:      |  nvsize=12, nvalign=4]
    515 // CHECK-X64: *** Dumping AST Record Layout
    516 // CHECK-X64: *** Dumping AST Record Layout
    517 // CHECK-X64: *** Dumping AST Record Layout
    518 // CHECK-X64-NEXT:    0 | struct D
    519 // CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
    520 // CHECK-X64-NEXT:    1 |   struct B2 (base) (empty)
    521 // CHECK-X64-NEXT:    2 |   struct B3 (base) (empty)
    522 // CHECK-X64-NEXT:    3 |   struct B4 (base) (empty)
    523 // CHECK-X64-NEXT:   16 |   struct B5 (base) (empty)
    524 // CHECK-X64-NEXT:    8 |   (D vbtable pointer)
    525 // CHECK-X64-NEXT:   16 |   int a
    526 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
    527 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    528 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    529 
    530 struct E : B1, B6, B3, B4, B5, virtual B0 {
    531 	int a;
    532 	E() : a(0x0000000E) { printf("E = %p\n", this); }
    533 };
    534 
    535 // CHECK: *** Dumping AST Record Layout
    536 // CHECK: *** Dumping AST Record Layout
    537 // CHECK-NEXT:    0 | struct E
    538 // CHECK-NEXT:    0 |   struct B1 (base) (empty)
    539 // CHECK-NEXT:    2 |   struct B6 (base) (empty)
    540 // CHECK-NEXT:    3 |   struct B3 (base) (empty)
    541 // CHECK-NEXT:    4 |   struct B4 (base) (empty)
    542 // CHECK-NEXT:   13 |   struct B5 (base) (empty)
    543 // CHECK-NEXT:    8 |   (E vbtable pointer)
    544 // CHECK-NEXT:   16 |   int a
    545 // CHECK-NEXT:   20 |   struct B0 (virtual base) (empty)
    546 // CHECK-NEXT:      | [sizeof=20, align=4
    547 // CHECK-NEXT:      |  nvsize=20, nvalign=4]
    548 // CHECK-X64: *** Dumping AST Record Layout
    549 // CHECK-X64: *** Dumping AST Record Layout
    550 // CHECK-X64-NEXT:    0 | struct E
    551 // CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
    552 // CHECK-X64-NEXT:    2 |   struct B6 (base) (empty)
    553 // CHECK-X64-NEXT:    3 |   struct B3 (base) (empty)
    554 // CHECK-X64-NEXT:    4 |   struct B4 (base) (empty)
    555 // CHECK-X64-NEXT:   17 |   struct B5 (base) (empty)
    556 // CHECK-X64-NEXT:    8 |   (E vbtable pointer)
    557 // CHECK-X64-NEXT:   20 |   int a
    558 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
    559 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    560 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    561 
    562 struct F : B1, B6, B4, B8, B5, virtual B0 {
    563 	int a;
    564 	F() : a(0x0000000F) { printf("&a = %p\n", &a); printf("F = %p\n", this); }
    565 };
    566 
    567 // CHECK: *** Dumping AST Record Layout
    568 // CHECK-NEXT:    0 | struct F
    569 // CHECK-NEXT:    0 |   struct B1 (base) (empty)
    570 // CHECK-NEXT:    2 |   struct B6 (base) (empty)
    571 // CHECK-NEXT:    3 |   struct B4 (base) (empty)
    572 // CHECK-NEXT:    3 |   struct B8 (base)
    573 // CHECK-NEXT:    3 |     char [5] c
    574 // CHECK-NEXT:   12 |   struct B5 (base) (empty)
    575 // CHECK-NEXT:    8 |   (F vbtable pointer)
    576 // CHECK-NEXT:   12 |   int a
    577 // CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
    578 // CHECK-NEXT:      | [sizeof=16, align=4
    579 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
    580 // CHECK-X64: *** Dumping AST Record Layout
    581 // CHECK-X64-NEXT:    0 | struct F
    582 // CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
    583 // CHECK-X64-NEXT:    2 |   struct B6 (base) (empty)
    584 // CHECK-X64-NEXT:    3 |   struct B4 (base) (empty)
    585 // CHECK-X64-NEXT:    3 |   struct B8 (base)
    586 // CHECK-X64-NEXT:    3 |     char [5] c
    587 // CHECK-X64-NEXT:   16 |   struct B5 (base) (empty)
    588 // CHECK-X64-NEXT:    8 |   (F vbtable pointer)
    589 // CHECK-X64-NEXT:   16 |   int a
    590 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
    591 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    592 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    593 
    594 struct G : B8, B1, virtual B0 {
    595 	int a;
    596 	__declspec(align(16)) int a1;
    597 	G() : a(0x00000010), a1(0xf0000010) { printf("G = %p\n", this); }
    598 };
    599 
    600 // CHECK: *** Dumping AST Record Layout
    601 // CHECK-NEXT:    0 | struct G
    602 // CHECK-NEXT:    0 |   struct B8 (base)
    603 // CHECK-NEXT:    0 |     char [5] c
    604 // CHECK-NEXT:   21 |   struct B1 (base) (empty)
    605 // CHECK-NEXT:    8 |   (G vbtable pointer)
    606 // CHECK-NEXT:   24 |   int a
    607 // CHECK-NEXT:   32 |   int a1
    608 // CHECK-NEXT:   48 |   struct B0 (virtual base) (empty)
    609 // CHECK-NEXT:      | [sizeof=48, align=16
    610 // CHECK-NEXT:      |  nvsize=48, nvalign=16]
    611 // CHECK-X64: *** Dumping AST Record Layout
    612 // CHECK-X64-NEXT:    0 | struct G
    613 // CHECK-X64-NEXT:    0 |   struct B8 (base)
    614 // CHECK-X64-NEXT:    0 |     char [5] c
    615 // CHECK-X64-NEXT:   21 |   struct B1 (base) (empty)
    616 // CHECK-X64-NEXT:    8 |   (G vbtable pointer)
    617 // CHECK-X64-NEXT:   24 |   int a
    618 // CHECK-X64-NEXT:   32 |   int a1
    619 // CHECK-X64-NEXT:   48 |   struct B0 (virtual base) (empty)
    620 // CHECK-X64-NEXT:      | [sizeof=48, align=16
    621 // CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
    622 
    623 struct AX : B1X, B2X, B3X, B4X, virtual B0X {
    624 	int a;
    625 	AX() : a(0x0000000A) { printf(" A = %p\n", this); }
    626 };
    627 
    628 // CHECK: *** Dumping AST Record Layout
    629 // CHECK: *** Dumping AST Record Layout
    630 // CHECK: *** Dumping AST Record Layout
    631 // CHECK: *** Dumping AST Record Layout
    632 // CHECK: *** Dumping AST Record Layout
    633 // CHECK: *** Dumping AST Record Layout
    634 // CHECK-NEXT:    0 | struct AX
    635 // CHECK-NEXT:    0 |   struct B1X (base) (empty)
    636 // CHECK-NEXT:   16 |   struct B2X (base) (empty)
    637 // CHECK-NEXT:   18 |   struct B3X (base) (empty)
    638 // CHECK-NEXT:   35 |   struct B4X (base) (empty)
    639 // CHECK-NEXT:   20 |   (AX vbtable pointer)
    640 // CHECK-NEXT:   36 |   int a
    641 // CHECK-NEXT:   48 |   struct B0X (virtual base) (empty)
    642 // CHECK-NEXT:      | [sizeof=48, align=16
    643 // CHECK-NEXT:      |  nvsize=48, nvalign=16]
    644 // CHECK-X64: *** Dumping AST Record Layout
    645 // CHECK-X64: *** Dumping AST Record Layout
    646 // CHECK-X64: *** Dumping AST Record Layout
    647 // CHECK-X64: *** Dumping AST Record Layout
    648 // CHECK-X64: *** Dumping AST Record Layout
    649 // CHECK-X64: *** Dumping AST Record Layout
    650 // CHECK-X64-NEXT:    0 | struct AX
    651 // CHECK-X64-NEXT:    0 |   struct B1X (base) (empty)
    652 // CHECK-X64-NEXT:   16 |   struct B2X (base) (empty)
    653 // CHECK-X64-NEXT:   18 |   struct B3X (base) (empty)
    654 // CHECK-X64-NEXT:   35 |   struct B4X (base) (empty)
    655 // CHECK-X64-NEXT:   24 |   (AX vbtable pointer)
    656 // CHECK-X64-NEXT:   36 |   int a
    657 // CHECK-X64-NEXT:   48 |   struct B0X (virtual base) (empty)
    658 // CHECK-X64-NEXT:      | [sizeof=48, align=16
    659 // CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
    660 
    661 struct BX : B2X, B1X, B3X, B4X, virtual B0X {
    662 	int a;
    663 	BX() : a(0x0000000B) { printf(" B = %p\n", this); }
    664 };
    665 
    666 // CHECK: *** Dumping AST Record Layout
    667 // CHECK-NEXT:    0 | struct BX
    668 // CHECK-NEXT:    0 |   struct B2X (base) (empty)
    669 // CHECK-NEXT:    1 |   struct B1X (base) (empty)
    670 // CHECK-NEXT:    2 |   struct B3X (base) (empty)
    671 // CHECK-NEXT:   19 |   struct B4X (base) (empty)
    672 // CHECK-NEXT:    4 |   (BX vbtable pointer)
    673 // CHECK-NEXT:   20 |   int a
    674 // CHECK-NEXT:   32 |   struct B0X (virtual base) (empty)
    675 // CHECK-NEXT:      | [sizeof=32, align=16
    676 // CHECK-NEXT:      |  nvsize=32, nvalign=16]
    677 // CHECK-X64: *** Dumping AST Record Layout
    678 // CHECK-X64-NEXT:    0 | struct BX
    679 // CHECK-X64-NEXT:    0 |   struct B2X (base) (empty)
    680 // CHECK-X64-NEXT:    1 |   struct B1X (base) (empty)
    681 // CHECK-X64-NEXT:    2 |   struct B3X (base) (empty)
    682 // CHECK-X64-NEXT:   19 |   struct B4X (base) (empty)
    683 // CHECK-X64-NEXT:    8 |   (BX vbtable pointer)
    684 // CHECK-X64-NEXT:   20 |   int a
    685 // CHECK-X64-NEXT:   32 |   struct B0X (virtual base) (empty)
    686 // CHECK-X64-NEXT:      | [sizeof=32, align=16
    687 // CHECK-X64-NEXT:      |  nvsize=32, nvalign=16]
    688 
    689 struct CX : B1X, B3X, B2X, virtual B0X {
    690 	int a;
    691 	CX() : a(0x0000000C) { printf(" C = %p\n", this); }
    692 };
    693 
    694 // CHECK: *** Dumping AST Record Layout
    695 // CHECK-NEXT:    0 | struct CX
    696 // CHECK-NEXT:    0 |   struct B1X (base) (empty)
    697 // CHECK-NEXT:    2 |   struct B3X (base) (empty)
    698 // CHECK-NEXT:   32 |   struct B2X (base) (empty)
    699 // CHECK-NEXT:   16 |   (CX vbtable pointer)
    700 // CHECK-NEXT:   32 |   int a
    701 // CHECK-NEXT:   48 |   struct B0X (virtual base) (empty)
    702 // CHECK-NEXT:      | [sizeof=48, align=16
    703 // CHECK-NEXT:      |  nvsize=48, nvalign=16]
    704 // CHECK-X64: *** Dumping AST Record Layout
    705 // CHECK-X64-NEXT:    0 | struct CX
    706 // CHECK-X64-NEXT:    0 |   struct B1X (base) (empty)
    707 // CHECK-X64-NEXT:    2 |   struct B3X (base) (empty)
    708 // CHECK-X64-NEXT:   32 |   struct B2X (base) (empty)
    709 // CHECK-X64-NEXT:   16 |   (CX vbtable pointer)
    710 // CHECK-X64-NEXT:   32 |   int a
    711 // CHECK-X64-NEXT:   48 |   struct B0X (virtual base) (empty)
    712 // CHECK-X64-NEXT:      | [sizeof=48, align=16
    713 // CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
    714 
    715 struct DX : B8X, B1X, virtual B0X {
    716 	int a;
    717 	DX() : a(0x0000000D) { printf(" D = %p\n", this); }
    718 };
    719 
    720 // CHECK: *** Dumping AST Record Layout
    721 // CHECK: *** Dumping AST Record Layout
    722 // CHECK-NEXT:    0 | struct DX
    723 // CHECK-NEXT:    0 |   struct B8X (base)
    724 // CHECK-NEXT:    0 |     short a
    725 // CHECK-NEXT:   10 |   struct B1X (base) (empty)
    726 // CHECK-NEXT:    4 |   (DX vbtable pointer)
    727 // CHECK-NEXT:   12 |   int a
    728 // CHECK-NEXT:   16 |   struct B0X (virtual base) (empty)
    729 // CHECK-NEXT:      | [sizeof=16, align=4
    730 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
    731 // CHECK-X64: *** Dumping AST Record Layout
    732 // CHECK-X64: *** Dumping AST Record Layout
    733 // CHECK-X64-NEXT:    0 | struct DX
    734 // CHECK-X64-NEXT:    0 |   struct B8X (base)
    735 // CHECK-X64-NEXT:    0 |     short a
    736 // CHECK-X64-NEXT:   18 |   struct B1X (base) (empty)
    737 // CHECK-X64-NEXT:    8 |   (DX vbtable pointer)
    738 // CHECK-X64-NEXT:   20 |   int a
    739 // CHECK-X64-NEXT:   24 |   struct B0X (virtual base) (empty)
    740 // CHECK-X64-NEXT:      | [sizeof=24, align=8
    741 // CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
    742 
    743 
    744 struct C0 {};
    745 struct C1 : public C0 { int C1F0; };
    746 struct C2 : public C1, public C0 {};
    747 
    748 // CHECK: *** Dumping AST Record Layout
    749 // CHECK: *** Dumping AST Record Layout
    750 // CHECK: *** Dumping AST Record Layout
    751 // CHECK-NEXT:    0 | struct C2
    752 // CHECK-NEXT:    0 |   struct C1 (base)
    753 // CHECK-NEXT:    0 |     struct C0 (base) (empty)
    754 // CHECK-NEXT:    0 |     int C1F0
    755 // CHECK-NEXT:    5 |   struct C0 (base) (empty)
    756 // CHECK-NEXT:      | [sizeof=8, align=4
    757 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
    758 // CHECK-X64: *** Dumping AST Record Layout
    759 // CHECK-X64: *** Dumping AST Record Layout
    760 // CHECK-X64: *** Dumping AST Record Layout
    761 // CHECK-X64-NEXT:    0 | struct C2
    762 // CHECK-X64-NEXT:    0 |   struct C1 (base)
    763 // CHECK-X64-NEXT:    0 |     struct C0 (base) (empty)
    764 // CHECK-X64-NEXT:    0 |     int C1F0
    765 // CHECK-X64-NEXT:    5 |   struct C0 (base) (empty)
    766 // CHECK-X64-NEXT:      | [sizeof=8, align=4
    767 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=4]
    768 
    769 struct JA { char a; };
    770 struct JB {
    771   char a;
    772   virtual void f() {}
    773 };
    774 struct JC { char a; };
    775 struct JD : JA, JB, virtual JC {};
    776 
    777 // CHECK: *** Dumping AST Record Layout
    778 // CHECK: *** Dumping AST Record Layout
    779 // CHECK: *** Dumping AST Record Layout
    780 // CHECK: *** Dumping AST Record Layout
    781 // CHECK-NEXT:    0 | struct JD
    782 // CHECK-NEXT:    0 |   struct JB (primary base)
    783 // CHECK-NEXT:    0 |     (JB vftable pointer)
    784 // CHECK-NEXT:    4 |     char a
    785 // CHECK-NEXT:   12 |   struct JA (base)
    786 // CHECK-NEXT:   12 |     char a
    787 // CHECK-NEXT:    8 |   (JD vbtable pointer)
    788 // CHECK-NEXT:   16 |   struct JC (virtual base)
    789 // CHECK-NEXT:   16 |     char a
    790 // CHECK-NEXT:      | [sizeof=17, align=4
    791 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
    792 // CHECK-X64: *** Dumping AST Record Layout
    793 // CHECK-X64: *** Dumping AST Record Layout
    794 // CHECK-X64: *** Dumping AST Record Layout
    795 // CHECK-X64: *** Dumping AST Record Layout
    796 // CHECK-X64-NEXT:    0 | struct JD
    797 // CHECK-X64-NEXT:    0 |   struct JB (primary base)
    798 // CHECK-X64-NEXT:    0 |     (JB vftable pointer)
    799 // CHECK-X64-NEXT:    8 |     char a
    800 // CHECK-X64-NEXT:   24 |   struct JA (base)
    801 // CHECK-X64-NEXT:   24 |     char a
    802 // CHECK-X64-NEXT:   16 |   (JD vbtable pointer)
    803 // CHECK-X64-NEXT:   32 |   struct JC (virtual base)
    804 // CHECK-X64-NEXT:   32 |     char a
    805 // CHECK-X64-NEXT:      | [sizeof=40, align=8
    806 // CHECK-X64-NEXT:      |  nvsize=32, nvalign=8]
    807 
    808 int a[
    809 sizeof(AA)+
    810 sizeof(AB)+
    811 sizeof(AC)+
    812 sizeof(AD)+
    813 sizeof(AA1)+
    814 sizeof(AB1)+
    815 sizeof(AC1)+
    816 sizeof(AD1)+
    817 sizeof(AA2)+
    818 sizeof(AB2)+
    819 sizeof(AC2)+
    820 sizeof(AD2)+
    821 sizeof(AA3)+
    822 sizeof(AB3)+
    823 sizeof(AC3)+
    824 sizeof(AD3)+
    825 sizeof(B)+
    826 sizeof(C)+
    827 sizeof(D)+
    828 sizeof(E)+
    829 sizeof(F)+
    830 sizeof(G)+
    831 sizeof(AX)+
    832 sizeof(BX)+
    833 sizeof(CX)+
    834 sizeof(DX)+
    835 sizeof(C2)+
    836 sizeof(JD)+
    837 0];
    838