From bd1b0c6916698f7d37c878681993fe02b33ea3a9 Mon Sep 17 00:00:00 2001 From: Warren Hunt Date: Mon, 14 Oct 2013 19:08:58 +0000 Subject: [PATCH] Lit tests for Microsoft C++ record layout. They weren't added with the rest of the microsoft record layout patch due me not doing svn add. llvm-svn: 192612 --- .../Layout/ms-x86-aligned-tail-padding.cpp | 338 ++++++++++++ clang/test/Layout/ms-x86-basic-layout.cpp | 488 ++++++++++++++++++ .../Layout/ms-x86-empty-nonvirtual-bases.cpp | 172 ++++++ .../test/Layout/ms-x86-empty-virtual-base.cpp | 453 ++++++++++++++++ .../ms-x86-lazy-empty-nonvirtual-base.cpp | 469 +++++++++++++++++ clang/test/Layout/ms-x86-primary-bases.cpp | 194 +++++++ .../Layout/ms-x86-size-alignment-fail.cpp | 67 +++ clang/test/Layout/ms-x86-vfvb-alignment.cpp | 220 ++++++++ clang/test/Layout/ms-x86-vfvb-sharing.cpp | 91 ++++ clang/test/Layout/ms-x86-vtordisp.cpp | 97 ++++ clang/test/Sema/ms_bitfield_layout.c | 241 +++++++++ 11 files changed, 2830 insertions(+) create mode 100644 clang/test/Layout/ms-x86-aligned-tail-padding.cpp create mode 100644 clang/test/Layout/ms-x86-basic-layout.cpp create mode 100644 clang/test/Layout/ms-x86-empty-nonvirtual-bases.cpp create mode 100644 clang/test/Layout/ms-x86-empty-virtual-base.cpp create mode 100644 clang/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp create mode 100644 clang/test/Layout/ms-x86-primary-bases.cpp create mode 100644 clang/test/Layout/ms-x86-size-alignment-fail.cpp create mode 100644 clang/test/Layout/ms-x86-vfvb-alignment.cpp create mode 100644 clang/test/Layout/ms-x86-vfvb-sharing.cpp create mode 100644 clang/test/Layout/ms-x86-vtordisp.cpp create mode 100644 clang/test/Sema/ms_bitfield_layout.c diff --git a/clang/test/Layout/ms-x86-aligned-tail-padding.cpp b/clang/test/Layout/ms-x86-aligned-tail-padding.cpp new file mode 100644 index 000000000000..53c4615b910f --- /dev/null +++ b/clang/test/Layout/ms-x86-aligned-tail-padding.cpp @@ -0,0 +1,338 @@ +// 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 + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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: | [sizeof=16, align=16 +// CHECK: | nvsize=16, nvalign=16] +// CHECK: 16 | int b +// CHECK: | [sizeof=32, align=16 +// CHECK: | 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] + +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] + +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] + +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] + +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/clang/test/Layout/ms-x86-basic-layout.cpp b/clang/test/Layout/ms-x86-basic-layout.cpp new file mode 100644 index 000000000000..5d671e12d21d --- /dev/null +++ b/clang/test/Layout/ms-x86-basic-layout.cpp @@ -0,0 +1,488 @@ +// 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 + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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/clang/test/Layout/ms-x86-empty-nonvirtual-bases.cpp b/clang/test/Layout/ms-x86-empty-nonvirtual-bases.cpp new file mode 100644 index 000000000000..f6e8f111ce51 --- /dev/null +++ b/clang/test/Layout/ms-x86-empty-nonvirtual-bases.cpp @@ -0,0 +1,172 @@ +// 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 + +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/clang/test/Layout/ms-x86-empty-virtual-base.cpp b/clang/test/Layout/ms-x86-empty-virtual-base.cpp new file mode 100644 index 000000000000..d417167779ab --- /dev/null +++ b/clang/test/Layout/ms-x86-empty-virtual-base.cpp @@ -0,0 +1,453 @@ +// 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 + +extern "C" int printf(const char *fmt, ...); + +struct __declspec(align(8)) B0 { B0() {printf("B0 : %3d\n", ((int)this)&0xfff);} }; +struct __declspec(align(8)) B1 { B1() {printf("B1 : %3d\n", ((int)this)&0xfff);} }; +struct __declspec(align(8)) B2 { B2() {printf("B2 : %3d\n", ((int)this)&0xfff);} }; +struct __declspec(align(8)) B3 { B3() {printf("B3 : %3d\n", ((int)this)&0xfff);} }; +struct __declspec(align(8)) B4 { B4() {printf("B4 : %3d\n", ((int)this)&0xfff);} }; + +struct C0 { int a; C0() : a(0xf00000C0) {printf("C0 : %3d\n", ((int)this)&0xfff);} }; +struct C1 { int a; C1() : a(0xf00000C1) {printf("C1 : %3d\n", ((int)this)&0xfff);} }; +struct C2 { int a; C2() : a(0xf00000C2) {printf("C2 : %3d\n", ((int)this)&0xfff);} }; +struct C3 { int a; C3() : a(0xf00000C3) {printf("C3 : %3d\n", ((int)this)&0xfff);} }; +struct C4 { int a; C4() : a(0xf00000C4) {printf("C4 : %3d\n", ((int)this)&0xfff);} }; + +struct __declspec(align(16)) D0 { D0() {printf("D0 : %3d\n", ((int)this)&0xfff);} virtual void f() {} }; +struct D1 { D1() {printf("D1 : %3d\n", ((int)this)&0xfff);} }; +struct D2 { int a[8]; D2() {printf("D2 : %3d\n", ((int)this)&0xfff);} }; + +struct A : virtual B0 { + int a; + A() : a(0xf000000A) {printf("X : %3d\n", ((int)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] + +struct B : virtual B0 { + B0 b0; + int a; + B() : a(0xf000000B) {printf("X : %3d\n", ((int)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] + +struct C : virtual B0, virtual B1, virtual B2, virtual B3, virtual B4 { + int a; + C() : a(0xf000000C) {printf("X : %3d\n", ((int)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] + +struct D { + B0 b0; + C0 c0; + C1 c1; + C2 c2; + B1 b1; + int a; + D() : a(0xf000000D) {printf("X : %3d\n", ((int)this)&0xfff);} +}; + +// 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 : virtual B0, virtual C0, virtual C1, virtual C2, virtual B1 { + int a; + E() : a(0xf000000E) {printf("X : %3d\n", ((int)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] + +struct F : virtual C0, virtual B0, virtual B1, virtual C1 { + int a; + F() : a(0xf000000F) {printf("X : %3d\n", ((int)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] + +struct G : virtual C0, virtual B0, virtual B1, D0, virtual C1 { + int a; + G() : a(0xf0000010) {printf("X : %3d\n", ((int)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] + +struct H : virtual C0, virtual B0, virtual B1, virtual D0, virtual C1 { + int a; + H() : a(0xf0000011) {printf("X : %3d\n", ((int)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] + +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)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] + +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)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] + +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)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] + +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)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] + +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)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] + +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)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] + +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)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] + +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)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] + +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)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] + +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)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] + +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)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] + +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)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] + +struct __declspec(align(32)) U : virtual B0, virtual B1 { + int a; + U() : a(0xf0000023) {printf("X : %3d\n", ((int)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] + +struct __declspec(align(32)) V : virtual D1 { + int a; + V() : a(0xf0000024) {printf("X : %3d\n", ((int)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] + +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/clang/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp b/clang/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp new file mode 100644 index 000000000000..87280b59824d --- /dev/null +++ b/clang/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp @@ -0,0 +1,469 @@ +// 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 + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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/clang/test/Layout/ms-x86-primary-bases.cpp b/clang/test/Layout/ms-x86-primary-bases.cpp new file mode 100644 index 000000000000..79e72f4b1615 --- /dev/null +++ b/clang/test/Layout/ms-x86-primary-bases.cpp @@ -0,0 +1,194 @@ +// 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 + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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/clang/test/Layout/ms-x86-size-alignment-fail.cpp b/clang/test/Layout/ms-x86-size-alignment-fail.cpp new file mode 100644 index 000000000000..c15d3825c2db --- /dev/null +++ b/clang/test/Layout/ms-x86-size-alignment-fail.cpp @@ -0,0 +1,67 @@ +// 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 + +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] + +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] + +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] + +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] + +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] + +int a[ +sizeof(A)+ +sizeof(B)+ +sizeof(C)+ +sizeof(D)+ +sizeof(E)]; diff --git a/clang/test/Layout/ms-x86-vfvb-alignment.cpp b/clang/test/Layout/ms-x86-vfvb-alignment.cpp new file mode 100644 index 000000000000..02056128100a --- /dev/null +++ b/clang/test/Layout/ms-x86-vfvb-alignment.cpp @@ -0,0 +1,220 @@ +// 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 + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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/clang/test/Layout/ms-x86-vfvb-sharing.cpp b/clang/test/Layout/ms-x86-vfvb-sharing.cpp new file mode 100644 index 000000000000..e736eaf095d0 --- /dev/null +++ b/clang/test/Layout/ms-x86-vfvb-sharing.cpp @@ -0,0 +1,91 @@ +// 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 + +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] + +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] + +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] + +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] + +int a[ +sizeof(A)+ +sizeof(B)+ +sizeof(C)+ +sizeof(D)]; diff --git a/clang/test/Layout/ms-x86-vtordisp.cpp b/clang/test/Layout/ms-x86-vtordisp.cpp new file mode 100644 index 000000000000..45ac64968210 --- /dev/null +++ b/clang/test/Layout/ms-x86-vtordisp.cpp @@ -0,0 +1,97 @@ +// 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 + +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] + +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] + +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] + +int a[ +sizeof(A)+ +sizeof(C)+ +sizeof(D)]; diff --git a/clang/test/Sema/ms_bitfield_layout.c b/clang/test/Sema/ms_bitfield_layout.c new file mode 100644 index 000000000000..7efa0b3b16e5 --- /dev/null +++ b/clang/test/Sema/ms_bitfield_layout.c @@ -0,0 +1,241 @@ +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -cxx-abi microsoft -fdump-record-layouts %s 2>/dev/null \ +// RUN: | FileCheck %s + +typedef struct A { + char x; + int a : 22; + int : 0; + int c : 10; + char b : 3; + char d: 4; + short y; +} A; + +// CHECK: Type: struct A +// CHECK: Size:128 +// CHECK: Alignment:32 +// CHECK: FieldOffsets: [0, 32, 64, 64, 96, 99, 112]> + +typedef struct B { + char x; + int : 0; + short a : 4; + char y; +} B; + +// CHECK: Type: struct B +// CHECK: Size:48 +// CHECK: Alignment:16 +// CHECK: FieldOffsets: [0, 8, 16, 32]> + +typedef struct C { + char x; + short a : 4; + int : 0; + char y; +} C; + +// CHECK: Type: struct C +// CHECK: Size:64 +// CHECK: Alignment:32 +// CHECK: FieldOffsets: [0, 16, 32, 32]> + +typedef struct D { + char x; + short : 0; + int : 0; + char y; +} D; + +// CHECK: Type: struct D +// CHECK: Size:16 +// CHECK: Alignment:8 +// CHECK: FieldOffsets: [0, 8, 8, 8]> + +typedef union E { + char x; + long long a : 3; + int b : 3; + long long : 0; + short y; +} E; + +// CHECK: Type: union E +// CHECK: Size:64 +// CHECK: Alignment:16 +// CHECK: FieldOffsets: [0, 0, 0, 0, 0]> + +typedef struct F { + char x; + char a : 3; + char b : 3; + char c : 3; + short d : 6; + short e : 6; + short f : 6; + short g : 11; + short h : 11; + short i : 11; + short y; +} F; + +// CHECK: Type: struct F +// CHECK: Size:128 +// CHECK: Alignment:16 +// CHECK: FieldOffsets: [0, 8, 11, 16, 32, 38, 48, 64, 80, 96, 112]> + +typedef union G { + char x; + int a : 3; + int : 0; + long long : 0; + short y; +} G; + +// CHECK: Type: union G +// CHECK: Size:32 +// CHECK: Alignment:16 +// CHECK: FieldOffsets: [0, 0, 0, 0, 0]> + +typedef struct H { + unsigned short a : 1; + unsigned char : 0; + unsigned long : 0; + unsigned short c : 1; +} H; + +// CHECK: Type: struct H +// CHECK: Size:32 +// CHECK: Alignment:16 +// CHECK: FieldOffsets: [0, 16, 16, 16]> + +#pragma pack(push, 1) + +typedef struct A1 { + char x; + int a : 22; + int : 0; + int c : 10; + char b : 3; + char d: 4; + short y; +} A1; + +// CHECK: Type: struct A1 +// CHECK: Size:96 +// CHECK: Alignment:8 +// CHECK: FieldOffsets: [0, 8, 40, 40, 72, 75, 80]> + +typedef struct B1 { + char x; + int : 0; + short a : 4; + char y; +} B1; + +// CHECK: Type: struct B1 +// CHECK: Size:32 +// CHECK: Alignment:8 +// CHECK: FieldOffsets: [0, 8, 8, 24]> + +typedef struct C1 { + char x; + short a : 4; + int : 0; + char y; +} C1; + +// CHECK: Type: struct C1 +// CHECK: Size:32 +// CHECK: Alignment:8 +// CHECK: FieldOffsets: [0, 8, 24, 24]> + +typedef struct D1 { + char x; + short : 0; + int : 0; + char y; +} D1; + +// CHECK: Type: struct D1 +// CHECK: Size:16 +// CHECK: Alignment:8 +// CHECK: FieldOffsets: [0, 8, 8, 8]> + +typedef union E1 { + char x; + long long a : 3; + int b : 3; + long long : 0; + short y; +} E1; + +// CHECK: Type: union E1 +// CHECK: Size:64 +// CHECK: Alignment:8 +// CHECK: FieldOffsets: [0, 0, 0, 0, 0]> + +typedef struct F1 { + char x; + char a : 3; + char b : 3; + char c : 3; + short d : 6; + short e : 6; + short f : 6; + short g : 11; + short h : 11; + short i : 11; + short y; +} F1; + +// CHECK: Type: struct F1 +// CHECK: Size:120 +// CHECK: Alignment:8 +// CHECK: FieldOffsets: [0, 8, 11, 16, 24, 30, 40, 56, 72, 88, 104]> + +typedef union G1 { + char x; + int a : 3; + int : 0; + long long : 0; + short y; +} G1; + +// CHECK: Type: union G1 +// CHECK: Size:32 +// CHECK: Alignment:8 +// CHECK: FieldOffsets: [0, 0, 0, 0, 0]> + +typedef struct H1 { + unsigned long a : 1; + unsigned char : 0; + unsigned long : 0; + unsigned long c : 1; +} H1; + +// CHECK: Type: struct H1 +// CHECK: Size:64 +// CHECK: Alignment:8 +// CHECK: FieldOffsets: [0, 32, 32, 32]> + +#pragma pack(pop) + +int x[ +sizeof(A ) + +sizeof(B ) + +sizeof(C ) + +sizeof(D ) + +sizeof(E ) + +sizeof(F ) + +sizeof(G ) + +sizeof(H ) + +sizeof(A1) + +sizeof(B1) + +sizeof(C1) + +sizeof(D1) + +sizeof(E1) + +sizeof(F1) + +sizeof(G1) + +sizeof(H1) + +0];