summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGVtable.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-02-16 04:59:55 +0000
committerAnders Carlsson <andersca@mac.com>2010-02-16 04:59:55 +0000
commit77904f1d5b03a453b116c3fe73437549c900f889 (patch)
tree91ebfb951e44e1c1fc977c3918c704ed562fe466 /clang/lib/CodeGen/CGVtable.cpp
parentdc2dba306ce6de717fc2f38c8e8519061ac3f90d (diff)
downloadbcm5719-llvm-77904f1d5b03a453b116c3fe73437549c900f889.tar.gz
bcm5719-llvm-77904f1d5b03a453b116c3fe73437549c900f889.zip
Emit vbase offsets.
llvm-svn: 96329
Diffstat (limited to 'clang/lib/CodeGen/CGVtable.cpp')
-rw-r--r--clang/lib/CodeGen/CGVtable.cpp42
1 files changed, 38 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp
index 9233838c93b..970bbd777f1 100644
--- a/clang/lib/CodeGen/CGVtable.cpp
+++ b/clang/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;
OpenPOWER on IntegriCloud