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 484e329..bf4a91a 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -98,18 +98,16 @@
/// 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<const CXXRecordDecl *, 1, bool> 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<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
@@ -135,7 +133,7 @@
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 @@
CharUnits SizeOfLargestEmptySubobject,
const CXXRecordDecl *PrimaryBase,
bool IsPrimaryBaseVirtual,
+ const CXXRecordDecl *BaseSharingVBPtr,
bool ForceAlign,
const BaseOffsetsMapTy& BaseOffsets,
const VBaseOffsetsMapTy& VBaseOffsets);
@@ -256,7 +255,7 @@
/// 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 @@
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 44af1f1..df5f79c 100644
--- a/lib/AST/RecordLayout.cpp
+++ b/lib/AST/RecordLayout.cpp
@@ -44,7 +44,6 @@
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 @@
CharUnits SizeOfLargestEmptySubobject,
const CXXRecordDecl *PrimaryBase,
bool IsPrimaryBaseVirtual,
+ const CXXRecordDecl *BaseSharingVBPtr,
bool AlignAfterVBases,
const BaseOffsetsMapTy& BaseOffsets,
const VBaseOffsetsMapTy& VBaseOffsets)
@@ -75,7 +75,7 @@
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 08c9da3..d0426fa 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -2673,11 +2673,11 @@
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 @@
Builder.Alignment,
Builder.HasOwnVFPtr,
RD->isDynamicClass(),
- false,
CharUnits::fromQuantity(-1),
DataSize,
Builder.FieldOffsets.data(),
@@ -2745,7 +2744,7 @@
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 142f550..fd768d8 100644
--- a/lib/AST/VTableBuilder.cpp
+++ b/lib/AST/VTableBuilder.cpp
@@ -3363,30 +3363,17 @@
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);
}
}