diff --git a/clang/lib/CodeGen/CGVTT.cpp b/clang/lib/CodeGen/CGVTT.cpp index 3bc41e52544f..a6849f8f3d21 100644 --- a/clang/lib/CodeGen/CGVTT.cpp +++ b/clang/lib/CodeGen/CGVTT.cpp @@ -53,6 +53,10 @@ class VTTBuilder { /// GenerateDefinition - Whether the VTT builder should generate LLVM IR for /// the VTT. bool GenerateDefinition; + + /// The linkage to use for any construction vtables required by this VTT. + /// Only required if we're building a definition. + llvm::GlobalVariable::LinkageTypes LinkageForConstructionVTables; /// GetAddrOfVTable - Returns the address of the vtable for the base class in /// the given vtable class. @@ -109,7 +113,9 @@ class VTTBuilder { public: VTTBuilder(CodeGenModule &CGM, const CXXRecordDecl *MostDerivedClass, - bool GenerateDefinition); + bool GenerateDefinition, + llvm::GlobalVariable::LinkageTypes LinkageForConstructionVTables + = (llvm::GlobalVariable::LinkageTypes) -1); // getVTTComponents - Returns a reference to the VTT components. const VTTComponentsVectorTy &getVTTComponents() const { @@ -132,10 +138,15 @@ public: VTTBuilder::VTTBuilder(CodeGenModule &CGM, const CXXRecordDecl *MostDerivedClass, - bool GenerateDefinition) + bool GenerateDefinition, + llvm::GlobalVariable::LinkageTypes LinkageForConstructionVTables) : CGM(CGM), MostDerivedClass(MostDerivedClass), MostDerivedClassLayout(CGM.getContext().getASTRecordLayout(MostDerivedClass)), - GenerateDefinition(GenerateDefinition) { + GenerateDefinition(GenerateDefinition), + LinkageForConstructionVTables(LinkageForConstructionVTables) { + assert(!GenerateDefinition || + LinkageForConstructionVTables + != (llvm::GlobalVariable::LinkageTypes) -1); // Lay out this VTT. LayoutVTT(BaseSubobject(MostDerivedClass, CharUnits::Zero()), @@ -157,6 +168,7 @@ VTTBuilder::GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual, return CGM.getVTables().GenerateConstructionVTable(MostDerivedClass, Base, BaseIsVirtual, + LinkageForConstructionVTables, AddressPoints); } @@ -371,7 +383,7 @@ void CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT, llvm::GlobalVariable::LinkageTypes Linkage, const CXXRecordDecl *RD) { - VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/true); + VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/true, Linkage); const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); const llvm::ArrayType *ArrayType = diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 6c1b331be781..17d3cde8b0f3 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -3065,6 +3065,7 @@ llvm::GlobalVariable * CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base, bool BaseIsVirtual, + llvm::GlobalVariable::LinkageTypes Linkage, VTableAddressPointsMapTy& AddressPoints) { VTableBuilder Builder(*this, Base.getBase(), CGM.getContext().toBits(Base.getBaseOffset()), @@ -3093,8 +3094,11 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, // Create the variable that will hold the construction vtable. llvm::GlobalVariable *VTable = - CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, - llvm::GlobalValue::InternalLinkage); + CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, Linkage); + CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForConstructionVTable); + + // V-tables are always unnamed_addr. + VTable->setUnnamedAddr(true); // Add the thunks. VTableThunksTy VTableThunks; diff --git a/clang/lib/CodeGen/CGVTables.h b/clang/lib/CodeGen/CGVTables.h index 7197a57298d0..b2f940185858 100644 --- a/clang/lib/CodeGen/CGVTables.h +++ b/clang/lib/CodeGen/CGVTables.h @@ -1,4 +1,4 @@ -//===--- CGVTables.h - Emit LLVM Code for C++ vtables ---------------------===// +//===--- CGVTables.h - Emit LLVM Code for C++ vtables -----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -260,6 +260,7 @@ public: llvm::GlobalVariable * GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base, bool BaseIsVirtual, + llvm::GlobalVariable::LinkageTypes Linkage, VTableAddressPointsMapTy& AddressPoints); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index e6fcf61473e8..aa6a0535a11c 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -313,6 +313,7 @@ public: enum TypeVisibilityKind { TVK_ForVTT, TVK_ForVTable, + TVK_ForConstructionVTable, TVK_ForRTTI, TVK_ForRTTIName }; diff --git a/clang/test/CodeGenCXX/mangle-subst-std.cpp b/clang/test/CodeGenCXX/mangle-subst-std.cpp index 8d79988da8e3..fea3582d321a 100644 --- a/clang/test/CodeGenCXX/mangle-subst-std.cpp +++ b/clang/test/CodeGenCXX/mangle-subst-std.cpp @@ -5,8 +5,8 @@ // CHECK: @_ZTTSd = linkonce_odr unnamed_addr constant // CHECK: @_ZTVSd = linkonce_odr unnamed_addr constant -// CHECK: @_ZTCSd0_Si = internal constant -// CHECK: @_ZTCSd16_So = internal constant +// CHECK: @_ZTCSd0_Si = linkonce_odr unnamed_addr constant +// CHECK: @_ZTCSd16_So = linkonce_odr unnamed_addr constant // CHECK: @_ZTTSo = linkonce_odr unnamed_addr constant // CHECK: @_ZTVSo = linkonce_odr unnamed_addr constant // CHECK: @_ZTTSi = linkonce_odr unnamed_addr constant