diff options
author | Anders Carlsson <andersca@mac.com> | 2011-01-29 19:16:51 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2011-01-29 19:16:51 +0000 |
commit | 1cbce125b91cad81c8be3f8bbae8df917211176c (patch) | |
tree | 069a00838664a0b905a83f260f8a2d05ecd4f586 /lib/CodeGen | |
parent | 96eaf2992b5955d1470fc9cce7a96e7e1e3b4ea7 (diff) |
Make emitting a VTT a two-step process, much like emitting a VTable. You first get the address of the VTT, and then pass it to EmitVTTDefinition.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124539 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGClass.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGRTTI.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGVTT.cpp | 73 | ||||
-rw-r--r-- | lib/CodeGen/CGVTables.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/CGVTables.h | 15 |
5 files changed, 46 insertions, 51 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index a7b8f65978..7efd2bc807 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -318,7 +318,7 @@ static llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD, VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex); } else { // We're the complete constructor, so get the VTT by name. - VTT = CGF.CGM.getVTables().getVTT(RD); + VTT = CGF.CGM.getVTables().GetAddrOfVTT(RD); VTT = CGF.Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex); } diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp index 4ba58c7163..244bca8095 100644 --- a/lib/CodeGen/CGRTTI.cpp +++ b/lib/CodeGen/CGRTTI.cpp @@ -522,7 +522,7 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) { llvm::SmallString<256> OutName; CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, OutName); llvm::StringRef Name = OutName.str(); - + llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name); if (OldGV && !OldGV->isDeclaration()) return llvm::ConstantExpr::getBitCast(OldGV, Int8PtrTy); diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp index 5a99059f1a..5ebe92b539 100644 --- a/lib/CodeGen/CGVTT.cpp +++ b/lib/CodeGen/CGVTT.cpp @@ -366,56 +366,45 @@ void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) { } -llvm::GlobalVariable * -CodeGenVTables::GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage, - bool GenerateDefinition, - const CXXRecordDecl *RD) { - // Only classes that have virtual bases need a VTT. - if (RD->getNumVBases() == 0) - return 0; +void +CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT, + llvm::GlobalVariable::LinkageTypes Linkage, + const CXXRecordDecl *RD) { + VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/true); - llvm::SmallString<256> OutName; - CGM.getCXXABI().getMangleContext().mangleCXXVTT(RD, OutName); - llvm::StringRef Name = OutName.str(); + const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); + const llvm::ArrayType *ArrayType = + llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size()); + + llvm::Constant *Init = + llvm::ConstantArray::get(ArrayType, Builder.getVTTComponents().data(), + Builder.getVTTComponents().size()); - D1(printf("vtt %s\n", RD->getNameAsCString())); + VTT->setInitializer(Init); - llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true); - if (GV == 0 || GV->isDeclaration()) { - const llvm::Type *Int8PtrTy = - llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); + // Set the correct linkage. + VTT->setLinkage(Linkage); +} - VTTBuilder Builder(CGM, RD, GenerateDefinition); +llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) { + assert(RD->getNumVBases() && "Only classes with virtual bases need a VTT"); - const llvm::ArrayType *Type = - llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size()); + llvm::SmallString<256> OutName; + CGM.getCXXABI().getMangleContext().mangleCXXVTT(RD, OutName); + llvm::StringRef Name = OutName.str(); - llvm::Constant *Init = 0; - if (GenerateDefinition) - Init = llvm::ConstantArray::get(Type, Builder.getVTTComponents().data(), - Builder.getVTTComponents().size()); + VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false); - llvm::GlobalVariable *OldGV = GV; - GV = new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true, - Linkage, Init, Name); - CGM.setGlobalVisibility(GV, RD, /*ForDefinition*/ GenerateDefinition); - GV->setUnnamedAddr(true); - - if (OldGV) { - GV->takeName(OldGV); - llvm::Constant *NewPtr = - llvm::ConstantExpr::getBitCast(GV, OldGV->getType()); - OldGV->replaceAllUsesWith(NewPtr); - OldGV->eraseFromParent(); - } - } - - return GV; -} + const llvm::Type *Int8PtrTy = + llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); + const llvm::ArrayType *ArrayType = + llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size()); -llvm::GlobalVariable *CodeGenVTables::getVTT(const CXXRecordDecl *RD) { - return GenerateVTT(llvm::GlobalValue::ExternalLinkage, - /*GenerateDefinition=*/false, RD); + llvm::GlobalVariable *GV = + CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, + llvm::GlobalValue::ExternalLinkage); + GV->setUnnamedAddr(true); + return GV; } bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) { diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp index 0ff41bb354..ad2269418b 100644 --- a/lib/CodeGen/CGVTables.cpp +++ b/lib/CodeGen/CGVTables.cpp @@ -3040,7 +3040,10 @@ CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, VTable = GetAddrOfVTable(RD); EmitVTableDefinition(VTable, Linkage, RD); - GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD); + if (RD->getNumVBases()) { + llvm::GlobalVariable *VTT = GetAddrOfVTT(RD); + EmitVTTDefinition(VTT, Linkage, RD); + } // If this is the magic class __cxxabiv1::__fundamental_type_info, // we will emit the typeinfo for the fundamental types. This is the diff --git a/lib/CodeGen/CGVTables.h b/lib/CodeGen/CGVTables.h index 3e3cd4b165..3aee49372d 100644 --- a/lib/CodeGen/CGVTables.h +++ b/lib/CodeGen/CGVTables.h @@ -182,10 +182,6 @@ class CodeGenVTables { void ComputeMethodVTableIndices(const CXXRecordDecl *RD); - llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage, - bool GenerateDefinition, - const CXXRecordDecl *RD); - /// EmitThunk - Emit a single thunk. void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk); @@ -257,8 +253,15 @@ public: GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base, bool BaseIsVirtual, VTableAddressPointsMapTy& AddressPoints); - - llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD); + + + /// GetAddrOfVTable - Get the address of the VTT for the given record decl. + llvm::GlobalVariable *GetAddrOfVTT(const CXXRecordDecl *RD); + + /// EmitVTTDefinition - Emit the definition of the given vtable. + void EmitVTTDefinition(llvm::GlobalVariable *VTT, + llvm::GlobalVariable::LinkageTypes Linkage, + const CXXRecordDecl *RD); /// EmitThunks - Emit the associated thunks for the given global decl. void EmitThunks(GlobalDecl GD); |