diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGClass.cpp | 12 | ||||
-rw-r--r-- | lib/CodeGen/CGVTT.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGVtable.cpp | 41 | ||||
-rw-r--r-- | lib/CodeGen/CGVtable.h | 11 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 2 |
5 files changed, 48 insertions, 20 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 4d5fdfe06e..af846329af 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -1560,9 +1560,10 @@ void CodeGenFunction::InitializeVtablePtrs(const CXXRecordDecl *ClassDecl) { if (!ClassDecl->isDynamicClass()) return; - llvm::Constant *VTable = CGM.getVTables().getVtable(ClassDecl); - CodeGenVTables::AddrSubMap_t& AddressPoints = - *(*CGM.getVTables().AddressPoints[ClassDecl])[ClassDecl]; + llvm::Constant *VTable = CGM.getVTables().getAddrOfVTable(ClassDecl); + const CodeGenVTables::AddrSubMap_t& AddressPoints = + CGM.getVTables().getAddressPoints(ClassDecl); + llvm::Value *ThisPtr = LoadCXXThis(); const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl); @@ -1584,7 +1585,7 @@ void CodeGenFunction::InitializeVtablePtrs(const CXXRecordDecl *ClassDecl) { void CodeGenFunction::InitializeVtablePtrsRecursive( const CXXRecordDecl *ClassDecl, llvm::Constant *Vtable, - CodeGenVTables::AddrSubMap_t& AddressPoints, + const CodeGenVTables::AddrSubMap_t& AddressPoints, llvm::Value *ThisPtr, uint64_t Offset) { if (!ClassDecl->isDynamicClass()) @@ -1607,7 +1608,8 @@ void CodeGenFunction::InitializeVtablePtrsRecursive( // Compute the address point assert(AddressPoints.count(std::make_pair(ClassDecl, Offset)) && "Missing address point for class"); - uint64_t AddressPoint = AddressPoints[std::make_pair(ClassDecl, Offset)]; + uint64_t AddressPoint = + AddressPoints.lookup(std::make_pair(ClassDecl, Offset)); llvm::Value *VtableAddressPoint = Builder.CreateConstInBoundsGEP2_64(Vtable, 0, AddressPoint); diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp index 990a5f625d..b7b24b84b6 100644 --- a/lib/CodeGen/CGVTT.cpp +++ b/lib/CodeGen/CGVTT.cpp @@ -268,7 +268,7 @@ public: GenerateDefinition(GenerateDefinition) { // First comes the primary virtual table pointer for the complete class... - ClassVtbl = GenerateDefinition ? CGM.getVTables().getVtable(Class) : 0; + ClassVtbl = GenerateDefinition ? CGM.getVTables().getAddrOfVTable(Class) :0; llvm::Constant *Init = BuildVtablePtr(ClassVtbl, Class, Class, 0); Inits.push_back(Init); diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index f4921699be..c9b099bcd9 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -3551,6 +3551,19 @@ int64_t CodeGenVTables::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, return I->second; } +const CodeGenVTables::AddrSubMap_t & +CodeGenVTables::getAddressPoints(const CXXRecordDecl *RD) { + if (!AddressPoints[RD]) { + AddressPointsMapTy AddressPoints; + OldVtableBuilder b(RD, RD, 0, CGM, false, AddressPoints); + + b.GenerateVtableForBase(RD, 0); + b.GenerateVtableForVBases(RD, 0); + } + + return *(*AddressPoints[RD])[RD]; +} + llvm::GlobalVariable * CodeGenVTables::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage, bool GenerateDefinition, @@ -3583,8 +3596,7 @@ CodeGenVTables::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage, llvm::StringRef Name = OutName.str(); llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); - if (GV == 0 || CGM.getVTables().AddressPoints[LayoutClass] == 0 || - GV->isDeclaration()) { + if (GV == 0 || GV->isDeclaration()) { OldVtableBuilder b(RD, LayoutClass, Offset, CGM, GenerateDefinition, AddressPoints); @@ -3906,17 +3918,26 @@ CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD); } -llvm::GlobalVariable *CodeGenVTables::getVtable(const CXXRecordDecl *RD) { - llvm::GlobalVariable *Vtable = Vtables.lookup(RD); +llvm::Constant *CodeGenVTables::getAddrOfVTable(const CXXRecordDecl *RD) { + llvm::SmallString<256> OutName; + CGM.getMangleContext().mangleCXXVtable(RD, OutName); + llvm::StringRef Name = OutName.str(); + + const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); + llvm::ArrayType *ArrayType = llvm::ArrayType::get(Int8PtrTy, 0); - if (!Vtable) { - AddressPointsMapTy AddressPoints; - Vtable = GenerateVtable(llvm::GlobalValue::ExternalLinkage, - /*GenerateDefinition=*/false, RD, RD, 0, - /*IsVirtual=*/false, AddressPoints); + llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); + if (GV) { + if (!GV->isDeclaration() || GV->getType()->getElementType() == ArrayType) + return GV; + + return llvm::ConstantExpr::getBitCast(GV, ArrayType->getPointerTo()); } + + GV = new llvm::GlobalVariable(CGM.getModule(), ArrayType, /*isConstant=*/true, + llvm::GlobalValue::ExternalLinkage, 0, Name); - return Vtable; + return GV; } void CodeGenVTables::EmitVTableRelatedData(GlobalDecl GD) { diff --git a/lib/CodeGen/CGVtable.h b/lib/CodeGen/CGVtable.h index ebccb514e9..a38153bc4b 100644 --- a/lib/CodeGen/CGVtable.h +++ b/lib/CodeGen/CGVtable.h @@ -222,13 +222,17 @@ public: typedef std::pair<const CXXRecordDecl *, uint64_t> CtorVtable_t; typedef llvm::DenseMap<CtorVtable_t, int64_t> AddrSubMap_t; typedef llvm::DenseMap<const CXXRecordDecl *, AddrSubMap_t *> AddrMap_t; - llvm::DenseMap<const CXXRecordDecl *, AddrMap_t*> AddressPoints; typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy; + const CodeGenVTables::AddrSubMap_t& getAddressPoints(const CXXRecordDecl *RD); + + llvm::DenseMap<const CXXRecordDecl *, AddrMap_t*> AddressPoints; + private: CodeGenModule &CGM; + /// MethodVtableIndices - Contains the index (relative to the vtable address /// point) where the function pointer for a virtual function is stored. typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVtableIndicesTy; @@ -312,8 +316,9 @@ public: int64_t getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase); - llvm::GlobalVariable *getVtable(const CXXRecordDecl *RD); - + /// getAddrOfVTable - Get the address of the vtable for the given record decl. + llvm::Constant *getAddrOfVTable(const CXXRecordDecl *RD); + /// CtorVtableInfo - Information about a constructor vtable. struct CtorVtableInfo { /// Vtable - The vtable itself. diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index cc5104516d..f5c25b275e 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -513,7 +513,7 @@ public: void InitializeVtablePtrsRecursive(const CXXRecordDecl *ClassDecl, llvm::Constant *Vtable, - CodeGenVTables::AddrSubMap_t& AddressPoints, + const CodeGenVTables::AddrSubMap_t& AddressPoints, llvm::Value *ThisPtr, uint64_t Offset); |