From: Timur Iskhodzhanov Date: Fri, 8 Nov 2013 11:45:35 +0000 (+0000) Subject: Thread the info about vbptr sharing through ASTRecordLayout X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6acb04f755cfc73d05772457d70aeb5adfaf6d8f;p=clang Thread the info about vbptr sharing through ASTRecordLayout Reviewed at http://llvm-reviews.chandlerc.com/D2120 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194256 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h index 484e32926b..bf4a91ad9c 100644 --- a/include/clang/AST/RecordLayout.h +++ b/include/clang/AST/RecordLayout.h @@ -98,18 +98,16 @@ private: /// HasVFPtr - Does this class have a vftable at all (could be inherited /// from its primary base.) bool HasVFPtr : 1; - - /// HasOwnVBPtr - Does this class provide a virtual function table - /// (vtable in Itanium, VBtbl in Microsoft) that is independent from - /// its base classes? - bool HasOwnVBPtr : 1; - + /// AlignAfterVBases - Force appropriate alignment after virtual bases are /// laid out in MS-C++-ABI. bool AlignAfterVBases : 1; /// PrimaryBase - The primary base info for this record. llvm::PointerIntPair PrimaryBase; + + /// BaseSharingVBPtr - The base we share vbptr with. + const CXXRecordDecl *BaseSharingVBPtr; /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :) typedef llvm::DenseMap BaseOffsetsMapTy; @@ -135,7 +133,7 @@ private: typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy; ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment, - bool hasOwnVFPtr, bool hasVFPtr, bool hasOwnVBPtr, + bool hasOwnVFPtr, bool hasVFPtr, CharUnits vbptroffset, CharUnits datasize, const uint64_t *fieldoffsets, unsigned fieldcount, @@ -143,6 +141,7 @@ private: CharUnits SizeOfLargestEmptySubobject, const CXXRecordDecl *PrimaryBase, bool IsPrimaryBaseVirtual, + const CXXRecordDecl *BaseSharingVBPtr, bool ForceAlign, const BaseOffsetsMapTy& BaseOffsets, const VBaseOffsetsMapTy& VBaseOffsets); @@ -256,7 +255,7 @@ public: /// of the ABI. bool hasOwnVBPtr() const { assert(CXXInfo && "Record layout does not have C++ specific info!"); - return CXXInfo->HasOwnVBPtr; + return hasVBPtr() && !CXXInfo->BaseSharingVBPtr; } /// hasVBPtr - Does this class have a virtual function table pointer. @@ -277,6 +276,11 @@ public: return CXXInfo->VBPtrOffset; } + const CXXRecordDecl *getBaseSharingVBPtr() const { + assert(CXXInfo && "Record layout does not have C++ specific info!"); + return CXXInfo->BaseSharingVBPtr; + } + const VBaseOffsetsMapTy &getVBaseOffsetsMap() const { assert(CXXInfo && "Record layout does not have C++ specific info!"); return CXXInfo->VBaseOffsets; diff --git a/lib/AST/RecordLayout.cpp b/lib/AST/RecordLayout.cpp index 44af1f18d9..df5f79c961 100644 --- a/lib/AST/RecordLayout.cpp +++ b/lib/AST/RecordLayout.cpp @@ -44,7 +44,6 @@ ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size, ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment, bool hasOwnVFPtr, bool hasVFPtr, - bool hasOwnVBPtr, CharUnits vbptroffset, CharUnits datasize, const uint64_t *fieldoffsets, @@ -54,6 +53,7 @@ ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits SizeOfLargestEmptySubobject, const CXXRecordDecl *PrimaryBase, bool IsPrimaryBaseVirtual, + const CXXRecordDecl *BaseSharingVBPtr, bool AlignAfterVBases, const BaseOffsetsMapTy& BaseOffsets, const VBaseOffsetsMapTy& VBaseOffsets) @@ -75,7 +75,7 @@ ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CXXInfo->HasOwnVFPtr = hasOwnVFPtr; CXXInfo->VBPtrOffset = vbptroffset; CXXInfo->HasVFPtr = hasVFPtr; - CXXInfo->HasOwnVBPtr = hasOwnVBPtr; + CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr; CXXInfo->AlignAfterVBases = AlignAfterVBases; diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index 08c9da3587..d0426fa8db 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -2673,11 +2673,11 @@ ASTContext::BuildMicrosoftASTRecordLayout(const RecordDecl *D) const { return new (*this) ASTRecordLayout( *this, Builder.Size, Builder.Alignment, Builder.HasVFPtr && !Builder.PrimaryBase, Builder.HasVFPtr, - Builder.HasVBPtr && !Builder.SharedVBPtrBase, Builder.VBPtrOffset, - Builder.DataSize, Builder.FieldOffsets.data(), + Builder.VBPtrOffset, Builder.DataSize, Builder.FieldOffsets.data(), Builder.FieldOffsets.size(), Builder.DataSize, Builder.NonVirtualAlignment, CharUnits::Zero(), Builder.PrimaryBase, - false, Builder.AlignAfterVBases, Builder.Bases, Builder.VBases); + false, Builder.SharedVBPtrBase, Builder.AlignAfterVBases, Builder.Bases, + Builder.VBases); } else { Builder.layout(D); return new (*this) ASTRecordLayout( @@ -2735,7 +2735,6 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const { Builder.Alignment, Builder.HasOwnVFPtr, RD->isDynamicClass(), - false, CharUnits::fromQuantity(-1), DataSize, Builder.FieldOffsets.data(), @@ -2745,7 +2744,7 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const { EmptySubobjects.SizeOfLargestEmptySubobject, Builder.PrimaryBase, Builder.PrimaryBaseIsVirtual, - true, + 0, true, Builder.Bases, Builder.VBases); } else { RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0); diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp index 142f550296..fd768d8126 100644 --- a/lib/AST/VTableBuilder.cpp +++ b/lib/AST/VTableBuilder.cpp @@ -3363,30 +3363,17 @@ void MicrosoftVTableContext::computeVBTableRelatedInformation( const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); BasesSetVectorTy VisitedBases; - // First, see if the Derived class shared the vbptr - // with the first non-virtual base. - for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), - E = RD->bases_end(); I != E; ++I) { - if (I->isVirtual()) - continue; - - const CXXRecordDecl *CurBase = I->getType()->getAsCXXRecordDecl(); - CharUnits DerivedVBPtrOffset = Layout.getVBPtrOffset(), - BaseOffset = Layout.getBaseClassOffset(CurBase); - const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(CurBase); - if (!BaseLayout.hasVBPtr() || - DerivedVBPtrOffset != BaseOffset + BaseLayout.getVBPtrOffset()) - continue; - + // First, see if the Derived class shared the vbptr with a non-virtual base. + if (const CXXRecordDecl *VBPtrBase = Layout.getBaseSharingVBPtr()) { // If the Derived class shares the vbptr with a non-virtual base, // it inherits its vbase indices. - computeVBTableRelatedInformation(CurBase); - for (CXXRecordDecl::base_class_const_iterator J = CurBase->vbases_begin(), - F = CurBase->vbases_end(); J != F; ++J) { - const CXXRecordDecl *SubVBase = J->getType()->getAsCXXRecordDecl(); - assert(VBTableIndices.count(ClassPairTy(CurBase, SubVBase))); + computeVBTableRelatedInformation(VBPtrBase); + for (CXXRecordDecl::base_class_const_iterator I = VBPtrBase->vbases_begin(), + E = VBPtrBase->vbases_end(); I != E; ++I) { + const CXXRecordDecl *SubVBase = I->getType()->getAsCXXRecordDecl(); + assert(VBTableIndices.count(ClassPairTy(VBPtrBase, SubVBase))); VBTableIndices[ClassPairTy(RD, SubVBase)] = - VBTableIndices[ClassPairTy(CurBase, SubVBase)]; + VBTableIndices[ClassPairTy(VBPtrBase, SubVBase)]; VisitedBases.insert(SubVBase); } }