diff options
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 76 | ||||
-rw-r--r-- | clang/test/Layout/ms-x86-aligned-tail-padding.cpp | 66 | ||||
-rw-r--r-- | clang/test/Layout/ms-x86-basic-layout.cpp | 120 | ||||
-rw-r--r-- | clang/test/Layout/ms-x86-empty-virtual-base.cpp | 2 | ||||
-rw-r--r-- | clang/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp | 10 | ||||
-rw-r--r-- | clang/test/Layout/ms-x86-vfvb-alignment.cpp | 66 | ||||
-rw-r--r-- | clang/test/Layout/ms-x86-vfvb-sharing.cpp | 24 |
7 files changed, 148 insertions, 216 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index cb5b1093436..0c21bde3820 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -2137,7 +2137,6 @@ public: const ASTRecordLayout *&PreviousBaseLayout); void injectVFPtr(const CXXRecordDecl *RD); void injectVBPtr(const CXXRecordDecl *RD); - void injectVPtrs(const CXXRecordDecl *RD); /// \brief Lays out the fields of the record. Also rounds size up to /// alignment. void layoutFields(const RecordDecl *RD); @@ -2300,7 +2299,10 @@ void MicrosoftRecordLayoutBuilder::cxxLayout(const CXXRecordDecl *RD) { initializeCXXLayout(RD); layoutNonVirtualBases(RD); layoutFields(RD); - injectVPtrs(RD); + injectVBPtr(RD); + injectVFPtr(RD); + if (HasOwnVFPtr || (HasVBPtr && !SharedVBPtrBase)) + Alignment = std::max(Alignment, PointerInfo.Alignment); NonVirtualSize = Size = Size.RoundUpToAlignment(Alignment); RequiredAlignment = std::max( RequiredAlignment, Context.toCharUnitsFromBits(RD->getMaxAlignment())); @@ -2570,76 +2572,6 @@ void MicrosoftRecordLayoutBuilder::injectVFPtr(const CXXRecordDecl *RD) { i->second += Offset; } -void MicrosoftRecordLayoutBuilder::injectVPtrs(const CXXRecordDecl *RD) { - if (!(HasOwnVFPtr || (HasVBPtr && !SharedVBPtrBase))) - return; - if (!Is64BitMode || RequiredAlignment <= CharUnits::fromQuantity(8)) { - // Note that the VBPtr is injected first. It depends on the alignment of - // the object *before* the alignment is updated by inserting a pointer into - // the record. - injectVBPtr(RD); - injectVFPtr(RD); - Alignment = std::max(Alignment, PointerInfo.Alignment); - return; - } - // In 64-bit mode, structs with RequiredAlignment greater than 8 get special - // layout rules. Likely this is to avoid excessive padding intruced around - // the vfptrs and vbptrs. The special rules involve re-laying out the struct - // and inserting the vfptr and vbptr as if they were fields/bases. - FieldOffsets.clear(); - Bases.clear(); - Size = CharUnits::Zero(); - Alignment = std::max(Alignment, PointerInfo.Alignment); - if (HasOwnVFPtr) - Size = PointerInfo.Size; - layoutNonVirtualBases(RD); - if (HasVBPtr && !SharedVBPtrBase) { - const CXXRecordDecl *PenultBaseDecl = 0; - const CXXRecordDecl *LastBaseDecl = 0; - // Iterate through the bases and find the last two non-virtual bases. - for (const auto &I : RD->bases()) { - if (I.isVirtual()) - continue; - const CXXRecordDecl *BaseDecl = I.getType()->getAsCXXRecordDecl(); - if (!LastBaseDecl || Bases[BaseDecl] > Bases[LastBaseDecl]) { - PenultBaseDecl = LastBaseDecl; - LastBaseDecl = BaseDecl; - } - } - const ASTRecordLayout *PenultBaseLayout = PenultBaseDecl ? - &Context.getASTRecordLayout(PenultBaseDecl) : 0; - const ASTRecordLayout *LastBaseLayout = LastBaseDecl ? - &Context.getASTRecordLayout(LastBaseDecl) : 0; - // Calculate the vbptr offset. The rule is different than in the general - // case layout. Particularly, if the last two non-virtual bases are both - // zero sized, the site of the vbptr is *before* the padding that occurs - // between the two zero sized bases and the vbptr potentially aliases with - // the first of these two bases. We have no understanding of why this is - // different from the general case layout but it may have to do with lazy - // placement of zero sized bases. - VBPtrOffset = Size; - if (LastBaseLayout && LastBaseLayout->getNonVirtualSize().isZero()) { - VBPtrOffset = Bases[LastBaseDecl]; - if (PenultBaseLayout && PenultBaseLayout->getNonVirtualSize().isZero()) - VBPtrOffset = Bases[PenultBaseDecl]; - } - // Once we've located a spot for the vbptr, place it. - VBPtrOffset = VBPtrOffset.RoundUpToAlignment(PointerInfo.Alignment); - Size = VBPtrOffset + PointerInfo.Size; - if (LastBaseLayout && LastBaseLayout->getNonVirtualSize().isZero()) { - // Add the padding between zero sized bases after the vbptr. - if (PenultBaseLayout && PenultBaseLayout->getNonVirtualSize().isZero()) - Size += CharUnits::One(); - Size = Size.RoundUpToAlignment(LastBaseLayout->getRequiredAlignment()); - Bases[LastBaseDecl] = Size; - } - } - layoutFields(RD); - // The presence of a vbptr suppresses zero sized objects that are not in - // virtual bases. - HasZeroSizedSubObject = false; -} - void MicrosoftRecordLayoutBuilder::layoutVirtualBases(const CXXRecordDecl *RD) { if (!HasVBPtr) return; diff --git a/clang/test/Layout/ms-x86-aligned-tail-padding.cpp b/clang/test/Layout/ms-x86-aligned-tail-padding.cpp index 36f7b973453..f919766546e 100644 --- a/clang/test/Layout/ms-x86-aligned-tail-padding.cpp +++ b/clang/test/Layout/ms-x86-aligned-tail-padding.cpp @@ -105,11 +105,11 @@ struct A : B1, B0, B2, virtual V { // CHECK-X64-NEXT: 16 | struct B2 (base) // CHECK-X64-NEXT: 16 | int a // CHECK-X64-NEXT: 32 | (A vbtable pointer) -// CHECK-X64-NEXT: 40 | int a -// CHECK-X64-NEXT: 48 | struct V (virtual base) -// CHECK-X64-NEXT: 48 | char a -// CHECK-X64-NEXT: | [sizeof=64, align=16 -// CHECK-X64-NEXT: | nvsize=48, nvalign=16] +// CHECK-X64-NEXT: 48 | int a +// CHECK-X64-NEXT: 64 | struct V (virtual base) +// CHECK-X64-NEXT: 64 | char a +// CHECK-X64-NEXT: | [sizeof=80, align=16 +// CHECK-X64-NEXT: | nvsize=64, nvalign=16] struct B : B2, B0, B1, virtual V { int a; @@ -139,7 +139,7 @@ struct B : B2, B0, B1, virtual V { // CHECK-X64-NEXT: 32 | struct B1 (base) // CHECK-X64-NEXT: 32 | int a // CHECK-X64-NEXT: 40 | (B vbtable pointer) -// CHECK-X64-NEXT: 48 | int a +// CHECK-X64-NEXT: 52 | int a // CHECK-X64-NEXT: 64 | struct V (virtual base) // CHECK-X64-NEXT: 64 | char a // CHECK-X64-NEXT: | [sizeof=80, align=16 @@ -171,12 +171,12 @@ struct C : B1, B0, virtual V { // CHECK-X64-NEXT: 4 | struct B0 (base) // CHECK-X64-NEXT: 4 | int a // CHECK-X64-NEXT: 8 | (C vbtable pointer) -// CHECK-X64-NEXT: 16 | int a -// CHECK-X64-NEXT: 24 | long long a1 -// CHECK-X64-NEXT: 32 | struct V (virtual base) -// CHECK-X64-NEXT: 32 | char a -// CHECK-X64-NEXT: | [sizeof=48, align=16 -// CHECK-X64-NEXT: | nvsize=32, nvalign=16] +// CHECK-X64-NEXT: 24 | int a +// CHECK-X64-NEXT: 32 | long long a1 +// CHECK-X64-NEXT: 48 | struct V (virtual base) +// CHECK-X64-NEXT: 48 | char a +// CHECK-X64-NEXT: | [sizeof=64, align=16 +// CHECK-X64-NEXT: | nvsize=48, nvalign=16] struct D : B2, B0, virtual V { int a; @@ -202,7 +202,7 @@ struct D : B2, B0, virtual V { // CHECK-X64-NEXT: 16 | struct B0 (base) // CHECK-X64-NEXT: 16 | int a // CHECK-X64-NEXT: 24 | (D vbtable pointer) -// CHECK-X64-NEXT: 32 | int a +// CHECK-X64-NEXT: 36 | int a // CHECK-X64-NEXT: 48 | struct V (virtual base) // CHECK-X64-NEXT: 48 | char a // CHECK-X64-NEXT: | [sizeof=64, align=16 @@ -236,7 +236,7 @@ struct E : B3, B0, virtual V { // CHECK-X64-NEXT: 16 | struct B0 (base) // CHECK-X64-NEXT: 16 | int a // CHECK-X64-NEXT: 24 | (E vbtable pointer) -// CHECK-X64-NEXT: 32 | int a +// CHECK-X64-NEXT: 36 | int a // CHECK-X64-NEXT: 48 | struct V (virtual base) // CHECK-X64-NEXT: 48 | char a // CHECK-X64-NEXT: | [sizeof=64, align=16 @@ -269,13 +269,13 @@ struct F : B0, virtual V1 { // CHECK-X64-NEXT: 0 | struct B0 (base) // CHECK-X64-NEXT: 0 | int a // CHECK-X64-NEXT: 8 | (F vbtable pointer) -// CHECK-X64-NEXT: 16 | int a -// CHECK-X64-NEXT: 60 | (vtordisp for vbase V1) -// CHECK-X64-NEXT: 64 | struct V1 (virtual base) -// CHECK-X64-NEXT: 64 | (V1 vftable pointer) -// CHECK-X64-NEXT: 96 | struct A16 (base) (empty) -// CHECK-X64-NEXT: | [sizeof=96, align=32 -// CHECK-X64-NEXT: | nvsize=32, nvalign=32] +// CHECK-X64-NEXT: 32 | int a +// CHECK-X64-NEXT: 92 | (vtordisp for vbase V1) +// CHECK-X64-NEXT: 96 | struct V1 (virtual base) +// CHECK-X64-NEXT: 96 | (V1 vftable pointer) +// CHECK-X64-NEXT: 128 | struct A16 (base) (empty) +// CHECK-X64-NEXT: | [sizeof=128, align=32 +// CHECK-X64-NEXT: | nvsize=48, nvalign=32] struct G : virtual V2, virtual V3 { int a; @@ -389,7 +389,7 @@ struct AX : B0X, virtual B2X, virtual B6X, virtual B3X { // CHECK-X64-NEXT: 16 | int a // CHECK-X64-NEXT: 20 | int a1 // CHECK-X64-NEXT: 24 | (AX vbtable pointer) -// CHECK-X64-NEXT: 32 | int a +// CHECK-X64-NEXT: 40 | int a // CHECK-X64-NEXT: 48 | struct B2X (virtual base) // CHECK-X64-NEXT: 48 | int a // CHECK-X64-NEXT: 52 | struct B6X (virtual base) @@ -439,17 +439,17 @@ struct BX : B4X, virtual B2X, virtual B6X, virtual B3X { // CHECK-X64-NEXT: 16 | int a // CHECK-X64-NEXT: 20 | int a1 // CHECK-X64-NEXT: 32 | (BX vbtable pointer) -// CHECK-X64-NEXT: 40 | int a -// CHECK-X64-NEXT: 48 | struct B2X (virtual base) -// CHECK-X64-NEXT: 48 | int a -// CHECK-X64-NEXT: 52 | struct B6X (virtual base) -// CHECK-X64-NEXT: 52 | int a -// CHECK-X64-NEXT: 76 | (vtordisp for vbase B3X) -// CHECK-X64-NEXT: 80 | struct B3X (virtual base) -// CHECK-X64-NEXT: 80 | (B3X vftable pointer) -// CHECK-X64-NEXT: 88 | int a -// CHECK-X64-NEXT: | [sizeof=96, align=16 -// CHECK-X64-NEXT: | nvsize=48, nvalign=16] +// CHECK-X64-NEXT: 48 | int a +// CHECK-X64-NEXT: 64 | struct B2X (virtual base) +// CHECK-X64-NEXT: 64 | int a +// CHECK-X64-NEXT: 68 | struct B6X (virtual base) +// CHECK-X64-NEXT: 68 | int a +// CHECK-X64-NEXT: 92 | (vtordisp for vbase B3X) +// CHECK-X64-NEXT: 96 | struct B3X (virtual base) +// CHECK-X64-NEXT: 96 | (B3X vftable pointer) +// CHECK-X64-NEXT: 104 | int a +// CHECK-X64-NEXT: | [sizeof=112, align=16 +// CHECK-X64-NEXT: | nvsize=64, nvalign=16] struct CX : B5X, virtual B2X, virtual B6X, virtual B3X { int a; diff --git a/clang/test/Layout/ms-x86-basic-layout.cpp b/clang/test/Layout/ms-x86-basic-layout.cpp index c7501a6cbb2..b6ffeee7114 100644 --- a/clang/test/Layout/ms-x86-basic-layout.cpp +++ b/clang/test/Layout/ms-x86-basic-layout.cpp @@ -428,12 +428,12 @@ struct TestFB : A16, virtual C16 { // CHECK-X64-NEXT: 16 | struct A16 (base) // CHECK-X64-NEXT: 16 | int a // CHECK-X64-NEXT: 32 | (TestFB vbtable pointer) -// CHECK-X64-NEXT: 40 | int a -// CHECK-X64-NEXT: 48 | struct C16 (virtual base) -// CHECK-X64-NEXT: 48 | (C16 vftable pointer) -// CHECK-X64-NEXT: 64 | int a -// CHECK-X64-NEXT: | [sizeof=80, align=16 -// CHECK-X64-NEXT: | nvsize=48, nvalign=16] +// CHECK-X64-NEXT: 48 | int a +// CHECK-X64-NEXT: 64 | struct C16 (virtual base) +// CHECK-X64-NEXT: 64 | (C16 vftable pointer) +// CHECK-X64-NEXT: 80 | int a +// CHECK-X64-NEXT: | [sizeof=96, align=16 +// CHECK-X64-NEXT: | nvsize=64, nvalign=16] struct TestFC : TestFB, A4 { int a; @@ -464,15 +464,15 @@ struct TestFC : TestFB, A4 { // CHECK-X64-NEXT: 16 | struct A16 (base) // CHECK-X64-NEXT: 16 | int a // CHECK-X64-NEXT: 32 | (TestFB vbtable pointer) -// CHECK-X64-NEXT: 40 | int a -// CHECK-X64-NEXT: 48 | struct A4 (base) // CHECK-X64-NEXT: 48 | int a -// CHECK-X64-NEXT: 52 | int a -// CHECK-X64-NEXT: 64 | struct C16 (virtual base) -// CHECK-X64-NEXT: 64 | (C16 vftable pointer) -// CHECK-X64-NEXT: 80 | int a -// CHECK-X64-NEXT: | [sizeof=96, align=16 -// CHECK-X64-NEXT: | nvsize=64, nvalign=16] +// CHECK-X64-NEXT: 64 | struct A4 (base) +// CHECK-X64-NEXT: 64 | int a +// CHECK-X64-NEXT: 68 | int a +// CHECK-X64-NEXT: 80 | struct C16 (virtual base) +// CHECK-X64-NEXT: 80 | (C16 vftable pointer) +// CHECK-X64-NEXT: 96 | int a +// CHECK-X64-NEXT: | [sizeof=112, align=16 +// CHECK-X64-NEXT: | nvsize=80, nvalign=16] struct A16f { @@ -525,22 +525,22 @@ struct F0 : A4, B { // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct F0 // CHECK-X64-NEXT: 0 | (F0 vftable pointer) -// CHECK-X64-NEXT: 8 | struct A4 (base) -// CHECK-X64-NEXT: 8 | int a -// CHECK-X64-NEXT: 16 | struct B (base) -// CHECK-X64-NEXT: 16 | struct A4 (base) -// CHECK-X64-NEXT: 16 | int a -// CHECK-X64-NEXT: 20 | struct Y (base) -// CHECK-X64-NEXT: 20 | char y -// CHECK-X64-NEXT: 32 | struct X (base) -// CHECK-X64-NEXT: 32 | (X vbtable pointer) -// CHECK-X64-NEXT: 40 | int a -// CHECK-X64-NEXT: 48 | int a -// CHECK-X64-NEXT: 64 | struct A16f (virtual base) -// CHECK-X64-NEXT: 64 | (A16f vftable pointer) -// CHECK-X64-NEXT: 80 | int a -// CHECK-X64-NEXT: | [sizeof=96, align=16 -// CHECK-X64-NEXT: | nvsize=64, nvalign=16] +// CHECK-X64-NEXT: 16 | struct A4 (base) +// CHECK-X64-NEXT: 16 | int a +// CHECK-X64-NEXT: 32 | struct B (base) +// CHECK-X64-NEXT: 32 | struct A4 (base) +// CHECK-X64-NEXT: 32 | int a +// CHECK-X64-NEXT: 36 | struct Y (base) +// CHECK-X64-NEXT: 36 | char y +// CHECK-X64-NEXT: 48 | struct X (base) +// CHECK-X64-NEXT: 48 | (X vbtable pointer) +// CHECK-X64-NEXT: 56 | int a +// CHECK-X64-NEXT: 64 | int a +// CHECK-X64-NEXT: 80 | struct A16f (virtual base) +// CHECK-X64-NEXT: 80 | (A16f vftable pointer) +// CHECK-X64-NEXT: 96 | int a +// CHECK-X64-NEXT: | [sizeof=112, align=16 +// CHECK-X64-NEXT: | nvsize=80, nvalign=16] struct F1 : B, A4 { int a; @@ -639,15 +639,15 @@ struct F3 : A4, virtual A16f { // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct F3 // CHECK-X64-NEXT: 0 | (F3 vftable pointer) -// CHECK-X64-NEXT: 8 | struct A4 (base) -// CHECK-X64-NEXT: 8 | int a -// CHECK-X64-NEXT: 16 | (F3 vbtable pointer) -// CHECK-X64-NEXT: 32 | int a -// CHECK-X64-NEXT: 48 | struct A16f (virtual base) -// CHECK-X64-NEXT: 48 | (A16f vftable pointer) -// CHECK-X64-NEXT: 64 | int a -// CHECK-X64-NEXT: | [sizeof=80, align=16 -// CHECK-X64-NEXT: | nvsize=48, nvalign=16] +// CHECK-X64-NEXT: 16 | struct A4 (base) +// CHECK-X64-NEXT: 16 | int a +// CHECK-X64-NEXT: 24 | (F3 vbtable pointer) +// CHECK-X64-NEXT: 48 | int a +// CHECK-X64-NEXT: 64 | struct A16f (virtual base) +// CHECK-X64-NEXT: 64 | (A16f vftable pointer) +// CHECK-X64-NEXT: 80 | int a +// CHECK-X64-NEXT: | [sizeof=96, align=16 +// CHECK-X64-NEXT: | nvsize=64, nvalign=16] struct F4 : A4, B { __declspec(align(16)) int a; @@ -677,22 +677,22 @@ struct F4 : A4, B { // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct F4 // CHECK-X64-NEXT: 0 | (F4 vftable pointer) -// CHECK-X64-NEXT: 8 | struct A4 (base) -// CHECK-X64-NEXT: 8 | int a -// CHECK-X64-NEXT: 16 | struct B (base) -// CHECK-X64-NEXT: 16 | struct A4 (base) -// CHECK-X64-NEXT: 16 | int a -// CHECK-X64-NEXT: 20 | struct Y (base) -// CHECK-X64-NEXT: 20 | char y -// CHECK-X64-NEXT: 32 | struct X (base) -// CHECK-X64-NEXT: 32 | (X vbtable pointer) -// CHECK-X64-NEXT: 40 | int a -// CHECK-X64-NEXT: 48 | int a -// CHECK-X64-NEXT: 64 | struct A16f (virtual base) -// CHECK-X64-NEXT: 64 | (A16f vftable pointer) -// CHECK-X64-NEXT: 80 | int a -// CHECK-X64-NEXT: | [sizeof=96, align=16 -// CHECK-X64-NEXT: | nvsize=64, nvalign=16] +// CHECK-X64-NEXT: 16 | struct A4 (base) +// CHECK-X64-NEXT: 16 | int a +// CHECK-X64-NEXT: 32 | struct B (base) +// CHECK-X64-NEXT: 32 | struct A4 (base) +// CHECK-X64-NEXT: 32 | int a +// CHECK-X64-NEXT: 36 | struct Y (base) +// CHECK-X64-NEXT: 36 | char y +// CHECK-X64-NEXT: 48 | struct X (base) +// CHECK-X64-NEXT: 48 | (X vbtable pointer) +// CHECK-X64-NEXT: 56 | int a +// CHECK-X64-NEXT: 64 | int a +// CHECK-X64-NEXT: 80 | struct A16f (virtual base) +// CHECK-X64-NEXT: 80 | (A16f vftable pointer) +// CHECK-X64-NEXT: 96 | int a +// CHECK-X64-NEXT: | [sizeof=112, align=16 +// CHECK-X64-NEXT: | nvsize=80, nvalign=16] struct F5 : A16f, virtual A4 { int a; @@ -717,11 +717,11 @@ struct F5 : A16f, virtual A4 { // CHECK-X64-NEXT: 0 | (A16f vftable pointer) // CHECK-X64-NEXT: 16 | int a // CHECK-X64-NEXT: 32 | (F5 vbtable pointer) -// CHECK-X64-NEXT: 40 | int a -// CHECK-X64-NEXT: 48 | struct A4 (virtual base) -// CHECK-X64-NEXT: 48 | int a -// CHECK-X64-NEXT: | [sizeof=64, align=16 -// CHECK-X64-NEXT: | nvsize=48, nvalign=16] +// CHECK-X64-NEXT: 48 | int a +// CHECK-X64-NEXT: 64 | struct A4 (virtual base) +// CHECK-X64-NEXT: 64 | int a +// CHECK-X64-NEXT: | [sizeof=80, align=16 +// CHECK-X64-NEXT: | nvsize=64, nvalign=16] struct F6 : virtual A16f, A4, virtual B { int a; diff --git a/clang/test/Layout/ms-x86-empty-virtual-base.cpp b/clang/test/Layout/ms-x86-empty-virtual-base.cpp index 267f82afef7..23e287acf93 100644 --- a/clang/test/Layout/ms-x86-empty-virtual-base.cpp +++ b/clang/test/Layout/ms-x86-empty-virtual-base.cpp @@ -240,7 +240,7 @@ struct G : virtual C0, virtual B0, virtual B1, D0, virtual C1 { // CHECK-X64-NEXT: 0 | struct D0 (primary base) // CHECK-X64-NEXT: 0 | (D0 vftable pointer) // CHECK-X64-NEXT: 8 | (G vbtable pointer) -// CHECK-X64-NEXT: 16 | int a +// CHECK-X64-NEXT: 24 | int a // CHECK-X64-NEXT: 32 | struct C0 (virtual base) // CHECK-X64-NEXT: 32 | int a // CHECK-X64-NEXT: 40 | struct B0 (virtual base) (empty) diff --git a/clang/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp b/clang/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp index 991bd4a22c2..5bea872ae11 100644 --- a/clang/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp +++ b/clang/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp @@ -612,9 +612,9 @@ struct G : B8, B1, virtual B0 { // CHECK-X64-NEXT: 0 | struct G // CHECK-X64-NEXT: 0 | struct B8 (base) // CHECK-X64-NEXT: 0 | char [5] c -// CHECK-X64-NEXT: 16 | struct B1 (base) (empty) +// CHECK-X64-NEXT: 21 | struct B1 (base) (empty) // CHECK-X64-NEXT: 8 | (G vbtable pointer) -// CHECK-X64-NEXT: 16 | int a +// CHECK-X64-NEXT: 24 | int a // CHECK-X64-NEXT: 32 | int a1 // CHECK-X64-NEXT: 48 | struct B0 (virtual base) (empty) // CHECK-X64-NEXT: | [sizeof=48, align=16 @@ -651,7 +651,7 @@ struct AX : B1X, B2X, B3X, B4X, virtual B0X { // CHECK-X64-NEXT: 0 | struct B1X (base) (empty) // CHECK-X64-NEXT: 16 | struct B2X (base) (empty) // CHECK-X64-NEXT: 18 | struct B3X (base) (empty) -// CHECK-X64-NEXT: 33 | struct B4X (base) (empty) +// CHECK-X64-NEXT: 35 | struct B4X (base) (empty) // CHECK-X64-NEXT: 24 | (AX vbtable pointer) // CHECK-X64-NEXT: 36 | int a // CHECK-X64-NEXT: 48 | struct B0X (virtual base) (empty) @@ -679,7 +679,7 @@ struct BX : B2X, B1X, B3X, B4X, virtual B0X { // CHECK-X64-NEXT: 0 | struct B2X (base) (empty) // CHECK-X64-NEXT: 1 | struct B1X (base) (empty) // CHECK-X64-NEXT: 2 | struct B3X (base) (empty) -// CHECK-X64-NEXT: 17 | struct B4X (base) (empty) +// CHECK-X64-NEXT: 19 | struct B4X (base) (empty) // CHECK-X64-NEXT: 8 | (BX vbtable pointer) // CHECK-X64-NEXT: 20 | int a // CHECK-X64-NEXT: 32 | struct B0X (virtual base) (empty) @@ -706,7 +706,7 @@ struct CX : B1X, B3X, B2X, virtual B0X { // CHECK-X64-NEXT: 0 | struct B1X (base) (empty) // CHECK-X64-NEXT: 2 | struct B3X (base) (empty) // CHECK-X64-NEXT: 32 | struct B2X (base) (empty) -// CHECK-X64-NEXT: 8 | (CX vbtable pointer) +// CHECK-X64-NEXT: 16 | (CX vbtable pointer) // CHECK-X64-NEXT: 32 | int a // CHECK-X64-NEXT: 48 | struct B0X (virtual base) (empty) // CHECK-X64-NEXT: | [sizeof=48, align=16 diff --git a/clang/test/Layout/ms-x86-vfvb-alignment.cpp b/clang/test/Layout/ms-x86-vfvb-alignment.cpp index f65adc15a66..54f74ac16d1 100644 --- a/clang/test/Layout/ms-x86-vfvb-alignment.cpp +++ b/clang/test/Layout/ms-x86-vfvb-alignment.cpp @@ -33,14 +33,14 @@ struct A : B0, virtual B1 { __declspec(align(16)) int a; A() : a(0xf000000A) {} // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct A // CHECK-X64-NEXT: 0 | (A vftable pointer) -// CHECK-X64-NEXT: 8 | struct B0 (base) -// CHECK-X64-NEXT: 8 | int a -// CHECK-X64-NEXT: 16 | (A vbtable pointer) -// CHECK-X64-NEXT: 32 | int a -// CHECK-X64-NEXT: 48 | struct B1 (virtual base) -// CHECK-X64-NEXT: 48 | char a -// CHECK-X64-NEXT: | [sizeof=64, align=16 -// CHECK-X64-NEXT: | nvsize=48, nvalign=16] +// CHECK-X64-NEXT: 16 | struct B0 (base) +// CHECK-X64-NEXT: 16 | int a +// CHECK-X64-NEXT: 24 | (A vbtable pointer) +// CHECK-X64-NEXT: 48 | int a +// CHECK-X64-NEXT: 64 | struct B1 (virtual base) +// CHECK-X64-NEXT: 64 | char a +// CHECK-X64-NEXT: | [sizeof=80, align=16 +// CHECK-X64-NEXT: | nvsize=64, nvalign=16] struct B : A, B2 { int a; B() : a(0xf000000B) {} virtual void f() { printf("B"); } }; @@ -66,18 +66,18 @@ struct B : A, B2 { int a; B() : a(0xf000000B) {} virtual void f() { printf("B"); // CHECK-X64-NEXT: 0 | struct B // CHECK-X64-NEXT: 0 | struct A (primary base) // CHECK-X64-NEXT: 0 | (A vftable pointer) -// CHECK-X64-NEXT: 8 | struct B0 (base) -// CHECK-X64-NEXT: 8 | int a -// CHECK-X64-NEXT: 16 | (A vbtable pointer) -// CHECK-X64-NEXT: 32 | int a -// CHECK-X64-NEXT: 48 | struct B2 (base) -// CHECK-X64-NEXT: 48 | (B2 vbtable pointer) -// CHECK-X64-NEXT: 56 | int a -// CHECK-X64-NEXT: 64 | int a -// CHECK-X64-NEXT: 80 | struct B1 (virtual base) -// CHECK-X64-NEXT: 80 | char a -// CHECK-X64-NEXT: | [sizeof=96, align=16 -// CHECK-X64-NEXT: | nvsize=80, nvalign=16] +// CHECK-X64-NEXT: 16 | struct B0 (base) +// CHECK-X64-NEXT: 16 | int a +// CHECK-X64-NEXT: 24 | (A vbtable pointer) +// CHECK-X64-NEXT: 48 | int a +// CHECK-X64-NEXT: 64 | struct B2 (base) +// CHECK-X64-NEXT: 64 | (B2 vbtable pointer) +// CHECK-X64-NEXT: 72 | int a +// CHECK-X64-NEXT: 80 | int a +// CHECK-X64-NEXT: 96 | struct B1 (virtual base) +// CHECK-X64-NEXT: 96 | char a +// CHECK-X64-NEXT: | [sizeof=112, align=16 +// CHECK-X64-NEXT: | nvsize=96, nvalign=16] struct C : B4 { int a; C() : a(0xf000000C) {} virtual void f() { printf("C"); } }; @@ -189,11 +189,11 @@ struct F : B3, virtual B0 { int a; F() : a(0xf000000F) {} virtual void f() { pri // CHECK-X64-NEXT: 16 | struct B3 (base) // CHECK-X64-NEXT: 16 | int a // CHECK-X64-NEXT: 32 | (F vbtable pointer) -// CHECK-X64-NEXT: 40 | int a -// CHECK-X64-NEXT: 48 | struct B0 (virtual base) -// CHECK-X64-NEXT: 48 | int a -// CHECK-X64-NEXT: | [sizeof=64, align=16 -// CHECK-X64-NEXT: | nvsize=48, nvalign=16] +// CHECK-X64-NEXT: 48 | int a +// CHECK-X64-NEXT: 64 | struct B0 (virtual base) +// CHECK-X64-NEXT: 64 | int a +// CHECK-X64-NEXT: | [sizeof=80, align=16 +// CHECK-X64-NEXT: | nvsize=64, nvalign=16] struct G : B2, B6, virtual B1 { int a; G() : a(0xf0000010) {} }; @@ -274,8 +274,8 @@ struct I : B0, virtual B1 { int a; int a1; __declspec(align(16)) int a2; I() : a // CHECK-X64-NEXT: 0 | struct B0 (base) // CHECK-X64-NEXT: 0 | int a // CHECK-X64-NEXT: 8 | (I vbtable pointer) -// CHECK-X64-NEXT: 16 | int a -// CHECK-X64-NEXT: 20 | int a1 +// CHECK-X64-NEXT: 20 | int a +// CHECK-X64-NEXT: 24 | int a1 // CHECK-X64-NEXT: 32 | int a2 // CHECK-X64-NEXT: 48 | struct B1 (virtual base) // CHECK-X64-NEXT: 48 | char a @@ -304,12 +304,12 @@ struct J : B0, B3, virtual B1 { int a; int a1; J() : a(0xf0000012), a1(0xf000001 // CHECK-X64-NEXT: 16 | struct B3 (base) // CHECK-X64-NEXT: 16 | int a // CHECK-X64-NEXT: 32 | (J vbtable pointer) -// CHECK-X64-NEXT: 40 | int a -// CHECK-X64-NEXT: 44 | int a1 -// CHECK-X64-NEXT: 48 | struct B1 (virtual base) -// CHECK-X64-NEXT: 48 | char a -// CHECK-X64-NEXT: | [sizeof=64, align=16 -// CHECK-X64-NEXT: | nvsize=48, nvalign=16] +// CHECK-X64-NEXT: 48 | int a +// CHECK-X64-NEXT: 52 | int a1 +// CHECK-X64-NEXT: 64 | struct B1 (virtual base) +// CHECK-X64-NEXT: 64 | char a +// CHECK-X64-NEXT: | [sizeof=80, align=16 +// CHECK-X64-NEXT: | nvsize=64, nvalign=16] struct K { int a; K() : a(0xf0000013) {} virtual void f() { printf("K"); } }; diff --git a/clang/test/Layout/ms-x86-vfvb-sharing.cpp b/clang/test/Layout/ms-x86-vfvb-sharing.cpp index 981fe688589..91f194f2a5e 100644 --- a/clang/test/Layout/ms-x86-vfvb-sharing.cpp +++ b/clang/test/Layout/ms-x86-vfvb-sharing.cpp @@ -35,14 +35,14 @@ struct A : B0, virtual B1 { // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct A // CHECK-X64-NEXT: 0 | (A vftable pointer) -// CHECK-X64-NEXT: 8 | struct B0 (base) -// CHECK-X64-NEXT: 8 | int a -// CHECK-X64-NEXT: 16 | (A vbtable pointer) -// CHECK-X64-NEXT: 32 | int a -// CHECK-X64-NEXT: 48 | struct B1 (virtual base) -// CHECK-X64-NEXT: 48 | int a -// CHECK-X64-NEXT: | [sizeof=64, align=16 -// CHECK-X64-NEXT: | nvsize=48, nvalign=16] +// CHECK-X64-NEXT: 16 | struct B0 (base) +// CHECK-X64-NEXT: 16 | int a +// CHECK-X64-NEXT: 24 | (A vbtable pointer) +// CHECK-X64-NEXT: 48 | int a +// CHECK-X64-NEXT: 64 | struct B1 (virtual base) +// CHECK-X64-NEXT: 64 | int a +// CHECK-X64-NEXT: | [sizeof=80, align=16 +// CHECK-X64-NEXT: | nvsize=64, nvalign=16] struct B : B2, B0, virtual B1 { __declspec(align(16)) int a; @@ -100,10 +100,10 @@ struct C : B3, B0, virtual B1 { // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct C // CHECK-X64-NEXT: 0 | (C vftable pointer) -// CHECK-X64-NEXT: 8 | struct B3 (base) -// CHECK-X64-NEXT: 8 | (B3 vbtable pointer) -// CHECK-X64-NEXT: 16 | struct B0 (base) -// CHECK-X64-NEXT: 16 | int a +// CHECK-X64-NEXT: 16 | struct B3 (base) +// CHECK-X64-NEXT: 16 | (B3 vbtable pointer) +// CHECK-X64-NEXT: 24 | struct B0 (base) +// CHECK-X64-NEXT: 24 | int a // CHECK-X64-NEXT: 32 | int a // CHECK-X64-NEXT: 48 | struct B1 (virtual base) // CHECK-X64-NEXT: 48 | int a |