diff options
Diffstat (limited to 'lib/CodeGen/CGVTT.cpp')
-rw-r--r-- | lib/CodeGen/CGVTT.cpp | 73 |
1 files changed, 31 insertions, 42 deletions
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) { |