Author: andersca Date: Mon Feb 15 22:59:55 2010 New Revision: 96329 URL: http://llvm.org/viewvc/llvm-project?rev=96329&view=rev Log: Emit vbase offsets.
Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp cfe/trunk/test/CodeGenCXX/vtable-layout.cpp Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=96329&r1=96328&r2=96329&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGVtable.cpp (original) +++ cfe/trunk/lib/CodeGen/CGVtable.cpp Mon Feb 15 22:59:55 2010 @@ -912,6 +912,27 @@ 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 @@ 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 @@ 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; Modified: cfe/trunk/test/CodeGenCXX/vtable-layout.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vtable-layout.cpp?rev=96329&r1=96328&r2=96329&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/vtable-layout.cpp (original) +++ cfe/trunk/test/CodeGenCXX/vtable-layout.cpp Mon Feb 15 22:59:55 2010 @@ -340,3 +340,28 @@ void B::f() { } } + +namespace Test9 { + +// Simple test of vbase offsets. + +struct A1 { int a1; }; +struct A2 { int a2; }; + +// CHECK: Vtable for 'Test9::B' (5 entries). +// CHECK-NEXT: 0 | vbase_offset (16) +// CHECK-NEXT: 1 | vbase_offset (12) +// CHECK-NEXT: 2 | offset_to_top (0) +// CHECK-NEXT: 3 | Test9::B RTTI +// CHECK-NEXT: -- (Test9::B, 0) vtable address -- +// CHECK-NEXT: 4 | void Test9::B::f() +struct B : virtual A1, virtual A2 { + int b; + + virtual void f(); +}; + + +void B::f() { } + +} _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits