diff options
author | Anders Carlsson <andersca@mac.com> | 2010-02-16 04:59:55 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-02-16 04:59:55 +0000 |
commit | 852213e54a1b2c2246776b4bb4e9527d70c98807 (patch) | |
tree | 8895f84f84a7a2bda7a9dd9286c6febd049506d8 /lib | |
parent | a661a54d50e33d8b58735ef4ded06b1ad639b165 (diff) |
Emit vbase offsets.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96329 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/CGVtable.cpp | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 9233838c93..970bbd777f 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -912,6 +912,27 @@ VtableBuilder::AddVCallAndVBaseOffsets(const CXXRecordDecl *RD, void VtableBuilder::AddVBaseOffsets(const CXXRecordDecl *RD, int64_t OffsetToTop, VisitedVirtualBasesSetTy &VBases) { + const ASTRecordLayout &MostDerivedClassLayout = + Context.getASTRecordLayout(MostDerivedClass); + + // Add vbase offsets. + for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), + E = RD->bases_end(); I != E; ++I) { + const CXXRecordDecl *BaseDecl = + cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); + + // Check if this is a virtual base that we haven't visited before. + if (I->isVirtual() && VBases.insert(BaseDecl)) { + // FIXME: We shouldn't use / 8 here. + uint64_t Offset = + OffsetToTop + MostDerivedClassLayout.getVBaseClassOffset(BaseDecl) / 8; + + VCallAndVBaseOffsets.push_back(VtableComponent::MakeVBaseOffset(Offset)); + } + + // Check the base class looking for more vbase offsets. + AddVBaseOffsets(BaseDecl, OffsetToTop, VBases); + } } void @@ -1008,13 +1029,22 @@ VtableBuilder::AddMethods(BaseSubobject Base, PrimaryBasesSetTy &PrimaryBases) { void VtableBuilder::LayoutVtable(BaseSubobject Base) { const CXXRecordDecl *RD = Base.getBase(); - assert(RD->isDynamicClass() && "class does not have a vtable!"); - // First, add the offset to top. + int64_t OffsetToTop = -(int64_t)Base.getBaseOffset() / 8; + + // Add vcall and vbase offsets for this vtable. + VisitedVirtualBasesSetTy VBases; + AddVCallAndVBaseOffsets(RD, OffsetToTop, VBases); + + // Reverse them and add them to the vtable components. + std::reverse(VCallAndVBaseOffsets.begin(), VCallAndVBaseOffsets.end()); + Components.append(VCallAndVBaseOffsets.begin(), VCallAndVBaseOffsets.end()); + VCallAndVBaseOffsets.clear(); + + // Add the offset to top. // FIXME: This is not going to be right for construction vtables. // FIXME: We should not use / 8 here. - int64_t OffsetToTop = -(int64_t)Base.getBaseOffset() / 8; Components.push_back(VtableComponent::MakeOffsetToTop(OffsetToTop)); // Next, add the RTTI. @@ -1137,7 +1167,11 @@ void VtableBuilder::dumpLayout(llvm::raw_ostream& Out) { default: assert(false && "Unhandled component kind!"); break; - + + case VtableComponent::CK_VBaseOffset: + Out << "vbase_offset (" << Component.getVBaseOffset() << ")"; + break; + case VtableComponent::CK_OffsetToTop: Out << "offset_to_top (" << Component.getOffsetToTop() << ")"; break; |