diff options
author | Anders Carlsson <andersca@mac.com> | 2009-10-06 22:43:30 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-10-06 22:43:30 +0000 |
commit | 2f1986b557fa671c4f8c9dd0d071398edfc073d5 (patch) | |
tree | a831fa1ba773c48b8992faf0086a80ec29a4f01d /lib/CodeGen/CGCXX.cpp | |
parent | ff38915e02f56a5077788bca1e9274d43f05e360 (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.cpp | 54 |
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. |