aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGVtable.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-02-16 04:49:44 +0000
committerAnders Carlsson <andersca@mac.com>2010-02-16 04:49:44 +0000
commita661a54d50e33d8b58735ef4ded06b1ad639b165 (patch)
tree14ba2fe37c1b45cb9efde4714bd4dba782d2c27a /lib/CodeGen/CGVtable.cpp
parentbff225ecf77fb891596ecb1b27196310d268365e (diff)
More work on the new layout code.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96328 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGVtable.cpp')
-rw-r--r--lib/CodeGen/CGVtable.cpp77
1 files changed, 66 insertions, 11 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp
index 2f952c54b6..9233838c93 100644
--- a/lib/CodeGen/CGVtable.cpp
+++ b/lib/CodeGen/CGVtable.cpp
@@ -612,6 +612,10 @@ public:
CK_DeletingDtorPointer
};
+ static VtableComponent MakeVBaseOffset(int64_t Offset) {
+ return VtableComponent(CK_VBaseOffset, Offset);
+ }
+
static VtableComponent MakeOffsetToTop(int64_t Offset) {
return VtableComponent(CK_OffsetToTop, Offset);
}
@@ -643,6 +647,12 @@ public:
return (Kind)(Value & 0x7);
}
+ int64_t getVBaseOffset() const {
+ assert(getKind() == CK_VBaseOffset && "Invalid component kind!");
+
+ return getOffset();
+ }
+
int64_t getOffsetToTop() const {
assert(getKind() == CK_OffsetToTop && "Invalid component kind!");
@@ -735,6 +745,10 @@ private:
/// FinalOverriders - The final overriders of the most derived class.
FinalOverriders Overriders;
+ /// VCallAndVBaseOffsets - The vcall and vbase offset, of the vtable we're
+ // building (in reverse order).
+ llvm::SmallVector<VtableComponent, 64> VCallAndVBaseOffsets;
+
/// Components - The components of the vtable being built.
llvm::SmallVector<VtableComponent, 64> Components;
@@ -777,6 +791,17 @@ private:
llvm::SmallVector<std::pair<uint64_t, ThisAdjustment>, 16>
ThisAdjustments;
+ typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
+
+ /// AddVCallAndVBaseOffsets - Add vcall offsets and vbase offsets for the
+ /// given class.
+ void AddVCallAndVBaseOffsets(const CXXRecordDecl *RD, int64_t OffsetToTop,
+ VisitedVirtualBasesSetTy &VBases);
+
+ /// AddVBaseOffsets - Add vbase offsets for the given class.
+ void AddVBaseOffsets(const CXXRecordDecl *RD, int64_t OffsetToTop,
+ VisitedVirtualBasesSetTy &VBases);
+
/// ComputeReturnAdjustment - Compute the return adjustment given a return
/// adjustment base offset.
ReturnAdjustment ComputeReturnAdjustment(FinalOverriders::BaseOffset Offset);
@@ -794,15 +819,15 @@ private:
/// primary bases to the vtable components vector.
void AddMethods(BaseSubobject Base, PrimaryBasesSetTy &PrimaryBases);
- /// layoutVtable - Layout a vtable and all its secondary vtables.
- void layoutVtable(BaseSubobject Base);
+ /// LayoutVtable - Layout a vtable and all its secondary vtables.
+ void LayoutVtable(BaseSubobject Base);
public:
VtableBuilder(CGVtableInfo &VtableInfo, const CXXRecordDecl *MostDerivedClass)
: VtableInfo(VtableInfo), MostDerivedClass(MostDerivedClass),
Context(MostDerivedClass->getASTContext()), Overriders(MostDerivedClass) {
- layoutVtable(BaseSubobject(MostDerivedClass, 0));
+ LayoutVtable(BaseSubobject(MostDerivedClass, 0));
}
/// dumpLayout - Dump the vtable layout.
@@ -864,6 +889,32 @@ VtableBuilder::ComputeThisAdjustment(FinalOverriders::BaseOffset Offset) {
}
void
+VtableBuilder::AddVCallAndVBaseOffsets(const CXXRecordDecl *RD,
+ int64_t OffsetToTop,
+ VisitedVirtualBasesSetTy &VBases) {
+ const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+
+ // Itanium C++ ABI 2.5.2:
+ // ..in classes sharing a virtual table with a primary base class, the vcall
+ // and vbase offsets added by the derived class all come before the vcall
+ // and vbase offsets required by the base class, so that the latter may be
+ // laid out as required by the base class without regard to additions from
+ // the derived class(es).
+
+ // (Since we're emitting the vcall and vbase offsets in reverse order, we'll
+ // emit them for the primary base first).
+ if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase())
+ AddVCallAndVBaseOffsets(PrimaryBase, OffsetToTop, VBases);
+
+ AddVBaseOffsets(RD, OffsetToTop, VBases);
+}
+
+void VtableBuilder::AddVBaseOffsets(const CXXRecordDecl *RD,
+ int64_t OffsetToTop,
+ VisitedVirtualBasesSetTy &VBases) {
+}
+
+void
VtableBuilder::AddMethod(const CXXMethodDecl *MD,
ReturnAdjustment ReturnAdjustment,
ThisAdjustment ThisAdjustment) {
@@ -955,7 +1006,7 @@ VtableBuilder::AddMethods(BaseSubobject Base, PrimaryBasesSetTy &PrimaryBases) {
}
}
-void VtableBuilder::layoutVtable(BaseSubobject Base) {
+void VtableBuilder::LayoutVtable(BaseSubobject Base) {
const CXXRecordDecl *RD = Base.getBase();
assert(RD->isDynamicClass() && "class does not have a vtable!");
@@ -998,23 +1049,27 @@ void VtableBuilder::layoutVtable(BaseSubobject Base) {
const CXXRecordDecl *BaseDecl =
cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+ // Ignore bases that don't have a vtable.
+ if (!BaseDecl->isDynamicClass())
+ continue;
+
// Ignore the primary base.
if (BaseDecl == PrimaryBase)
continue;
- // Ignore bases that don't have a vtable.
- if (!BaseDecl->isDynamicClass())
+ // Ignore virtual bases, we'll emit them later.
+ if (I->isVirtual())
continue;
-
- assert(!I->isVirtual() && "FIXME: Handle virtual bases");
// Get the base offset of this base.
uint64_t BaseOffset = Base.getBaseOffset() +
Layout.getBaseClassOffset(BaseDecl);
// Layout this secondary vtable.
- layoutVtable(BaseSubobject(BaseDecl, BaseOffset));
+ LayoutVtable(BaseSubobject(BaseDecl, BaseOffset));
}
+
+ // FIXME: Emit vtables for virtual bases here.
}
/// dumpLayout - Dump the vtable layout.
@@ -2327,8 +2382,8 @@ void CGVtableInfo::ComputeMethodVtableIndices(const CXXRecordDecl *RD) {
if (ImplicitVirtualDtor) {
// Itanium C++ ABI 2.5.2:
- // If a class has an implicitly-defined virtual destructor,
- // its entries come after the declared virtual function pointers.
+ // If a class has an implicitly-defined virtual destructor,
+ // its entries come after the declared virtual function pointers.
// Add the complete dtor.
MethodVtableIndices[GlobalDecl(ImplicitVirtualDtor, Dtor_Complete)] =