diff options
author | Warren Hunt <whunt@google.com> | 2014-04-10 23:23:34 +0000 |
---|---|---|
committer | Warren Hunt <whunt@google.com> | 2014-04-10 23:23:34 +0000 |
commit | bb9c3c33e94f3e5a17990b7a8ab9d076d0c7e594 (patch) | |
tree | dff6dd016a24937cd5330b91855a8b4da41c743b /clang | |
parent | 42d71b990677afc974c404fb0482cb5af176c3d0 (diff) | |
download | llvm-bb9c3c33e94f3e5a17990b7a8ab9d076d0c7e594.tar.gz |
[MS-ABI] Fix to vbptr injection site calculation.
The vbptr is injected after the last non-virtual base lexographically
rather than the last non-virtual base in layout order. Test case
included. Also, some line ending fixes.
llvm-svn: 206000
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 16 | ||||
-rw-r--r-- | clang/test/Layout/ms-x86-alias-avoidance-padding.cpp | 216 | ||||
-rw-r--r-- | clang/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp | 43 |
3 files changed, 158 insertions, 117 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 623d164d221f..1ea2be41b3bd 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -2211,8 +2211,6 @@ public: bool HasOwnVFPtr : 1; /// \brief True if the class has a vbtable pointer. bool HasVBPtr : 1; - /// \brief Lets us know if we're in 64-bit mode - bool Is64BitMode : 1; /// \brief True if the last sub-object within the type is zero sized or the /// object itself is zero sized. This *does not* count members that are not /// records. Only used for MS-ABI. @@ -2310,13 +2308,13 @@ void MicrosoftRecordLayoutBuilder::cxxLayout(const CXXRecordDecl *RD) { void MicrosoftRecordLayoutBuilder::initializeLayout(const RecordDecl *RD) { IsUnion = RD->isUnion(); - Is64BitMode = Context.getTargetInfo().getPointerWidth(0) == 64; Size = CharUnits::Zero(); Alignment = CharUnits::One(); // In 64-bit mode we always perform an alignment step after laying out vbases. // In 32-bit mode we do not. The check to see if we need to perform alignment // checks the RequiredAlignment field and performs alignment if it isn't 0. - RequiredAlignment = Is64BitMode ? CharUnits::One() : CharUnits::Zero(); + RequiredAlignment = Context.getTargetInfo().getPointerWidth(0) == 64 ? + CharUnits::One() : CharUnits::Zero(); // Compute the maximum field alignment. MaxFieldAlignment = CharUnits::Zero(); // Honor the default struct packing maximum alignment flag. @@ -2402,8 +2400,10 @@ MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(const CXXRecordDecl *RD) { const CXXRecordDecl *BaseDecl = I.getType()->getAsCXXRecordDecl(); const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl); // Only lay out bases without extendable VFPtrs on the second pass. - if (BaseLayout.hasExtendableVFPtr()) + if (BaseLayout.hasExtendableVFPtr()) { + VBPtrOffset = Bases[BaseDecl] + BaseLayout.getNonVirtualSize(); continue; + } // If this is the first layout, check to see if it leads with a zero sized // object. If it does, so do we. if (CheckLeadingLayout) { @@ -2412,6 +2412,7 @@ MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(const CXXRecordDecl *RD) { } // Lay out the base. layoutNonVirtualBase(BaseDecl, BaseLayout, PreviousBaseLayout); + VBPtrOffset = Bases[BaseDecl] + BaseLayout.getNonVirtualSize(); } // Set our VBPtroffset if we know it at this point. if (!HasVBPtr) @@ -2437,7 +2438,6 @@ void MicrosoftRecordLayoutBuilder::layoutNonVirtualBase( Bases.insert(std::make_pair(BaseDecl, BaseOffset)); Size = BaseOffset + BaseLayout.getNonVirtualSize(); PreviousBaseLayout = &BaseLayout; - VBPtrOffset = Size; } void MicrosoftRecordLayoutBuilder::layoutFields(const RecordDecl *RD) { @@ -2542,8 +2542,8 @@ void MicrosoftRecordLayoutBuilder::injectVBPtr(const CXXRecordDecl *RD) { *i += Context.toBits(Offset); for (BaseOffsetsMapTy::iterator i = Bases.begin(), e = Bases.end(); i != e; ++i) - if (i->second >= InjectionSite) - i->second += Offset; + if (i->second >= InjectionSite) + i->second += Offset; } void MicrosoftRecordLayoutBuilder::injectVFPtr(const CXXRecordDecl *RD) { diff --git a/clang/test/Layout/ms-x86-alias-avoidance-padding.cpp b/clang/test/Layout/ms-x86-alias-avoidance-padding.cpp index 94ed031734c9..7a78f8732ca3 100644 --- a/clang/test/Layout/ms-x86-alias-avoidance-padding.cpp +++ b/clang/test/Layout/ms-x86-alias-avoidance-padding.cpp @@ -327,19 +327,19 @@ struct RZ0 : RX0, RY {}; // CHECK-NEXT: 2 | struct RY (base) (empty) // CHECK-NEXT: | [sizeof=2, align=1 // CHECK-NEXT: | nvsize=2, nvalign=1] -// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT: 0 | struct RZ0
-// CHECK-X64-NEXT: 0 | struct RX0 (base)
-// CHECK-X64-NEXT: 0 | struct RB (base)
-// CHECK-X64-NEXT: 0 | char c
-// CHECK-X64-NEXT: 1 | struct RA (base) (empty)
-// CHECK-X64-NEXT: 2 | struct RY (base) (empty)
-// CHECK-X64-NEXT: | [sizeof=2, align=1
-// CHECK-X64-NEXT: | nvsize=2, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64-NEXT: 0 | struct RZ0 +// CHECK-X64-NEXT: 0 | struct RX0 (base) +// CHECK-X64-NEXT: 0 | struct RB (base) +// CHECK-X64-NEXT: 0 | char c +// CHECK-X64-NEXT: 1 | struct RA (base) (empty) +// CHECK-X64-NEXT: 2 | struct RY (base) (empty) +// CHECK-X64-NEXT: | [sizeof=2, align=1 +// CHECK-X64-NEXT: | nvsize=2, nvalign=1] struct RZ1 : RX1, RY {}; // CHECK: *** Dumping AST Record Layout @@ -352,16 +352,16 @@ struct RZ1 : RX1, RY {}; // CHECK-NEXT: 1 | struct RY (base) (empty) // CHECK-NEXT: | [sizeof=1, align=1 // CHECK-NEXT: | nvsize=1, nvalign=1] -// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT: 0 | struct RZ1
-// CHECK-X64-NEXT: 0 | struct RX1 (base)
-// CHECK-X64-NEXT: 0 | struct RA (base) (empty)
-// CHECK-X64-NEXT: 0 | struct RB (base)
-// CHECK-X64-NEXT: 0 | char c
-// CHECK-X64-NEXT: 1 | struct RY (base) (empty)
-// CHECK-X64-NEXT: | [sizeof=1, align=1
-// CHECK-X64-NEXT: | nvsize=1, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64-NEXT: 0 | struct RZ1 +// CHECK-X64-NEXT: 0 | struct RX1 (base) +// CHECK-X64-NEXT: 0 | struct RA (base) (empty) +// CHECK-X64-NEXT: 0 | struct RB (base) +// CHECK-X64-NEXT: 0 | char c +// CHECK-X64-NEXT: 1 | struct RY (base) (empty) +// CHECK-X64-NEXT: | [sizeof=1, align=1 +// CHECK-X64-NEXT: | nvsize=1, nvalign=1] struct RZ2 : RX2, RY {}; // CHECK: *** Dumping AST Record Layout @@ -373,15 +373,15 @@ struct RZ2 : RX2, RY {}; // CHECK-NEXT: 2 | struct RY (base) (empty) // CHECK-NEXT: | [sizeof=2, align=1 // CHECK-NEXT: | nvsize=2, nvalign=1] -// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT: 0 | struct RZ2
-// CHECK-X64-NEXT: 0 | struct RX2 (base)
-// CHECK-X64-NEXT: 0 | struct RA (base) (empty)
-// CHECK-X64-NEXT: 0 | char a
-// CHECK-X64-NEXT: 2 | struct RY (base) (empty)
-// CHECK-X64-NEXT: | [sizeof=2, align=1
-// CHECK-X64-NEXT: | nvsize=2, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64-NEXT: 0 | struct RZ2 +// CHECK-X64-NEXT: 0 | struct RX2 (base) +// CHECK-X64-NEXT: 0 | struct RA (base) (empty) +// CHECK-X64-NEXT: 0 | char a +// CHECK-X64-NEXT: 2 | struct RY (base) (empty) +// CHECK-X64-NEXT: | [sizeof=2, align=1 +// CHECK-X64-NEXT: | nvsize=2, nvalign=1] struct RZ3 : RX3, RY {}; // CHECK: *** Dumping AST Record Layout @@ -396,18 +396,18 @@ struct RZ3 : RX3, RY {}; // CHECK-NEXT: 1 | struct RY (base) (empty) // CHECK-NEXT: | [sizeof=1, align=1 // CHECK-NEXT: | nvsize=1, nvalign=1] -// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT: 0 | struct RZ3
-// CHECK-X64-NEXT: 0 | struct RX3 (base)
-// CHECK-X64-NEXT: 0 | struct RA (base) (empty)
-// CHECK-X64-NEXT: 0 | struct RB a
-// CHECK-X64-NEXT: 0 | char c
-// CHECK-X64-NEXT: | [sizeof=1, align=1
-// CHECK-X64-NEXT: | nvsize=1, nvalign=1]
-// CHECK-X64-NEXT: 1 | struct RY (base) (empty)
-// CHECK-X64-NEXT: | [sizeof=1, align=1
-// CHECK-X64-NEXT: | nvsize=1, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64-NEXT: 0 | struct RZ3 +// CHECK-X64-NEXT: 0 | struct RX3 (base) +// CHECK-X64-NEXT: 0 | struct RA (base) (empty) +// CHECK-X64-NEXT: 0 | struct RB a +// CHECK-X64-NEXT: 0 | char c +// CHECK-X64-NEXT: | [sizeof=1, align=1 +// CHECK-X64-NEXT: | nvsize=1, nvalign=1] +// CHECK-X64-NEXT: 1 | struct RY (base) (empty) +// CHECK-X64-NEXT: | [sizeof=1, align=1 +// CHECK-X64-NEXT: | nvsize=1, nvalign=1] struct RZ4 : RX4, RY {}; // CHECK: *** Dumping AST Record Layout @@ -421,17 +421,17 @@ struct RZ4 : RX4, RY {}; // CHECK-NEXT: 3 | struct RY (base) (empty) // CHECK-NEXT: | [sizeof=3, align=1 // CHECK-NEXT: | nvsize=3, nvalign=1] -// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT: 0 | struct RZ4
-// CHECK-X64-NEXT: 0 | struct RX4 (base)
-// CHECK-X64-NEXT: 0 | struct RA a (empty)
-// CHECK-X64-NEXT: | [sizeof=1, align=1
-// CHECK-X64-NEXT: | nvsize=0, nvalign=1]
-// CHECK-X64-NEXT: 1 | char b
-// CHECK-X64-NEXT: 3 | struct RY (base) (empty)
-// CHECK-X64-NEXT: | [sizeof=3, align=1
-// CHECK-X64-NEXT: | nvsize=3, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64-NEXT: 0 | struct RZ4 +// CHECK-X64-NEXT: 0 | struct RX4 (base) +// CHECK-X64-NEXT: 0 | struct RA a (empty) +// CHECK-X64-NEXT: | [sizeof=1, align=1 +// CHECK-X64-NEXT: | nvsize=0, nvalign=1] +// CHECK-X64-NEXT: 1 | char b +// CHECK-X64-NEXT: 3 | struct RY (base) (empty) +// CHECK-X64-NEXT: | [sizeof=3, align=1 +// CHECK-X64-NEXT: | nvsize=3, nvalign=1] struct RZ5 : RX5, RY {}; // CHECK: *** Dumping AST Record Layout @@ -448,20 +448,20 @@ struct RZ5 : RX5, RY {}; // CHECK-NEXT: 2 | struct RY (base) (empty) // CHECK-NEXT: | [sizeof=2, align=1 // CHECK-NEXT: | nvsize=2, nvalign=1] -// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT: 0 | struct RZ5
-// CHECK-X64-NEXT: 0 | struct RX5 (base)
-// CHECK-X64-NEXT: 0 | struct RA a (empty)
-// CHECK-X64-NEXT: | [sizeof=1, align=1
-// CHECK-X64-NEXT: | nvsize=0, nvalign=1]
-// CHECK-X64-NEXT: 1 | struct RB b
-// CHECK-X64-NEXT: 1 | char c
-// CHECK-X64-NEXT: | [sizeof=1, align=1
-// CHECK-X64-NEXT: | nvsize=1, nvalign=1]
-// CHECK-X64-NEXT: 2 | struct RY (base) (empty)
-// CHECK-X64-NEXT: | [sizeof=2, align=1
-// CHECK-X64-NEXT: | nvsize=2, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64-NEXT: 0 | struct RZ5 +// CHECK-X64-NEXT: 0 | struct RX5 (base) +// CHECK-X64-NEXT: 0 | struct RA a (empty) +// CHECK-X64-NEXT: | [sizeof=1, align=1 +// CHECK-X64-NEXT: | nvsize=0, nvalign=1] +// CHECK-X64-NEXT: 1 | struct RB b +// CHECK-X64-NEXT: 1 | char c +// CHECK-X64-NEXT: | [sizeof=1, align=1 +// CHECK-X64-NEXT: | nvsize=1, nvalign=1] +// CHECK-X64-NEXT: 2 | struct RY (base) (empty) +// CHECK-X64-NEXT: | [sizeof=2, align=1 +// CHECK-X64-NEXT: | nvsize=2, nvalign=1] struct RZ6 : RX6, RY {}; // CHECK: *** Dumping AST Record Layout @@ -478,20 +478,20 @@ struct RZ6 : RX6, RY {}; // CHECK-NEXT: 12 | struct RV (virtual base) (empty) // CHECK-NEXT: | [sizeof=12, align=4 // CHECK-NEXT: | nvsize=12, nvalign=4] -// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT: 0 | struct RZ6
-// CHECK-X64-NEXT: 0 | struct RX6 (base)
-// CHECK-X64-NEXT: 0 | (RX6 vbtable pointer)
-// CHECK-X64-NEXT: 8 | struct RB a
-// CHECK-X64-NEXT: 8 | char c
-// CHECK-X64-NEXT: | [sizeof=1, align=1
-// CHECK-X64-NEXT: | nvsize=1, nvalign=1]
-// CHECK-X64-NEXT: 17 | struct RY (base) (empty)
-// CHECK-X64-NEXT: 24 | struct RV (virtual base) (empty)
-// CHECK-X64-NEXT: | [sizeof=24, align=8
-// CHECK-X64-NEXT: | nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64-NEXT: 0 | struct RZ6 +// CHECK-X64-NEXT: 0 | struct RX6 (base) +// CHECK-X64-NEXT: 0 | (RX6 vbtable pointer) +// CHECK-X64-NEXT: 8 | struct RB a +// CHECK-X64-NEXT: 8 | char c +// CHECK-X64-NEXT: | [sizeof=1, align=1 +// CHECK-X64-NEXT: | nvsize=1, nvalign=1] +// CHECK-X64-NEXT: 17 | struct RY (base) (empty) +// CHECK-X64-NEXT: 24 | struct RV (virtual base) (empty) +// CHECK-X64-NEXT: | [sizeof=24, align=8 +// CHECK-X64-NEXT: | nvsize=24, nvalign=8] struct RZ7 : RX7, RY {}; // CHECK: *** Dumping AST Record Layout @@ -508,20 +508,20 @@ struct RZ7 : RX7, RY {}; // CHECK-NEXT: 8 | char c // CHECK-NEXT: | [sizeof=9, align=4 // CHECK-NEXT: | nvsize=8, nvalign=4] -// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT: 0 | struct RZ7
-// CHECK-X64-NEXT: 0 | struct RX7 (base)
-// CHECK-X64-NEXT: 0 | (RX7 vbtable pointer)
-// CHECK-X64-NEXT: 8 | struct RA a (empty)
-// CHECK-X64-NEXT: | [sizeof=1, align=1
-// CHECK-X64-NEXT: | nvsize=0, nvalign=1]
-// CHECK-X64-NEXT: 16 | struct RY (base) (empty)
-// CHECK-X64-NEXT: 16 | struct RW (virtual base)
-// CHECK-X64-NEXT: 16 | char c
-// CHECK-X64-NEXT: | [sizeof=24, align=8
-// CHECK-X64-NEXT: | nvsize=16, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64-NEXT: 0 | struct RZ7 +// CHECK-X64-NEXT: 0 | struct RX7 (base) +// CHECK-X64-NEXT: 0 | (RX7 vbtable pointer) +// CHECK-X64-NEXT: 8 | struct RA a (empty) +// CHECK-X64-NEXT: | [sizeof=1, align=1 +// CHECK-X64-NEXT: | nvsize=0, nvalign=1] +// CHECK-X64-NEXT: 16 | struct RY (base) (empty) +// CHECK-X64-NEXT: 16 | struct RW (virtual base) +// CHECK-X64-NEXT: 16 | char c +// CHECK-X64-NEXT: | [sizeof=24, align=8 +// CHECK-X64-NEXT: | nvsize=16, nvalign=8] struct RZ8 : RX8, RY {}; // CHECK: *** Dumping AST Record Layout @@ -535,17 +535,17 @@ struct RZ8 : RX8, RY {}; // CHECK-NEXT: 4 | char c // CHECK-NEXT: | [sizeof=5, align=4 // CHECK-NEXT: | nvsize=4, nvalign=4] -// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT: 0 | struct RZ8
-// CHECK-X64-NEXT: 0 | struct RX8 (base)
-// CHECK-X64-NEXT: 8 | struct RA (base) (empty)
-// CHECK-X64-NEXT: 0 | (RX8 vbtable pointer)
-// CHECK-X64-NEXT: 8 | struct RY (base) (empty)
-// CHECK-X64-NEXT: 8 | struct RW (virtual base)
-// CHECK-X64-NEXT: 8 | char c
-// CHECK-X64-NEXT: | [sizeof=16, align=8
-// CHECK-X64-NEXT: | nvsize=8, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64-NEXT: 0 | struct RZ8 +// CHECK-X64-NEXT: 0 | struct RX8 (base) +// CHECK-X64-NEXT: 8 | struct RA (base) (empty) +// CHECK-X64-NEXT: 0 | (RX8 vbtable pointer) +// CHECK-X64-NEXT: 8 | struct RY (base) (empty) +// CHECK-X64-NEXT: 8 | struct RW (virtual base) +// CHECK-X64-NEXT: 8 | char c +// CHECK-X64-NEXT: | [sizeof=16, align=8 +// CHECK-X64-NEXT: | nvsize=8, nvalign=8] 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 5bea872ae115..34ae0cf9dde8 100644 --- a/clang/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp +++ b/clang/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp @@ -766,6 +766,45 @@ struct C2 : public C1, public C0 {}; // CHECK-X64-NEXT: | [sizeof=8, align=4 // CHECK-X64-NEXT: | nvsize=8, nvalign=4] +struct JA { char a; }; +struct JB { + char a; + virtual void f() {} +}; +struct JC { char a; }; +struct JD : JA, JB, virtual JC {}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: *** Dumping AST Record Layout +// CHECK: *** Dumping AST Record Layout +// CHECK: *** Dumping AST Record Layout +// CHECK-NEXT: 0 | struct JD +// CHECK-NEXT: 0 | struct JB (primary base) +// CHECK-NEXT: 0 | (JB vftable pointer) +// CHECK-NEXT: 4 | char a +// CHECK-NEXT: 12 | struct JA (base) +// CHECK-NEXT: 12 | char a +// CHECK-NEXT: 8 | (JD vbtable pointer) +// CHECK-NEXT: 16 | struct JC (virtual base) +// CHECK-NEXT: 16 | char a +// CHECK-NEXT: | [sizeof=17, align=4 +// CHECK-NEXT: | nvsize=16, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64-NEXT: 0 | struct JD +// CHECK-X64-NEXT: 0 | struct JB (primary base) +// CHECK-X64-NEXT: 0 | (JB vftable pointer) +// CHECK-X64-NEXT: 8 | char a +// CHECK-X64-NEXT: 24 | struct JA (base) +// CHECK-X64-NEXT: 24 | char a +// CHECK-X64-NEXT: 16 | (JD vbtable pointer) +// CHECK-X64-NEXT: 32 | struct JC (virtual base) +// CHECK-X64-NEXT: 32 | char a +// CHECK-X64-NEXT: | [sizeof=40, align=8 +// CHECK-X64-NEXT: | nvsize=32, nvalign=8] + int a[ sizeof(AA)+ sizeof(AB)+ @@ -793,4 +832,6 @@ sizeof(AX)+ sizeof(BX)+ sizeof(CX)+ sizeof(DX)+ -sizeof(C2)]; +sizeof(C2)+ +sizeof(JD)+ +0]; |