// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \ // RUN: | FileCheck %s // RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \ // RUN: | FileCheck %s -check-prefix CHECK-X64 extern "C" int printf(const char *fmt, ...); __declspec(align(4096)) char buffer[4096]; struct AT {}; struct V : AT { char c; V() { printf("V - this: %d\n", (int)((char*)this - buffer)); } }; struct AT0 { union { struct { int a; AT t; } y; int b; } x; char c; AT0() { printf("AT0 - this: %d\n", (int)((char*)this - buffer)); } }; struct AT1 : V { int a; AT1() { printf("AT1 - this: %d\n", (int)((char*)this - buffer)); } }; struct AT2 { AT0 t; char AT2FieldName0; AT2() { printf("AT2 - this: %d\n", (int)((char*)this - buffer)); printf("AT2 - Fiel: %d\n", (int)((char*)&AT2FieldName0 - buffer)); } }; struct AT3 : AT2, AT1 { AT3() { printf("AT3 - this: %d\n", (int)((char*)this - buffer)); } }; // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct AT3 // CHECK-NEXT: 0 | struct AT2 (base) // CHECK-NEXT: 0 | struct AT0 t // CHECK-NEXT: 0 | union AT0::(anonymous at {{.*}} x // CHECK-NEXT: 0 | struct AT0::(anonymous at {{.*}} y // CHECK-NEXT: 0 | int a // CHECK-NEXT: 4 | struct AT t (empty) // CHECK: 0 | int b // CHECK: 8 | char c // CHECK: 12 | char AT2FieldName0 // CHECK-NEXT: 20 | struct AT1 (base) // CHECK-NEXT: 20 | struct V (base) // CHECK-NEXT: 20 | struct AT (base) (empty) // CHECK-NEXT: 20 | char c // CHECK-NEXT: 24 | int a // CHECK-NEXT: | [sizeof=28, align=4 // CHECK-NEXT: | nvsize=28, nvalign=4] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct AT3 // CHECK-X64-NEXT: 0 | struct AT2 (base) // CHECK-X64-NEXT: 0 | struct AT0 t // CHECK-X64-NEXT: 0 | union AT0::(anonymous at {{.*}} x // CHECK-X64-NEXT: 0 | struct AT0::(anonymous at {{.*}} y // CHECK-X64-NEXT: 0 | int a // CHECK-X64-NEXT: 4 | struct AT t (empty) // CHECK-X64: 0 | int b // CHECK-X64: 8 | char c // CHECK-X64: 12 | char AT2FieldName0 // CHECK-X64-NEXT: 20 | struct AT1 (base) // CHECK-X64-NEXT: 20 | struct V (base) // CHECK-X64-NEXT: 20 | struct AT (base) (empty) // CHECK-X64-NEXT: 20 | char c // CHECK-X64-NEXT: 24 | int a // CHECK-X64-NEXT: | [sizeof=28, align=4 // CHECK-X64-NEXT: | nvsize=28, nvalign=4] struct BT0 { BT0() { printf("BT0 - this: %d\n", (int)((char*)this - buffer)); } }; struct BT2 : BT0 { char BT2FieldName0; BT2() { printf("BT2 - this: %d\n", (int)((char*)this - buffer)); printf("BT2 - Fiel: %d\n", (int)((char*)&BT2FieldName0 - buffer)); } }; struct BT3 : BT0, BT2 { BT3() { printf("BT3 - this: %d\n", (int)((char*)this - buffer)); } }; // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct BT3 // CHECK-NEXT: 0 | struct BT0 (base) (empty) // CHECK-NEXT: 1 | struct BT2 (base) // CHECK-NEXT: 1 | struct BT0 (base) (empty) // CHECK-NEXT: 1 | char BT2FieldName0 // CHECK-NEXT: | [sizeof=2, align=1 // CHECK-NEXT: | nvsize=2, nvalign=1] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct BT3 // CHECK-X64-NEXT: 0 | struct BT0 (base) (empty) // CHECK-X64-NEXT: 1 | struct BT2 (base) // CHECK-X64-NEXT: 1 | struct BT0 (base) (empty) // CHECK-X64-NEXT: 1 | char BT2FieldName0 // CHECK-X64-NEXT: | [sizeof=2, align=1 // CHECK-X64-NEXT: | nvsize=2, nvalign=1] struct T0 : AT { T0() { printf("T0 (this) : %d\n", (int)((char*)this - buffer)); } }; struct T1 : T0 { char a; T1() { printf("T1 (this) : %d\n", (int)((char*)this - buffer)); printf("T1 (fiel) : %d\n", (int)((char*)&a - buffer)); } }; struct T2 : AT { char a; T2() { printf("T2 (this) : %d\n", (int)((char*)this - buffer)); printf("T2 (fiel) : %d\n", (int)((char*)&a - buffer)); } }; struct __declspec(align(1)) T3 : virtual T1, virtual T2 { T3() { printf("T3 (this) : %d\n", (int)((char*)this - buffer)); } }; // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct T3 // CHECK-NEXT: 0 | (T3 vbtable pointer) // CHECK-NEXT: 4 | struct T1 (virtual base) // CHECK-NEXT: 4 | struct T0 (base) (empty) // CHECK-NEXT: 4 | struct AT (base) (empty) // CHECK-NEXT: 4 | char a // CHECK-NEXT: 12 | struct T2 (virtual base) // CHECK-NEXT: 12 | struct AT (base) (empty) // CHECK-NEXT: 12 | char a // CHECK-NEXT: | [sizeof=16, align=4 // CHECK-NEXT: | nvsize=4, nvalign=4] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct T3 // CHECK-X64-NEXT: 0 | (T3 vbtable pointer) // CHECK-X64-NEXT: 8 | struct T1 (virtual base) // CHECK-X64-NEXT: 8 | struct T0 (base) (empty) // CHECK-X64-NEXT: 8 | struct AT (base) (empty) // CHECK-X64-NEXT: 8 | char a // CHECK-X64-NEXT: 16 | struct T2 (virtual base) // CHECK-X64-NEXT: 16 | struct AT (base) (empty) // CHECK-X64-NEXT: 16 | char a // CHECK-X64-NEXT: | [sizeof=24, align=8 // CHECK-X64-NEXT: | nvsize=8, nvalign=8] struct B {}; struct C { int a; }; struct D : B, virtual C { B b; }; struct E : D, B {}; // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct E // CHECK-NEXT: 0 | struct D (base) // CHECK-NEXT: 4 | struct B (base) (empty) // CHECK-NEXT: 0 | (D vbtable pointer) // CHECK-NEXT: 4 | struct B b (empty) // CHECK: 8 | struct B (base) (empty) // CHECK-NEXT: 8 | struct C (virtual base) // CHECK-NEXT: 8 | int a // CHECK-NEXT: | [sizeof=12, align=4 // CHECK-NEXT: | nvsize=8, nvalign=4] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct E // CHECK-X64-NEXT: 0 | struct D (base) // CHECK-X64-NEXT: 8 | struct B (base) (empty) // CHECK-X64-NEXT: 0 | (D vbtable pointer) // CHECK-X64-NEXT: 8 | struct B b (empty) // CHECK-X64: 16 | struct B (base) (empty) // CHECK-X64-NEXT: 16 | struct C (virtual base) // CHECK-X64-NEXT: 16 | int a // CHECK-X64-NEXT: | [sizeof=24, align=8 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] struct F : virtual D, virtual B {}; // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct F // CHECK-NEXT: 0 | (F vbtable pointer) // CHECK-NEXT: 4 | struct C (virtual base) // CHECK-NEXT: 4 | int a // CHECK-NEXT: 8 | struct D (virtual base) // CHECK-NEXT: 12 | struct B (base) (empty) // CHECK-NEXT: 8 | (D vbtable pointer) // CHECK-NEXT: 12 | struct B b (empty) // CHECK: 16 | struct B (virtual base) (empty) // CHECK-NEXT: | [sizeof=16, align=4 // CHECK-NEXT: | nvsize=4, nvalign=4] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct F // CHECK-X64-NEXT: 0 | (F vbtable pointer) // CHECK-X64-NEXT: 8 | struct C (virtual base) // CHECK-X64-NEXT: 8 | int a // CHECK-X64-NEXT: 16 | struct D (virtual base) // CHECK-X64-NEXT: 24 | struct B (base) (empty) // CHECK-X64-NEXT: 16 | (D vbtable pointer) // CHECK-X64-NEXT: 24 | struct B b (empty) // CHECK-X64: 32 | struct B (virtual base) (empty) // CHECK-X64-NEXT: | [sizeof=32, align=8 // CHECK-X64-NEXT: | nvsize=8, nvalign=8] struct JC0 { JC0() { printf("JC0 : %d\n", (int)((char*)this - buffer)); } }; struct JC1 : JC0 { virtual void f() {} JC1() { printf("JC1 : %d\n", (int)((char*)this - buffer)); } }; struct JC2 : JC1 { JC2() { printf("JC2 : %d\n", (int)((char*)this - buffer)); } }; struct JC4 : JC1, JC2 { JC4() { printf("JC4 : %d\n", (int)((char*)this - buffer)); } }; // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct JC4 // CHECK-NEXT: 0 | struct JC1 (primary base) // CHECK-NEXT: 0 | (JC1 vftable pointer) // CHECK-NEXT: 4 | struct JC0 (base) (empty) // CHECK-NEXT: 8 | struct JC2 (base) // CHECK-NEXT: 8 | struct JC1 (primary base) // CHECK-NEXT: 8 | (JC1 vftable pointer) // CHECK-NEXT: 12 | struct JC0 (base) (empty) // CHECK-NEXT: | [sizeof=12, align=4 // CHECK-NEXT: | nvsize=12, nvalign=4] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct JC4 // CHECK-X64-NEXT: 0 | struct JC1 (primary base) // CHECK-X64-NEXT: 0 | (JC1 vftable pointer) // CHECK-X64-NEXT: 8 | struct JC0 (base) (empty) // CHECK-X64-NEXT: 16 | struct JC2 (base) // CHECK-X64-NEXT: 16 | struct JC1 (primary base) // CHECK-X64-NEXT: 16 | (JC1 vftable pointer) // CHECK-X64-NEXT: 24 | struct JC0 (base) (empty) // CHECK-X64-NEXT: | [sizeof=24, align=8 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] struct RA {}; struct RB { char c; }; struct RV {}; struct RW { char c; }; struct RY { RY() { printf("%Id\n", (char*)this - buffer); } }; struct RX0 : RB, RA {}; struct RX1 : RA, RB {}; struct RX2 : RA { char a; }; struct RX3 : RA { RB a; }; struct RX4 { RA a; char b; }; struct RX5 { RA a; RB b; }; struct RX6 : virtual RV { RB a; }; struct RX7 : virtual RW { RA a; }; struct RX8 : RA, virtual RW {}; struct RZ0 : RX0, RY {}; // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct RZ0 // CHECK-NEXT: 0 | struct RX0 (base) // CHECK-NEXT: 0 | struct RB (base) // CHECK-NEXT: 0 | char c // CHECK-NEXT: 1 | struct RA (base) (empty) // CHECK-NEXT: 2 | struct RY (base) (empty) // CHECK-NEXT: | [sizeof=2, align=1 // CHECK-NEXT: | nvsize=2, nvalign=1] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct RZ0 // CHECK-X64-NEXT: 0 | struct RX0 (base) // CHECK-X64-NEXT: 0 | struct RB (base) // CHECK-X64-NEXT: 0 | char c // CHECK-X64-NEXT: 1 | struct RA (base) (empty) // CHECK-X64-NEXT: 2 | struct RY (base) (empty) // CHECK-X64-NEXT: | [sizeof=2, align=1 // CHECK-X64-NEXT: | nvsize=2, nvalign=1] struct RZ1 : RX1, RY {}; // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct RZ1 // CHECK-NEXT: 0 | struct RX1 (base) // CHECK-NEXT: 0 | struct RA (base) (empty) // CHECK-NEXT: 0 | struct RB (base) // CHECK-NEXT: 0 | char c // CHECK-NEXT: 1 | struct RY (base) (empty) // CHECK-NEXT: | [sizeof=1, align=1 // CHECK-NEXT: | nvsize=1, nvalign=1] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct RZ1 // CHECK-X64-NEXT: 0 | struct RX1 (base) // CHECK-X64-NEXT: 0 | struct RA (base) (empty) // CHECK-X64-NEXT: 0 | struct RB (base) // CHECK-X64-NEXT: 0 | char c // CHECK-X64-NEXT: 1 | struct RY (base) (empty) // CHECK-X64-NEXT: | [sizeof=1, align=1 // CHECK-X64-NEXT: | nvsize=1, nvalign=1] struct RZ2 : RX2, RY {}; // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct RZ2 // CHECK-NEXT: 0 | struct RX2 (base) // CHECK-NEXT: 0 | struct RA (base) (empty) // CHECK-NEXT: 0 | char a // CHECK-NEXT: 2 | struct RY (base) (empty) // CHECK-NEXT: | [sizeof=2, align=1 // CHECK-NEXT: | nvsize=2, nvalign=1] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct RZ2 // CHECK-X64-NEXT: 0 | struct RX2 (base) // CHECK-X64-NEXT: 0 | struct RA (base) (empty) // CHECK-X64-NEXT: 0 | char a // CHECK-X64-NEXT: 2 | struct RY (base) (empty) // CHECK-X64-NEXT: | [sizeof=2, align=1 // CHECK-X64-NEXT: | nvsize=2, nvalign=1] struct RZ3 : RX3, RY {}; // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct RZ3 // CHECK-NEXT: 0 | struct RX3 (base) // CHECK-NEXT: 0 | struct RA (base) (empty) // CHECK-NEXT: 0 | struct RB a // CHECK-NEXT: 0 | char c // CHECK-NEXT: | [sizeof=1, align=1 // CHECK-NEXT: | nvsize=1, nvalign=1] // CHECK-NEXT: 1 | struct RY (base) (empty) // CHECK-NEXT: | [sizeof=1, align=1 // CHECK-NEXT: | nvsize=1, nvalign=1] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct RZ3 // CHECK-X64-NEXT: 0 | struct RX3 (base) // CHECK-X64-NEXT: 0 | struct RA (base) (empty) // CHECK-X64-NEXT: 0 | struct RB a // CHECK-X64-NEXT: 0 | char c // CHECK-X64-NEXT: | [sizeof=1, align=1 // CHECK-X64-NEXT: | nvsize=1, nvalign=1] // CHECK-X64-NEXT: 1 | struct RY (base) (empty) // CHECK-X64-NEXT: | [sizeof=1, align=1 // CHECK-X64-NEXT: | nvsize=1, nvalign=1] struct RZ4 : RX4, RY {}; // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct RZ4 // CHECK-NEXT: 0 | struct RX4 (base) // CHECK-NEXT: 0 | struct RA a (empty) // CHECK-NEXT: | [sizeof=1, align=1 // CHECK-NEXT: | nvsize=0, nvalign=1] // CHECK-NEXT: 1 | char b // CHECK-NEXT: 3 | struct RY (base) (empty) // CHECK-NEXT: | [sizeof=3, align=1 // CHECK-NEXT: | nvsize=3, nvalign=1] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct RZ4 // CHECK-X64-NEXT: 0 | struct RX4 (base) // CHECK-X64-NEXT: 0 | struct RA a (empty) // CHECK-X64-NEXT: | [sizeof=1, align=1 // CHECK-X64-NEXT: | nvsize=0, nvalign=1] // CHECK-X64-NEXT: 1 | char b // CHECK-X64-NEXT: 3 | struct RY (base) (empty) // CHECK-X64-NEXT: | [sizeof=3, align=1 // CHECK-X64-NEXT: | nvsize=3, nvalign=1] struct RZ5 : RX5, RY {}; // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct RZ5 // CHECK-NEXT: 0 | struct RX5 (base) // CHECK-NEXT: 0 | struct RA a (empty) // CHECK-NEXT: | [sizeof=1, align=1 // CHECK-NEXT: | nvsize=0, nvalign=1] // CHECK-NEXT: 1 | struct RB b // CHECK-NEXT: 1 | char c // CHECK-NEXT: | [sizeof=1, align=1 // CHECK-NEXT: | nvsize=1, nvalign=1] // CHECK-NEXT: 2 | struct RY (base) (empty) // CHECK-NEXT: | [sizeof=2, align=1 // CHECK-NEXT: | nvsize=2, nvalign=1] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct RZ5 // CHECK-X64-NEXT: 0 | struct RX5 (base) // CHECK-X64-NEXT: 0 | struct RA a (empty) // CHECK-X64-NEXT: | [sizeof=1, align=1 // CHECK-X64-NEXT: | nvsize=0, nvalign=1] // CHECK-X64-NEXT: 1 | struct RB b // CHECK-X64-NEXT: 1 | char c // CHECK-X64-NEXT: | [sizeof=1, align=1 // CHECK-X64-NEXT: | nvsize=1, nvalign=1] // CHECK-X64-NEXT: 2 | struct RY (base) (empty) // CHECK-X64-NEXT: | [sizeof=2, align=1 // CHECK-X64-NEXT: | nvsize=2, nvalign=1] struct RZ6 : RX6, RY {}; // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct RZ6 // CHECK-NEXT: 0 | struct RX6 (base) // CHECK-NEXT: 0 | (RX6 vbtable pointer) // CHECK-NEXT: 4 | struct RB a // CHECK-NEXT: 4 | char c // CHECK-NEXT: | [sizeof=1, align=1 // CHECK-NEXT: | nvsize=1, nvalign=1] // CHECK-NEXT: 9 | struct RY (base) (empty) // CHECK-NEXT: 12 | struct RV (virtual base) (empty) // CHECK-NEXT: | [sizeof=12, align=4 // CHECK-NEXT: | nvsize=12, nvalign=4] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct RZ6 // CHECK-X64-NEXT: 0 | struct RX6 (base) // CHECK-X64-NEXT: 0 | (RX6 vbtable pointer) // CHECK-X64-NEXT: 8 | struct RB a // CHECK-X64-NEXT: 8 | char c // CHECK-X64-NEXT: | [sizeof=1, align=1 // CHECK-X64-NEXT: | nvsize=1, nvalign=1] // CHECK-X64-NEXT: 17 | struct RY (base) (empty) // CHECK-X64-NEXT: 24 | struct RV (virtual base) (empty) // CHECK-X64-NEXT: | [sizeof=24, align=8 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] struct RZ7 : RX7, RY {}; // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct RZ7 // CHECK-NEXT: 0 | struct RX7 (base) // CHECK-NEXT: 0 | (RX7 vbtable pointer) // CHECK-NEXT: 4 | struct RA a (empty) // CHECK-NEXT: | [sizeof=1, align=1 // CHECK-NEXT: | nvsize=0, nvalign=1] // CHECK-NEXT: 8 | struct RY (base) (empty) // CHECK-NEXT: 8 | struct RW (virtual base) // CHECK-NEXT: 8 | char c // CHECK-NEXT: | [sizeof=9, align=4 // CHECK-NEXT: | nvsize=8, nvalign=4] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct RZ7 // CHECK-X64-NEXT: 0 | struct RX7 (base) // CHECK-X64-NEXT: 0 | (RX7 vbtable pointer) // CHECK-X64-NEXT: 8 | struct RA a (empty) // CHECK-X64-NEXT: | [sizeof=1, align=1 // CHECK-X64-NEXT: | nvsize=0, nvalign=1] // CHECK-X64-NEXT: 16 | struct RY (base) (empty) // CHECK-X64-NEXT: 16 | struct RW (virtual base) // CHECK-X64-NEXT: 16 | char c // CHECK-X64-NEXT: | [sizeof=24, align=8 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] struct RZ8 : RX8, RY {}; // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct RZ8 // CHECK-NEXT: 0 | struct RX8 (base) // CHECK-NEXT: 4 | struct RA (base) (empty) // CHECK-NEXT: 0 | (RX8 vbtable pointer) // CHECK-NEXT: 4 | struct RY (base) (empty) // CHECK-NEXT: 4 | struct RW (virtual base) // CHECK-NEXT: 4 | char c // CHECK-NEXT: | [sizeof=5, align=4 // CHECK-NEXT: | nvsize=4, nvalign=4] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct RZ8 // CHECK-X64-NEXT: 0 | struct RX8 (base) // CHECK-X64-NEXT: 8 | struct RA (base) (empty) // CHECK-X64-NEXT: 0 | (RX8 vbtable pointer) // CHECK-X64-NEXT: 8 | struct RY (base) (empty) // CHECK-X64-NEXT: 8 | struct RW (virtual base) // CHECK-X64-NEXT: 8 | char c // CHECK-X64-NEXT: | [sizeof=16, align=8 // CHECK-X64-NEXT: | nvsize=8, nvalign=8] struct JA {}; struct JB {}; struct JC : JA { virtual void f() {} }; struct JD : virtual JB, virtual JC { virtual void f() {} JD() {} }; // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct JD // CHECK-NEXT: 0 | (JD vbtable pointer) // CHECK-NEXT: 4 | struct JB (virtual base) (empty) // CHECK-NEXT: 4 | (vtordisp for vbase JC) // CHECK-NEXT: 8 | struct JC (virtual base) // CHECK-NEXT: 8 | (JC vftable pointer) // CHECK-NEXT: 12 | struct JA (base) (empty) // CHECK-NEXT: | [sizeof=12, align=4 // CHECK-NEXT: | nvsize=4, nvalign=4] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct JD // CHECK-X64-NEXT: 0 | (JD vbtable pointer) // CHECK-X64-NEXT: 8 | struct JB (virtual base) (empty) // CHECK-X64-NEXT: 12 | (vtordisp for vbase JC) // CHECK-X64-NEXT: 16 | struct JC (virtual base) // CHECK-X64-NEXT: 16 | (JC vftable pointer) // CHECK-X64-NEXT: 24 | struct JA (base) (empty) // CHECK-X64-NEXT: | [sizeof=24, align=8 // CHECK-X64-NEXT: | nvsize=8, nvalign=8] int a[ sizeof(AT3) + sizeof(BT3) + sizeof(T3) + sizeof(E) + sizeof(F) + sizeof(JC4) + sizeof(RZ0) + sizeof(RZ1) + sizeof(RZ2) + sizeof(RZ3) + sizeof(RZ4) + sizeof(RZ5) + sizeof(RZ6) + sizeof(RZ7) + sizeof(RZ8) + sizeof(JD) + 0];