|
@@ -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) {
|