From: Anders Carlsson Date: Sat, 5 Dec 2009 21:28:12 +0000 (+0000) Subject: CodeGenModule::GenerateVtable now returns a pointer directly to the vtable and not... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bb27d868ac3ca429bfe0f52c5f091f849368fff8;p=clang CodeGenModule::GenerateVtable now returns a pointer directly to the vtable and not to the address point. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90676 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index c536350ad4..a2674b82d1 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -1682,8 +1682,7 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, const CXXRecordDecl *ClassDecl = CD->getParent(); // FIXME: Add vbase initialization - llvm::Value *LoadOfThis = 0; - + for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(), E = CD->init_end(); B != E; ++B) { @@ -1705,15 +1704,21 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, if (!ClassDecl->isDynamicClass()) return; - // Initialize the vtable pointer - if (!LoadOfThis) - LoadOfThis = LoadCXXThis(); + // Initialize the vtable pointer. + // FIXME: This needs to initialize secondary vtable pointers too. + llvm::Value *ThisPtr = LoadCXXThis(); - const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); + llvm::Constant *Vtable = CGM.getVtableInfo().getVtable(ClassDecl); + uint64_t AddressPoint = CGM.getVtableInfo().getVtableAddressPoint(ClassDecl); + + llvm::Value *VtableAddressPoint = + Builder.CreateConstInBoundsGEP2_64(Vtable, 0, AddressPoint); + llvm::Value *VtableField = - Builder.CreateBitCast(LoadOfThis, Int8PtrTy->getPointerTo()); - llvm::Value *vtable = CGM.getVtableInfo().getVtable(ClassDecl); - Builder.CreateStore(vtable, VtableField); + Builder.CreateBitCast(ThisPtr, + VtableAddressPoint->getType()->getPointerTo()); + + Builder.CreateStore(VtableAddressPoint, VtableField); } /// EmitDtorEpilogue - Emit all code that comes at the end of class's diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 8bf940b40c..e41712ecf9 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -1155,16 +1155,8 @@ llvm::Constant *CodeGenModule::GenerateVtable(const CXXRecordDecl *LayoutClass, if (Hidden) GV->setVisibility(llvm::GlobalVariable::HiddenVisibility); } - llvm::Constant *vtable = llvm::ConstantExpr::getBitCast(GV, Ptr8Ty); - llvm::Constant *AddressPointC; - uint32_t LLVMPointerWidth = getContext().Target.getPointerWidth(0); - AddressPointC = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), - AddressPoint*LLVMPointerWidth/8); - vtable = llvm::ConstantExpr::getInBoundsGetElementPtr(vtable, &AddressPointC, - 1); - - assert(vtable->getType() == Ptr8Ty); - return vtable; + + return GV; } namespace { @@ -1184,12 +1176,13 @@ class VTTBuilder { llvm::LLVMContext &VMContext; /// BuildVtablePtr - Build up a referene to the given secondary vtable - llvm::Constant *BuildVtablePtr(llvm::Constant *vtbl, - const CXXRecordDecl *VtblClass, + llvm::Constant *BuildVtablePtr(llvm::Constant *Vtable, + const CXXRecordDecl *VtableClass, const CXXRecordDecl *RD, uint64_t Offset) { - int64_t AddressPoint; - AddressPoint = (*AddressPoints[VtblClass])[std::make_pair(RD, Offset)]; + int64_t AddressPoint = + (*AddressPoints[VtableClass])[std::make_pair(RD, Offset)]; + // FIXME: We can never have 0 address point. Do this for now so gepping // retains the same structure. Later we'll just assert. if (AddressPoint == 0) @@ -1197,12 +1190,17 @@ class VTTBuilder { D1(printf("XXX address point for %s in %s layout %s at offset %d was %d\n", RD->getNameAsCString(), VtblClass->getNameAsCString(), Class->getNameAsCString(), (int)Offset, (int)AddressPoint)); - uint32_t LLVMPointerWidth = CGM.getContext().Target.getPointerWidth(0); - llvm::Constant *init; - init = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), - AddressPoint*LLVMPointerWidth/8); - init = llvm::ConstantExpr::getInBoundsGetElementPtr(vtbl, &init, 1); - return init; + + llvm::Value *Idxs[] = { + llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 0), + llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), AddressPoint) + }; + + llvm::Constant *Init = + llvm::ConstantExpr::getInBoundsGetElementPtr(Vtable, Idxs, 2); + + const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); + return llvm::ConstantExpr::getBitCast(Init, Int8PtrTy); } /// Secondary - Add the secondary vtable pointers to Inits. Offset is the @@ -1321,8 +1319,7 @@ public: VMContext(cgm.getModule().getContext()) { // First comes the primary virtual table pointer for the complete class... - ClassVtbl = cast(CGM.getVtableInfo().getVtable(Class) - ->getOperand(0)); + ClassVtbl = CGM.getVtableInfo().getVtable(Class); Inits.push_back(BuildVtablePtr(ClassVtbl, Class, Class, 0)); // then the secondary VTTs... @@ -1423,9 +1420,7 @@ llvm::Constant *CGVtableInfo::getVtable(const CXXRecordDecl *RD) { llvm::Constant *CGVtableInfo::getCtorVtable(const CXXRecordDecl *LayoutClass, const CXXRecordDecl *RD, uint64_t Offset) { - llvm::Constant *Vtable = CGM.GenerateVtable(LayoutClass, RD, Offset); - - return cast(Vtable->getOperand(0)); + return CGM.GenerateVtable(LayoutClass, RD, Offset); } void CGVtableInfo::MaybeEmitVtable(GlobalDecl GD) {