From e87fae9afa223534d48da8ea3f9462ef297aff42 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sun, 28 Mar 2010 19:40:00 +0000 Subject: [PATCH] Factor vtable pointer setting code out into a separate function. llvm-svn: 99773 --- clang/lib/CodeGen/CGClass.cpp | 53 +++++++++++++++++------------ clang/lib/CodeGen/CodeGenFunction.h | 14 +++++++- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 8a084926e76a..2fa583728953 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -139,7 +139,7 @@ CodeGenFunction::GetAddressOfBaseOfCompleteClass(llvm::Value *This, V = Builder.CreateBitCast(V, ConvertType(Base)->getPointerTo()); return V; -} +} llvm::Value * CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, @@ -1556,6 +1556,34 @@ CodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This, return VBaseOffset; } +void +CodeGenFunction::InitializeVTablePointer(BaseSubobject Base, + bool BaseIsMorallyVirtual, + llvm::Constant *VTable, + const CXXRecordDecl *VTableClass) { + + // Compute the address point. + const CodeGenVTables::AddrSubMap_t& AddressPoints = + CGM.getVTables().getAddressPoints(VTableClass); + + uint64_t AddressPoint = + AddressPoints.lookup(std::make_pair(Base.getBase(), Base.getBaseOffset())); + llvm::Value *VTableAddressPoint = + Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint); + + // Compute where to store the address point. + const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); + llvm::Value *VTableField = Builder.CreateBitCast(LoadCXXThis(), Int8PtrTy); + VTableField = + Builder.CreateConstInBoundsGEP1_64(VTableField, Base.getBaseOffset() / 8); + + // Finally, store the address point. + const llvm::Type *AddressPointPtrTy = + VTableAddressPoint->getType()->getPointerTo(); + VTableField = Builder.CreateBitCast(VTableField, AddressPointPtrTy); + Builder.CreateStore(VTableAddressPoint, VTableField); +} + void CodeGenFunction::InitializeVtablePtrs(const CXXRecordDecl *RD) { if (!RD->isDynamicClass()) return; @@ -1607,25 +1635,8 @@ void CodeGenFunction::InitializeVtablePtrs(BaseSubobject Base, InitializeVtablePtrs(BaseSubobject(BaseDecl, BaseOffset), VTable, VTableClass); } - - // Compute the address point. - const CodeGenVTables::AddrSubMap_t& AddressPoints = - CGM.getVTables().getAddressPoints(VTableClass); - - uint64_t AddressPoint = - AddressPoints.lookup(std::make_pair(Base.getBase(), Base.getBaseOffset())); - llvm::Value *VTableAddressPoint = - Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint); - // Compute where to store the address point. - const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); - llvm::Value *VTableField = Builder.CreateBitCast(LoadCXXThis(), Int8PtrTy); - VTableField = - Builder.CreateConstInBoundsGEP1_64(VTableField, Base.getBaseOffset() / 8); - - // Finally, store the address point. - const llvm::Type *AddressPointPtrTy = - VTableAddressPoint->getType()->getPointerTo(); - VTableField = Builder.CreateBitCast(VTableField, AddressPointPtrTy); - Builder.CreateStore(VTableAddressPoint, VTableField); + // FIXME: BaseIsMorallyVirtual is not correct here. + InitializeVTablePointer(Base, /*BaseIsMorallyVirtual=*/false, VTable, + VTableClass); } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 4ecb03dca05d..3d7165b0a977 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -509,11 +509,23 @@ public: void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type); - void InitializeVtablePtrs(const CXXRecordDecl *ClassDecl); + /// InitializeVTablePointer - Initialize the vtable pointer of the given + /// subobject. + /// + /// \param BaseIsMorallyVirtual - Whether the base subobject is a virtual base + /// or a direct or indirect base of a virtual base. + void InitializeVTablePointer(BaseSubobject Base, bool BaseIsMorallyVirtual, + llvm::Constant *VTable, + const CXXRecordDecl *VTableClass); + + typedef llvm::SmallPtrSet VisitedVirtualBasesSetTy; void InitializeVtablePtrs(BaseSubobject Base, llvm::Constant *VTable, const CXXRecordDecl *VTableClass); + void InitializeVtablePtrs(const CXXRecordDecl *ClassDecl); + + void SynthesizeCXXCopyConstructor(const FunctionArgList &Args); void SynthesizeCXXCopyAssignment(const FunctionArgList &Args);