Index: lib/CodeGen/CGBlocks.cpp =================================================================== --- lib/CodeGen/CGBlocks.cpp +++ lib/CodeGen/CGBlocks.cpp @@ -1642,7 +1642,7 @@ false, false); - CGM.SetInternalFunctionAttributes(nullptr, Fn, FI); + CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); StartFunction(FD, C.VoidTy, Fn, FI, args); ApplyDebugLocation NL{*this, blockInfo.getBlockExpr()->getLocStart()}; @@ -1812,7 +1812,7 @@ nullptr, SC_Static, false, false); - CGM.SetInternalFunctionAttributes(nullptr, Fn, FI); + CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); StartFunction(FD, C.VoidTy, Fn, FI, args); ApplyDebugLocation NL{*this, blockInfo.getBlockExpr()->getLocStart()}; @@ -2057,7 +2057,7 @@ SC_Static, false, false); - CGF.CGM.SetInternalFunctionAttributes(nullptr, Fn, FI); + CGF.CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); CGF.StartFunction(FD, R, Fn, FI, args); @@ -2131,7 +2131,7 @@ SC_Static, false, false); - CGF.CGM.SetInternalFunctionAttributes(nullptr, Fn, FI); + CGF.CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); CGF.StartFunction(FD, R, Fn, FI, args); Index: lib/CodeGen/CGCXX.cpp =================================================================== --- lib/CodeGen/CGCXX.cpp +++ lib/CodeGen/CGCXX.cpp @@ -205,7 +205,7 @@ } // Finally, set up the alias with its proper name and attributes. - setAliasAttributes(AliasDecl, Alias); + SetCommonAttributes(AliasDecl, Alias); return false; } @@ -227,7 +227,6 @@ } setFunctionLinkage(GD, Fn); - setFunctionDLLStorageClass(GD, Fn); CodeGenFunction(*this).GenerateCode(GD, Fn, FnInfo); setFunctionDefinitionAttributes(GD, Fn); Index: lib/CodeGen/CGCXXABI.h =================================================================== --- lib/CodeGen/CGCXXABI.h +++ lib/CodeGen/CGCXXABI.h @@ -433,6 +433,7 @@ /// base tables. virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD) = 0; + virtual bool exportThunk() = 0; virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD, bool ReturnAdjustment) = 0; Index: lib/CodeGen/CGDecl.cpp =================================================================== --- lib/CodeGen/CGDecl.cpp +++ lib/CodeGen/CGDecl.cpp @@ -247,13 +247,6 @@ if (D.getTLSKind()) setTLSMode(GV, D); - if (D.isExternallyVisible()) { - if (D.hasAttr()) - GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass); - else if (D.hasAttr()) - GV->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass); - } - setGVProperties(GV, &D); // Make sure the result is of the correct type. Index: lib/CodeGen/CGDeclCXX.cpp =================================================================== --- lib/CodeGen/CGDeclCXX.cpp +++ lib/CodeGen/CGDeclCXX.cpp @@ -311,7 +311,7 @@ Fn->setSection(Section); } - SetInternalFunctionAttributes(nullptr, Fn, FI); + SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); Fn->setCallingConv(getRuntimeCC()); Index: lib/CodeGen/CGObjC.cpp =================================================================== --- lib/CodeGen/CGObjC.cpp +++ lib/CodeGen/CGObjC.cpp @@ -3243,7 +3243,7 @@ "__assign_helper_atomic_property_", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(nullptr, Fn, FI); + CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); StartFunction(FD, C.VoidTy, Fn, FI, args); @@ -3324,8 +3324,8 @@ llvm::Function *Fn = llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, "__copy_helper_atomic_property_", &CGM.getModule()); - - CGM.SetInternalFunctionAttributes(nullptr, Fn, FI); + + CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); StartFunction(FD, C.VoidTy, Fn, FI, args); Index: lib/CodeGen/CGObjCGNU.cpp =================================================================== --- lib/CodeGen/CGObjCGNU.cpp +++ lib/CodeGen/CGObjCGNU.cpp @@ -1035,16 +1035,8 @@ const ObjCInterfaceDecl *OID) { auto *Value = GetClassNamed(CGF, OID->getNameAsString(), OID->isWeakImported()); - if (CGM.getTriple().isOSBinFormatCOFF()) { - if (auto *ClassSymbol = dyn_cast(Value)) { - auto DLLStorage = llvm::GlobalValue::DefaultStorageClass; - if (OID->hasAttr()) - DLLStorage = llvm::GlobalValue::DLLExportStorageClass; - else if (OID->hasAttr()) - DLLStorage = llvm::GlobalValue::DLLImportStorageClass; - ClassSymbol->setDLLStorageClass(DLLStorage); - } - } + if (auto *ClassSymbol = dyn_cast(Value)) + CGM.setGVProperties(ClassSymbol, OID); return Value; } @@ -1061,13 +1053,7 @@ if ((VD = dyn_cast(Result))) break; - auto DLLStorage = llvm::GlobalValue::DefaultStorageClass; - if (!VD || VD->hasAttr()) - DLLStorage = llvm::GlobalValue::DLLImportStorageClass; - else if (VD->hasAttr()) - DLLStorage = llvm::GlobalValue::DLLExportStorageClass; - - ClassSymbol->setDLLStorageClass(DLLStorage); + CGM.setGVProperties(ClassSymbol, VD); } } return Value; @@ -2336,14 +2322,8 @@ NULLPtr, NULLPtr, 0x12L, ClassName.c_str(), nullptr, Zeros[0], GenerateIvarList(empty, empty, empty), ClassMethodList, NULLPtr, NULLPtr, NULLPtr, ZeroPtr, ZeroPtr, true); - if (CGM.getTriple().isOSBinFormatCOFF()) { - auto Storage = llvm::GlobalValue::DefaultStorageClass; - if (OID->getClassInterface()->hasAttr()) - Storage = llvm::GlobalValue::DLLImportStorageClass; - else if (OID->getClassInterface()->hasAttr()) - Storage = llvm::GlobalValue::DLLExportStorageClass; - cast(MetaClassStruct)->setDLLStorageClass(Storage); - } + CGM.setGVProperties(cast(MetaClassStruct), + OID->getClassInterface()); // Generate the class structure llvm::Constant *ClassStruct = GenerateClassStructure( @@ -2351,14 +2331,8 @@ llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList, GenerateProtocolList(Protocols), IvarOffsetArray, Properties, StrongIvarBitmap, WeakIvarBitmap); - if (CGM.getTriple().isOSBinFormatCOFF()) { - auto Storage = llvm::GlobalValue::DefaultStorageClass; - if (OID->getClassInterface()->hasAttr()) - Storage = llvm::GlobalValue::DLLImportStorageClass; - else if (OID->getClassInterface()->hasAttr()) - Storage = llvm::GlobalValue::DLLExportStorageClass; - cast(ClassStruct)->setDLLStorageClass(Storage); - } + CGM.setGVProperties(cast(ClassStruct), + OID->getClassInterface()); // Resolve the class aliases, if they exist. if (ClassPtrAlias) { Index: lib/CodeGen/CGObjCMac.cpp =================================================================== --- lib/CodeGen/CGObjCMac.cpp +++ lib/CodeGen/CGObjCMac.cpp @@ -6305,9 +6305,7 @@ llvm::GlobalVariable *MetaTClass = BuildClassObject(CI, /*metaclass*/ true, IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden); - if (CGM.getTriple().isOSBinFormatCOFF()) - if (CI->hasAttr()) - MetaTClass->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + CGM.setGVProperties(MetaTClass, CI); DefinedMetaClasses.push_back(MetaTClass); // Metadata for the class @@ -6347,9 +6345,7 @@ llvm::GlobalVariable *ClassMD = BuildClassObject(CI, /*metaclass*/ false, MetaTClass, SuperClassGV, CLASS_RO_GV, classIsHidden); - if (CGM.getTriple().isOSBinFormatCOFF()) - if (CI->hasAttr()) - ClassMD->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + CGM.setGVProperties(ClassMD, CI); DefinedClasses.push_back(ClassMD); ImplementedClasses.push_back(CI); @@ -7524,12 +7520,7 @@ Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, llvm::GlobalValue::ExternalLinkage, nullptr, EHTypeName); - if (CGM.getTriple().isOSBinFormatCOFF()) { - if (ID->hasAttr()) - Entry->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); - else if (ID->hasAttr()) - Entry->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); - } + CGM.setGVProperties(Entry, ID); return Entry; } } @@ -7568,10 +7559,8 @@ CGM.getPointerAlign(), /*constant*/ false, L); - if (CGM.getTriple().isOSBinFormatCOFF()) - if (hasObjCExceptionAttribute(CGM.getContext(), ID)) - if (ID->hasAttr()) - Entry->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + if (hasObjCExceptionAttribute(CGM.getContext(), ID)) + CGM.setGVProperties(Entry, ID); } assert(Entry->getLinkage() == L); Index: lib/CodeGen/CGOpenMPRuntime.cpp =================================================================== --- lib/CodeGen/CGOpenMPRuntime.cpp +++ lib/CodeGen/CGOpenMPRuntime.cpp @@ -1209,7 +1209,7 @@ auto *Fn = llvm::Function::Create( FnTy, llvm::GlobalValue::InternalLinkage, IsCombiner ? ".omp_combiner." : ".omp_initializer.", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, FnInfo); + CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo); Fn->removeFnAttr(llvm::Attribute::NoInline); Fn->removeFnAttr(llvm::Attribute::OptimizeNone); Fn->addFnAttr(llvm::Attribute::AlwaysInline); @@ -2804,7 +2804,7 @@ auto *Fn = llvm::Function::Create( CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage, ".omp.copyprivate.copy_func", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, CGFI); + CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI); CodeGenFunction CGF(CGM); CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc); // Dest = (void*[n])(LHSArg); @@ -3952,7 +3952,7 @@ auto *TaskEntry = llvm::Function::Create(TaskEntryTy, llvm::GlobalValue::InternalLinkage, ".omp_task_entry.", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(/*D=*/nullptr, TaskEntry, TaskEntryFnInfo); + CGM.SetInternalFunctionAttributes(GlobalDecl(), TaskEntry, TaskEntryFnInfo); CodeGenFunction CGF(CGM); CGF.StartFunction(GlobalDecl(), KmpInt32Ty, TaskEntry, TaskEntryFnInfo, Args, Loc, Loc); @@ -4052,7 +4052,7 @@ auto *DestructorFn = llvm::Function::Create(DestructorFnTy, llvm::GlobalValue::InternalLinkage, ".omp_task_destructor.", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(/*D=*/nullptr, DestructorFn, + CGM.SetInternalFunctionAttributes(GlobalDecl(), DestructorFn, DestructorFnInfo); CodeGenFunction CGF(CGM); CGF.StartFunction(GlobalDecl(), KmpInt32Ty, DestructorFn, DestructorFnInfo, @@ -4142,7 +4142,7 @@ auto *TaskPrivatesMap = llvm::Function::Create( TaskPrivatesMapTy, llvm::GlobalValue::InternalLinkage, ".omp_task_privates_map.", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(/*D=*/nullptr, TaskPrivatesMap, + CGM.SetInternalFunctionAttributes(GlobalDecl(), TaskPrivatesMap, TaskPrivatesMapFnInfo); TaskPrivatesMap->removeFnAttr(llvm::Attribute::NoInline); TaskPrivatesMap->removeFnAttr(llvm::Attribute::OptimizeNone); @@ -4330,7 +4330,7 @@ auto *TaskDup = llvm::Function::Create(TaskDupTy, llvm::GlobalValue::InternalLinkage, ".omp_task_dup.", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(/*D=*/nullptr, TaskDup, TaskDupFnInfo); + CGM.SetInternalFunctionAttributes(GlobalDecl(), TaskDup, TaskDupFnInfo); CodeGenFunction CGF(CGM); CGF.StartFunction(GlobalDecl(), C.VoidTy, TaskDup, TaskDupFnInfo, Args, Loc, Loc); @@ -4972,7 +4972,7 @@ auto *Fn = llvm::Function::Create( CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage, ".omp.reduction.reduction_func", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, CGFI); + CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI); CodeGenFunction CGF(CGM); CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc); @@ -5387,7 +5387,7 @@ auto *FnTy = CGM.getTypes().GetFunctionType(FnInfo); auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage, ".red_init.", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, FnInfo); + CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo); CodeGenFunction CGF(CGM); CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc); Address PrivateAddr = CGF.EmitLoadOfPointer( @@ -5459,7 +5459,7 @@ auto *FnTy = CGM.getTypes().GetFunctionType(FnInfo); auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage, ".red_comb.", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, FnInfo); + CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo); CodeGenFunction CGF(CGM); CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc); llvm::Value *Size = nullptr; @@ -5527,7 +5527,7 @@ auto *FnTy = CGM.getTypes().GetFunctionType(FnInfo); auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage, ".red_fini.", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, FnInfo); + CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo); CodeGenFunction CGF(CGM); CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc); Address PrivateAddr = CGF.EmitLoadOfPointer( Index: lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp =================================================================== --- lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp +++ lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -263,7 +263,7 @@ WorkerFn = llvm::Function::Create( CGM.getTypes().GetFunctionType(*CGFI), llvm::GlobalValue::InternalLinkage, /*placeholder=*/"_worker", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(/*D=*/nullptr, WorkerFn, *CGFI); + CGM.SetInternalFunctionAttributes(GlobalDecl(), WorkerFn, *CGFI); } bool CGOpenMPRuntimeNVPTX::isInSpmdExecutionMode() const { @@ -1369,7 +1369,7 @@ auto *Fn = llvm::Function::Create( CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage, "_omp_reduction_load_and_reduce", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(/*DC=*/nullptr, Fn, CGFI); + CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI); CodeGenFunction CGF(CGM); CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc); @@ -1490,7 +1490,7 @@ auto *Fn = llvm::Function::Create( CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage, "_omp_reduction_copy_to_scratchpad", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(/*DC=*/nullptr, Fn, CGFI); + CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI); CodeGenFunction CGF(CGM); CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc); @@ -1571,7 +1571,7 @@ auto *Fn = llvm::Function::Create( CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage, "_omp_reduction_inter_warp_copy_func", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(/*DC=*/nullptr, Fn, CGFI); + CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI); CodeGenFunction CGF(CGM); CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc); @@ -1821,7 +1821,7 @@ auto *Fn = llvm::Function::Create( CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage, "_omp_reduction_shuffle_and_reduce_func", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, CGFI); + CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI); CodeGenFunction CGF(CGM); CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc); @@ -2454,7 +2454,7 @@ auto *Fn = llvm::Function::Create( CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage, OutlinedParallelFn->getName() + "_wrapper", &CGM.getModule()); - CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, CGFI); + CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI); Fn->setLinkage(llvm::GlobalValue::InternalLinkage); CodeGenFunction CGF(CGM, /*suppressNewContext=*/true); Index: lib/CodeGen/CGVTables.cpp =================================================================== --- lib/CodeGen/CGVTables.cpp +++ lib/CodeGen/CGVTables.cpp @@ -57,7 +57,12 @@ !Thunk.Return.isEmpty()); // Set the right visibility. - CGM.setGVProperties(ThunkFn, cast(GD.getDecl())); + CGM.setGVProperties(ThunkFn, GD); + + if (!CGM.getCXXABI().exportThunk()) { + ThunkFn->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); + ThunkFn->setDSOLocal(true); + } if (CGM.supportsCOMDAT() && ThunkFn->isWeakForLinker()) ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName())); Index: lib/CodeGen/CodeGenModule.h =================================================================== --- lib/CodeGen/CodeGenModule.h +++ lib/CodeGen/CodeGenModule.h @@ -721,11 +721,16 @@ /// Set the visibility for the given LLVM GlobalValue. void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D) const; + void setGlobalVisibilityAndLocal(llvm::GlobalValue *GV, + const NamedDecl *D) const; + void setDSOLocal(llvm::GlobalValue *GV) const; - /// Set visibility and dso_local. + void setDLLImportDLLExport(llvm::GlobalValue *GV, GlobalDecl D) const; + void setDLLImportDLLExport(llvm::GlobalValue *GV, const NamedDecl *D) const; + /// Set visibility, dllimport/dllexport and dso_local. /// This must be called after dllimport/dllexport is set. - /// FIXME: should this set dllimport/dllexport instead? + void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const; void setGVProperties(llvm::GlobalValue *GV, const NamedDecl *D) const; /// Set the TLS mode for the given LLVM GlobalValue for the thread-local @@ -1017,7 +1022,7 @@ /// Set the attributes on the LLVM function for the given decl and function /// info. This applies attributes necessary for handling the ABI as well as /// user specified attributes like section. - void SetInternalFunctionAttributes(const Decl *D, llvm::Function *F, + void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI); /// Set the LLVM function attributes (sext, zext, etc). @@ -1108,9 +1113,6 @@ F->setLinkage(getFunctionLinkage(GD)); } - /// Set the DLL storage class on F. - void setFunctionDLLStorageClass(GlobalDecl GD, llvm::Function *F); - /// Return the appropriate linkage for the vtable, VTT, and type information /// of the given class. llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD); @@ -1191,13 +1193,7 @@ /// Objective-C method, function, global variable). /// /// NOTE: This should only be called for definitions. - void SetCommonAttributes(const Decl *D, llvm::GlobalValue *GV); - - /// Set attributes which must be preserved by an alias. This includes common - /// attributes (i.e. it includes a call to SetCommonAttributes). - /// - /// NOTE: This should only be called for definitions. - void setAliasAttributes(GlobalDecl GD, llvm::GlobalValue *GV); + void SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV); void addReplacement(StringRef Name, llvm::Constant *C); @@ -1277,7 +1273,7 @@ bool GetCPUAndFeaturesAttributes(const Decl *D, llvm::AttrBuilder &AttrBuilder); - void setNonAliasAttributes(const Decl *D, llvm::GlobalObject *GO); + void setNonAliasAttributes(GlobalDecl GD, llvm::GlobalObject *GO); /// Set function attributes for a function declaration. void SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -777,8 +777,43 @@ GV->setDSOLocal(true); } +void CodeGenModule::setDLLImportDLLExport(llvm::GlobalValue *GV, + GlobalDecl GD) const { + const auto *D = dyn_cast(GD.getDecl()); + if (const auto *Dtor = dyn_cast_or_null(D)) { + if (getCXXABI().useThunkForDtorVariant(Dtor, GD.getDtorType())) { + // Don't dllexport/import destructor thunks. + GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); + return; + } + } + setDLLImportDLLExport(GV, D); +} + +void CodeGenModule::setDLLImportDLLExport(llvm::GlobalValue *GV, + const NamedDecl *D) const { + if (D->isExternallyVisible()) { + if (D->hasAttr()) + GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass); + else if (D->hasAttr() && !GV->isDeclarationForLinker()) + GV->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass); + } +} + +void CodeGenModule::setGVProperties(llvm::GlobalValue *GV, + GlobalDecl GD) const { + setDLLImportDLLExport(GV, GD); + setGlobalVisibilityAndLocal(GV, dyn_cast(GD.getDecl())); +} + void CodeGenModule::setGVProperties(llvm::GlobalValue *GV, const NamedDecl *D) const { + setDLLImportDLLExport(GV, D); + setGlobalVisibilityAndLocal(GV, D); +} + +void CodeGenModule::setGlobalVisibilityAndLocal(llvm::GlobalValue *GV, + const NamedDecl *D) const { setGlobalVisibility(GV, D); setDSOLocal(GV); } @@ -1054,25 +1089,6 @@ return getLLVMLinkageForDeclarator(D, Linkage, /*isConstantVariable=*/false); } -void CodeGenModule::setFunctionDLLStorageClass(GlobalDecl GD, llvm::Function *F) { - const auto *FD = cast(GD.getDecl()); - - if (const auto *Dtor = dyn_cast_or_null(FD)) { - if (getCXXABI().useThunkForDtorVariant(Dtor, GD.getDtorType())) { - // Don't dllexport/import destructor thunks. - F->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); - return; - } - } - - if (FD->hasAttr()) - F->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass); - else if (FD->hasAttr()) - F->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass); - else - F->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass); -} - llvm::ConstantInt *CodeGenModule::CreateCrossDsoCfiTypeId(llvm::Metadata *MD) { llvm::MDString *MDS = dyn_cast(MD); if (!MDS) return nullptr; @@ -1082,7 +1098,7 @@ void CodeGenModule::setFunctionDefinitionAttributes(GlobalDecl GD, llvm::Function *F) { - setNonAliasAttributes(GD.getDecl(), F); + setNonAliasAttributes(GD, F); } void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D, @@ -1237,10 +1253,10 @@ CreateFunctionTypeMetadata(FD, F); } -void CodeGenModule::SetCommonAttributes(const Decl *D, - llvm::GlobalValue *GV) { - if (const auto *ND = dyn_cast_or_null(D)) - setGVProperties(GV, ND); +void CodeGenModule::SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV) { + const Decl *D = GD.getDecl(); + if (dyn_cast_or_null(D)) + setGVProperties(GV, GD); else GV->setVisibility(llvm::GlobalValue::DefaultVisibility); @@ -1248,16 +1264,6 @@ addUsedGlobal(GV); } -void CodeGenModule::setAliasAttributes(GlobalDecl GD, llvm::GlobalValue *GV) { - const Decl *D = GD.getDecl(); - SetCommonAttributes(D, GV); - - // Process the dllexport attribute based on whether the original definition - // (not necessarily the aliasee) was exported. - if (D->hasAttr()) - GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); -} - bool CodeGenModule::GetCPUAndFeaturesAttributes(const Decl *D, llvm::AttrBuilder &Attrs) { // Add target-cpu and target-features attributes to functions. If @@ -1304,9 +1310,10 @@ return AddedAttr; } -void CodeGenModule::setNonAliasAttributes(const Decl *D, +void CodeGenModule::setNonAliasAttributes(GlobalDecl GD, llvm::GlobalObject *GO) { - SetCommonAttributes(D, GO); + const Decl *D = GD.getDecl(); + SetCommonAttributes(GD, GO); if (D) { if (auto *GV = dyn_cast(GO)) { @@ -1341,35 +1348,27 @@ getTargetCodeGenInfo().setTargetAttributes(D, GO, *this); } -void CodeGenModule::SetInternalFunctionAttributes(const Decl *D, +void CodeGenModule::SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI) { + const Decl *D = GD.getDecl(); SetLLVMFunctionAttributes(D, FI, F); SetLLVMFunctionAttributesForDefinition(D, F); F->setLinkage(llvm::Function::InternalLinkage); - setNonAliasAttributes(D, F); + setNonAliasAttributes(GD, F); } -static void setLinkageForGV(llvm::GlobalValue *GV, - const NamedDecl *ND) { +static void setLinkageForGV(llvm::GlobalValue *GV, const NamedDecl *ND) { // Set linkage and visibility in case we never see a definition. LinkageInfo LV = ND->getLinkageAndVisibility(); - if (!isExternallyVisible(LV.getLinkage())) { - // Don't set internal linkage on declarations. - } else { - if (ND->hasAttr()) { - GV->setLinkage(llvm::GlobalValue::ExternalLinkage); - GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); - } else if (ND->hasAttr()) { - GV->setLinkage(llvm::GlobalValue::ExternalLinkage); - } else if (ND->hasAttr() || ND->isWeakImported()) { - // "extern_weak" is overloaded in LLVM; we probably should have - // separate linkage types for this. - GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); - } - } + // Don't set internal linkage on declarations. + // "extern_weak" is overloaded in LLVM; we probably should have + // separate linkage types for this. + if (isExternallyVisible(LV.getLinkage()) && + (ND->hasAttr() || ND->isWeakImported())) + GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); } void CodeGenModule::CreateFunctionTypeMetadata(const FunctionDecl *FD, @@ -3580,10 +3579,9 @@ // declarations). auto *Fn = cast(GV); setFunctionLinkage(GD, Fn); - setFunctionDLLStorageClass(GD, Fn); // FIXME: this is redundant with part of setFunctionDefinitionAttributes - setGVProperties(Fn, D); + setGVProperties(Fn, GD); MaybeHandleStaticInExternC(D, Fn); @@ -3675,7 +3673,7 @@ if (VD->getTLSKind()) setTLSMode(GA, *VD); - setAliasAttributes(GD, GA); + SetCommonAttributes(GD, GA); } void CodeGenModule::emitIFuncDefinition(GlobalDecl GD) { @@ -3734,7 +3732,7 @@ } else GIF->setName(MangledName); - SetCommonAttributes(D, GIF); + SetCommonAttributes(GD, GIF); } llvm::Function *CodeGenModule::getIntrinsic(unsigned IID, Index: lib/CodeGen/ItaniumCXXABI.cpp =================================================================== --- lib/CodeGen/ItaniumCXXABI.cpp +++ lib/CodeGen/ItaniumCXXABI.cpp @@ -300,16 +300,11 @@ // linkage together with vtables when needed. if (ForVTable && !Thunk->hasLocalLinkage()) Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage); - - // Propagate dllexport storage, to enable the linker to generate import - // thunks as necessary (e.g. when a parent class has a key function and a - // child class doesn't, and the construction vtable for the parent in the - // child needs to reference the parent's thunks). - const CXXMethodDecl *MD = cast(GD.getDecl()); - if (MD->hasAttr()) - Thunk->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + CGM.setGVProperties(Thunk, GD); } + bool exportThunk() override { return true; } + llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This, const ThisAdjustment &TA) override; @@ -1642,11 +1637,6 @@ Name, VTableType, llvm::GlobalValue::ExternalLinkage); VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); - if (RD->hasAttr()) - VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); - else if (RD->hasAttr()) - VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); - CGM.setGVProperties(VTable, RD); return VTable; @@ -2627,8 +2617,7 @@ Name); if (const RecordType *RecordTy = dyn_cast(Ty)) { const CXXRecordDecl *RD = cast(RecordTy->getDecl()); - if (RD->hasAttr()) - GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass); + CGM.setGVProperties(GV, RD); } } @@ -3637,7 +3626,7 @@ } // Finally, set up the alias with its proper name and attributes. - CGM.setAliasAttributes(AliasDecl, Alias); + CGM.SetCommonAttributes(AliasDecl, Alias); } void ItaniumCXXABI::emitCXXStructor(const CXXMethodDecl *MD, Index: lib/CodeGen/MicrosoftCXXABI.cpp =================================================================== --- lib/CodeGen/MicrosoftCXXABI.cpp +++ lib/CodeGen/MicrosoftCXXABI.cpp @@ -357,9 +357,6 @@ void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD, bool ReturnAdjustment) override { - // Never dllimport/dllexport thunks. - Thunk->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); - GVALinkage Linkage = getContext().GetGVALinkageForFunction(cast(GD.getDecl())); @@ -371,6 +368,8 @@ Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage); } + bool exportThunk() override { return false; } + llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This, const ThisAdjustment &TA) override; @@ -1248,7 +1247,7 @@ if (!hasDefaultCXXMethodCC(getContext(), D) || D->getNumParams() != 0) { llvm::Function *Fn = getAddrOfCXXCtorClosure(D, Ctor_DefaultClosure); Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage); - Fn->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + CGM.setGVProperties(Fn, D); } } Index: test/CodeGenCXX/dllexport-ctor-closure.cpp =================================================================== --- test/CodeGenCXX/dllexport-ctor-closure.cpp +++ test/CodeGenCXX/dllexport-ctor-closure.cpp @@ -5,7 +5,7 @@ struct CtorWithClosure { __declspec(dllexport) CtorWithClosure(...) {} -// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorWithClosure@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat +// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"\01??_FCtorWithClosure@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat // CHECK: %[[this_addr:.*]] = alloca %struct.CtorWithClosure*, align 4 // CHECK: store %struct.CtorWithClosure* %this, %struct.CtorWithClosure** %[[this_addr]], align 4 // CHECK: %[[this:.*]] = load %struct.CtorWithClosure*, %struct.CtorWithClosure** %[[this_addr]] @@ -17,7 +17,7 @@ __declspec(dllexport) CtorWithClosureOutOfLine(...); }; CtorWithClosureOutOfLine::CtorWithClosureOutOfLine(...) {} -// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorWithClosureOutOfLine@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat +// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"\01??_FCtorWithClosureOutOfLine@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat #define DELETE_IMPLICIT_MEMBERS(ClassName) \ ClassName(ClassName &&) = delete; \ @@ -28,7 +28,7 @@ struct __declspec(dllexport) ClassWithClosure { DELETE_IMPLICIT_MEMBERS(ClassWithClosure); ClassWithClosure(...) {} -// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FClassWithClosure@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat +// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"\01??_FClassWithClosure@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat // CHECK: %[[this_addr:.*]] = alloca %struct.ClassWithClosure*, align 4 // CHECK: store %struct.ClassWithClosure* %this, %struct.ClassWithClosure** %[[this_addr]], align 4 // CHECK: %[[this:.*]] = load %struct.ClassWithClosure*, %struct.ClassWithClosure** %[[this_addr]] @@ -44,10 +44,10 @@ extern template struct TemplateWithClosure; template struct __declspec(dllexport) TemplateWithClosure; -// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_F?$TemplateWithClosure@D@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat +// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"\01??_F?$TemplateWithClosure@D@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat // CHECK: call {{.*}} @"\01??0?$TemplateWithClosure@D@@QAE@H@Z"({{.*}}, i32 1) -// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_F?$TemplateWithClosure@H@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat +// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"\01??_F?$TemplateWithClosure@H@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat // CHECK: call {{.*}} @"\01??0?$TemplateWithClosure@H@@QAE@H@Z"({{.*}}, i32 4) struct __declspec(dllexport) NestedOuter { @@ -59,8 +59,8 @@ }; }; -// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat -// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedInner@NestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat +// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"\01??_FNestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat +// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"\01??_FNestedInner@NestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat struct HasDtor { ~HasDtor(); @@ -76,7 +76,7 @@ }; CtorClosureOutOfLine::CtorClosureOutOfLine(const HasImplicitDtor2 &v) {} -// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorClosureInline@@QAEXXZ" +// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"\01??_FCtorClosureInline@@QAEXXZ" // CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"\01??1HasImplicitDtor1@@QAE@XZ" -// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorClosureOutOfLine@@QAEXXZ" +// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"\01??_FCtorClosureOutOfLine@@QAEXXZ" // CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"\01??1HasImplicitDtor2@@QAE@XZ" Index: test/CodeGenCXX/dllexport.cpp =================================================================== --- test/CodeGenCXX/dllexport.cpp +++ test/CodeGenCXX/dllexport.cpp @@ -521,7 +521,7 @@ // MSVC2013-DAG: define weak_odr dso_local dllexport {{.+}} @"\01??4?$SomeTemplate@H@@Q{{.+}}0@A{{.+}}0@@Z" struct __declspec(dllexport) InheritFromTemplate : SomeTemplate {}; -// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_F?$SomeTemplate@H@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat +// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"\01??_F?$SomeTemplate@H@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat namespace PR23801 { template @@ -538,7 +538,7 @@ } // -// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FB@PR23801@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat +// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"\01??_FB@PR23801@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat struct __declspec(dllexport) T { // Copy assignment operator: @@ -847,7 +847,7 @@ B(int = 0) {} A m_fn1() {} }; -// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FB@pr26490@@QAEXXZ" +// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"\01??_FB@pr26490@@QAEXXZ" } // dllexport trumps dllimport on an explicit instantiation. Index: test/CodeGenObjC/dllstorage.m =================================================================== --- test/CodeGenObjC/dllstorage.m +++ test/CodeGenObjC/dllstorage.m @@ -16,11 +16,11 @@ @interface J : I @end -// CHECK-IR-DAG: @"OBJC_METACLASS_$_J" = dllexport global %struct._class_t -// CHECK-IR-DAG: @"OBJC_CLASS_$_J" = dllexport global %struct._class_t +// CHECK-IR-DAG: @"OBJC_METACLASS_$_J" = dso_local dllexport global %struct._class_t +// CHECK-IR-DAG: @"OBJC_CLASS_$_J" = dso_local dllexport global %struct._class_t -// CHECK-FW-DAG: @_OBJC_METACLASS_J = dllexport global -// CHECK-FW-DAG: @_OBJC_CLASS_J = dllexport global +// CHECK-FW-DAG: @_OBJC_METACLASS_J = dso_local dllexport global +// CHECK-FW-DAG: @_OBJC_CLASS_J = dso_local dllexport global @implementation J { id _ivar; @@ -32,11 +32,11 @@ @interface K : J @end -// CHECK-IR-DAG: @"OBJC_METACLASS_$_K" = global %struct._class_t -// CHECK-IR-DAG: @"OBJC_CLASS_$_K" = global %struct._class_t +// CHECK-IR-DAG: @"OBJC_METACLASS_$_K" = dso_local global %struct._class_t +// CHECK-IR-DAG: @"OBJC_CLASS_$_K" = dso_local global %struct._class_t -// CHECK-FW-DAG: @_OBJC_METACLASS_K = global -// CHECK-FW-DAG: @_OBJC_CLASS_K = global +// CHECK-FW-DAG: @_OBJC_METACLASS_K = dso_local global +// CHECK-FW-DAG: @_OBJC_CLASS_K = dso_local global @implementation K { id _ivar; @@ -49,11 +49,11 @@ @interface L : K @end -// CHECK-IR-DAG: @"OBJC_METACLASS_$_L" = dllexport global %struct._class_t -// CHECK-IR-DAG: @"OBJC_CLASS_$_L" = dllexport global %struct._class_t +// CHECK-IR-DAG: @"OBJC_METACLASS_$_L" = dso_local dllexport global %struct._class_t +// CHECK-IR-DAG: @"OBJC_CLASS_$_L" = dso_local dllexport global %struct._class_t -// CHECK-FW-DAG: @_OBJC_METACLASS_L = dllexport global -// CHECK-FW-DAG: @_OBJC_CLASS_L = dllexport global +// CHECK-FW-DAG: @_OBJC_METACLASS_L = dso_local dllexport global +// CHECK-FW-DAG: @_OBJC_CLASS_L = dso_local dllexport global @implementation L { id _none; @@ -94,13 +94,13 @@ @interface N : I @end -// CHECK-FW-DAG: @_OBJC_METACLASS_N = dllexport global -// CHECK-FW-DAG: @_OBJC_CLASS_N = dllexport global +// CHECK-FW-DAG: @_OBJC_METACLASS_N = dso_local dllexport global +// CHECK-FW-DAG: @_OBJC_CLASS_N = dso_local dllexport global @implementation N : I @end -// CHECK-IR-DAG: @"OBJC_EHTYPE_$_N" = dllexport global %struct._objc_typeinfo +// CHECK-IR-DAG: @"OBJC_EHTYPE_$_N" = dso_local dllexport global %struct._objc_typeinfo __declspec(dllimport) __attribute__((__objc_exception__)) @@ -113,7 +113,7 @@ @interface P : I @end -// CHECK-IR-DAG: @"OBJC_EHTYPE_$_P" = external global %struct._objc_typeinfo +// CHECK-IR-DAG: @"OBJC_EHTYPE_$_P" = external dso_local global %struct._objc_typeinfo @interface Q : M @end Index: test/PCH/dllexport-default-arg-closure.cpp =================================================================== --- test/PCH/dllexport-default-arg-closure.cpp +++ test/PCH/dllexport-default-arg-closure.cpp @@ -17,7 +17,7 @@ // Demangles as: // void Foo::`default constructor closure'(void) -// CHECK: define weak_odr dllexport void @"\01??_FFoo@@QEAAXXZ"(%struct.Foo*{{.*}}) +// CHECK: define weak_odr dso_local dllexport void @"\01??_FFoo@@QEAAXXZ"(%struct.Foo*{{.*}}) // CHECK: call %struct.Foo* @"\01??0Foo@@QEAA@W4E@0@@Z"(%struct.Foo* {{.*}}, i32 0) #else