diff options
Diffstat (limited to 'test/Layout')
-rw-r--r-- | test/Layout/ms-x86-aligned-tail-padding.cpp | 502 | ||||
-rw-r--r-- | test/Layout/ms-x86-basic-layout.cpp | 775 | ||||
-rw-r--r-- | test/Layout/ms-x86-bitfields-vbases.cpp | 84 | ||||
-rw-r--r-- | test/Layout/ms-x86-empty-base-after-base-with-vbptr.cpp | 216 | ||||
-rw-r--r-- | test/Layout/ms-x86-empty-nonvirtual-bases.cpp | 174 | ||||
-rw-r--r-- | test/Layout/ms-x86-empty-virtual-base.cpp | 704 | ||||
-rw-r--r-- | test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp | 735 | ||||
-rw-r--r-- | test/Layout/ms-x86-misalignedarray.cpp | 23 | ||||
-rw-r--r-- | test/Layout/ms-x86-primary-bases.cpp | 317 | ||||
-rw-r--r-- | test/Layout/ms-x86-size-alignment-fail.cpp | 123 | ||||
-rw-r--r-- | test/Layout/ms-x86-vfvb-alignment.cpp | 376 | ||||
-rw-r--r-- | test/Layout/ms-x86-vfvb-sharing.cpp | 140 | ||||
-rw-r--r-- | test/Layout/ms-x86-vtordisp.cpp | 170 |
13 files changed, 4339 insertions, 0 deletions
diff --git a/test/Layout/ms-x86-aligned-tail-padding.cpp b/test/Layout/ms-x86-aligned-tail-padding.cpp new file mode 100644 index 0000000..b9020f3 --- /dev/null +++ b/test/Layout/ms-x86-aligned-tail-padding.cpp @@ -0,0 +1,502 @@ +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %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 -cxx-abi microsoft %s 2>/dev/null \ +// RUN: | FileCheck %s -check-prefix CHECK-X64 + +extern "C" int printf(const char *fmt, ...); + +struct B0 { + int a; + B0() : a(0xf00000B0) {} +}; +struct __declspec(align(16)) B1 { + int a; + B1() : a(0xf00000B1) {} +}; +struct B2 { + __declspec(align(16)) int a; + B2() : a(0xf00000B2) {} +}; +struct __declspec(align(16)) B3 { + long long a1; + int a; + B3() : a(0xf00000B3), a1(0xf00000B3f00000B3ll) {} +}; +struct V { + char a; + V() : a(0X11) {} +}; +struct __declspec(align(32)) A16 {}; +struct V1 : A16 { virtual void f() {} }; +struct V2 { + long long a; + int a1; + V2() : a(0xf0000011f0000011ll), a1(0xf0000011) {} +}; +struct V3 { + int a; + V3() : a(0xf0000022) {} +}; +struct __declspec(align(16)) A16X { +}; +struct __declspec(align(16)) B0X { + int a, a1; + B0X() : a(0xf00000B0), a1(0xf00000B0) {} +}; +struct B1X { + int a; + B1X() : a(0xf00000B1) {} +}; +struct B2X { + int a; + B2X() : a(0xf00000B2) {} +}; +struct __declspec(align(16)) B3X { + int a; + B3X() : a(0xf00000B3) {} + virtual void g() {} +}; +struct B4X : A16X { + int a, a1; + B4X() : a(0xf00000B4), a1(0xf00000B4) {} +}; +struct B5X : virtual A16X { + int a, a1; + B5X() : a(0xf00000B5), a1(0xf00000B5) {} +}; +struct B6X { + int a; + B6X() : a(0xf00000B6) {} +}; + +struct A : B1, B0, B2, virtual V { + int a; + A() : a(0xf000000A) {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct A +// CHECK: 0 | struct B1 (base) +// CHECK: 0 | int a +// CHECK: 4 | struct B0 (base) +// CHECK: 4 | int a +// CHECK: 16 | struct B2 (base) +// CHECK: 16 | int a +// CHECK: 32 | (A vbtable pointer) +// CHECK: 48 | int a +// CHECK: 64 | struct V (virtual base) +// CHECK: 64 | char a +// CHECK: | [sizeof=80, align=16 +// CHECK: | nvsize=64, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct A +// CHECK-X64: 0 | struct B1 (base) +// CHECK-X64: 0 | int a +// CHECK-X64: 4 | struct B0 (base) +// CHECK-X64: 4 | int a +// CHECK-X64: 16 | struct B2 (base) +// CHECK-X64: 16 | int a +// CHECK-X64: 32 | (A vbtable pointer) +// CHECK-X64: 40 | int a +// CHECK-X64: 48 | struct V (virtual base) +// CHECK-X64: 48 | char a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct B : B2, B0, B1, virtual V { + int a; + B() : a(0xf000000B) {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct B +// CHECK: 0 | struct B2 (base) +// CHECK: 0 | int a +// CHECK: 16 | struct B0 (base) +// CHECK: 16 | int a +// CHECK: 32 | struct B1 (base) +// CHECK: 32 | int a +// CHECK: 36 | (B vbtable pointer) +// CHECK: 52 | int a +// CHECK: 64 | struct V (virtual base) +// CHECK: 64 | char a +// CHECK: | [sizeof=80, align=16 +// CHECK: | nvsize=64, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct B +// CHECK-X64: 0 | struct B2 (base) +// CHECK-X64: 0 | int a +// CHECK-X64: 16 | struct B0 (base) +// CHECK-X64: 16 | int a +// CHECK-X64: 32 | struct B1 (base) +// CHECK-X64: 32 | int a +// CHECK-X64: 40 | (B vbtable pointer) +// CHECK-X64: 48 | int a +// CHECK-X64: 64 | struct V (virtual base) +// CHECK-X64: 64 | char a +// CHECK-X64: | [sizeof=80, align=16 +// CHECK-X64: | nvsize=64, nvalign=16] + +struct C : B1, B0, virtual V { + int a; + long long a1; + C() : a(0xf000000C), a1(0xf000000Cf000000Cll) {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct C +// CHECK: 0 | struct B1 (base) +// CHECK: 0 | int a +// CHECK: 4 | struct B0 (base) +// CHECK: 4 | int a +// CHECK: 8 | (C vbtable pointer) +// CHECK: 24 | int a +// CHECK: 32 | long long a1 +// CHECK: 48 | struct V (virtual base) +// CHECK: 48 | char a +// CHECK: | [sizeof=64, align=16 +// CHECK: | nvsize=48, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct C +// CHECK-X64: 0 | struct B1 (base) +// CHECK-X64: 0 | int a +// CHECK-X64: 4 | struct B0 (base) +// CHECK-X64: 4 | int a +// CHECK-X64: 8 | (C vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | long long a1 +// CHECK-X64: 32 | struct V (virtual base) +// CHECK-X64: 32 | char a +// CHECK-X64: | [sizeof=48, align=16 +// CHECK-X64: | nvsize=32, nvalign=16] + +struct D : B2, B0, virtual V { + int a; + D() : a(0xf000000D) {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct D +// CHECK: 0 | struct B2 (base) +// CHECK: 0 | int a +// CHECK: 16 | struct B0 (base) +// CHECK: 16 | int a +// CHECK: 20 | (D vbtable pointer) +// CHECK: 36 | int a +// CHECK: 48 | struct V (virtual base) +// CHECK: 48 | char a +// CHECK: | [sizeof=64, align=16 +// CHECK: | nvsize=48, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct D +// CHECK-X64: 0 | struct B2 (base) +// CHECK-X64: 0 | int a +// CHECK-X64: 16 | struct B0 (base) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | (D vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 48 | struct V (virtual base) +// CHECK-X64: 48 | char a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct E : B3, B0, virtual V { + int a; + E() : a(0xf000000E) {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct E +// CHECK: 0 | struct B3 (base) +// CHECK: 0 | long long a1 +// CHECK: 8 | int a +// CHECK: 16 | struct B0 (base) +// CHECK: 16 | int a +// CHECK: 20 | (E vbtable pointer) +// CHECK: 36 | int a +// CHECK: 48 | struct V (virtual base) +// CHECK: 48 | char a +// CHECK: | [sizeof=64, align=16 +// CHECK: | nvsize=48, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct E +// CHECK-X64: 0 | struct B3 (base) +// CHECK-X64: 0 | long long a1 +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct B0 (base) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | (E vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 48 | struct V (virtual base) +// CHECK-X64: 48 | char a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct F : B0, virtual V1 { + __declspec(align(16)) int a; + F() : a(0xf000000F) {} + virtual void f() {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct F +// CHECK: 0 | struct B0 (base) +// CHECK: 0 | int a +// CHECK: 4 | (F vbtable pointer) +// CHECK: 32 | int a +// CHECK: 92 | (vtordisp for vbase V1) +// CHECK: 96 | struct V1 (virtual base) +// CHECK: 96 | (V1 vftable pointer) +// CHECK: 128 | struct A16 (base) (empty) +// CHECK: | [sizeof=128, align=32 +// CHECK: | nvsize=48, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct F +// CHECK-X64: 0 | struct B0 (base) +// CHECK-X64: 0 | int a +// CHECK-X64: 8 | (F vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 60 | (vtordisp for vbase V1) +// CHECK-X64: 64 | struct V1 (virtual base) +// CHECK-X64: 64 | (V1 vftable pointer) +// CHECK-X64: 96 | struct A16 (base) (empty) +// CHECK-X64: | [sizeof=96, align=32 +// CHECK-X64: | nvsize=32, nvalign=16] + +struct G : virtual V2, virtual V3 { + int a; + G() : a(0xf0000001) {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct G +// CHECK: 0 | (G vbtable pointer) +// CHECK: 4 | int a +// CHECK: 8 | struct V2 (virtual base) +// CHECK: 8 | long long a +// CHECK: 16 | int a1 +// CHECK: 24 | struct V3 (virtual base) +// CHECK: 24 | int a +// CHECK: | [sizeof=28, align=8 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct G +// CHECK-X64: 0 | (G vbtable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct V2 (virtual base) +// CHECK-X64: 16 | long long a +// CHECK-X64: 24 | int a1 +// CHECK-X64: 32 | struct V3 (virtual base) +// CHECK-X64: 32 | int a +// CHECK-X64: | [sizeof=40, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct H { + __declspec(align(16)) int a; + int b; + H() : a(0xf0000010), b(0xf0000010) {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct H +// CHECK: 0 | int a +// CHECK: 4 | int b +// CHECK: | [sizeof=16, align=16 +// CHECK: | nvsize=16, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct H +// CHECK-X64: 0 | int a +// CHECK-X64: 4 | int b +// CHECK-X64: | [sizeof=16, align=16 +// CHECK-X64: | nvsize=16, nvalign=16] + +struct I { + B2 a; + int b; + I() : b(0xf0000010) {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct I +// CHECK: 0 | struct B2 a +// CHECK: 0 | int a +// CHECK: 16 | int b +// CHECK: | [sizeof=32, align=16 +// CHECK: | nvsize=32, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct I +// CHECK-X64: 0 | struct B2 a +// CHECK-X64: 0 | int a +// CHECK-X64: 16 | int b +// CHECK-X64: | [sizeof=32, align=16 +// CHECK-X64: | nvsize=32, nvalign=16] + +struct AX : B0X, virtual B2X, virtual B6X, virtual B3X { + int a; + AX() : a(0xf000000A) {} + virtual void f() {} + virtual void g() {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AX +// CHECK: 0 | (AX vftable pointer) +// CHECK: 16 | struct B0X (base) +// CHECK: 16 | int a +// CHECK: 20 | int a1 +// CHECK: 24 | (AX vbtable pointer) +// CHECK: 40 | int a +// CHECK: 48 | struct B2X (virtual base) +// CHECK: 48 | int a +// CHECK: 52 | struct B6X (virtual base) +// CHECK: 52 | int a +// CHECK: 76 | (vtordisp for vbase B3X) +// CHECK: 80 | struct B3X (virtual base) +// CHECK: 80 | (B3X vftable pointer) +// CHECK: 84 | int a +// CHECK: | [sizeof=96, align=16 +// CHECK: | nvsize=48, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AX +// CHECK-X64: 0 | (AX vftable pointer) +// CHECK-X64: 16 | struct B0X (base) +// CHECK-X64: 16 | int a +// CHECK-X64: 20 | int a1 +// CHECK-X64: 24 | (AX vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 48 | struct B2X (virtual base) +// CHECK-X64: 48 | int a +// CHECK-X64: 52 | struct B6X (virtual base) +// CHECK-X64: 52 | int a +// CHECK-X64: 76 | (vtordisp for vbase B3X) +// CHECK-X64: 80 | struct B3X (virtual base) +// CHECK-X64: 80 | (B3X vftable pointer) +// CHECK-X64: 88 | int a +// CHECK-X64: | [sizeof=96, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct BX : B4X, virtual B2X, virtual B6X, virtual B3X { + int a; + BX() : a(0xf000000B) {} + virtual void f() {} + virtual void g() {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct BX +// CHECK: 0 | (BX vftable pointer) +// CHECK: 16 | struct B4X (base) +// CHECK: 16 | struct A16X (base) (empty) +// CHECK: 16 | int a +// CHECK: 20 | int a1 +// CHECK: 32 | (BX vbtable pointer) +// CHECK: 48 | int a +// CHECK: 64 | struct B2X (virtual base) +// CHECK: 64 | int a +// CHECK: 68 | struct B6X (virtual base) +// CHECK: 68 | int a +// CHECK: 92 | (vtordisp for vbase B3X) +// CHECK: 96 | struct B3X (virtual base) +// CHECK: 96 | (B3X vftable pointer) +// CHECK: 100 | int a +// CHECK: | [sizeof=112, align=16 +// CHECK: | nvsize=64, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct BX +// CHECK-X64: 0 | (BX vftable pointer) +// CHECK-X64: 16 | struct B4X (base) +// CHECK-X64: 16 | struct A16X (base) (empty) +// CHECK-X64: 16 | int a +// CHECK-X64: 20 | int a1 +// CHECK-X64: 32 | (BX vbtable pointer) +// CHECK-X64: 40 | int a +// CHECK-X64: 48 | struct B2X (virtual base) +// CHECK-X64: 48 | int a +// CHECK-X64: 52 | struct B6X (virtual base) +// CHECK-X64: 52 | int a +// CHECK-X64: 76 | (vtordisp for vbase B3X) +// CHECK-X64: 80 | struct B3X (virtual base) +// CHECK-X64: 80 | (B3X vftable pointer) +// CHECK-X64: 88 | int a +// CHECK-X64: | [sizeof=96, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct CX : B5X, virtual B2X, virtual B6X, virtual B3X { + int a; + CX() : a(0xf000000C) {} + virtual void f() {} + virtual void g() {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct CX +// CHECK: 0 | (CX vftable pointer) +// CHECK: 16 | struct B5X (base) +// CHECK: 16 | (B5X vbtable pointer) +// CHECK: 20 | int a +// CHECK: 24 | int a1 +// CHECK: 28 | int a +// CHECK: 32 | struct A16X (virtual base) (empty) +// CHECK: 32 | struct B2X (virtual base) +// CHECK: 32 | int a +// CHECK: 36 | struct B6X (virtual base) +// CHECK: 36 | int a +// CHECK: 60 | (vtordisp for vbase B3X) +// CHECK: 64 | struct B3X (virtual base) +// CHECK: 64 | (B3X vftable pointer) +// CHECK: 68 | int a +// CHECK: | [sizeof=80, align=16 +// CHECK: | nvsize=32, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct CX +// CHECK-X64: 0 | (CX vftable pointer) +// CHECK-X64: 16 | struct B5X (base) +// CHECK-X64: 16 | (B5X vbtable pointer) +// CHECK-X64: 24 | int a +// CHECK-X64: 28 | int a1 +// CHECK-X64: 32 | int a +// CHECK-X64: 48 | struct A16X (virtual base) (empty) +// CHECK-X64: 48 | struct B2X (virtual base) +// CHECK-X64: 48 | int a +// CHECK-X64: 52 | struct B6X (virtual base) +// CHECK-X64: 52 | int a +// CHECK-X64: 76 | (vtordisp for vbase B3X) +// CHECK-X64: 80 | struct B3X (virtual base) +// CHECK-X64: 80 | (B3X vftable pointer) +// CHECK-X64: 88 | int a +// CHECK-X64: | [sizeof=96, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct __declspec(align(16)) DX { + int a; + DX() : a(0xf000000D) {} + virtual void f() {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct DX +// CHECK: 0 | (DX vftable pointer) +// CHECK: 4 | int a +// CHECK: | [sizeof=16, align=16 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct DX +// CHECK-X64: 0 | (DX vftable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: | [sizeof=16, align=16 +// CHECK-X64: | nvsize=16, nvalign=8] + +int a[ +sizeof(A)+ +sizeof(B)+ +sizeof(C)+ +sizeof(D)+ +sizeof(E)+ +sizeof(F)+ +sizeof(G)+ +sizeof(H)+ +sizeof(I)+ +sizeof(AX)+ +sizeof(BX)+ +sizeof(CX)+ +sizeof(DX)]; diff --git a/test/Layout/ms-x86-basic-layout.cpp b/test/Layout/ms-x86-basic-layout.cpp new file mode 100644 index 0000000..86b3553 --- /dev/null +++ b/test/Layout/ms-x86-basic-layout.cpp @@ -0,0 +1,775 @@ +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %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 -cxx-abi microsoft %s 2>/dev/null \ +// RUN: | FileCheck %s -check-prefix CHECK-X64 + +extern "C" int printf(const char *fmt, ...); + +struct A4 { + int a; + A4() : a(0xf00000a4) {} +}; + +struct B4 { + int a; + B4() : a(0xf00000b4) {} +}; + +struct C4 { + int a; + C4() : a(0xf00000c4) {} + virtual void f() {printf("C4");} +}; + +struct A16 { + __declspec(align(16)) int a; + A16() : a(0xf0000a16) {} +}; + +struct C16 { + __declspec(align(16)) int a; + C16() : a(0xf0000c16) {} + virtual void f() {printf("C16");} +}; + +struct TestF0 : A4, virtual B4 { + int a; + TestF0() : a(0xf00000F0) {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct TestF0 +// CHECK: 0 | struct A4 (base) +// CHECK: 0 | int a +// CHECK: 4 | (TestF0 vbtable pointer) +// CHECK: 8 | int a +// CHECK: 12 | struct B4 (virtual base) +// CHECK: 12 | int a +// CHECK: | [sizeof=16, align=4 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct TestF0 +// CHECK-X64: 0 | struct A4 (base) +// CHECK-X64: 0 | int a +// CHECK-X64: 8 | (TestF0 vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | struct B4 (virtual base) +// CHECK-X64: 24 | int a +// CHECK-X64: | [sizeof=32, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct TestF1 : A4, virtual A16 { + int a; + TestF1() : a(0xf00000f1) {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct TestF1 +// CHECK: 0 | struct A4 (base) +// CHECK: 0 | int a +// CHECK: 4 | (TestF1 vbtable pointer) +// CHECK: 8 | int a +// CHECK: 16 | struct A16 (virtual base) +// CHECK: 16 | int a +// CHECK: | [sizeof=32, align=16 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct TestF1 +// CHECK-X64: 0 | struct A4 (base) +// CHECK-X64: 0 | int a +// CHECK-X64: 8 | (TestF1 vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 32 | struct A16 (virtual base) +// CHECK-X64: 32 | int a +// CHECK-X64: | [sizeof=48, align=16 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct TestF2 : A4, virtual C4 { + int a; + TestF2() : a(0xf00000f2) {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct TestF2 +// CHECK: 0 | struct A4 (base) +// CHECK: 0 | int a +// CHECK: 4 | (TestF2 vbtable pointer) +// CHECK: 8 | int a +// CHECK: 12 | struct C4 (virtual base) +// CHECK: 12 | (C4 vftable pointer) +// CHECK: 16 | int a +// CHECK: | [sizeof=20, align=4 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct TestF2 +// CHECK-X64: 0 | struct A4 (base) +// CHECK-X64: 0 | int a +// CHECK-X64: 8 | (TestF2 vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | struct C4 (virtual base) +// CHECK-X64: 24 | (C4 vftable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: | [sizeof=40, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct TestF3 : A4, virtual C16 { + int a; + TestF3() : a(0xf00000f3) {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct TestF3 +// CHECK: 0 | struct A4 (base) +// CHECK: 0 | int a +// CHECK: 4 | (TestF3 vbtable pointer) +// CHECK: 8 | int a +// CHECK: 16 | struct C16 (virtual base) +// CHECK: 16 | (C16 vftable pointer) +// CHECK: 32 | int a +// CHECK: | [sizeof=48, align=16 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct TestF3 +// CHECK-X64: 0 | struct A4 (base) +// CHECK-X64: 0 | int a +// CHECK-X64: 8 | (TestF3 vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 32 | struct C16 (virtual base) +// CHECK-X64: 32 | (C16 vftable pointer) +// CHECK-X64: 48 | int a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct TestF4 : TestF3, A4 { + int a; + TestF4() : a(0xf00000f4) {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct TestF4 +// CHECK: 0 | struct TestF3 (base) +// CHECK: 0 | struct A4 (base) +// CHECK: 0 | int a +// CHECK: 4 | (TestF3 vbtable pointer) +// CHECK: 8 | int a +// CHECK: 12 | struct A4 (base) +// CHECK: 12 | int a +// CHECK: 16 | int a +// CHECK: 32 | struct C16 (virtual base) +// CHECK: 32 | (C16 vftable pointer) +// CHECK: 48 | int a +// CHECK: | [sizeof=64, align=16 +// CHECK: | nvsize=32, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct TestF4 +// CHECK-X64: 0 | struct TestF3 (base) +// CHECK-X64: 0 | struct A4 (base) +// CHECK-X64: 0 | int a +// CHECK-X64: 8 | (TestF3 vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | struct A4 (base) +// CHECK-X64: 24 | int a +// CHECK-X64: 28 | int a +// CHECK-X64: 32 | struct C16 (virtual base) +// CHECK-X64: 32 | (C16 vftable pointer) +// CHECK-X64: 48 | int a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=32, nvalign=16] + +struct TestF5 : TestF3, A4 { + int a; + TestF5() : a(0xf00000f5) {} + virtual void g() {printf("F5");} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct TestF5 +// CHECK: 0 | (TestF5 vftable pointer) +// CHECK: 16 | struct TestF3 (base) +// CHECK: 16 | struct A4 (base) +// CHECK: 16 | int a +// CHECK: 20 | (TestF3 vbtable pointer) +// CHECK: 24 | int a +// CHECK: 28 | struct A4 (base) +// CHECK: 28 | int a +// CHECK: 32 | int a +// CHECK: 48 | struct C16 (virtual base) +// CHECK: 48 | (C16 vftable pointer) +// CHECK: 64 | int a +// CHECK: | [sizeof=80, align=16 +// CHECK: | nvsize=48, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct TestF5 +// CHECK-X64: 0 | (TestF5 vftable pointer) +// CHECK-X64: 16 | struct TestF3 (base) +// CHECK-X64: 16 | struct A4 (base) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | (TestF3 vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 40 | struct A4 (base) +// CHECK-X64: 40 | int a +// CHECK-X64: 44 | int a +// CHECK-X64: 48 | struct C16 (virtual base) +// CHECK-X64: 48 | (C16 vftable pointer) +// CHECK-X64: 64 | int a +// CHECK-X64: | [sizeof=80, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct TestF6 : TestF3, A4 { + int a; + TestF6() : a(0xf00000f6) {} + virtual void f() {printf("F6");} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct TestF6 +// CHECK: 0 | struct TestF3 (base) +// CHECK: 0 | struct A4 (base) +// CHECK: 0 | int a +// CHECK: 4 | (TestF3 vbtable pointer) +// CHECK: 8 | int a +// CHECK: 12 | struct A4 (base) +// CHECK: 12 | int a +// CHECK: 16 | int a +// CHECK: 44 | (vtordisp for vbase C16) +// CHECK: 48 | struct C16 (virtual base) +// CHECK: 48 | (C16 vftable pointer) +// CHECK: 64 | int a +// CHECK: | [sizeof=80, align=16 +// CHECK: | nvsize=32, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct TestF6 +// CHECK-X64: 0 | struct TestF3 (base) +// CHECK-X64: 0 | struct A4 (base) +// CHECK-X64: 0 | int a +// CHECK-X64: 8 | (TestF3 vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | struct A4 (base) +// CHECK-X64: 24 | int a +// CHECK-X64: 28 | int a +// CHECK-X64: 44 | (vtordisp for vbase C16) +// CHECK-X64: 48 | struct C16 (virtual base) +// CHECK-X64: 48 | (C16 vftable pointer) +// CHECK-X64: 64 | int a +// CHECK-X64: | [sizeof=80, align=16 +// CHECK-X64: | nvsize=32, nvalign=16] + +struct TestF7 : A4, virtual C16 { + int a; + TestF7() : a(0xf00000f7) {} + virtual void f() {printf("F7");} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct TestF7 +// CHECK: 0 | struct A4 (base) +// CHECK: 0 | int a +// CHECK: 4 | (TestF7 vbtable pointer) +// CHECK: 8 | int a +// CHECK: 28 | (vtordisp for vbase C16) +// CHECK: 32 | struct C16 (virtual base) +// CHECK: 32 | (C16 vftable pointer) +// CHECK: 48 | int a +// CHECK: | [sizeof=64, align=16 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct TestF7 +// CHECK-X64: 0 | struct A4 (base) +// CHECK-X64: 0 | int a +// CHECK-X64: 8 | (TestF7 vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 44 | (vtordisp for vbase C16) +// CHECK-X64: 48 | struct C16 (virtual base) +// CHECK-X64: 48 | (C16 vftable pointer) +// CHECK-X64: 64 | int a +// CHECK-X64: | [sizeof=80, align=16 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct TestF8 : TestF7, A4 { + int a; + TestF8() : a(0xf00000f8) {} + virtual void f() {printf("F8");} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct TestF8 +// CHECK: 0 | struct TestF7 (base) +// CHECK: 0 | struct A4 (base) +// CHECK: 0 | int a +// CHECK: 4 | (TestF7 vbtable pointer) +// CHECK: 8 | int a +// CHECK: 12 | struct A4 (base) +// CHECK: 12 | int a +// CHECK: 16 | int a +// CHECK: 44 | (vtordisp for vbase C16) +// CHECK: 48 | struct C16 (virtual base) +// CHECK: 48 | (C16 vftable pointer) +// CHECK: 64 | int a +// CHECK: | [sizeof=80, align=16 +// CHECK: | nvsize=32, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct TestF8 +// CHECK-X64: 0 | struct TestF7 (base) +// CHECK-X64: 0 | struct A4 (base) +// CHECK-X64: 0 | int a +// CHECK-X64: 8 | (TestF7 vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | struct A4 (base) +// CHECK-X64: 24 | int a +// CHECK-X64: 28 | int a +// CHECK-X64: 44 | (vtordisp for vbase C16) +// CHECK-X64: 48 | struct C16 (virtual base) +// CHECK-X64: 48 | (C16 vftable pointer) +// CHECK-X64: 64 | int a +// CHECK-X64: | [sizeof=80, align=16 +// CHECK-X64: | nvsize=32, nvalign=16] + +struct TestF9 : A4, virtual C16 { + int a; + TestF9() : a(0xf00000f9) {} + virtual void g() {printf("F9");} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct TestF9 +// CHECK: 0 | (TestF9 vftable pointer) +// CHECK: 4 | struct A4 (base) +// CHECK: 4 | int a +// CHECK: 8 | (TestF9 vbtable pointer) +// CHECK: 12 | int a +// CHECK: 16 | struct C16 (virtual base) +// CHECK: 16 | (C16 vftable pointer) +// CHECK: 32 | int a +// CHECK: | [sizeof=48, align=16 +// CHECK: | nvsize=16, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct TestF9 +// CHECK-X64: 0 | (TestF9 vftable pointer) +// CHECK-X64: 8 | struct A4 (base) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | (TestF9 vbtable pointer) +// CHECK-X64: 24 | int a +// CHECK-X64: 32 | struct C16 (virtual base) +// CHECK-X64: 32 | (C16 vftable pointer) +// CHECK-X64: 48 | int a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=32, nvalign=8] + +struct TestFA : TestF9, A4 { + int a; + TestFA() : a(0xf00000fa) {} + virtual void g() {printf("FA");} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct TestFA +// CHECK: 0 | struct TestF9 (primary base) +// CHECK: 0 | (TestF9 vftable pointer) +// CHECK: 4 | struct A4 (base) +// CHECK: 4 | int a +// CHECK: 8 | (TestF9 vbtable pointer) +// CHECK: 12 | int a +// CHECK: 16 | struct A4 (base) +// CHECK: 16 | int a +// CHECK: 20 | int a +// CHECK: 32 | struct C16 (virtual base) +// CHECK: 32 | (C16 vftable pointer) +// CHECK: 48 | int a +// CHECK: | [sizeof=64, align=16 +// CHECK: | nvsize=32, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct TestFA +// CHECK-X64: 0 | struct TestF9 (primary base) +// CHECK-X64: 0 | (TestF9 vftable pointer) +// CHECK-X64: 8 | struct A4 (base) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | (TestF9 vbtable pointer) +// CHECK-X64: 24 | int a +// CHECK-X64: 32 | struct A4 (base) +// CHECK-X64: 32 | int a +// CHECK-X64: 36 | int a +// CHECK-X64: 48 | struct C16 (virtual base) +// CHECK-X64: 48 | (C16 vftable pointer) +// CHECK-X64: 64 | int a +// CHECK-X64: | [sizeof=80, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct TestFB : A16, virtual C16 { + int a; + TestFB() : a(0xf00000fb) {} + virtual void g() {printf("Fb");} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct TestFB +// CHECK: 0 | (TestFB vftable pointer) +// CHECK: 16 | struct A16 (base) +// CHECK: 16 | int a +// CHECK: 32 | (TestFB vbtable pointer) +// CHECK: 48 | int a +// CHECK: 64 | struct C16 (virtual base) +// CHECK: 64 | (C16 vftable pointer) +// CHECK: 80 | int a +// CHECK: | [sizeof=96, align=16 +// CHECK: | nvsize=64, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct TestFB +// CHECK-X64: 0 | (TestFB vftable pointer) +// CHECK-X64: 16 | struct A16 (base) +// CHECK-X64: 16 | int a +// CHECK-X64: 32 | (TestFB vbtable pointer) +// CHECK-X64: 40 | int a +// CHECK-X64: 48 | struct C16 (virtual base) +// CHECK-X64: 48 | (C16 vftable pointer) +// CHECK-X64: 64 | int a +// CHECK-X64: | [sizeof=80, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct TestFC : TestFB, A4 { + int a; + TestFC() : a(0xf00000fc) {} + virtual void g() {printf("FC");} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct TestFC +// CHECK: 0 | struct TestFB (primary base) +// CHECK: 0 | (TestFB vftable pointer) +// CHECK: 16 | struct A16 (base) +// CHECK: 16 | int a +// CHECK: 32 | (TestFB vbtable pointer) +// CHECK: 48 | int a +// CHECK: 64 | struct A4 (base) +// CHECK: 64 | int a +// CHECK: 68 | int a +// CHECK: 80 | struct C16 (virtual base) +// CHECK: 80 | (C16 vftable pointer) +// CHECK: 96 | int a +// CHECK: | [sizeof=112, align=16 +// CHECK: | nvsize=80, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct TestFC +// CHECK-X64: 0 | struct TestFB (primary base) +// CHECK-X64: 0 | (TestFB vftable pointer) +// CHECK-X64: 16 | struct A16 (base) +// CHECK-X64: 16 | int a +// CHECK-X64: 32 | (TestFB vbtable pointer) +// CHECK-X64: 40 | int a +// CHECK-X64: 48 | struct A4 (base) +// CHECK-X64: 48 | int a +// CHECK-X64: 52 | int a +// CHECK-X64: 64 | struct C16 (virtual base) +// CHECK-X64: 64 | (C16 vftable pointer) +// CHECK-X64: 80 | int a +// CHECK-X64: | [sizeof=96, align=16 +// CHECK-X64: | nvsize=64, nvalign=16] + + +struct A16f { + __declspec(align(16)) int a; + A16f() : a(0xf0000a16) {} + virtual void f() {printf("A16f");} +}; + +struct Y { char y; Y() : y(0xaa) {} }; +struct X : virtual A16f {}; + +struct B : A4, Y, X { + int a; + B() : a(0xf000000b) {} +}; + +struct F0 : A4, B { + int a; + F0() : a(0xf00000f0) {} + virtual void g() {printf("F0");} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct F0 +// CHECK: 0 | (F0 vftable pointer) +// CHECK: 16 | struct A4 (base) +// CHECK: 16 | int a +// CHECK: 32 | struct B (base) +// CHECK: 32 | struct A4 (base) +// CHECK: 32 | int a +// CHECK: 36 | struct Y (base) +// CHECK: 36 | char y +// CHECK: 48 | struct X (base) +// CHECK: 48 | (X vbtable pointer) +// CHECK: 52 | int a +// CHECK: 64 | int a +// CHECK: 80 | struct A16f (virtual base) +// CHECK: 80 | (A16f vftable pointer) +// CHECK: 96 | int a +// CHECK: | [sizeof=112, align=16 +// CHECK: | nvsize=80, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct F0 +// CHECK-X64: 0 | (F0 vftable pointer) +// CHECK-X64: 8 | struct A4 (base) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct B (base) +// CHECK-X64: 16 | struct A4 (base) +// CHECK-X64: 16 | int a +// CHECK-X64: 20 | struct Y (base) +// CHECK-X64: 20 | char y +// CHECK-X64: 32 | struct X (base) +// CHECK-X64: 32 | (X vbtable pointer) +// CHECK-X64: 40 | int a +// CHECK-X64: 48 | int a +// CHECK-X64: 64 | struct A16f (virtual base) +// CHECK-X64: 64 | (A16f vftable pointer) +// CHECK-X64: 80 | int a +// CHECK-X64: | [sizeof=96, align=16 +// CHECK-X64: | nvsize=64, nvalign=16] + +struct F1 : B, A4 { + int a; + F1() : a(0xf00000f1) {} + virtual void g() {printf("F1");} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct F1 +// CHECK: 0 | (F1 vftable pointer) +// CHECK: 16 | struct B (base) +// CHECK: 16 | struct A4 (base) +// CHECK: 16 | int a +// CHECK: 20 | struct Y (base) +// CHECK: 20 | char y +// CHECK: 32 | struct X (base) +// CHECK: 32 | (X vbtable pointer) +// CHECK: 36 | int a +// CHECK: 48 | struct A4 (base) +// CHECK: 48 | int a +// CHECK: 52 | int a +// CHECK: 64 | struct A16f (virtual base) +// CHECK: 64 | (A16f vftable pointer) +// CHECK: 80 | int a +// CHECK: | [sizeof=96, align=16 +// CHECK: | nvsize=64, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct F1 +// CHECK-X64: 0 | (F1 vftable pointer) +// CHECK-X64: 16 | struct B (base) +// CHECK-X64: 16 | struct A4 (base) +// CHECK-X64: 16 | int a +// CHECK-X64: 20 | struct Y (base) +// CHECK-X64: 20 | char y +// CHECK-X64: 32 | struct X (base) +// CHECK-X64: 32 | (X vbtable pointer) +// CHECK-X64: 40 | int a +// CHECK-X64: 48 | struct A4 (base) +// CHECK-X64: 48 | int a +// CHECK-X64: 52 | int a +// CHECK-X64: 64 | struct A16f (virtual base) +// CHECK-X64: 64 | (A16f vftable pointer) +// CHECK-X64: 80 | int a +// CHECK-X64: | [sizeof=96, align=16 +// CHECK-X64: | nvsize=64, nvalign=16] + +struct F2 : A4, virtual A16f { + int a; + F2() : a(0xf00000f2) {} + virtual void g() {printf("F2");} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct F2 +// CHECK: 0 | (F2 vftable pointer) +// CHECK: 4 | struct A4 (base) +// CHECK: 4 | int a +// CHECK: 8 | (F2 vbtable pointer) +// CHECK: 12 | int a +// CHECK: 16 | struct A16f (virtual base) +// CHECK: 16 | (A16f vftable pointer) +// CHECK: 32 | int a +// CHECK: | [sizeof=48, align=16 +// CHECK: | nvsize=16, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct F2 +// CHECK-X64: 0 | (F2 vftable pointer) +// CHECK-X64: 8 | struct A4 (base) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | (F2 vbtable pointer) +// CHECK-X64: 24 | int a +// CHECK-X64: 32 | struct A16f (virtual base) +// CHECK-X64: 32 | (A16f vftable pointer) +// CHECK-X64: 48 | int a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=32, nvalign=8] + +struct F3 : A4, virtual A16f { + __declspec(align(16)) int a; + F3() : a(0xf00000f3) {} + virtual void g() {printf("F3");} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct F3 +// CHECK: 0 | (F3 vftable pointer) +// CHECK: 16 | struct A4 (base) +// CHECK: 16 | int a +// CHECK: 20 | (F3 vbtable pointer) +// CHECK: 48 | int a +// CHECK: 64 | struct A16f (virtual base) +// CHECK: 64 | (A16f vftable pointer) +// CHECK: 80 | int a +// CHECK: | [sizeof=96, align=16 +// CHECK: | nvsize=64, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct F3 +// CHECK-X64: 0 | (F3 vftable pointer) +// CHECK-X64: 8 | struct A4 (base) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | (F3 vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 48 | struct A16f (virtual base) +// CHECK-X64: 48 | (A16f vftable pointer) +// CHECK-X64: 64 | int a +// CHECK-X64: | [sizeof=80, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct F4 : A4, B { + __declspec(align(16)) int a; + F4() : a(0xf00000f4) {} + virtual void g() {printf("F4");} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct F4 +// CHECK: 0 | (F4 vftable pointer) +// CHECK: 16 | struct A4 (base) +// CHECK: 16 | int a +// CHECK: 32 | struct B (base) +// CHECK: 32 | struct A4 (base) +// CHECK: 32 | int a +// CHECK: 36 | struct Y (base) +// CHECK: 36 | char y +// CHECK: 48 | struct X (base) +// CHECK: 48 | (X vbtable pointer) +// CHECK: 52 | int a +// CHECK: 64 | int a +// CHECK: 80 | struct A16f (virtual base) +// CHECK: 80 | (A16f vftable pointer) +// CHECK: 96 | int a +// CHECK: | [sizeof=112, align=16 +// CHECK: | nvsize=80, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct F4 +// CHECK-X64: 0 | (F4 vftable pointer) +// CHECK-X64: 8 | struct A4 (base) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct B (base) +// CHECK-X64: 16 | struct A4 (base) +// CHECK-X64: 16 | int a +// CHECK-X64: 20 | struct Y (base) +// CHECK-X64: 20 | char y +// CHECK-X64: 32 | struct X (base) +// CHECK-X64: 32 | (X vbtable pointer) +// CHECK-X64: 40 | int a +// CHECK-X64: 48 | int a +// CHECK-X64: 64 | struct A16f (virtual base) +// CHECK-X64: 64 | (A16f vftable pointer) +// CHECK-X64: 80 | int a +// CHECK-X64: | [sizeof=96, align=16 +// CHECK-X64: | nvsize=64, nvalign=16] + +struct F5 : A16f, virtual A4 { + int a; + F5() : a(0xf00000f5) {} + virtual void g() {printf("F5");} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct F5 +// CHECK: 0 | struct A16f (primary base) +// CHECK: 0 | (A16f vftable pointer) +// CHECK: 16 | int a +// CHECK: 32 | (F5 vbtable pointer) +// CHECK: 48 | int a +// CHECK: 64 | struct A4 (virtual base) +// CHECK: 64 | int a +// CHECK: | [sizeof=80, align=16 +// CHECK: | nvsize=64, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct F5 +// CHECK-X64: 0 | struct A16f (primary base) +// CHECK-X64: 0 | (A16f vftable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 32 | (F5 vbtable pointer) +// CHECK-X64: 40 | int a +// CHECK-X64: 48 | struct A4 (virtual base) +// CHECK-X64: 48 | int a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct F6 : virtual A16f, A4, virtual B { + int a; + F6() : a(0xf00000f6) {} + virtual void g() {printf("F6");} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct F6 +// CHECK: 0 | (F6 vftable pointer) +// CHECK: 4 | struct A4 (base) +// CHECK: 4 | int a +// CHECK: 8 | (F6 vbtable pointer) +// CHECK: 12 | int a +// CHECK: 16 | struct A16f (virtual base) +// CHECK: 16 | (A16f vftable pointer) +// CHECK: 32 | int a +// CHECK: 48 | struct B (virtual base) +// CHECK: 48 | struct A4 (base) +// CHECK: 48 | int a +// CHECK: 52 | struct Y (base) +// CHECK: 52 | char y +// CHECK: 64 | struct X (base) +// CHECK: 64 | (X vbtable pointer) +// CHECK: 68 | int a +// CHECK: | [sizeof=80, align=16 +// CHECK: | nvsize=16, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct F6 +// CHECK-X64: 0 | (F6 vftable pointer) +// CHECK-X64: 8 | struct A4 (base) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | (F6 vbtable pointer) +// CHECK-X64: 24 | int a +// CHECK-X64: 32 | struct A16f (virtual base) +// CHECK-X64: 32 | (A16f vftable pointer) +// CHECK-X64: 48 | int a +// CHECK-X64: 64 | struct B (virtual base) +// CHECK-X64: 64 | struct A4 (base) +// CHECK-X64: 64 | int a +// CHECK-X64: 68 | struct Y (base) +// CHECK-X64: 68 | char y +// CHECK-X64: 80 | struct X (base) +// CHECK-X64: 80 | (X vbtable pointer) +// CHECK-X64: 88 | int a +// CHECK-X64: | [sizeof=96, align=16 +// CHECK-X64: | nvsize=32, nvalign=8] + +int a[ +sizeof(TestF0)+ +sizeof(TestF1)+ +sizeof(TestF2)+ +sizeof(TestF3)+ +sizeof(TestF4)+ +sizeof(TestF5)+ +sizeof(TestF6)+ +sizeof(TestF7)+ +sizeof(TestF8)+ +sizeof(TestF9)+ +sizeof(TestFA)+ +sizeof(TestFB)+ +sizeof(TestFC)+ +sizeof(F0)+ +sizeof(F1)+ +sizeof(F2)+ +sizeof(F3)+ +sizeof(F4)+ +sizeof(F5)+ +sizeof(F6)]; diff --git a/test/Layout/ms-x86-bitfields-vbases.cpp b/test/Layout/ms-x86-bitfields-vbases.cpp new file mode 100644 index 0000000..e11ef67 --- /dev/null +++ b/test/Layout/ms-x86-bitfields-vbases.cpp @@ -0,0 +1,84 @@ +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>&1 \ +// RUN: | FileCheck %s +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \ +// RUN: | FileCheck %s -check-prefix CHECK-X64 + +struct B0 { };
+
+struct A : virtual B0 { char a : 1; };
+ +// CHECK: *** Dumping AST Record Layout
+// CHECK: 0 | struct A
+// CHECK: 0 | (A vbtable pointer)
+// CHECK: 4 | char a
+// CHECK: 9 | struct B0 (virtual base) (empty)
+// CHECK: | [sizeof=9, align=4
+// CHECK: | nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct A
+// CHECK-X64: 0 | (A vbtable pointer)
+// CHECK-X64: 8 | char a
+// CHECK-X64: 17 | struct B0 (virtual base) (empty)
+// CHECK-X64: | [sizeof=24, align=8
+// CHECK-X64: | nvsize=16, nvalign=8]
+ +struct B : virtual B0 { short a : 1; };
+ +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct B
+// CHECK: 0 | (B vbtable pointer)
+// CHECK: 4 | short a
+// CHECK: 10 | struct B0 (virtual base) (empty)
+// CHECK: | [sizeof=10, align=4
+// CHECK: | nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct B
+// CHECK-X64: 0 | (B vbtable pointer)
+// CHECK-X64: 8 | short a
+// CHECK-X64: 18 | struct B0 (virtual base) (empty)
+// CHECK-X64: | [sizeof=24, align=8
+// CHECK-X64: | nvsize=16, nvalign=8]
+ +struct C : virtual B0 { char a : 1; char : 0; };
+ +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct C
+// CHECK: 0 | (C vbtable pointer)
+// CHECK: 4 | char a
+// CHECK: 5 | char
+// CHECK: 8 | struct B0 (virtual base) (empty)
+// CHECK: | [sizeof=8, align=4
+// CHECK: | nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct C
+// CHECK-X64: 0 | (C vbtable pointer)
+// CHECK-X64: 8 | char a
+// CHECK-X64: 9 | char
+// CHECK-X64: 16 | struct B0 (virtual base) (empty)
+// CHECK-X64: | [sizeof=16, align=8
+// CHECK-X64: | nvsize=16, nvalign=8]
+ +struct D : virtual B0 { char a : 1; char b; };
+ +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct D
+// CHECK: 0 | (D vbtable pointer)
+// CHECK: 4 | char a
+// CHECK: 5 | char b
+// CHECK: 8 | struct B0 (virtual base) (empty)
+// CHECK: | [sizeof=8, align=4
+// CHECK: | nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct D
+// CHECK-X64: 0 | (D vbtable pointer)
+// CHECK-X64: 8 | char a
+// CHECK-X64: 9 | char b
+// CHECK-X64: 16 | struct B0 (virtual base) (empty)
+// CHECK-X64: | [sizeof=16, align=8
+// CHECK-X64: | nvsize=16, nvalign=8]
+ +int a[ +sizeof(A)+ +sizeof(B)+ +sizeof(C)+ +sizeof(D)]; diff --git a/test/Layout/ms-x86-empty-base-after-base-with-vbptr.cpp b/test/Layout/ms-x86-empty-base-after-base-with-vbptr.cpp new file mode 100644 index 0000000..293a61b --- /dev/null +++ b/test/Layout/ms-x86-empty-base-after-base-with-vbptr.cpp @@ -0,0 +1,216 @@ +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -cxx-abi microsoft %s 2>/dev/null \ +// RUN: | FileCheck %s +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -cxx-abi microsoft %s 2>/dev/null \ +// RUN: | FileCheck %s -check-prefix CHECK-X64 + + +struct U { char a; }; +struct V { }; +struct W { }; +struct X : virtual V { char a; }; +struct Y : virtual V { char a; }; +struct Z : Y { }; + +struct A : X, W { char a; }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct A +// CHECK: 0 | struct X (base) +// CHECK: 0 | (X vbtable pointer) +// CHECK: 4 | char a +// CHECK: 9 | struct W (base) (empty) +// CHECK: 9 | char a +// CHECK: 12 | struct V (virtual base) (empty) +// CHECK: | [sizeof=12, align=4 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct A +// CHECK-X64: 0 | struct X (base) +// CHECK-X64: 0 | (X vbtable pointer) +// CHECK-X64: 8 | char a +// CHECK-X64: 17 | struct W (base) (empty) +// CHECK-X64: 17 | char a +// CHECK-X64: 24 | struct V (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct B : X, U, W { char a; }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct B +// CHECK: 0 | struct X (base) +// CHECK: 0 | (X vbtable pointer) +// CHECK: 4 | char a +// CHECK: 8 | struct U (base) +// CHECK: 8 | char a +// CHECK: 9 | struct W (base) (empty) +// CHECK: 9 | char a +// CHECK: 12 | struct V (virtual base) (empty) +// CHECK: | [sizeof=12, align=4 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct B +// CHECK-X64: 0 | struct X (base) +// CHECK-X64: 0 | (X vbtable pointer) +// CHECK-X64: 8 | char a +// CHECK-X64: 16 | struct U (base) +// CHECK-X64: 16 | char a +// CHECK-X64: 17 | struct W (base) (empty) +// CHECK-X64: 17 | char a +// CHECK-X64: 24 | struct V (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct C : X, V, W { char a; }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct C +// CHECK: 0 | struct X (base) +// CHECK: 0 | (X vbtable pointer) +// CHECK: 4 | char a +// CHECK: 9 | struct V (base) (empty) +// CHECK: 10 | struct W (base) (empty) +// CHECK: 10 | char a +// CHECK: 12 | struct V (virtual base) (empty) +// CHECK: | [sizeof=12, align=4 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct C +// CHECK-X64: 0 | struct X (base) +// CHECK-X64: 0 | (X vbtable pointer) +// CHECK-X64: 8 | char a +// CHECK-X64: 17 | struct V (base) (empty) +// CHECK-X64: 18 | struct W (base) (empty) +// CHECK-X64: 18 | char a +// CHECK-X64: 24 | struct V (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct D : X, U, V, W { char a; }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct D +// CHECK: 0 | struct X (base) +// CHECK: 0 | (X vbtable pointer) +// CHECK: 4 | char a +// CHECK: 8 | struct U (base) +// CHECK: 8 | char a +// CHECK: 9 | struct V (base) (empty) +// CHECK: 10 | struct W (base) (empty) +// CHECK: 10 | char a +// CHECK: 12 | struct V (virtual base) (empty) +// CHECK: | [sizeof=12, align=4 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct D +// CHECK-X64: 0 | struct X (base) +// CHECK-X64: 0 | (X vbtable pointer) +// CHECK-X64: 8 | char a +// CHECK-X64: 16 | struct U (base) +// CHECK-X64: 16 | char a +// CHECK-X64: 17 | struct V (base) (empty) +// CHECK-X64: 18 | struct W (base) (empty) +// CHECK-X64: 18 | char a +// CHECK-X64: 24 | struct V (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct E : X, U, Y, V, W { char a; }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct E +// CHECK: 0 | struct X (base) +// CHECK: 0 | (X vbtable pointer) +// CHECK: 4 | char a +// CHECK: 8 | struct U (base) +// CHECK: 8 | char a +// CHECK: 12 | struct Y (base) +// CHECK: 12 | (Y vbtable pointer) +// CHECK: 16 | char a +// CHECK: 21 | struct V (base) (empty) +// CHECK: 22 | struct W (base) (empty) +// CHECK: 22 | char a +// CHECK: 24 | struct V (virtual base) (empty) +// CHECK: | [sizeof=24, align=4 +// CHECK: | nvsize=24, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct E +// CHECK-X64: 0 | struct X (base) +// CHECK-X64: 0 | (X vbtable pointer) +// CHECK-X64: 8 | char a +// CHECK-X64: 16 | struct U (base) +// CHECK-X64: 16 | char a +// CHECK-X64: 24 | struct Y (base) +// CHECK-X64: 24 | (Y vbtable pointer) +// CHECK-X64: 32 | char a +// CHECK-X64: 41 | struct V (base) (empty) +// CHECK-X64: 42 | struct W (base) (empty) +// CHECK-X64: 42 | char a +// CHECK-X64: 48 | struct V (virtual base) (empty) +// CHECK-X64: | [sizeof=48, align=8 +// CHECK-X64: | nvsize=48, nvalign=8] + +struct F : Z, W { char a; }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct F +// CHECK: 0 | struct Z (base) +// CHECK: 0 | struct Y (base) +// CHECK: 0 | (Y vbtable pointer) +// CHECK: 4 | char a +// CHECK: 9 | struct W (base) (empty) +// CHECK: 9 | char a +// CHECK: 12 | struct V (virtual base) (empty) +// CHECK: | [sizeof=12, align=4 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct F +// CHECK-X64: 0 | struct Z (base) +// CHECK-X64: 0 | struct Y (base) +// CHECK-X64: 0 | (Y vbtable pointer) +// CHECK-X64: 8 | char a +// CHECK-X64: 17 | struct W (base) (empty) +// CHECK-X64: 17 | char a +// CHECK-X64: 24 | struct V (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct G : X, W, Y, V { char a; }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct G +// CHECK: 0 | struct X (base) +// CHECK: 0 | (X vbtable pointer) +// CHECK: 4 | char a +// CHECK: 9 | struct W (base) (empty) +// CHECK: 12 | struct Y (base) +// CHECK: 12 | (Y vbtable pointer) +// CHECK: 16 | char a +// CHECK: 21 | struct V (base) (empty) +// CHECK: 21 | char a +// CHECK: 24 | struct V (virtual base) (empty) +// CHECK: | [sizeof=24, align=4 +// CHECK: | nvsize=24, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct G +// CHECK-X64: 0 | struct X (base) +// CHECK-X64: 0 | (X vbtable pointer) +// CHECK-X64: 8 | char a +// CHECK-X64: 17 | struct W (base) (empty) +// CHECK-X64: 24 | struct Y (base) +// CHECK-X64: 24 | (Y vbtable pointer) +// CHECK-X64: 32 | char a +// CHECK-X64: 41 | struct V (base) (empty) +// CHECK-X64: 41 | char a +// CHECK-X64: 48 | struct V (virtual base) (empty) +// CHECK-X64: | [sizeof=48, align=8 +// CHECK-X64: | nvsize=48, nvalign=8] + +int a[ +sizeof(A)+ +sizeof(B)+ +sizeof(C)+ +sizeof(D)+ +sizeof(E)+ +sizeof(F)+ +sizeof(G)]; diff --git a/test/Layout/ms-x86-empty-nonvirtual-bases.cpp b/test/Layout/ms-x86-empty-nonvirtual-bases.cpp new file mode 100644 index 0000000..01d10c9 --- /dev/null +++ b/test/Layout/ms-x86-empty-nonvirtual-bases.cpp @@ -0,0 +1,174 @@ +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %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 -cxx-abi microsoft %s 2>/dev/null \ +// RUN: | FileCheck %s + +extern "C" int printf(const char *fmt, ...); + +struct __declspec(align(8)) B0 { B0() {printf("B0 : %p\n", this);} }; +struct __declspec(align(8)) B1 { B1() {printf("B1 : %p\n", this);} }; +struct __declspec(align(8)) B2 { B2() {printf("B2 : %p\n", this);} }; +struct __declspec(align(8)) B3 { B3() {printf("B3 : %p\n", this);} }; +struct __declspec(align(8)) B4 { B4() {printf("B4 : %p\n", this);} }; + +struct C0 { int a; C0() : a(0xf00000C0) {printf("C0 : %p\n", this);} }; +struct C1 { int a; C1() : a(0xf00000C1) {printf("C1 : %p\n", this);} }; +struct C2 { int a; C2() : a(0xf00000C2) {printf("C2 : %p\n", this);} }; +struct C3 { int a; C3() : a(0xf00000C3) {printf("C3 : %p\n", this);} }; +struct C4 { int a; C4() : a(0xf00000C4) {printf("C4 : %p\n", this);} }; + +struct A : B0 { + int a; + A() : a(0xf000000A) {printf("X : %p\n", this);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct A +// CHECK: 0 | struct B0 (base) (empty) +// CHECK: 0 | int a +// CHECK: | [sizeof=8, align=8 +// CHECK: | nvsize=8, nvalign=8] + +struct B : B0 { + B0 b0; + int a; + B() : a(0xf000000B) {printf("X : %p\n", this);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct B +// CHECK: 0 | struct B0 (base) (empty) +// CHECK: 0 | struct B0 b0 (empty) +// CHECK: | [sizeof=8, align=8 +// CHECK: | nvsize=0, nvalign=1] +// CHECK: 8 | int a +// CHECK: | [sizeof=16, align=8 +// CHECK: | nvsize=16, nvalign=8] + +struct C : B0, B1, B2, B3, B4 { + int a; + C() : a(0xf000000C) {printf("X : %p\n", this);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct C +// CHECK: 0 | struct B0 (base) (empty) +// CHECK: 8 | struct B1 (base) (empty) +// CHECK: 16 | struct B2 (base) (empty) +// CHECK: 24 | struct B3 (base) (empty) +// CHECK: 32 | struct B4 (base) (empty) +// CHECK: 32 | int a +// CHECK: | [sizeof=40, align=8 +// CHECK: | nvsize=40, nvalign=8] + +struct D { + B0 b0; + C0 c0; + C1 c1; + C2 c2; + B1 b1; + int a; + D() : a(0xf000000D) {printf("X : %p\n", this);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct D +// CHECK: 0 | struct B0 b0 (empty) +// CHECK: | [sizeof=8, align=8 +// CHECK: | nvsize=0, nvalign=1] +// CHECK: 8 | struct C0 c0 +// CHECK: 8 | int a +// CHECK: | [sizeof=4, align=4 +// CHECK: | nvsize=4, nvalign=4] +// CHECK: 12 | struct C1 c1 +// CHECK: 12 | int a +// CHECK: | [sizeof=4, align=4 +// CHECK: | nvsize=4, nvalign=4] +// CHECK: 16 | struct C2 c2 +// CHECK: 16 | int a +// CHECK: | [sizeof=4, align=4 +// CHECK: | nvsize=4, nvalign=4] +// CHECK: 24 | struct B1 b1 (empty) +// CHECK: | [sizeof=8, align=8 +// CHECK: | nvsize=0, nvalign=1] +// CHECK: 32 | int a +// CHECK: | [sizeof=40, align=8 +// CHECK: | nvsize=40, nvalign=8] + +struct E : B0, C0, C1, C2, B1 { + int a; + E() : a(0xf000000E) {printf("X : %p\n", this);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct E +// CHECK: 0 | struct B0 (base) (empty) +// CHECK: 0 | struct C0 (base) +// CHECK: 0 | int a +// CHECK: 4 | struct C1 (base) +// CHECK: 4 | int a +// CHECK: 8 | struct C2 (base) +// CHECK: 8 | int a +// CHECK: 16 | struct B1 (base) (empty) +// CHECK: 16 | int a +// CHECK: | [sizeof=24, align=8 +// CHECK: | nvsize=24, nvalign=8] + +struct F : C0, B0, B1, C1 { + int a; + F() : a(0xf000000F) {printf("X : %p\n", this);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct F +// CHECK: 0 | struct C0 (base) +// CHECK: 0 | int a +// CHECK: 8 | struct B0 (base) (empty) +// CHECK: 16 | struct B1 (base) (empty) +// CHECK: 16 | struct C1 (base) +// CHECK: 16 | int a +// CHECK: 20 | int a +// CHECK: | [sizeof=24, align=8 +// CHECK: | nvsize=24, nvalign=8] + +struct G : B0, B1, B2, B3, B4 { + __declspec(align(32)) int a; + G() : a(0xf0000011) {printf("X : %p\n", this);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct G +// CHECK: 0 | struct B0 (base) (empty) +// CHECK: 8 | struct B1 (base) (empty) +// CHECK: 16 | struct B2 (base) (empty) +// CHECK: 24 | struct B3 (base) (empty) +// CHECK: 32 | struct B4 (base) (empty) +// CHECK: 32 | int a +// CHECK: | [sizeof=64, align=32 +// CHECK: | nvsize=64, nvalign=32] + +struct __declspec(align(32)) H : B0, B1, B2, B3, B4 { + int a; + H() : a(0xf0000011) {printf("X : %p\n", this);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct H +// CHECK: 0 | struct B0 (base) (empty) +// CHECK: 8 | struct B1 (base) (empty) +// CHECK: 16 | struct B2 (base) (empty) +// CHECK: 24 | struct B3 (base) (empty) +// CHECK: 32 | struct B4 (base) (empty) +// CHECK: 32 | int a +// CHECK: | [sizeof=64, align=32 +// CHECK: | nvsize=40, nvalign=8] + +int a[ +sizeof(A)+ +sizeof(B)+ +sizeof(C)+ +sizeof(D)+ +sizeof(E)+ +sizeof(F)+ +sizeof(G)+ +sizeof(H)]; diff --git a/test/Layout/ms-x86-empty-virtual-base.cpp b/test/Layout/ms-x86-empty-virtual-base.cpp new file mode 100644 index 0000000..ef6f081 --- /dev/null +++ b/test/Layout/ms-x86-empty-virtual-base.cpp @@ -0,0 +1,704 @@ +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %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 -cxx-abi microsoft %s 2>/dev/null \ +// RUN: | FileCheck %s -check-prefix CHECK-X64 + +extern "C" int printf(const char *fmt, ...); + +struct __declspec(align(8)) B0 { B0() {printf("B0 : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} }; +struct __declspec(align(8)) B1 { B1() {printf("B1 : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} }; +struct __declspec(align(8)) B2 { B2() {printf("B2 : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} }; +struct __declspec(align(8)) B3 { B3() {printf("B3 : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} }; +struct __declspec(align(8)) B4 { B4() {printf("B4 : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} }; + +struct C0 { int a; C0() : a(0xf00000C0) {printf("C0 : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} }; +struct C1 { int a; C1() : a(0xf00000C1) {printf("C1 : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} }; +struct C2 { int a; C2() : a(0xf00000C2) {printf("C2 : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} }; +struct C3 { int a; C3() : a(0xf00000C3) {printf("C3 : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} }; +struct C4 { int a; C4() : a(0xf00000C4) {printf("C4 : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} }; + +struct __declspec(align(16)) D0 { D0() {printf("D0 : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} virtual void f() {} }; +struct D1 { D1() {printf("D1 : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} }; +struct D2 { int a[8]; D2() {printf("D2 : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} }; + +struct A : virtual B0 { + int a; + A() : a(0xf000000A) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct A +// CHECK: 0 | (A vbtable pointer) +// CHECK: 4 | int a +// CHECK: 8 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=8, align=8 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct A +// CHECK-X64: 0 | (A vbtable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=16, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct B : virtual B0 { + B0 b0; + int a; + B() : a(0xf000000B) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct B +// CHECK: 0 | (B vbtable pointer) +// CHECK: 8 | struct B0 b0 (empty) +// CHECK: | [sizeof=8, align=8 +// CHECK: | nvsize=0, nvalign=1] +// CHECK: 16 | int a +// CHECK: 24 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=24, align=8 +// CHECK: | nvsize=24, nvalign=8] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct B +// CHECK-X64: 0 | (B vbtable pointer) +// CHECK-X64: 8 | struct B0 b0 (empty) +// CHECK-X64: | [sizeof=8, align=8 +// CHECK-X64: | nvsize=0, nvalign=1] +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct C : virtual B0, virtual B1, virtual B2, virtual B3, virtual B4 { + int a; + C() : a(0xf000000C) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct C +// CHECK: 0 | (C vbtable pointer) +// CHECK: 4 | int a +// CHECK: 8 | struct B0 (virtual base) (empty) +// CHECK: 16 | struct B1 (virtual base) (empty) +// CHECK: 24 | struct B2 (virtual base) (empty) +// CHECK: 32 | struct B3 (virtual base) (empty) +// CHECK: 40 | struct B4 (virtual base) (empty) +// CHECK: | [sizeof=40, align=8 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct C +// CHECK-X64: 0 | (C vbtable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct B0 (virtual base) (empty) +// CHECK-X64: 24 | struct B1 (virtual base) (empty) +// CHECK-X64: 32 | struct B2 (virtual base) (empty) +// CHECK-X64: 40 | struct B3 (virtual base) (empty) +// CHECK-X64: 48 | struct B4 (virtual base) (empty) +// CHECK-X64: | [sizeof=48, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct D { + B0 b0; + C0 c0; + C1 c1; + C2 c2; + B1 b1; + int a; + D() : a(0xf000000D) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct D +// CHECK: 0 | struct B0 b0 (empty) +// CHECK: 8 | struct C0 c0 +// CHECK: 8 | int a +// CHECK: 12 | struct C1 c1 +// CHECK: 12 | int a +// CHECK: 16 | struct C2 c2 +// CHECK: 16 | int a +// CHECK: 24 | struct B1 b1 (empty) +// CHECK: 32 | int a +// CHECK: | [sizeof=40, align=8 +// CHECK: | nvsize=40, nvalign=8] +// CHECK-64: *** Dumping AST Record Layout +// CHECK-64: 0 | struct D +// CHECK-64: 0 | struct B0 b0 (empty) +// CHECK-64: 8 | struct C0 c0 +// CHECK-64: 8 | int a +// CHECK-64: 12 | struct C1 c1 +// CHECK-64: 12 | int a +// CHECK-64: 16 | struct C2 c2 +// CHECK-64: 16 | int a +// CHECK-64: 24 | struct B1 b1 (empty) +// CHECK-64: 32 | int a +// CHECK-64: | [sizeof=40, align=8 +// CHECK-64: | nvsize=40, nvalign=8] + +struct E : virtual B0, virtual C0, virtual C1, virtual C2, virtual B1 { + int a; + E() : a(0xf000000E) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct E +// CHECK: 0 | (E vbtable pointer) +// CHECK: 4 | int a +// CHECK: 8 | struct B0 (virtual base) (empty) +// CHECK: 8 | struct C0 (virtual base) +// CHECK: 8 | int a +// CHECK: 12 | struct C1 (virtual base) +// CHECK: 12 | int a +// CHECK: 16 | struct C2 (virtual base) +// CHECK: 16 | int a +// CHECK: 24 | struct B1 (virtual base) (empty) +// CHECK: | [sizeof=24, align=8 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct E +// CHECK-X64: 0 | (E vbtable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct B0 (virtual base) (empty) +// CHECK-X64: 16 | struct C0 (virtual base) +// CHECK-X64: 16 | int a +// CHECK-X64: 20 | struct C1 (virtual base) +// CHECK-X64: 20 | int a +// CHECK-X64: 24 | struct C2 (virtual base) +// CHECK-X64: 24 | int a +// CHECK-X64: 32 | struct B1 (virtual base) (empty) +// CHECK-X64: | [sizeof=32, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct F : virtual C0, virtual B0, virtual B1, virtual C1 { + int a; + F() : a(0xf000000F) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct F +// CHECK: 0 | (F vbtable pointer) +// CHECK: 4 | int a +// CHECK: 8 | struct C0 (virtual base) +// CHECK: 8 | int a +// CHECK: 16 | struct B0 (virtual base) (empty) +// CHECK: 24 | struct B1 (virtual base) (empty) +// CHECK: 24 | struct C1 (virtual base) +// CHECK: 24 | int a +// CHECK: | [sizeof=32, align=8 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct F +// CHECK-X64: 0 | (F vbtable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct C0 (virtual base) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: 32 | struct B1 (virtual base) (empty) +// CHECK-X64: 32 | struct C1 (virtual base) +// CHECK-X64: 32 | int a +// CHECK-X64: | [sizeof=40, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct G : virtual C0, virtual B0, virtual B1, D0, virtual C1 { + int a; + G() : a(0xf0000010) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} + virtual void f() {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct G +// CHECK: 0 | struct D0 (primary base) +// CHECK: 0 | (D0 vftable pointer) +// CHECK: 4 | (G vbtable pointer) +// CHECK: 20 | int a +// CHECK: 32 | struct C0 (virtual base) +// CHECK: 32 | int a +// CHECK: 40 | struct B0 (virtual base) (empty) +// CHECK: 56 | struct B1 (virtual base) (empty) +// CHECK: 56 | struct C1 (virtual base) +// CHECK: 56 | int a +// CHECK: | [sizeof=64, align=16 +// CHECK: | nvsize=32, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct G +// CHECK-X64: 0 | struct D0 (primary base) +// CHECK-X64: 0 | (D0 vftable pointer) +// CHECK-X64: 8 | (G vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 32 | struct C0 (virtual base) +// CHECK-X64: 32 | int a +// CHECK-X64: 40 | struct B0 (virtual base) (empty) +// CHECK-X64: 56 | struct B1 (virtual base) (empty) +// CHECK-X64: 56 | struct C1 (virtual base) +// CHECK-X64: 56 | int a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=32, nvalign=16] + +struct H : virtual C0, virtual B0, virtual B1, virtual D0, virtual C1 { + int a; + H() : a(0xf0000011) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} + virtual void f() {} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct H +// CHECK: 0 | (H vbtable pointer) +// CHECK: 4 | int a +// CHECK: 8 | struct C0 (virtual base) +// CHECK: 8 | int a +// CHECK: 16 | struct B0 (virtual base) (empty) +// CHECK: 24 | struct B1 (virtual base) (empty) +// CHECK: 44 | (vtordisp for vbase D0) +// CHECK: 48 | struct D0 (virtual base) +// CHECK: 48 | (D0 vftable pointer) +// CHECK: 52 | struct C1 (virtual base) +// CHECK: 52 | int a +// CHECK: | [sizeof=64, align=16 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct H +// CHECK-X64: 0 | (H vbtable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct C0 (virtual base) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: 40 | struct B1 (virtual base) (empty) +// CHECK-X64: 60 | (vtordisp for vbase D0) +// CHECK-X64: 64 | struct D0 (virtual base) +// CHECK-X64: 64 | (D0 vftable pointer) +// CHECK-X64: 72 | struct C1 (virtual base) +// CHECK-X64: 72 | int a +// CHECK-X64: | [sizeof=80, align=16 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct I : virtual B0, virtual B1, virtual B2, virtual B3, virtual B4 { + __declspec(align(32)) int a; + I() : a(0xf0000012) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct I +// CHECK: 0 | (I vbtable pointer) +// CHECK: 32 | int a +// CHECK: 64 | struct B0 (virtual base) (empty) +// CHECK: 72 | struct B1 (virtual base) (empty) +// CHECK: 104 | struct B2 (virtual base) (empty) +// CHECK: 136 | struct B3 (virtual base) (empty) +// CHECK: 168 | struct B4 (virtual base) (empty) +// CHECK: | [sizeof=192, align=32 +// CHECK: | nvsize=64, nvalign=32] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct I +// CHECK-X64: 0 | (I vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 64 | struct B0 (virtual base) (empty) +// CHECK-X64: 72 | struct B1 (virtual base) (empty) +// CHECK-X64: 104 | struct B2 (virtual base) (empty) +// CHECK-X64: 136 | struct B3 (virtual base) (empty) +// CHECK-X64: 168 | struct B4 (virtual base) (empty) +// CHECK-X64: | [sizeof=192, align=32 +// CHECK-X64: | nvsize=64, nvalign=32] + +struct __declspec(align(32)) J : virtual B0, virtual B1, virtual B2, virtual B3, virtual B4 { + int a; + J() : a(0xf0000012) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct J +// CHECK: 0 | (J vbtable pointer) +// CHECK: 4 | int a +// CHECK: 8 | struct B0 (virtual base) (empty) +// CHECK: 40 | struct B1 (virtual base) (empty) +// CHECK: 72 | struct B2 (virtual base) (empty) +// CHECK: 104 | struct B3 (virtual base) (empty) +// CHECK: 136 | struct B4 (virtual base) (empty) +// CHECK: | [sizeof=160, align=32 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct J +// CHECK-X64: 0 | (J vbtable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct B0 (virtual base) (empty) +// CHECK-X64: 40 | struct B1 (virtual base) (empty) +// CHECK-X64: 72 | struct B2 (virtual base) (empty) +// CHECK-X64: 104 | struct B3 (virtual base) (empty) +// CHECK-X64: 136 | struct B4 (virtual base) (empty) +// CHECK-X64: | [sizeof=160, align=32 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct K : virtual D1, virtual B1, virtual B2, virtual B3, virtual B4 { + __declspec(align(32)) int a; + K() : a(0xf0000013) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct K +// CHECK: 0 | (K vbtable pointer) +// CHECK: 32 | int a +// CHECK: 64 | struct D1 (virtual base) (empty) +// CHECK: 72 | struct B1 (virtual base) (empty) +// CHECK: 104 | struct B2 (virtual base) (empty) +// CHECK: 136 | struct B3 (virtual base) (empty) +// CHECK: 168 | struct B4 (virtual base) (empty) +// CHECK: | [sizeof=192, align=32 +// CHECK: | nvsize=64, nvalign=32] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct K +// CHECK-X64: 0 | (K vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 64 | struct D1 (virtual base) (empty) +// CHECK-X64: 72 | struct B1 (virtual base) (empty) +// CHECK-X64: 104 | struct B2 (virtual base) (empty) +// CHECK-X64: 136 | struct B3 (virtual base) (empty) +// CHECK-X64: 168 | struct B4 (virtual base) (empty) +// CHECK-X64: | [sizeof=192, align=32 +// CHECK-X64: | nvsize=64, nvalign=32] + +struct L : virtual B1, virtual D1, virtual B2, virtual B3, virtual B4 { + __declspec(align(32)) int a; + L() : a(0xf0000014) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct L +// CHECK: 0 | (L vbtable pointer) +// CHECK: 32 | int a +// CHECK: 64 | struct B1 (virtual base) (empty) +// CHECK: 68 | struct D1 (virtual base) (empty) +// CHECK: 104 | struct B2 (virtual base) (empty) +// CHECK: 136 | struct B3 (virtual base) (empty) +// CHECK: 168 | struct B4 (virtual base) (empty) +// CHECK: | [sizeof=192, align=32 +// CHECK: | nvsize=64, nvalign=32] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct L +// CHECK-X64: 0 | (L vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 64 | struct B1 (virtual base) (empty) +// CHECK-X64: 68 | struct D1 (virtual base) (empty) +// CHECK-X64: 104 | struct B2 (virtual base) (empty) +// CHECK-X64: 136 | struct B3 (virtual base) (empty) +// CHECK-X64: 168 | struct B4 (virtual base) (empty) +// CHECK-X64: | [sizeof=192, align=32 +// CHECK-X64: | nvsize=64, nvalign=32] + +struct M : virtual B1, virtual B2, virtual D1, virtual B3, virtual B4 { + __declspec(align(32)) int a; + M() : a(0xf0000015) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct M +// CHECK: 0 | (M vbtable pointer) +// CHECK: 32 | int a +// CHECK: 64 | struct B1 (virtual base) (empty) +// CHECK: 72 | struct B2 (virtual base) (empty) +// CHECK: 100 | struct D1 (virtual base) (empty) +// CHECK: 136 | struct B3 (virtual base) (empty) +// CHECK: 168 | struct B4 (virtual base) (empty) +// CHECK: | [sizeof=192, align=32 +// CHECK: | nvsize=64, nvalign=32] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct M +// CHECK-X64: 0 | (M vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 64 | struct B1 (virtual base) (empty) +// CHECK-X64: 72 | struct B2 (virtual base) (empty) +// CHECK-X64: 100 | struct D1 (virtual base) (empty) +// CHECK-X64: 136 | struct B3 (virtual base) (empty) +// CHECK-X64: 168 | struct B4 (virtual base) (empty) +// CHECK-X64: | [sizeof=192, align=32 +// CHECK-X64: | nvsize=64, nvalign=32] + +struct N : virtual C0, virtual B1, virtual D1, virtual B2, virtual B3, virtual B4 { + __declspec(align(32)) int a; + N() : a(0xf0000016) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct N +// CHECK: 0 | (N vbtable pointer) +// CHECK: 32 | int a +// CHECK: 64 | struct C0 (virtual base) +// CHECK: 64 | int a +// CHECK: 72 | struct B1 (virtual base) (empty) +// CHECK: 100 | struct D1 (virtual base) (empty) +// CHECK: 136 | struct B2 (virtual base) (empty) +// CHECK: 168 | struct B3 (virtual base) (empty) +// CHECK: 200 | struct B4 (virtual base) (empty) +// CHECK: | [sizeof=224, align=32 +// CHECK: | nvsize=64, nvalign=32] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct N +// CHECK-X64: 0 | (N vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 64 | struct C0 (virtual base) +// CHECK-X64: 64 | int a +// CHECK-X64: 72 | struct B1 (virtual base) (empty) +// CHECK-X64: 100 | struct D1 (virtual base) (empty) +// CHECK-X64: 136 | struct B2 (virtual base) (empty) +// CHECK-X64: 168 | struct B3 (virtual base) (empty) +// CHECK-X64: 200 | struct B4 (virtual base) (empty) +// CHECK-X64: | [sizeof=224, align=32 +// CHECK-X64: | nvsize=64, nvalign=32] + +struct O : virtual C0, virtual B1, virtual B2, virtual D1, virtual B3, virtual B4 { + __declspec(align(32)) int a; + O() : a(0xf0000017) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct O +// CHECK: 0 | (O vbtable pointer) +// CHECK: 32 | int a +// CHECK: 64 | struct C0 (virtual base) +// CHECK: 64 | int a +// CHECK: 72 | struct B1 (virtual base) (empty) +// CHECK: 104 | struct B2 (virtual base) (empty) +// CHECK: 132 | struct D1 (virtual base) (empty) +// CHECK: 168 | struct B3 (virtual base) (empty) +// CHECK: 200 | struct B4 (virtual base) (empty) +// CHECK: | [sizeof=224, align=32 +// CHECK: | nvsize=64, nvalign=32] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct O +// CHECK-X64: 0 | (O vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 64 | struct C0 (virtual base) +// CHECK-X64: 64 | int a +// CHECK-X64: 72 | struct B1 (virtual base) (empty) +// CHECK-X64: 104 | struct B2 (virtual base) (empty) +// CHECK-X64: 132 | struct D1 (virtual base) (empty) +// CHECK-X64: 168 | struct B3 (virtual base) (empty) +// CHECK-X64: 200 | struct B4 (virtual base) (empty) +// CHECK-X64: | [sizeof=224, align=32 +// CHECK-X64: | nvsize=64, nvalign=32] + +struct P : virtual B1, virtual C0, virtual D1, virtual B2, virtual B3, virtual B4 { + __declspec(align(32)) int a; + P() : a(0xf0000018) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct P +// CHECK: 0 | (P vbtable pointer) +// CHECK: 32 | int a +// CHECK: 64 | struct B1 (virtual base) (empty) +// CHECK: 64 | struct C0 (virtual base) +// CHECK: 64 | int a +// CHECK: 68 | struct D1 (virtual base) (empty) +// CHECK: 104 | struct B2 (virtual base) (empty) +// CHECK: 136 | struct B3 (virtual base) (empty) +// CHECK: 168 | struct B4 (virtual base) (empty) +// CHECK: | [sizeof=192, align=32 +// CHECK: | nvsize=64, nvalign=32] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct P +// CHECK-X64: 0 | (P vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 64 | struct B1 (virtual base) (empty) +// CHECK-X64: 64 | struct C0 (virtual base) +// CHECK-X64: 64 | int a +// CHECK-X64: 68 | struct D1 (virtual base) (empty) +// CHECK-X64: 104 | struct B2 (virtual base) (empty) +// CHECK-X64: 136 | struct B3 (virtual base) (empty) +// CHECK-X64: 168 | struct B4 (virtual base) (empty) +// CHECK-X64: | [sizeof=192, align=32 +// CHECK-X64: | nvsize=64, nvalign=32] + +struct Q : virtual B1, virtual C0, virtual B2, virtual D1, virtual B3, virtual B4 { + __declspec(align(32)) int a; + Q() : a(0xf0000019) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct Q +// CHECK: 0 | (Q vbtable pointer) +// CHECK: 32 | int a +// CHECK: 64 | struct B1 (virtual base) (empty) +// CHECK: 64 | struct C0 (virtual base) +// CHECK: 64 | int a +// CHECK: 72 | struct B2 (virtual base) (empty) +// CHECK: 100 | struct D1 (virtual base) (empty) +// CHECK: 136 | struct B3 (virtual base) (empty) +// CHECK: 168 | struct B4 (virtual base) (empty) +// CHECK: | [sizeof=192, align=32 +// CHECK: | nvsize=64, nvalign=32] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct Q +// CHECK-X64: 0 | (Q vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 64 | struct B1 (virtual base) (empty) +// CHECK-X64: 64 | struct C0 (virtual base) +// CHECK-X64: 64 | int a +// CHECK-X64: 72 | struct B2 (virtual base) (empty) +// CHECK-X64: 100 | struct D1 (virtual base) (empty) +// CHECK-X64: 136 | struct B3 (virtual base) (empty) +// CHECK-X64: 168 | struct B4 (virtual base) (empty) +// CHECK-X64: | [sizeof=192, align=32 +// CHECK-X64: | nvsize=64, nvalign=32] + +struct R : virtual B0, virtual B1, virtual B2, virtual C0, virtual B3, virtual B4 { + __declspec(align(32)) int a; + R() : a(0xf0000020) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct R +// CHECK: 0 | (R vbtable pointer) +// CHECK: 32 | int a +// CHECK: 64 | struct B0 (virtual base) (empty) +// CHECK: 72 | struct B1 (virtual base) (empty) +// CHECK: 104 | struct B2 (virtual base) (empty) +// CHECK: 104 | struct C0 (virtual base) +// CHECK: 104 | int a +// CHECK: 112 | struct B3 (virtual base) (empty) +// CHECK: 136 | struct B4 (virtual base) (empty) +// CHECK: | [sizeof=160, align=32 +// CHECK: | nvsize=64, nvalign=32] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct R +// CHECK-X64: 0 | (R vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 64 | struct B0 (virtual base) (empty) +// CHECK-X64: 72 | struct B1 (virtual base) (empty) +// CHECK-X64: 104 | struct B2 (virtual base) (empty) +// CHECK-X64: 104 | struct C0 (virtual base) +// CHECK-X64: 104 | int a +// CHECK-X64: 112 | struct B3 (virtual base) (empty) +// CHECK-X64: 136 | struct B4 (virtual base) (empty) +// CHECK-X64: | [sizeof=160, align=32 +// CHECK-X64: | nvsize=64, nvalign=32] + +struct S : virtual B0, virtual B1, virtual C0, virtual B2, virtual B3, virtual B4 { + __declspec(align(32)) int a; + S() : a(0xf0000021) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct S +// CHECK: 0 | (S vbtable pointer) +// CHECK: 32 | int a +// CHECK: 64 | struct B0 (virtual base) (empty) +// CHECK: 72 | struct B1 (virtual base) (empty) +// CHECK: 72 | struct C0 (virtual base) +// CHECK: 72 | int a +// CHECK: 80 | struct B2 (virtual base) (empty) +// CHECK: 104 | struct B3 (virtual base) (empty) +// CHECK: 136 | struct B4 (virtual base) (empty) +// CHECK: | [sizeof=160, align=32 +// CHECK: | nvsize=64, nvalign=32] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct S +// CHECK-X64: 0 | (S vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 64 | struct B0 (virtual base) (empty) +// CHECK-X64: 72 | struct B1 (virtual base) (empty) +// CHECK-X64: 72 | struct C0 (virtual base) +// CHECK-X64: 72 | int a +// CHECK-X64: 80 | struct B2 (virtual base) (empty) +// CHECK-X64: 104 | struct B3 (virtual base) (empty) +// CHECK-X64: 136 | struct B4 (virtual base) (empty) +// CHECK-X64: | [sizeof=160, align=32 +// CHECK-X64: | nvsize=64, nvalign=32] + +struct T : virtual B0, virtual B1, virtual C0, virtual D2, virtual B2, virtual B3, virtual B4 { + __declspec(align(16)) int a; + T() : a(0xf0000022) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct T +// CHECK: 0 | (T vbtable pointer) +// CHECK: 16 | int a +// CHECK: 32 | struct B0 (virtual base) (empty) +// CHECK: 40 | struct B1 (virtual base) (empty) +// CHECK: 40 | struct C0 (virtual base) +// CHECK: 40 | int a +// CHECK: 44 | struct D2 (virtual base) +// CHECK: 44 | int [8] a +// CHECK: 80 | struct B2 (virtual base) (empty) +// CHECK: 88 | struct B3 (virtual base) (empty) +// CHECK: 104 | struct B4 (virtual base) (empty) +// CHECK: | [sizeof=112, align=16 +// CHECK: | nvsize=32, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct T +// CHECK-X64: 0 | (T vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 32 | struct B0 (virtual base) (empty) +// CHECK-X64: 40 | struct B1 (virtual base) (empty) +// CHECK-X64: 40 | struct C0 (virtual base) +// CHECK-X64: 40 | int a +// CHECK-X64: 44 | struct D2 (virtual base) +// CHECK-X64: 44 | int [8] a +// CHECK-X64: 80 | struct B2 (virtual base) (empty) +// CHECK-X64: 88 | struct B3 (virtual base) (empty) +// CHECK-X64: 104 | struct B4 (virtual base) (empty) +// CHECK-X64: | [sizeof=112, align=16 +// CHECK-X64: | nvsize=32, nvalign=16] + +struct __declspec(align(32)) U : virtual B0, virtual B1 { + int a; + U() : a(0xf0000023) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct U +// CHECK: 0 | (U vbtable pointer) +// CHECK: 4 | int a +// CHECK: 8 | struct B0 (virtual base) (empty) +// CHECK: 40 | struct B1 (virtual base) (empty) +// CHECK: | [sizeof=64, align=32 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct U +// CHECK-X64: 0 | (U vbtable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct B0 (virtual base) (empty) +// CHECK-X64: 40 | struct B1 (virtual base) (empty) +// CHECK-X64: | [sizeof=64, align=32 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct __declspec(align(32)) V : virtual D1 { + int a; + V() : a(0xf0000024) {printf("X : %3d\n", ((int)(__SIZE_TYPE__)this)&0xfff);} +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct V +// CHECK: 0 | (V vbtable pointer) +// CHECK: 4 | int a +// CHECK: 8 | struct D1 (virtual base) (empty) +// CHECK: | [sizeof=32, align=32 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct V +// CHECK-X64: 0 | (V vbtable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct D1 (virtual base) (empty) +// CHECK-X64: | [sizeof=32, align=32 +// CHECK-X64: | nvsize=16, nvalign=8] + +int a[ +sizeof(A)+ +sizeof(B)+ +sizeof(C)+ +sizeof(D)+ +sizeof(E)+ +sizeof(F)+ +sizeof(G)+ +sizeof(H)+ +sizeof(I)+ +sizeof(J)+ +sizeof(K)+ +sizeof(L)+ +sizeof(M)+ +sizeof(N)+ +sizeof(O)+ +sizeof(P)+ +sizeof(Q)+ +sizeof(R)+ +sizeof(S)+ +sizeof(T)+ +sizeof(U)+ +sizeof(V)];
\ No newline at end of file diff --git a/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp b/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp new file mode 100644 index 0000000..7dd3fad --- /dev/null +++ b/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp @@ -0,0 +1,735 @@ +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %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 -cxx-abi microsoft %s 2>/dev/null \ +// RUN: | FileCheck %s -check-prefix CHECK-X64 + +extern "C" int printf(const char *fmt, ...); + +struct B0 { B0() { printf("B0 = %p\n", this); } }; +struct B1 { B1() { printf("B1 = %p\n", this); } }; +struct B2 { B2() { printf("B2 = %p\n", this); } }; +struct B3 { B3() { printf("B3 = %p\n", this); } }; +struct B4 { B4() { printf("B4 = %p\n", this); } }; +struct B5 { B5() { printf("B5 = %p\n", this); } }; +struct __declspec(align(2)) B6 { B6() { printf("B6 = %p\n", this); } }; +struct __declspec(align(16)) B7 { B7() { printf("B7 = %p\n", this); } }; +struct B8 { char c[5]; B8() { printf("B8 = %p\n", this); } }; +struct B9 { char c[6]; B9() { printf("B9 = %p\n", this); } }; +struct B10 { char c[7]; B10() { printf("B10 = %p\n", this); } }; +struct B11 { char c[8]; B11() { printf("B11 = %p\n", this); } }; +struct B0X { B0X() { printf("B0 = %p\n", this); } }; +struct B1X { B1X() { printf("B1 = %p\n", this); } }; +struct __declspec(align(16)) B2X { B2X() { printf("B2 = %p\n", this); } }; +struct __declspec(align(2)) B3X { B3X() { printf("B3 = %p\n", this); } }; +struct B4X { B4X() { printf("B4 = %p\n", this); } }; +struct B5X { B5X() { printf("B5 = %p\n", this); } }; +struct B6X { B6X() { printf("B6 = %p\n", this); } }; +struct B8X { short a; B8X() : a(0xf00000B8) { printf("B8 = %p\n", this); } }; + +struct AA : B8, B1, virtual B0 { + int a; + AA() : a(0xf00000AA) { printf("AA = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AA +// CHECK: 0 | struct B8 (base) +// CHECK: 0 | char [5] c +// CHECK: 13 | struct B1 (base) (empty) +// CHECK: 8 | (AA vbtable pointer) +// CHECK: 16 | int a +// CHECK: 20 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=20, align=4 +// CHECK: | nvsize=20, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AA +// CHECK-X64: 0 | struct B8 (base) +// CHECK-X64: 0 | char [5] c +// CHECK-X64: 17 | struct B1 (base) (empty) +// CHECK-X64: 8 | (AA vbtable pointer) +// CHECK-X64: 20 | int a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct AB : B8, B1, virtual B0 { + short a; + AB() : a(0xf00000AB) { printf("AB = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AB +// CHECK: 0 | struct B8 (base) +// CHECK: 0 | char [5] c +// CHECK: 13 | struct B1 (base) (empty) +// CHECK: 8 | (AB vbtable pointer) +// CHECK: 14 | short a +// CHECK: 16 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=16, align=4 +// CHECK: | nvsize=16, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AB +// CHECK-X64: 0 | struct B8 (base) +// CHECK-X64: 0 | char [5] c +// CHECK-X64: 17 | struct B1 (base) (empty) +// CHECK-X64: 8 | (AB vbtable pointer) +// CHECK-X64: 18 | short a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct AC : B8, B1, virtual B0 { + char a; + AC() : a(0xf00000AC) { printf("AC = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AC +// CHECK: 0 | struct B8 (base) +// CHECK: 0 | char [5] c +// CHECK: 12 | struct B1 (base) (empty) +// CHECK: 8 | (AC vbtable pointer) +// CHECK: 12 | char a +// CHECK: 16 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=16, align=4 +// CHECK: | nvsize=16, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AC +// CHECK-X64: 0 | struct B8 (base) +// CHECK-X64: 0 | char [5] c +// CHECK-X64: 16 | struct B1 (base) (empty) +// CHECK-X64: 8 | (AC vbtable pointer) +// CHECK-X64: 16 | char a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct AD : B8, B1, virtual B0 { + AD() { printf("AD = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AD +// CHECK: 0 | struct B8 (base) +// CHECK: 0 | char [5] c +// CHECK: 12 | struct B1 (base) (empty) +// CHECK: 8 | (AD vbtable pointer) +// CHECK: 12 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=12, align=4 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AD +// CHECK-X64: 0 | struct B8 (base) +// CHECK-X64: 0 | char [5] c +// CHECK-X64: 16 | struct B1 (base) (empty) +// CHECK-X64: 8 | (AD vbtable pointer) +// CHECK-X64: 16 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=16, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct AA1 : B9, B1, virtual B0 { + int a; + AA1() : a(0xf0000AA1) { printf("AA1 = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AA1 +// CHECK: 0 | struct B9 (base) +// CHECK: 0 | char [6] c +// CHECK: 14 | struct B1 (base) (empty) +// CHECK: 8 | (AA1 vbtable pointer) +// CHECK: 16 | int a +// CHECK: 20 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=20, align=4 +// CHECK: | nvsize=20, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AA1 +// CHECK-X64: 0 | struct B9 (base) +// CHECK-X64: 0 | char [6] c +// CHECK-X64: 18 | struct B1 (base) (empty) +// CHECK-X64: 8 | (AA1 vbtable pointer) +// CHECK-X64: 20 | int a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct AB1 : B9, B1, virtual B0 { + short a; + AB1() : a(0xf0000AB1) { printf("AB1 = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AB1 +// CHECK: 0 | struct B9 (base) +// CHECK: 0 | char [6] c +// CHECK: 12 | struct B1 (base) (empty) +// CHECK: 8 | (AB1 vbtable pointer) +// CHECK: 12 | short a +// CHECK: 16 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=16, align=4 +// CHECK: | nvsize=16, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AB1 +// CHECK-X64: 0 | struct B9 (base) +// CHECK-X64: 0 | char [6] c +// CHECK-X64: 16 | struct B1 (base) (empty) +// CHECK-X64: 8 | (AB1 vbtable pointer) +// CHECK-X64: 16 | short a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct AC1 : B9, B1, virtual B0 { + char a; + AC1() : a(0xf0000AC1) { printf("AC1 = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AC1 +// CHECK: 0 | struct B9 (base) +// CHECK: 0 | char [6] c +// CHECK: 12 | struct B1 (base) (empty) +// CHECK: 8 | (AC1 vbtable pointer) +// CHECK: 12 | char a +// CHECK: 16 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=16, align=4 +// CHECK: | nvsize=16, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AC1 +// CHECK-X64: 0 | struct B9 (base) +// CHECK-X64: 0 | char [6] c +// CHECK-X64: 16 | struct B1 (base) (empty) +// CHECK-X64: 8 | (AC1 vbtable pointer) +// CHECK-X64: 16 | char a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct AD1 : B9, B1, virtual B0 { + AD1() { printf("AD1 = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AD1 +// CHECK: 0 | struct B9 (base) +// CHECK: 0 | char [6] c +// CHECK: 12 | struct B1 (base) (empty) +// CHECK: 8 | (AD1 vbtable pointer) +// CHECK: 12 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=12, align=4 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AD1 +// CHECK-X64: 0 | struct B9 (base) +// CHECK-X64: 0 | char [6] c +// CHECK-X64: 16 | struct B1 (base) (empty) +// CHECK-X64: 8 | (AD1 vbtable pointer) +// CHECK-X64: 16 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=16, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct AA2 : B10, B1, virtual B0 { + int a; + AA2() : a(0xf0000AA2) { printf("AA2 = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AA2 +// CHECK: 0 | struct B10 (base) +// CHECK: 0 | char [7] c +// CHECK: 15 | struct B1 (base) (empty) +// CHECK: 8 | (AA2 vbtable pointer) +// CHECK: 16 | int a +// CHECK: 20 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=20, align=4 +// CHECK: | nvsize=20, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AA2 +// CHECK-X64: 0 | struct B10 (base) +// CHECK-X64: 0 | char [7] c +// CHECK-X64: 19 | struct B1 (base) (empty) +// CHECK-X64: 8 | (AA2 vbtable pointer) +// CHECK-X64: 20 | int a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct AB2 : B10, B1, virtual B0 { + short a; + AB2() : a(0xf0000AB2) { printf("AB2 = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AB2 +// CHECK: 0 | struct B10 (base) +// CHECK: 0 | char [7] c +// CHECK: 13 | struct B1 (base) (empty) +// CHECK: 8 | (AB2 vbtable pointer) +// CHECK: 14 | short a +// CHECK: 16 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=16, align=4 +// CHECK: | nvsize=16, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AB2 +// CHECK-X64: 0 | struct B10 (base) +// CHECK-X64: 0 | char [7] c +// CHECK-X64: 17 | struct B1 (base) (empty) +// CHECK-X64: 8 | (AB2 vbtable pointer) +// CHECK-X64: 18 | short a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct AC2 : B10, B1, virtual B0 { + char a; + AC2() : a(0xf0000AC2) { printf("AC2 = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AC2 +// CHECK: 0 | struct B10 (base) +// CHECK: 0 | char [7] c +// CHECK: 12 | struct B1 (base) (empty) +// CHECK: 8 | (AC2 vbtable pointer) +// CHECK: 12 | char a +// CHECK: 16 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=16, align=4 +// CHECK: | nvsize=16, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AC2 +// CHECK-X64: 0 | struct B10 (base) +// CHECK-X64: 0 | char [7] c +// CHECK-X64: 16 | struct B1 (base) (empty) +// CHECK-X64: 8 | (AC2 vbtable pointer) +// CHECK-X64: 16 | char a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct AD2 : B10, B1, virtual B0 { + AD2() { printf("AD2 = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AD2 +// CHECK: 0 | struct B10 (base) +// CHECK: 0 | char [7] c +// CHECK: 12 | struct B1 (base) (empty) +// CHECK: 8 | (AD2 vbtable pointer) +// CHECK: 12 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=12, align=4 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AD2 +// CHECK-X64: 0 | struct B10 (base) +// CHECK-X64: 0 | char [7] c +// CHECK-X64: 16 | struct B1 (base) (empty) +// CHECK-X64: 8 | (AD2 vbtable pointer) +// CHECK-X64: 16 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=16, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct AA3 : B11, B1, virtual B0 { + int a; + AA3() : a(0xf0000AA3) { printf("AA3 = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AA3 +// CHECK: 0 | struct B11 (base) +// CHECK: 0 | char [8] c +// CHECK: 12 | struct B1 (base) (empty) +// CHECK: 8 | (AA3 vbtable pointer) +// CHECK: 12 | int a +// CHECK: 16 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=16, align=4 +// CHECK: | nvsize=16, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AA3 +// CHECK-X64: 0 | struct B11 (base) +// CHECK-X64: 0 | char [8] c +// CHECK-X64: 16 | struct B1 (base) (empty) +// CHECK-X64: 8 | (AA3 vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct AB3 : B11, B1, virtual B0 { + short a; + AB3() : a(0xf0000AB3) { printf("AB3 = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AB3 +// CHECK: 0 | struct B11 (base) +// CHECK: 0 | char [8] c +// CHECK: 12 | struct B1 (base) (empty) +// CHECK: 8 | (AB3 vbtable pointer) +// CHECK: 12 | short a +// CHECK: 16 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=16, align=4 +// CHECK: | nvsize=16, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AB3 +// CHECK-X64: 0 | struct B11 (base) +// CHECK-X64: 0 | char [8] c +// CHECK-X64: 16 | struct B1 (base) (empty) +// CHECK-X64: 8 | (AB3 vbtable pointer) +// CHECK-X64: 16 | short a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct AC3 : B11, B1, virtual B0 { + char a; + AC3() : a(0xf0000AC3) { printf("AC3 = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AC3 +// CHECK: 0 | struct B11 (base) +// CHECK: 0 | char [8] c +// CHECK: 12 | struct B1 (base) (empty) +// CHECK: 8 | (AC3 vbtable pointer) +// CHECK: 12 | char a +// CHECK: 16 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=16, align=4 +// CHECK: | nvsize=16, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AC3 +// CHECK-X64: 0 | struct B11 (base) +// CHECK-X64: 0 | char [8] c +// CHECK-X64: 16 | struct B1 (base) (empty) +// CHECK-X64: 8 | (AC3 vbtable pointer) +// CHECK-X64: 16 | char a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct AD3 : B11, B1, virtual B0 { + AD3() { printf("AD3 = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AD3 +// CHECK: 0 | struct B11 (base) +// CHECK: 0 | char [8] c +// CHECK: 12 | struct B1 (base) (empty) +// CHECK: 8 | (AD3 vbtable pointer) +// CHECK: 12 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=12, align=4 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AD3 +// CHECK-X64: 0 | struct B11 (base) +// CHECK-X64: 0 | char [8] c +// CHECK-X64: 16 | struct B1 (base) (empty) +// CHECK-X64: 8 | (AD3 vbtable pointer) +// CHECK-X64: 16 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=16, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct B : B1, B2, virtual B0 { + B() { printf("B = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct B +// CHECK: 0 | struct B1 (base) (empty) +// CHECK: 8 | struct B2 (base) (empty) +// CHECK: 4 | (B vbtable pointer) +// CHECK: 8 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=8, align=4 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct B +// CHECK-X64: 0 | struct B1 (base) (empty) +// CHECK-X64: 16 | struct B2 (base) (empty) +// CHECK-X64: 8 | (B vbtable pointer) +// CHECK-X64: 16 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=16, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct C : B1, B2, B3, virtual B0 { + char a; + C() : a(0xf000000C) { printf("C = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct C +// CHECK: 0 | struct B1 (base) (empty) +// CHECK: 1 | struct B2 (base) (empty) +// CHECK: 8 | struct B3 (base) (empty) +// CHECK: 4 | (C vbtable pointer) +// CHECK: 8 | char a +// CHECK: 12 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=12, align=4 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct C +// CHECK-X64: 0 | struct B1 (base) (empty) +// CHECK-X64: 1 | struct B2 (base) (empty) +// CHECK-X64: 16 | struct B3 (base) (empty) +// CHECK-X64: 8 | (C vbtable pointer) +// CHECK-X64: 16 | char a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct D : B1, B2, B3, B4, B5, virtual B0 { + int a; + D() : a(0xf000000D) { printf("D = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct D +// CHECK: 0 | struct B1 (base) (empty) +// CHECK: 1 | struct B2 (base) (empty) +// CHECK: 2 | struct B3 (base) (empty) +// CHECK: 3 | struct B4 (base) (empty) +// CHECK: 8 | struct B5 (base) (empty) +// CHECK: 4 | (D vbtable pointer) +// CHECK: 8 | int a +// CHECK: 12 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=12, align=4 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct D +// CHECK-X64: 0 | struct B1 (base) (empty) +// CHECK-X64: 1 | struct B2 (base) (empty) +// CHECK-X64: 2 | struct B3 (base) (empty) +// CHECK-X64: 3 | struct B4 (base) (empty) +// CHECK-X64: 16 | struct B5 (base) (empty) +// CHECK-X64: 8 | (D vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct E : B1, B6, B3, B4, B5, virtual B0 { + int a; + E() : a(0xf000000E) { printf("E = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct E +// CHECK: 0 | struct B1 (base) (empty) +// CHECK: 2 | struct B6 (base) (empty) +// CHECK: 3 | struct B3 (base) (empty) +// CHECK: 4 | struct B4 (base) (empty) +// CHECK: 13 | struct B5 (base) (empty) +// CHECK: 8 | (E vbtable pointer) +// CHECK: 16 | int a +// CHECK: 20 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=20, align=4 +// CHECK: | nvsize=20, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct E +// CHECK-X64: 0 | struct B1 (base) (empty) +// CHECK-X64: 2 | struct B6 (base) (empty) +// CHECK-X64: 3 | struct B3 (base) (empty) +// CHECK-X64: 4 | struct B4 (base) (empty) +// CHECK-X64: 17 | struct B5 (base) (empty) +// CHECK-X64: 8 | (E vbtable pointer) +// CHECK-X64: 20 | int a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct F : B1, B6, B4, B8, B5, virtual B0 { + int a; + F() : a(0xf000000F) { printf("&a = %p\n", &a); printf("F = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct F +// CHECK: 0 | struct B1 (base) (empty) +// CHECK: 2 | struct B6 (base) (empty) +// CHECK: 3 | struct B4 (base) (empty) +// CHECK: 3 | struct B8 (base) +// CHECK: 3 | char [5] c +// CHECK: 12 | struct B5 (base) (empty) +// CHECK: 8 | (F vbtable pointer) +// CHECK: 12 | int a +// CHECK: 16 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=16, align=4 +// CHECK: | nvsize=16, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct F +// CHECK-X64: 0 | struct B1 (base) (empty) +// CHECK-X64: 2 | struct B6 (base) (empty) +// CHECK-X64: 3 | struct B4 (base) (empty) +// CHECK-X64: 3 | struct B8 (base) +// CHECK-X64: 3 | char [5] c +// CHECK-X64: 16 | struct B5 (base) (empty) +// CHECK-X64: 8 | (F vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct G : B8, B1, virtual B0 { + int a; + __declspec(align(16)) int a1; + G() : a(0xf0000010), a1(0xf0000010) { printf("G = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct G +// CHECK: 0 | struct B8 (base) +// CHECK: 0 | char [5] c +// CHECK: 21 | struct B1 (base) (empty) +// CHECK: 8 | (G vbtable pointer) +// CHECK: 24 | int a +// CHECK: 32 | int a1 +// CHECK: 48 | struct B0 (virtual base) (empty) +// CHECK: | [sizeof=48, align=16 +// CHECK: | nvsize=48, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct G +// CHECK-X64: 0 | struct B8 (base) +// CHECK-X64: 0 | char [5] c +// CHECK-X64: 16 | struct B1 (base) (empty) +// CHECK-X64: 8 | (G vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 32 | int a1 +// CHECK-X64: 48 | struct B0 (virtual base) (empty) +// CHECK-X64: | [sizeof=48, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct AX : B1X, B2X, B3X, B4X, virtual B0X { + int a; + AX() : a(0xf000000A) { printf(" A = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AX +// CHECK: 0 | struct B1X (base) (empty) +// CHECK: 16 | struct B2X (base) (empty) +// CHECK: 18 | struct B3X (base) (empty) +// CHECK: 35 | struct B4X (base) (empty) +// CHECK: 20 | (AX vbtable pointer) +// CHECK: 36 | int a +// CHECK: 48 | struct B0X (virtual base) (empty) +// CHECK: | [sizeof=48, align=16 +// CHECK: | nvsize=48, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AX +// CHECK-X64: 0 | struct B1X (base) (empty) +// CHECK-X64: 16 | struct B2X (base) (empty) +// CHECK-X64: 18 | struct B3X (base) (empty) +// CHECK-X64: 33 | struct B4X (base) (empty) +// CHECK-X64: 24 | (AX vbtable pointer) +// CHECK-X64: 36 | int a +// CHECK-X64: 48 | struct B0X (virtual base) (empty) +// CHECK-X64: | [sizeof=48, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct BX : B2X, B1X, B3X, B4X, virtual B0X { + int a; + BX() : a(0xf000000B) { printf(" B = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct BX +// CHECK: 0 | struct B2X (base) (empty) +// CHECK: 1 | struct B1X (base) (empty) +// CHECK: 2 | struct B3X (base) (empty) +// CHECK: 19 | struct B4X (base) (empty) +// CHECK: 4 | (BX vbtable pointer) +// CHECK: 20 | int a +// CHECK: 32 | struct B0X (virtual base) (empty) +// CHECK: | [sizeof=32, align=16 +// CHECK: | nvsize=32, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct BX +// CHECK-X64: 0 | struct B2X (base) (empty) +// CHECK-X64: 1 | struct B1X (base) (empty) +// CHECK-X64: 2 | struct B3X (base) (empty) +// CHECK-X64: 17 | struct B4X (base) (empty) +// CHECK-X64: 8 | (BX vbtable pointer) +// CHECK-X64: 20 | int a +// CHECK-X64: 32 | struct B0X (virtual base) (empty) +// CHECK-X64: | [sizeof=32, align=16 +// CHECK-X64: | nvsize=32, nvalign=16] + +struct CX : B1X, B3X, B2X, virtual B0X { + int a; + CX() : a(0xf000000C) { printf(" C = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct CX +// CHECK: 0 | struct B1X (base) (empty) +// CHECK: 2 | struct B3X (base) (empty) +// CHECK: 32 | struct B2X (base) (empty) +// CHECK: 4 | (CX vbtable pointer) +// CHECK: 32 | int a +// CHECK: 48 | struct B0X (virtual base) (empty) +// CHECK: | [sizeof=48, align=16 +// CHECK: | nvsize=48, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct CX +// CHECK-X64: 0 | struct B1X (base) (empty) +// CHECK-X64: 2 | struct B3X (base) (empty) +// CHECK-X64: 32 | struct B2X (base) (empty) +// CHECK-X64: 8 | (CX vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 48 | struct B0X (virtual base) (empty) +// CHECK-X64: | [sizeof=48, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct DX : B8X, B1X, virtual B0X { + int a; + DX() : a(0xf000000D) { printf(" D = %p\n", this); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct DX +// CHECK: 0 | struct B8X (base) +// CHECK: 0 | short a +// CHECK: 10 | struct B1X (base) (empty) +// CHECK: 4 | (DX vbtable pointer) +// CHECK: 12 | int a +// CHECK: 16 | struct B0X (virtual base) (empty) +// CHECK: | [sizeof=16, align=4 +// CHECK: | nvsize=16, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct DX +// CHECK-X64: 0 | struct B8X (base) +// CHECK-X64: 0 | short a +// CHECK-X64: 18 | struct B1X (base) (empty) +// CHECK-X64: 8 | (DX vbtable pointer) +// CHECK-X64: 20 | int a +// CHECK-X64: 24 | struct B0X (virtual base) (empty) +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +int a[ +sizeof(AA)+ +sizeof(AB)+ +sizeof(AC)+ +sizeof(AD)+ +sizeof(AA1)+ +sizeof(AB1)+ +sizeof(AC1)+ +sizeof(AD1)+ +sizeof(AA2)+ +sizeof(AB2)+ +sizeof(AC2)+ +sizeof(AD2)+ +sizeof(AA3)+ +sizeof(AB3)+ +sizeof(AC3)+ +sizeof(AD3)+ +sizeof(B)+ +sizeof(C)+ +sizeof(D)+ +sizeof(E)+ +sizeof(F)+ +sizeof(G)+ +sizeof(AX)+ +sizeof(BX)+ +sizeof(CX)+ +sizeof(DX)]; diff --git a/test/Layout/ms-x86-misalignedarray.cpp b/test/Layout/ms-x86-misalignedarray.cpp new file mode 100644 index 0000000..f6887da --- /dev/null +++ b/test/Layout/ms-x86-misalignedarray.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>&1 \ +// RUN: | FileCheck %s +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \ +// RUN: | FileCheck %s -check-prefix CHECK-X64 + +struct T0 { char c; };
+struct T2 : virtual T0 { };
+struct T3 { T2 a[1]; char c; };
+ +// CHECK: *** Dumping AST Record Layout
+// CHECK: 0 | struct T3
+// CHECK: 0 | struct T2 [1] a
+// CHECK: 5 | char c
+// CHECK: | [sizeof=8, align=4
+// CHECK: | nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: 0 | struct T3
+// CHECK-X64: 0 | struct T2 [1] a
+// CHECK-X64: 16 | char c
+// CHECK-X64: | [sizeof=24, align=8
+// CHECK-X64: | nvsize=24, nvalign=8]
+ +int a[sizeof(T3)]; diff --git a/test/Layout/ms-x86-primary-bases.cpp b/test/Layout/ms-x86-primary-bases.cpp new file mode 100644 index 0000000..bc9b801 --- /dev/null +++ b/test/Layout/ms-x86-primary-bases.cpp @@ -0,0 +1,317 @@ +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %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 -cxx-abi microsoft %s 2>/dev/null \ +// RUN: | FileCheck %s -check-prefix CHECK-X64 + +extern "C" int printf(const char *fmt, ...); + +struct B0 { int a; B0() : a(0xf00000B0) { printf("B0 = %p\n", this); } virtual void f() { printf("B0"); } }; +struct B1 { int a; B1() : a(0xf00000B1) { printf("B1 = %p\n", this); } virtual void g() { printf("B1"); } }; +struct B2 { int a; B2() : a(0xf00000B2) { printf("B1 = %p\n", this); } }; +struct B0X { int a; B0X() : a(0xf00000B0) {} }; +struct B1X { int a; B1X() : a(0xf00000B1) {} virtual void f() { printf("B0"); } }; +struct B2X : virtual B1X { int a; B2X() : a(0xf00000B2) {} }; + +struct A : virtual B0 { +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct A +// CHECK: 0 | (A vbtable pointer) +// CHECK: 4 | struct B0 (virtual base) +// CHECK: 4 | (B0 vftable pointer) +// CHECK: 8 | int a +// CHECK: | [sizeof=12, align=4 +// CHECK: | nvsize=4, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct A +// CHECK-X64: 0 | (A vbtable pointer) +// CHECK-X64: 8 | struct B0 (virtual base) +// CHECK-X64: 8 | (B0 vftable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=8, nvalign=8] + +struct B : virtual B0 { + virtual void f() { printf("B"); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct B +// CHECK: 0 | (B vbtable pointer) +// CHECK: 4 | struct B0 (virtual base) +// CHECK: 4 | (B0 vftable pointer) +// CHECK: 8 | int a +// CHECK: | [sizeof=12, align=4 +// CHECK: | nvsize=4, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct B +// CHECK-X64: 0 | (B vbtable pointer) +// CHECK-X64: 8 | struct B0 (virtual base) +// CHECK-X64: 8 | (B0 vftable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=8, nvalign=8] + +struct C : virtual B0 { + virtual void g() { printf("A"); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct C +// CHECK: 0 | (C vftable pointer) +// CHECK: 4 | (C vbtable pointer) +// CHECK: 8 | struct B0 (virtual base) +// CHECK: 8 | (B0 vftable pointer) +// CHECK: 12 | int a +// CHECK: | [sizeof=16, align=4 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct C +// CHECK-X64: 0 | (C vftable pointer) +// CHECK-X64: 8 | (C vbtable pointer) +// CHECK-X64: 16 | struct B0 (virtual base) +// CHECK-X64: 16 | (B0 vftable pointer) +// CHECK-X64: 24 | int a +// CHECK-X64: | [sizeof=32, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct D : virtual B2, virtual B0 { + virtual void f() { printf("D"); } + virtual void g() { printf("D"); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct D +// CHECK: 0 | (D vftable pointer) +// CHECK: 4 | (D vbtable pointer) +// CHECK: 8 | struct B2 (virtual base) +// CHECK: 8 | int a +// CHECK: 12 | struct B0 (virtual base) +// CHECK: 12 | (B0 vftable pointer) +// CHECK: 16 | int a +// CHECK: | [sizeof=20, align=4 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct D +// CHECK-X64: 0 | (D vftable pointer) +// CHECK-X64: 8 | (D vbtable pointer) +// CHECK-X64: 16 | struct B2 (virtual base) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | struct B0 (virtual base) +// CHECK-X64: 24 | (B0 vftable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: | [sizeof=40, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct E : B0, virtual B1 { + virtual void f() { printf("E"); } + virtual void g() { printf("E"); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct E +// CHECK: 0 | struct B0 (primary base) +// CHECK: 0 | (B0 vftable pointer) +// CHECK: 4 | int a +// CHECK: 8 | (E vbtable pointer) +// CHECK: 12 | struct B1 (virtual base) +// CHECK: 12 | (B1 vftable pointer) +// CHECK: 16 | int a +// CHECK: | [sizeof=20, align=4 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct E +// CHECK-X64: 0 | struct B0 (primary base) +// CHECK-X64: 0 | (B0 vftable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | (E vbtable pointer) +// CHECK-X64: 24 | struct B1 (virtual base) +// CHECK-X64: 24 | (B1 vftable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: | [sizeof=40, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct F : virtual B0, virtual B1 { +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct F +// CHECK: 0 | (F vbtable pointer) +// CHECK: 4 | struct B0 (virtual base) +// CHECK: 4 | (B0 vftable pointer) +// CHECK: 8 | int a +// CHECK: 12 | struct B1 (virtual base) +// CHECK: 12 | (B1 vftable pointer) +// CHECK: 16 | int a +// CHECK: | [sizeof=20, align=4 +// CHECK: | nvsize=4, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct F +// CHECK-X64: 0 | (F vbtable pointer) +// CHECK-X64: 8 | struct B0 (virtual base) +// CHECK-X64: 8 | (B0 vftable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | struct B1 (virtual base) +// CHECK-X64: 24 | (B1 vftable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: | [sizeof=40, align=8 +// CHECK-X64: | nvsize=8, nvalign=8] + +struct AX : B0X, B1X { int a; AX() : a(0xf000000A) {} virtual void f() { printf("A"); } }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct AX +// CHECK: 8 | struct B0X (base) +// CHECK: 8 | int a +// CHECK: 0 | struct B1X (primary base) +// CHECK: 0 | (B1X vftable pointer) +// CHECK: 4 | int a +// CHECK: 12 | int a +// CHECK: | [sizeof=16, align=4 +// CHECK: | nvsize=16, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct AX +// CHECK-X64: 16 | struct B0X (base) +// CHECK-X64: 16 | int a +// CHECK-X64: 0 | struct B1X (primary base) +// CHECK-X64: 0 | (B1X vftable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 20 | int a +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct BX : B0X, B1X { int a; BX() : a(0xf000000B) {} virtual void g() { printf("B"); } }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct BX +// CHECK: 8 | struct B0X (base) +// CHECK: 8 | int a +// CHECK: 0 | struct B1X (primary base) +// CHECK: 0 | (B1X vftable pointer) +// CHECK: 4 | int a +// CHECK: 12 | int a +// CHECK: | [sizeof=16, align=4 +// CHECK: | nvsize=16, nvalign=4] +// CHECK-x64: *** Dumping AST Record Layout +// CHECK-x64: 0 | struct BX +// CHECK-x64: 16 | struct B0X (base) +// CHECK-x64: 16 | int a +// CHECK-x64: 0 | struct B1X (primary base) +// CHECK-x64: 0 | (B1X vftable pointer) +// CHECK-x64: 8 | int a +// CHECK-x64: 24 | int a +// CHECK-x64: | [sizeof=24, align=8 +// CHECK-x64: | nvsize=24, nvalign=8] + +struct CX : B0X, B2X { int a; CX() : a(0xf000000C) {} virtual void g() { printf("C"); } }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct CX +// CHECK: 0 | (CX vftable pointer) +// CHECK: 4 | struct B0X (base) +// CHECK: 4 | int a +// CHECK: 8 | struct B2X (base) +// CHECK: 8 | (B2X vbtable pointer) +// CHECK: 12 | int a +// CHECK: 16 | int a +// CHECK: 20 | struct B1X (virtual base) +// CHECK: 20 | (B1X vftable pointer) +// CHECK: 24 | int a +// CHECK: | [sizeof=28, align=4 +// CHECK: | nvsize=20, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct CX +// CHECK-X64: 0 | (CX vftable pointer) +// CHECK-X64: 8 | struct B0X (base) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct B2X (base) +// CHECK-X64: 16 | (B2X vbtable pointer) +// CHECK-X64: 24 | int a +// CHECK-X64: 32 | int a +// CHECK-X64: 40 | struct B1X (virtual base) +// CHECK-X64: 40 | (B1X vftable pointer) +// CHECK-X64: 48 | int a +// CHECK-X64: | [sizeof=56, align=8 +// CHECK-X64: | nvsize=40, nvalign=8] + +struct DX : virtual B1X { int a; DX() : a(0xf000000D) {} virtual void f() { printf("D"); } }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct DX +// CHECK: 0 | (DX vbtable pointer) +// CHECK: 4 | int a +// CHECK: 8 | (vtordisp for vbase B1X) +// CHECK: 12 | struct B1X (virtual base) +// CHECK: 12 | (B1X vftable pointer) +// CHECK: 16 | int a +// CHECK: | [sizeof=20, align=4 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct DX +// CHECK-X64: 0 | (DX vbtable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 20 | (vtordisp for vbase B1X) +// CHECK-X64: 24 | struct B1X (virtual base) +// CHECK-X64: 24 | (B1X vftable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: | [sizeof=40, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct EX : virtual B1X { int a; EX() : a(0xf000000E) {} virtual void g() { printf("E"); } }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct EX +// CHECK: 0 | (EX vftable pointer) +// CHECK: 4 | (EX vbtable pointer) +// CHECK: 8 | int a +// CHECK: 12 | struct B1X (virtual base) +// CHECK: 12 | (B1X vftable pointer) +// CHECK: 16 | int a +// CHECK: | [sizeof=20, align=4 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct EX +// CHECK-X64: 0 | (EX vftable pointer) +// CHECK-X64: 8 | (EX vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | struct B1X (virtual base) +// CHECK-X64: 24 | (B1X vftable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: | [sizeof=40, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct FX : virtual B1X { int a; FX() : a(0xf000000F) {} }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct FX +// CHECK: 0 | (FX vbtable pointer) +// CHECK: 4 | int a +// CHECK: 8 | struct B1X (virtual base) +// CHECK: 8 | (B1X vftable pointer) +// CHECK: 12 | int a +// CHECK: | [sizeof=16, align=4 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct FX +// CHECK-X64: 0 | (FX vbtable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct B1X (virtual base) +// CHECK-X64: 16 | (B1X vftable pointer) +// CHECK-X64: 24 | int a +// CHECK-X64: | [sizeof=32, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +int a[ +sizeof(A)+ +sizeof(B)+ +sizeof(C)+ +sizeof(D)+ +sizeof(E)+ +sizeof(F)+ +sizeof(AX)+ +sizeof(BX)+ +sizeof(CX)+ +sizeof(DX)+ +sizeof(EX)+ +sizeof(FX)]; diff --git a/test/Layout/ms-x86-size-alignment-fail.cpp b/test/Layout/ms-x86-size-alignment-fail.cpp new file mode 100644 index 0000000..f998ee1 --- /dev/null +++ b/test/Layout/ms-x86-size-alignment-fail.cpp @@ -0,0 +1,123 @@ +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -cxx-abi microsoft %s 2>/dev/null \ +// RUN: | FileCheck %s +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -cxx-abi microsoft %s 2>/dev/null \ +// RUN: | FileCheck %s -check-prefix CHECK-X64 + +extern "C" int printf(const char *fmt, ...); + +struct B0 { char a; B0() : a(0xB0) {} }; +struct __declspec(align(1)) B1 {}; + +struct A : virtual B0 {}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct A +// CHECK: 0 | (A vbtable pointer) +// CHECK: 4 | struct B0 (virtual base) +// CHECK: 4 | char a +// CHECK: | [sizeof=5, align=4 +// CHECK: | nvsize=4, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct A +// CHECK-X64: 0 | (A vbtable pointer) +// CHECK-X64: 8 | struct B0 (virtual base) +// CHECK-X64: 8 | char a +// CHECK-X64: | [sizeof=16, align=8 +// CHECK-X64: | nvsize=8, nvalign=8] + +struct __declspec(align(1)) B : virtual B0 {}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct B +// CHECK: 0 | (B vbtable pointer) +// CHECK: 4 | struct B0 (virtual base) +// CHECK: 4 | char a +// CHECK: | [sizeof=8, align=4 +// CHECK: | nvsize=4, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct B +// CHECK-X64: 0 | (B vbtable pointer) +// CHECK-X64: 8 | struct B0 (virtual base) +// CHECK-X64: 8 | char a +// CHECK-X64: | [sizeof=16, align=8 +// CHECK-X64: | nvsize=8, nvalign=8] + +struct C : virtual B0 { int a; C() : a(0xC) {} }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct C +// CHECK: 0 | (C vbtable pointer) +// CHECK: 4 | int a +// CHECK: 8 | struct B0 (virtual base) +// CHECK: 8 | char a +// CHECK: | [sizeof=9, align=4 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct C +// CHECK-X64: 0 | (C vbtable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct B0 (virtual base) +// CHECK-X64: 16 | char a +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct D : virtual B0 { __declspec(align(1)) int a; D() : a(0xD) {} }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct D +// CHECK: 0 | (D vbtable pointer) +// CHECK: 4 | int a +// CHECK: 8 | struct B0 (virtual base) +// CHECK: 8 | char a +// CHECK: | [sizeof=12, align=4 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct D +// CHECK-X64: 0 | (D vbtable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct B0 (virtual base) +// CHECK-X64: 16 | char a +// CHECK-X64: | [sizeof=24, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct E : virtual B0, virtual B1 {}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct E +// CHECK: 0 | (E vbtable pointer) +// CHECK: 4 | struct B0 (virtual base) +// CHECK: 4 | char a +// CHECK: 5 | struct B1 (virtual base) (empty) +// CHECK: | [sizeof=8, align=4 +// CHECK: | nvsize=4, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct E +// CHECK-X64: 0 | (E vbtable pointer) +// CHECK-X64: 8 | struct B0 (virtual base) +// CHECK-X64: 8 | char a +// CHECK-X64: 9 | struct B1 (virtual base) (empty) +// CHECK-X64: | [sizeof=16, align=8 +// CHECK-X64: | nvsize=8, nvalign=8] + +struct F { char a; virtual ~F(); }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct F +// CHECK: 0 | (F vftable pointer) +// CHECK: 4 | char a +// CHECK: | [sizeof=8, align=4 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct F +// CHECK-X64: 0 | (F vftable pointer) +// CHECK-X64: 8 | char a +// CHECK-X64: | [sizeof=16, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +int a[ +sizeof(A)+ +sizeof(B)+ +sizeof(C)+ +sizeof(D)+ +sizeof(E)+ +sizeof(F)]; diff --git a/test/Layout/ms-x86-vfvb-alignment.cpp b/test/Layout/ms-x86-vfvb-alignment.cpp new file mode 100644 index 0000000..8eea209 --- /dev/null +++ b/test/Layout/ms-x86-vfvb-alignment.cpp @@ -0,0 +1,376 @@ +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>&1 \ +// RUN: | FileCheck %s +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \ +// RUN: | FileCheck %s -check-prefix CHECK-X64 + +extern "C" int printf(const char *fmt, ...); + +struct B0 { int a; B0() : a(0xf00000B0) {} }; +struct B1 { char a; B1() : a(0xB1) {} }; +struct B2 : virtual B1 { int a; B2() : a(0xf00000B2) {} }; +struct B3 { __declspec(align(16)) int a; B3() : a(0xf00000B3) {} }; +struct B4 : virtual B3 { int a; B4() : a(0xf00000B4) {} }; +struct B5 { __declspec(align(32)) int a; B5() : a(0xf00000B5) {} }; +struct B6 { int a; B6() : a(0xf00000B6) {} virtual void f() { printf("B6"); } }; + +struct A : B0, virtual B1 { __declspec(align(16)) int a; A() : a(0xf000000A) {} virtual void f() { printf("A"); } }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct A +// CHECK: 0 | (A vftable pointer) +// CHECK: 16 | struct B0 (base) +// CHECK: 16 | int a +// CHECK: 20 | (A vbtable pointer) +// CHECK: 48 | int a +// CHECK: 64 | struct B1 (virtual base) +// CHECK: 64 | char a +// CHECK: | [sizeof=80, align=16 +// CHECK: | nvsize=64, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct A +// CHECK-X64: 0 | (A vftable pointer) +// CHECK-X64: 8 | struct B0 (base) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | (A vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 48 | struct B1 (virtual base) +// CHECK-X64: 48 | char a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct B : A, B2 { int a; B() : a(0xf000000B) {} virtual void f() { printf("B"); } }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct B +// CHECK: 0 | struct A (primary base) +// CHECK: 0 | (A vftable pointer) +// CHECK: 16 | struct B0 (base) +// CHECK: 16 | int a +// CHECK: 20 | (A vbtable pointer) +// CHECK: 48 | int a +// CHECK: 64 | struct B2 (base) +// CHECK: 64 | (B2 vbtable pointer) +// CHECK: 68 | int a +// CHECK: 72 | int a +// CHECK: 80 | struct B1 (virtual base) +// CHECK: 80 | char a +// CHECK: | [sizeof=96, align=16 +// CHECK: | nvsize=80, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct B +// CHECK-X64: 0 | struct A (primary base) +// CHECK-X64: 0 | (A vftable pointer) +// CHECK-X64: 8 | struct B0 (base) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | (A vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 48 | struct B2 (base) +// CHECK-X64: 48 | (B2 vbtable pointer) +// CHECK-X64: 56 | int a +// CHECK-X64: 64 | int a +// CHECK-X64: 80 | struct B1 (virtual base) +// CHECK-X64: 80 | char a +// CHECK-X64: | [sizeof=96, align=16 +// CHECK-X64: | nvsize=80, nvalign=16] + +struct C : B4 { int a; C() : a(0xf000000C) {} virtual void f() { printf("C"); } }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct C +// CHECK: 0 | (C vftable pointer) +// CHECK: 16 | struct B4 (base) +// CHECK: 16 | (B4 vbtable pointer) +// CHECK: 20 | int a +// CHECK: 24 | int a +// CHECK: 32 | struct B3 (virtual base) +// CHECK: 32 | int a +// CHECK: | [sizeof=48, align=16 +// CHECK: | nvsize=32, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct C +// CHECK-X64: 0 | (C vftable pointer) +// CHECK-X64: 16 | struct B4 (base) +// CHECK-X64: 16 | (B4 vbtable pointer) +// CHECK-X64: 24 | int a +// CHECK-X64: 32 | int a +// CHECK-X64: 48 | struct B3 (virtual base) +// CHECK-X64: 48 | int a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct D : C { int a; D() : a(0xf000000D) {} virtual void f() { printf("D"); } }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct D +// CHECK: 0 | struct C (primary base) +// CHECK: 0 | (C vftable pointer) +// CHECK: 16 | struct B4 (base) +// CHECK: 16 | (B4 vbtable pointer) +// CHECK: 20 | int a +// CHECK: 24 | int a +// CHECK: 32 | int a +// CHECK: 48 | struct B3 (virtual base) +// CHECK: 48 | int a +// CHECK: | [sizeof=64, align=16 +// CHECK: | nvsize=48, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct D +// CHECK-X64: 0 | struct C (primary base) +// CHECK-X64: 0 | (C vftable pointer) +// CHECK-X64: 16 | struct B4 (base) +// CHECK-X64: 16 | (B4 vbtable pointer) +// CHECK-X64: 24 | int a +// CHECK-X64: 32 | int a +// CHECK-X64: 48 | int a +// CHECK-X64: 64 | struct B3 (virtual base) +// CHECK-X64: 64 | int a +// CHECK-X64: | [sizeof=80, align=16 +// CHECK-X64: | nvsize=64, nvalign=16] + +struct E : virtual C { int a; E() : a(0xf000000E) {} virtual void f() { printf("E"); } }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct E +// CHECK: 0 | (E vbtable pointer) +// CHECK: 4 | int a +// CHECK: 16 | struct B3 (virtual base) +// CHECK: 16 | int a +// CHECK: 44 | (vtordisp for vbase C) +// CHECK: 48 | struct C (virtual base) +// CHECK: 48 | (C vftable pointer) +// CHECK: 64 | struct B4 (base) +// CHECK: 64 | (B4 vbtable pointer) +// CHECK: 68 | int a +// CHECK: 72 | int a +// CHECK: | [sizeof=80, align=16 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct E +// CHECK-X64: 0 | (E vbtable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct B3 (virtual base) +// CHECK-X64: 16 | int a +// CHECK-X64: 44 | (vtordisp for vbase C) +// CHECK-X64: 48 | struct C (virtual base) +// CHECK-X64: 48 | (C vftable pointer) +// CHECK-X64: 64 | struct B4 (base) +// CHECK-X64: 64 | (B4 vbtable pointer) +// CHECK-X64: 72 | int a +// CHECK-X64: 80 | int a +// CHECK-X64: | [sizeof=96, align=16 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct F : B3, virtual B0 { int a; F() : a(0xf000000F) {} virtual void f() { printf("F"); } }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct F +// CHECK: 0 | (F vftable pointer) +// CHECK: 16 | struct B3 (base) +// CHECK: 16 | int a +// CHECK: 32 | (F vbtable pointer) +// CHECK: 48 | int a +// CHECK: 64 | struct B0 (virtual base) +// CHECK: 64 | int a +// CHECK: | [sizeof=80, align=16 +// CHECK: | nvsize=64, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct F +// CHECK-X64: 0 | (F vftable pointer) +// CHECK-X64: 16 | struct B3 (base) +// CHECK-X64: 16 | int a +// CHECK-X64: 32 | (F vbtable pointer) +// CHECK-X64: 40 | int a +// CHECK-X64: 48 | struct B0 (virtual base) +// CHECK-X64: 48 | int a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct G : B2, B6, virtual B1 { int a; G() : a(0xf0000010) {} }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct G +// CHECK: 8 | struct B2 (base) +// CHECK: 8 | (B2 vbtable pointer) +// CHECK: 12 | int a +// CHECK: 0 | struct B6 (primary base) +// CHECK: 0 | (B6 vftable pointer) +// CHECK: 4 | int a +// CHECK: 16 | int a +// CHECK: 20 | struct B1 (virtual base) +// CHECK: 20 | char a +// CHECK: | [sizeof=21, align=4 +// CHECK: | nvsize=20, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct G +// CHECK-X64: 16 | struct B2 (base) +// CHECK-X64: 16 | (B2 vbtable pointer) +// CHECK-X64: 24 | int a +// CHECK-X64: 0 | struct B6 (primary base) +// CHECK-X64: 0 | (B6 vftable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 32 | int a +// CHECK-X64: 40 | struct B1 (virtual base) +// CHECK-X64: 40 | char a +// CHECK-X64: | [sizeof=48, align=8 +// CHECK-X64: | nvsize=40, nvalign=8] + +struct H : B6, B2, virtual B1 { int a; H() : a(0xf0000011) {} }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct H +// CHECK: 0 | struct B6 (primary base) +// CHECK: 0 | (B6 vftable pointer) +// CHECK: 4 | int a +// CHECK: 8 | struct B2 (base) +// CHECK: 8 | (B2 vbtable pointer) +// CHECK: 12 | int a +// CHECK: 16 | int a +// CHECK: 20 | struct B1 (virtual base) +// CHECK: 20 | char a +// CHECK: | [sizeof=21, align=4 +// CHECK: | nvsize=20, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct H +// CHECK-X64: 0 | struct B6 (primary base) +// CHECK-X64: 0 | (B6 vftable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | struct B2 (base) +// CHECK-X64: 16 | (B2 vbtable pointer) +// CHECK-X64: 24 | int a +// CHECK-X64: 32 | int a +// CHECK-X64: 40 | struct B1 (virtual base) +// CHECK-X64: 40 | char a +// CHECK-X64: | [sizeof=48, align=8 +// CHECK-X64: | nvsize=40, nvalign=8] + +struct I : B0, virtual B1 { int a; int a1; __declspec(align(16)) int a2; I() : a(0xf0000011), a1(0xf0000011), a2(0xf0000011) {} }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct I +// CHECK: 0 | struct B0 (base) +// CHECK: 0 | int a +// CHECK: 4 | (I vbtable pointer) +// CHECK: 20 | int a +// CHECK: 24 | int a1 +// CHECK: 32 | int a2 +// CHECK: 48 | struct B1 (virtual base) +// CHECK: 48 | char a +// CHECK: | [sizeof=64, align=16 +// CHECK: | nvsize=48, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct I +// CHECK-X64: 0 | struct B0 (base) +// CHECK-X64: 0 | int a +// CHECK-X64: 8 | (I vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 20 | int a1 +// CHECK-X64: 32 | int a2 +// CHECK-X64: 48 | struct B1 (virtual base) +// CHECK-X64: 48 | char a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct J : B0, B3, virtual B1 { int a; int a1; J() : a(0xf0000012), a1(0xf0000012) {} }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct J +// CHECK: 0 | struct B0 (base) +// CHECK: 0 | int a +// CHECK: 16 | struct B3 (base) +// CHECK: 16 | int a +// CHECK: 32 | (J vbtable pointer) +// CHECK: 48 | int a +// CHECK: 52 | int a1 +// CHECK: 64 | struct B1 (virtual base) +// CHECK: 64 | char a +// CHECK: | [sizeof=80, align=16 +// CHECK: | nvsize=64, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct J +// CHECK-X64: 0 | struct B0 (base) +// CHECK-X64: 0 | int a +// CHECK-X64: 16 | struct B3 (base) +// CHECK-X64: 16 | int a +// CHECK-X64: 32 | (J vbtable pointer) +// CHECK-X64: 40 | int a +// CHECK-X64: 44 | int a1 +// CHECK-X64: 48 | struct B1 (virtual base) +// CHECK-X64: 48 | char a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct K { int a; K() : a(0xf0000013) {} virtual void f() { printf("K"); } }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct K +// CHECK: 0 | (K vftable pointer) +// CHECK: 4 | int a +// CHECK: | [sizeof=8, align=4 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct K +// CHECK-X64: 0 | (K vftable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: | [sizeof=16, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +struct L : virtual K { int a; L() : a(0xf0000014) {} virtual void g() { printf("L"); } }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct L +// CHECK: 0 | (L vftable pointer) +// CHECK: 4 | (L vbtable pointer) +// CHECK: 8 | int a +// CHECK: 12 | struct K (virtual base) +// CHECK: 12 | (K vftable pointer) +// CHECK: 16 | int a +// CHECK: | [sizeof=20, align=4 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct L +// CHECK-X64: 0 | (L vftable pointer) +// CHECK-X64: 8 | (L vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 24 | struct K (virtual base) +// CHECK-X64: 24 | (K vftable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: | [sizeof=40, align=8 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct M : virtual K { int a; M() : a(0xf0000015) {} virtual void f() { printf("M"); } }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct M +// CHECK: 0 | (M vbtable pointer) +// CHECK: 4 | int a +// CHECK: 8 | (vtordisp for vbase K) +// CHECK: 12 | struct K (virtual base) +// CHECK: 12 | (K vftable pointer) +// CHECK: 16 | int a +// CHECK: | [sizeof=20, align=4 +// CHECK: | nvsize=8, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct M +// CHECK-X64: 0 | (M vbtable pointer) +// CHECK-X64: 8 | int a +// CHECK-X64: 20 | (vtordisp for vbase K) +// CHECK-X64: 24 | struct K (virtual base) +// CHECK-X64: 24 | (K vftable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: | [sizeof=40, align=8 +// CHECK-X64: | nvsize=16, nvalign=8] + +int a[ +sizeof(A)+ +sizeof(B)+ +sizeof(C)+ +sizeof(D)+ +sizeof(E)+ +sizeof(F)+ +sizeof(G)+ +sizeof(H)+ +sizeof(I)+ +sizeof(J)+ +sizeof(K)+ +sizeof(L)+ +sizeof(M)]; diff --git a/test/Layout/ms-x86-vfvb-sharing.cpp b/test/Layout/ms-x86-vfvb-sharing.cpp new file mode 100644 index 0000000..2b3d08e --- /dev/null +++ b/test/Layout/ms-x86-vfvb-sharing.cpp @@ -0,0 +1,140 @@ +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>&1 \ +// RUN: | FileCheck %s +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \ +// RUN: | FileCheck %s -check-prefix CHECK-X64 + +extern "C" int printf(const char *fmt, ...); + +struct B0 { int a; B0() : a(0xf00000B0) { printf("B0 = %p\n", this); } }; +struct B1 { int a; B1() : a(0xf00000B1) { printf("B1 = %p\n", this); } }; +struct B2 { B2() { printf("B2 = %p\n", this); } virtual void g() { printf("B2"); } }; +struct B3 : virtual B1 { B3() { printf("B3 = %p\n", this); } }; +struct B4 : virtual B1 { B4() { printf("B4 = %p\n", this); } virtual void g() { printf("B4"); } }; + +struct A : B0, virtual B1 { + __declspec(align(16)) int a; + A() : a(0xf000000A) { printf(" A = %p\n\n", this); } + virtual void f() { printf("A"); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct A +// CHECK: 0 | (A vftable pointer) +// CHECK: 16 | struct B0 (base) +// CHECK: 16 | int a +// CHECK: 20 | (A vbtable pointer) +// CHECK: 48 | int a +// CHECK: 64 | struct B1 (virtual base) +// CHECK: 64 | int a +// CHECK: | [sizeof=80, align=16 +// CHECK: | nvsize=64, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct A +// CHECK-X64: 0 | (A vftable pointer) +// CHECK-X64: 8 | struct B0 (base) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | (A vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 48 | struct B1 (virtual base) +// CHECK-X64: 48 | int a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct B : B2, B0, virtual B1 { + __declspec(align(16)) int a; + B() : a(0xf000000B) { printf(" B = %p\n\n", this); } + virtual void f() { printf("B"); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct B +// CHECK: 0 | struct B2 (primary base) +// CHECK: 0 | (B2 vftable pointer) +// CHECK: 4 | struct B0 (base) +// CHECK: 4 | int a +// CHECK: 8 | (B vbtable pointer) +// CHECK: 32 | int a +// CHECK: 48 | struct B1 (virtual base) +// CHECK: 48 | int a +// CHECK: | [sizeof=64, align=16 +// CHECK: | nvsize=48, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct B +// CHECK-X64: 0 | struct B2 (primary base) +// CHECK-X64: 0 | (B2 vftable pointer) +// CHECK-X64: 8 | struct B0 (base) +// CHECK-X64: 8 | int a +// CHECK-X64: 16 | (B vbtable pointer) +// CHECK-X64: 32 | int a +// CHECK-X64: 48 | struct B1 (virtual base) +// CHECK-X64: 48 | int a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct C : B3, B0, virtual B1 { + __declspec(align(16)) int a; + C() : a(0xf000000C) { printf(" C = %p\n\n", this); } + virtual void f() { printf("C"); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct C +// CHECK: 0 | (C vftable pointer) +// CHECK: 16 | struct B3 (base) +// CHECK: 16 | (B3 vbtable pointer) +// CHECK: 20 | struct B0 (base) +// CHECK: 20 | int a +// CHECK: 32 | int a +// CHECK: 48 | struct B1 (virtual base) +// CHECK: 48 | int a +// CHECK: | [sizeof=64, align=16 +// CHECK: | nvsize=48, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct C +// CHECK-X64: 0 | (C vftable pointer) +// CHECK-X64: 8 | struct B3 (base) +// CHECK-X64: 8 | (B3 vbtable pointer) +// CHECK-X64: 16 | struct B0 (base) +// CHECK-X64: 16 | int a +// CHECK-X64: 32 | int a +// CHECK-X64: 48 | struct B1 (virtual base) +// CHECK-X64: 48 | int a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +struct D : B4, B0, virtual B1 { + __declspec(align(16)) int a; + D() : a(0xf000000D) { printf(" D = %p\n\n", this); } + virtual void f() { printf("D"); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct D +// CHECK: 0 | struct B4 (primary base) +// CHECK: 0 | (B4 vftable pointer) +// CHECK: 4 | (B4 vbtable pointer) +// CHECK: 8 | struct B0 (base) +// CHECK: 8 | int a +// CHECK: 16 | int a +// CHECK: 32 | struct B1 (virtual base) +// CHECK: 32 | int a +// CHECK: | [sizeof=48, align=16 +// CHECK: | nvsize=32, nvalign=16] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct D +// CHECK-X64: 0 | struct B4 (primary base) +// CHECK-X64: 0 | (B4 vftable pointer) +// CHECK-X64: 8 | (B4 vbtable pointer) +// CHECK-X64: 16 | struct B0 (base) +// CHECK-X64: 16 | int a +// CHECK-X64: 32 | int a +// CHECK-X64: 48 | struct B1 (virtual base) +// CHECK-X64: 48 | int a +// CHECK-X64: | [sizeof=64, align=16 +// CHECK-X64: | nvsize=48, nvalign=16] + +int a[ +sizeof(A)+ +sizeof(B)+ +sizeof(C)+ +sizeof(D)]; diff --git a/test/Layout/ms-x86-vtordisp.cpp b/test/Layout/ms-x86-vtordisp.cpp new file mode 100644 index 0000000..b16f09e --- /dev/null +++ b/test/Layout/ms-x86-vtordisp.cpp @@ -0,0 +1,170 @@ +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>&1 \ +// RUN: | FileCheck %s +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \ +// RUN: | FileCheck %s -check-prefix CHECK-X64 + +extern "C" int printf(const char *fmt, ...); + +struct B0 { + int a; + B0() : a(0xf00000B0) {} + virtual void f() { printf("B0"); } +}; + +struct __declspec(align(16)) B1 { + int a; + B1() : a(0xf00000B1) {} + virtual void f() { printf("B1"); } +}; + +struct __declspec(align(16)) Align16 {}; +struct __declspec(align(32)) Align32 {}; +struct VAlign16 : virtual Align16 {}; +struct VAlign32 : virtual Align32 {}; + +struct A : virtual B0, virtual B1 { + int a; + A() : a(0xf000000A) {} + virtual void f() { printf("A"); } + virtual void g() { printf("A"); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct A +// CHECK: 0 | (A vftable pointer) +// CHECK: 4 | (A vbtable pointer) +// CHECK: 8 | int a +// CHECK: 16 | (vtordisp for vbase B0) +// CHECK: 20 | struct B0 (virtual base) +// CHECK: 20 | (B0 vftable pointer) +// CHECK: 24 | int a +// CHECK: 44 | (vtordisp for vbase B1) +// CHECK: 48 | struct B1 (virtual base) +// CHECK: 48 | (B1 vftable pointer) +// CHECK: 52 | int a +// CHECK: | [sizeof=64, align=16 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct A +// CHECK-X64: 0 | (A vftable pointer) +// CHECK-X64: 8 | (A vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 36 | (vtordisp for vbase B0) +// CHECK-X64: 40 | struct B0 (virtual base) +// CHECK-X64: 40 | (B0 vftable pointer) +// CHECK-X64: 48 | int a +// CHECK-X64: 76 | (vtordisp for vbase B1) +// CHECK-X64: 80 | struct B1 (virtual base) +// CHECK-X64: 80 | (B1 vftable pointer) +// CHECK-X64: 88 | int a +// CHECK-X64: | [sizeof=96, align=16 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct C : virtual B0, virtual B1, VAlign32 { + int a; + C() : a(0xf000000C) {} + virtual void f() { printf("C"); } + virtual void g() { printf("C"); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct C +// CHECK: 0 | (C vftable pointer) +// CHECK: 32 | struct VAlign32 (base) +// CHECK: 32 | (VAlign32 vbtable pointer) +// CHECK: 36 | int a +// CHECK: 64 | (vtordisp for vbase B0) +// CHECK: 68 | struct B0 (virtual base) +// CHECK: 68 | (B0 vftable pointer) +// CHECK: 72 | int a +// CHECK: 108 | (vtordisp for vbase B1) +// CHECK: 112 | struct B1 (virtual base) +// CHECK: 112 | (B1 vftable pointer) +// CHECK: 116 | int a +// CHECK: 128 | struct Align32 (virtual base) (empty) +// CHECK: | [sizeof=128, align=32 +// CHECK: | nvsize=64, nvalign=32] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct C +// CHECK-X64: 0 | (C vftable pointer) +// CHECK-X64: 32 | struct VAlign32 (base) +// CHECK-X64: 32 | (VAlign32 vbtable pointer) +// CHECK-X64: 40 | int a +// CHECK-X64: 68 | (vtordisp for vbase B0) +// CHECK-X64: 72 | struct B0 (virtual base) +// CHECK-X64: 72 | (B0 vftable pointer) +// CHECK-X64: 80 | int a +// CHECK-X64: 108 | (vtordisp for vbase B1) +// CHECK-X64: 112 | struct B1 (virtual base) +// CHECK-X64: 112 | (B1 vftable pointer) +// CHECK-X64: 120 | int a +// CHECK-X64: 128 | struct Align32 (virtual base) (empty) +// CHECK-X64: | [sizeof=128, align=32 +// CHECK-X64: | nvsize=64, nvalign=32] + +struct __declspec(align(32)) D : virtual B0, virtual B1 { + int a; + D() : a(0xf000000D) {} + virtual void f() { printf("D"); } + virtual void g() { printf("D"); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct D +// CHECK: 0 | (D vftable pointer) +// CHECK: 4 | (D vbtable pointer) +// CHECK: 8 | int a +// CHECK: 32 | (vtordisp for vbase B0) +// CHECK: 36 | struct B0 (virtual base) +// CHECK: 36 | (B0 vftable pointer) +// CHECK: 40 | int a +// CHECK: 76 | (vtordisp for vbase B1) +// CHECK: 80 | struct B1 (virtual base) +// CHECK: 80 | (B1 vftable pointer) +// CHECK: 84 | int a +// CHECK: | [sizeof=96, align=32 +// CHECK: | nvsize=12, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct D +// CHECK-X64: 0 | (D vftable pointer) +// CHECK-X64: 8 | (D vbtable pointer) +// CHECK-X64: 16 | int a +// CHECK-X64: 36 | (vtordisp for vbase B0) +// CHECK-X64: 40 | struct B0 (virtual base) +// CHECK-X64: 40 | (B0 vftable pointer) +// CHECK-X64: 48 | int a +// CHECK-X64: 76 | (vtordisp for vbase B1) +// CHECK-X64: 80 | struct B1 (virtual base) +// CHECK-X64: 80 | (B1 vftable pointer) +// CHECK-X64: 88 | int a +// CHECK-X64: | [sizeof=96, align=32 +// CHECK-X64: | nvsize=24, nvalign=8] + +struct AT { + virtual ~AT(){} +}; +struct CT : virtual AT { + virtual ~CT(); +}; +CT::~CT(){} + +// CHECK: *** Dumping AST Record Layout +// CHECK: 0 | struct CT +// CHECK: 0 | (CT vbtable pointer) +// CHECK: 4 | struct AT (virtual base) +// CHECK: 4 | (AT vftable pointer) +// CHECK: | [sizeof=8, align=4 +// CHECK: | nvsize=4, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: 0 | struct CT +// CHECK-X64: 0 | (CT vbtable pointer) +// CHECK-X64: 8 | struct AT (virtual base) +// CHECK-X64: 8 | (AT vftable pointer) +// CHECK-X64: | [sizeof=16, align=8 +// CHECK-X64: | nvsize=8, nvalign=8] + +int a[ +sizeof(A)+ +sizeof(C)+ +sizeof(D)+ +sizeof(CT)]; |