aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGCXX.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-10-06 22:43:30 +0000
committerAnders Carlsson <andersca@mac.com>2009-10-06 22:43:30 +0000
commit2f1986b557fa671c4f8c9dd0d071398edfc073d5 (patch)
treea831fa1ba773c48b8992faf0086a80ec29a4f01d /lib/CodeGen/CGCXX.cpp
parentff38915e02f56a5077788bca1e9274d43f05e360 (diff)
Change GetAddressCXXOfBaseClass to use CXXBasePaths for calculating base class offsets. Fix the code to handle virtual bases as well.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83426 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
-rw-r--r--lib/CodeGen/CGCXX.cpp54
1 files changed, 46 insertions, 8 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index a119c5af93..20b2bdcd5e 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -782,8 +782,8 @@ public:
return i->second;
// FIXME: temporal botch, is this data here, by the time we need it?
- // FIXME: Locate the containing virtual base first.
- return 42;
+ assert(false && "FIXME: Locate the containing virtual base first");
+ return 0;
}
bool OverrideMethod(const CXXMethodDecl *MD, llvm::Constant *m,
@@ -888,18 +888,26 @@ public:
const CXXRecordDecl *RD = i->first;
int64_t Offset = i->second;
for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
- ++mi)
- if (mi->isVirtual()) {
- const CXXMethodDecl *MD = *mi;
+ ++mi) {
+ if (!mi->isVirtual())
+ continue;
+
+ const CXXMethodDecl *MD = *mi;
+ llvm::Constant *m = 0;
+// if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(MD))
+// m = wrap(CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete));
+// else {
const FunctionProtoType *FPT =
MD->getType()->getAs<FunctionProtoType>();
const llvm::Type *Ty =
CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
FPT->isVariadic());
- llvm::Constant *m = wrap(CGM.GetAddrOfFunction(MD, Ty));
- OverrideMethod(MD, m, MorallyVirtual, Offset);
- }
+ m = wrap(CGM.GetAddrOfFunction(MD, Ty));
+// }
+
+ OverrideMethod(MD, m, MorallyVirtual, Offset);
+ }
}
}
@@ -1323,6 +1331,36 @@ llvm::Constant *CodeGenModule::BuildCovariantThunk(const CXXMethodDecl *MD,
}
llvm::Value *
+CodeGenFunction::GetVirtualCXXBaseClassOffset(llvm::Value *This,
+ const CXXRecordDecl *ClassDecl,
+ const CXXRecordDecl *BaseClassDecl) {
+ // FIXME: move to Context
+ if (vtableinfo == 0)
+ vtableinfo = new VtableInfo(CGM);
+
+ const llvm::Type *Int8PtrTy =
+ llvm::Type::getInt8Ty(VMContext)->getPointerTo();
+
+ llvm::Value *VTablePtr = Builder.CreateBitCast(This,
+ Int8PtrTy->getPointerTo());
+ VTablePtr = Builder.CreateLoad(VTablePtr, "vtable");
+
+ llvm::Value *VBaseOffsetPtr =
+ Builder.CreateConstGEP1_64(VTablePtr,
+ vtableinfo->VBlookup(ClassDecl, BaseClassDecl),
+ "vbase.offset.ptr");
+ const llvm::Type *PtrDiffTy =
+ ConvertType(getContext().getPointerDiffType());
+
+ VBaseOffsetPtr = Builder.CreateBitCast(VBaseOffsetPtr,
+ PtrDiffTy->getPointerTo());
+
+ llvm::Value *VBaseOffset = Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset");
+
+ return VBaseOffset;
+}
+
+llvm::Value *
CodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *&This,
const llvm::Type *Ty) {
// FIXME: If we know the dynamic type, we don't have to do a virtual dispatch.