diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGVtable.cpp | 88 | ||||
-rw-r--r-- | lib/CodeGen/CGVtable.h | 12 |
2 files changed, 78 insertions, 22 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index f44b7ccb18..2f725df814 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -3610,16 +3610,24 @@ int64_t CodeGenVTables::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, return I->second; } +static bool UseNewVTableCode = false; + uint64_t CodeGenVTables::getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD) { - const CodeGenVTables::AddrSubMap_t& AddressPoints = getAddressPoints(RD); + // FIXME: Always use the new vtable code once we know it works. + if (!UseNewVTableCode) { + const CodeGenVTables::AddrSubMap_t& AddressPoints = getAddressPoints(RD); - uint64_t AddressPoint = - AddressPoints.lookup(std::make_pair(Base.getBase(), - Base.getBaseOffset())); + uint64_t AddressPoint = + AddressPoints.lookup(std::make_pair(Base.getBase(), + Base.getBaseOffset())); - assert(AddressPoint && "Address point must not be zero!"); + assert(AddressPoint && "Address point must not be zero!"); + } + uint64_t AddressPoint = AddressPoints.lookup(std::make_pair(RD, Base)); + assert(AddressPoint && "Address point must not be zero!"); + return AddressPoint; } @@ -4024,22 +4032,6 @@ void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD) { } } -void -CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, - const CXXRecordDecl *RD) { - llvm::GlobalVariable *&Vtable = Vtables[RD]; - if (Vtable) { - assert(Vtable->getInitializer() && "Vtable doesn't have a definition!"); - return; - } - - llvm::DenseMap<BaseSubobject, uint64_t> AddressPoints; - Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0, - /*IsVirtual=*/false, - AddressPoints); - GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD); -} - llvm::Constant * CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD, const uint64_t *Components, @@ -4176,6 +4168,8 @@ GetGlobalVariable(llvm::Module &Module, llvm::StringRef Name, return GV; } +// FIXME: When the new code is in place, we can change this to return a +// GlobalVariable. llvm::Constant *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) { llvm::SmallString<256> OutName; CGM.getMangleContext().mangleCXXVtable(RD, OutName); @@ -4186,7 +4180,12 @@ llvm::Constant *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) { const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); llvm::ArrayType *ArrayType = llvm::ArrayType::get(Int8PtrTy, getNumVTableComponents(RD)); - + + // FIXME: Always use the new vtable code once we know it works. + if (UseNewVTableCode) + return GetGlobalVariable(CGM.getModule(), Name, ArrayType, + llvm::GlobalValue::ExternalLinkage); + llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name); if (GV) { if (!GV->isDeclaration() || GV->getType()->getElementType() == ArrayType) @@ -4201,6 +4200,29 @@ llvm::Constant *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) { return GV; } +void +CodeGenVTables::EmitVTableDefinition(llvm::GlobalVariable *VTable, + llvm::GlobalVariable::LinkageTypes Linkage, + const CXXRecordDecl *RD) { + // Dump the vtable layout if necessary. + if (CGM.getLangOptions().DumpVtableLayouts) { + VtableBuilder Builder(*this, RD, 0, /*MostDerivedClassIsVirtual=*/0, RD); + + Builder.dumpLayout(llvm::errs()); + } + + assert(VTableThunksMap.count(RD) && + "No thunk status for this record decl!"); + + const VTableThunksTy& Thunks = VTableThunksMap[RD]; + + // Create and set the initializer. + llvm::Constant *Init = + CreateVTableInitializer(RD, getVTableComponentsData(RD), + getNumVTableComponents(RD), Thunks); + VTable->setInitializer(Init); +} + llvm::GlobalVariable * CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base, @@ -4250,6 +4272,28 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, return VTable; } +void +CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, + const CXXRecordDecl *RD) { + llvm::GlobalVariable *&VTable = Vtables[RD]; + if (VTable) { + assert(VTable->getInitializer() && "Vtable doesn't have a definition!"); + return; + } + + // FIXME: Always use the new vtable code once we know it works. + if (UseNewVTableCode) { + VTable = cast<llvm::GlobalVariable>(GetAddrOfVTable(RD)); + EmitVTableDefinition(VTable, Linkage, RD); + } else { + llvm::DenseMap<BaseSubobject, uint64_t> AddressPoints; + VTable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0, + /*IsVirtual=*/false, + AddressPoints); + } + GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD); +} + void CodeGenVTables::EmitVTableRelatedData(GlobalDecl GD) { const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); const CXXRecordDecl *RD = MD->getParent(); diff --git a/lib/CodeGen/CGVtable.h b/lib/CodeGen/CGVtable.h index 6dd37a4902..6a37eb26d1 100644 --- a/lib/CodeGen/CGVtable.h +++ b/lib/CodeGen/CGVtable.h @@ -292,6 +292,13 @@ private: return VTableLayoutMap.lookup(RD)[0]; } + const uint64_t *getVTableComponentsData(const CXXRecordDecl *RD) const { + assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!"); + + uint64_t *Components = VTableLayoutMap.lookup(RD); + return &Components[1]; + } + typedef llvm::DenseMap<ClassPairTy, uint64_t> SubVTTIndiciesMapTy; /// SubVTTIndicies - Contains indices into the various sub-VTTs. @@ -380,6 +387,11 @@ public: /// GetAddrOfVTable - Get the address of the vtable for the given record decl. llvm::Constant *GetAddrOfVTable(const CXXRecordDecl *RD); + /// EmitVTableDefinition - Emit the definition of the given vtable. + void EmitVTableDefinition(llvm::GlobalVariable *VTable, + llvm::GlobalVariable::LinkageTypes Linkage, + const CXXRecordDecl *RD); + /// GenerateConstructionVTable - Generate a construction vtable for the given /// base subobject. llvm::GlobalVariable * |