Index: clang/lib/CodeGen/CGBlocks.cpp =================================================================== --- clang/lib/CodeGen/CGBlocks.cpp +++ clang/lib/CodeGen/CGBlocks.cpp @@ -2423,10 +2423,9 @@ // TODO: support static blocks runtime if (GV->isDeclaration() && (!ND || !ND->hasAttr())) { - GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + GV->setDLLImport(true); GV->setLinkage(llvm::GlobalValue::ExternalLinkage); } else { - GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); GV->setLinkage(llvm::GlobalValue::ExternalLinkage); } } Index: clang/lib/CodeGen/CGDecl.cpp =================================================================== --- clang/lib/CodeGen/CGDecl.cpp +++ clang/lib/CodeGen/CGDecl.cpp @@ -244,9 +244,9 @@ if (D.isExternallyVisible()) { if (D.hasAttr()) - GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass); + GV->setDLLImport(true); else if (D.hasAttr()) - GV->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass); + GV->addDLLExportFlag(); } // Make sure the result is of the correct type. Index: clang/lib/CodeGen/CGObjCGNU.cpp =================================================================== --- clang/lib/CodeGen/CGObjCGNU.cpp +++ clang/lib/CodeGen/CGObjCGNU.cpp @@ -1042,12 +1042,10 @@ 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; + ClassSymbol->addDLLExportFlag(); else if (OID->hasAttr()) - DLLStorage = llvm::GlobalValue::DLLImportStorageClass; - ClassSymbol->setDLLStorageClass(DLLStorage); + ClassSymbol->setDLLImport(true); } } return Value; @@ -1066,13 +1064,10 @@ if ((VD = dyn_cast(Result))) break; - auto DLLStorage = llvm::GlobalValue::DefaultStorageClass; if (!VD || VD->hasAttr()) - DLLStorage = llvm::GlobalValue::DLLImportStorageClass; + ClassSymbol->setDLLImport(true); else if (VD->hasAttr()) - DLLStorage = llvm::GlobalValue::DLLExportStorageClass; - - ClassSymbol->setDLLStorageClass(DLLStorage); + ClassSymbol->addDLLExportFlag(); } } return Value; @@ -2345,12 +2340,11 @@ 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; + cast(MetaClassStruct) + ->setDLLImport(true); else if (OID->getClassInterface()->hasAttr()) - Storage = llvm::GlobalValue::DLLExportStorageClass; - cast(MetaClassStruct)->setDLLStorageClass(Storage); + cast(MetaClassStruct)->addDLLExportFlag(); } // Generate the class structure @@ -2360,12 +2354,11 @@ GenerateProtocolList(Protocols), IvarOffsetArray, Properties, StrongIvarBitmap, WeakIvarBitmap); if (CGM.getTriple().isOSBinFormatCOFF()) { - auto Storage = llvm::GlobalValue::DefaultStorageClass; if (OID->getClassInterface()->hasAttr()) - Storage = llvm::GlobalValue::DLLImportStorageClass; + cast(MetaClassStruct) + ->setDLLImport(true); else if (OID->getClassInterface()->hasAttr()) - Storage = llvm::GlobalValue::DLLExportStorageClass; - cast(ClassStruct)->setDLLStorageClass(Storage); + cast(MetaClassStruct)->addDLLExportFlag(); } // Resolve the class aliases, if they exist. Index: clang/lib/CodeGen/CGObjCMac.cpp =================================================================== --- clang/lib/CodeGen/CGObjCMac.cpp +++ clang/lib/CodeGen/CGObjCMac.cpp @@ -6222,9 +6222,8 @@ InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth(); } -static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM, - StringRef Name) { - IdentifierInfo &II = CGM.getContext().Idents.get(Name); +static void setDLLStorage(CodeGenModule &CGM, llvm::GlobalValue *GV) { + IdentifierInfo &II = CGM.getContext().Idents.get(GV->getName()); TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl(); DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); @@ -6233,13 +6232,18 @@ if ((VD = dyn_cast(Result))) break; - if (!VD) - return llvm::GlobalValue::DLLImportStorageClass; - if (VD->hasAttr()) - return llvm::GlobalValue::DLLExportStorageClass; - if (VD->hasAttr()) - return llvm::GlobalValue::DLLImportStorageClass; - return llvm::GlobalValue::DefaultStorageClass; + if (!VD) { + GV->setDLLImport(true); + return; + } + if (VD->hasAttr()) { + GV->addDLLExportFlag(); + return; + } + if (VD->hasAttr()) { + GV->setDLLImport(true); + return; + } } void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { @@ -6249,7 +6253,7 @@ llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_cache"); if (CGM.getTriple().isOSBinFormatCOFF()) - ObjCEmptyCacheVar->setDLLStorageClass(getStorage(CGM, "_objc_empty_cache")); + setDLLStorage(CGM, ObjCEmptyCacheVar); // Only OS X with deployment version <10.9 use the empty vtable symbol const llvm::Triple &Triple = CGM.getTarget().getTriple(); @@ -6314,7 +6318,7 @@ IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden); if (CGM.getTriple().isOSBinFormatCOFF()) if (CI->hasAttr()) - MetaTClass->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + MetaTClass->addDLLExportFlag(); DefinedMetaClasses.push_back(MetaTClass); // Metadata for the class @@ -6356,7 +6360,7 @@ MetaTClass, SuperClassGV, CLASS_RO_GV, classIsHidden); if (CGM.getTriple().isOSBinFormatCOFF()) if (CI->hasAttr()) - ClassMD->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + ClassMD->addDLLExportFlag(); DefinedClasses.push_back(ClassMD); ImplementedClasses.push_back(CI); @@ -6621,9 +6625,9 @@ Ivar->getAccessControl() == ObjCIvarDecl::Package; if (ID->hasAttr() && !IsPrivateOrPackage) - IvarOffsetGV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + IvarOffsetGV->addDLLExportFlag(); else if (ID->hasAttr()) - IvarOffsetGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + IvarOffsetGV->setDLLImport(true); } } return IvarOffsetGV; @@ -7143,7 +7147,7 @@ false, L, nullptr, Name); if (DLLImport) - GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + GV->setDLLImport(true); } assert(GV->getLinkage() == L); @@ -7462,7 +7466,7 @@ llvm::GlobalValue::ExternalLinkage, nullptr, "OBJC_EHTYPE_id"); if (CGM.getTriple().isOSBinFormatCOFF()) - IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id")); + setDLLStorage(CGM, IDEHType); } return IDEHType; } @@ -7525,9 +7529,9 @@ nullptr, EHTypeName); if (CGM.getTriple().isOSBinFormatCOFF()) { if (ID->hasAttr()) - Entry->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + Entry->addDLLExportFlag(); else if (ID->hasAttr()) - Entry->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + Entry->setDLLImport(true); } return Entry; } @@ -7544,7 +7548,7 @@ llvm::GlobalValue::ExternalLinkage, nullptr, VTableName); if (CGM.getTriple().isOSBinFormatCOFF()) - VTableGV->setDLLStorageClass(getStorage(CGM, VTableName)); + setDLLStorage(CGM, VTableGV); } llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2); @@ -7569,7 +7573,7 @@ if (CGM.getTriple().isOSBinFormatCOFF()) if (hasObjCExceptionAttribute(CGM.getContext(), ID)) if (ID->hasAttr()) - Entry->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + Entry->addDLLExportFlag(); } assert(Entry->getLinkage() == L); Index: clang/lib/CodeGen/CodeGenModule.h =================================================================== --- clang/lib/CodeGen/CodeGenModule.h +++ clang/lib/CodeGen/CodeGenModule.h @@ -430,7 +430,7 @@ llvm::SmallPtrSet EmittedModuleInitializers; /// \brief A vector of metadata strings. - SmallVector LinkerOptionsMetadata; + SmallVector LinkerOptionsMetadata; /// @name Cache for Objective-C runtime types /// @{ Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -808,17 +808,17 @@ 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); + F->setDLLImport(false); return; } } if (FD->hasAttr()) - F->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass); + F->setDLLImport(true); else if (FD->hasAttr()) - F->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass); + F->addDLLExportFlag(); else - F->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass); + F->setDLLImport(false); } llvm::ConstantInt *CodeGenModule::CreateCrossDsoCfiTypeId(llvm::Metadata *MD) { @@ -999,7 +999,7 @@ // Process the dllexport attribute based on whether the original definition // (not necessarily the aliasee) was exported. if (D->hasAttr()) - GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + GV->addDLLExportFlag(); } void CodeGenModule::setNonAliasAttributes(const Decl *D, @@ -1033,10 +1033,9 @@ } else { if (ND->hasAttr()) { GV->setLinkage(llvm::GlobalValue::ExternalLinkage); - GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + GV->setDLLImport(true); } else if (ND->hasAttr()) { GV->setLinkage(llvm::GlobalValue::ExternalLinkage); - GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); } else if (ND->hasAttr() || ND->isWeakImported()) { // "extern_weak" is overloaded in LLVM; we probably should have // separate linkage types for this. @@ -1204,7 +1203,7 @@ /// \brief Add link options implied by the given module, including modules /// it depends on, using a postorder walk. static void addLinkOptionsPostorder(CodeGenModule &CGM, Module *Mod, - SmallVectorImpl &Metadata, + SmallVectorImpl &Metadata, llvm::SmallPtrSet &Visited) { // Import this module's parent. if (Mod->Parent && Visited.insert(Mod->Parent).second) { @@ -1292,7 +1291,7 @@ // Add link options for all of the imported modules in reverse topological // order. We don't do anything to try to order import link flags with respect // to linker options inserted by things like #pragma comment(). - SmallVector MetadataArgs; + SmallVector MetadataArgs; Visited.clear(); for (Module *M : LinkModules) if (Visited.insert(M).second) @@ -1301,9 +1300,9 @@ LinkerOptionsMetadata.append(MetadataArgs.begin(), MetadataArgs.end()); // Add the linker options metadata flag. - getModule().addModuleFlag(llvm::Module::AppendUnique, "Linker Options", - llvm::MDNode::get(getLLVMContext(), - LinkerOptionsMetadata)); + auto *NMD = getModule().getOrInsertNamedMetadata("llvm.linker.options"); + for (auto *MD : LinkerOptionsMetadata) + NMD->addOperand(MD); } void CodeGenModule::EmitDeferred() { @@ -1930,8 +1929,9 @@ } // Handle dropped DLL attributes. - if (D && !D->hasAttr() && !D->hasAttr()) - Entry->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); + if (D && !D->hasAttr() && !D->hasAttr()) { + Entry->setDLLImport(false); + } // If there are two attempts to define the same mangled name, issue an // error. @@ -2148,7 +2148,7 @@ !getCodeGenOpts().LTOVisibilityPublicStd) { const FunctionDecl *FD = GetRuntimeFunctionDecl(Context, Name); if (!FD || FD->hasAttr()) { - F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + F->setDLLImport(true); F->setLinkage(llvm::GlobalValue::ExternalLinkage); } } @@ -2218,8 +2218,9 @@ } // Handle dropped DLL attributes. - if (D && !D->hasAttr() && !D->hasAttr()) - Entry->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); + if (D && !D->hasAttr() && !D->hasAttr()) { + Entry->setDLLImport(false); + } if (Entry->getType() == Ty) return Entry; @@ -2711,11 +2712,11 @@ GV->setLinkage(Linkage); if (D->hasAttr()) - GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass); + GV->setDLLImport(true); else if (D->hasAttr()) - GV->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass); + GV->addDLLExportFlag(); else - GV->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass); + GV->setDLLImport(false); if (Linkage == llvm::GlobalVariable::CommonLinkage) { // common vars aren't constant even if declared const. @@ -3278,10 +3279,10 @@ break; if (!VD || !VD->hasAttr()) { - CGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + CGV->setDLLImport(true); CGV->setLinkage(llvm::GlobalValue::ExternalLinkage); } else { - CGV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + CGV->addDLLExportFlag(); CGV->setLinkage(llvm::GlobalValue::ExternalLinkage); } } Index: clang/lib/CodeGen/ItaniumCXXABI.cpp =================================================================== --- clang/lib/CodeGen/ItaniumCXXABI.cpp +++ clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -1606,9 +1606,9 @@ VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); if (RD->hasAttr()) - VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + VTable->setDLLImport(true); else if (RD->hasAttr()) - VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + VTable->addDLLExportFlag(); return VTable; } @@ -2580,7 +2580,7 @@ if (const RecordType *RecordTy = dyn_cast(Ty)) { const CXXRecordDecl *RD = cast(RecordTy->getDecl()); if (RD->hasAttr()) - GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass); + GV->setDLLImport(true); } } @@ -3163,11 +3163,11 @@ if (CGM.getTriple().isWindowsItaniumEnvironment()) { auto RD = Ty->getAsCXXRecordDecl(); if (DLLExport || (RD && RD->hasAttr())) { - TypeName->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); - GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + TypeName->addDLLExportFlag(); + GV->addDLLExportFlag(); } else if (CGM.getLangOpts().RTTI && RD && RD->hasAttr()) { - TypeName->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); - GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + TypeName->setDLLImport(true); + GV->setDLLImport(true); // Because the typename and the typeinfo are DLL import, convert them to // declarations rather than definitions. The initializers still need to Index: clang/lib/CodeGen/MicrosoftCXXABI.cpp =================================================================== --- clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -360,8 +360,8 @@ void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD, bool ReturnAdjustment) override { - // Never dllimport/dllexport thunks. - Thunk->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); + // Never dllimport thunks. + Thunk->setDLLImport(false); GVALinkage Linkage = getContext().GetGVALinkageForFunction(cast(GD.getDecl())); @@ -1231,7 +1231,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); + Fn->addDLLExportFlag(); } } @@ -1802,7 +1802,7 @@ VTable->setComdat(C); if (RD->hasAttr()) - VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + VFTable->addDLLExportFlag(); VFTablesMap[ID] = VFTable; return VTable; @@ -2010,9 +2010,9 @@ GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); if (RD->hasAttr()) - GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + GV->setDLLImport(true); else if (RD->hasAttr()) - GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + GV->addDLLExportFlag(); if (!GV->hasExternalLinkage()) emitVBTableDefinition(VBT, RD, GV); @@ -2440,7 +2440,9 @@ new llvm::GlobalVariable(CGM.getModule(), GuardTy, /*isConstant=*/false, GV->getLinkage(), Zero, GuardName.str()); GuardVar->setVisibility(GV->getVisibility()); - GuardVar->setDLLStorageClass(GV->getDLLStorageClass()); + GuardVar->setDLLImport(GV->isDLLImport()); + if (D.hasAttr() && !GV->hasLocalLinkage()) + GV->addDLLExportFlag(); GuardVar->setAlignment(GuardAlign.getQuantity()); if (GuardVar->isWeakForLinker()) GuardVar->setComdat( Index: llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h =================================================================== --- llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -94,9 +94,8 @@ void Initialize(MCContext &Ctx, const TargetMachine &TM) override; /// Emit the module flags that specify the garbage collection information. - void emitModuleFlags(MCStreamer &Streamer, - ArrayRef ModuleFlags, - const TargetMachine &TM) const override; + void emitModuleMetadata(MCStreamer &Streamer, Module &M, + const TargetMachine &TM) const override; MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override; @@ -149,19 +148,14 @@ MCSection *getSectionForJumpTable(const Function &F, const TargetMachine &TM) const override; - /// Emit Obj-C garbage collection and linker options. Only linker option - /// emission is implemented for COFF. - void emitModuleFlags(MCStreamer &Streamer, - ArrayRef ModuleFlags, - const TargetMachine &TM) const override; + /// Emit linker options. + void emitModuleMetadata(MCStreamer &Streamer, Module &M, + const TargetMachine &TM) const override; MCSection *getStaticCtorSection(unsigned Priority, const MCSymbol *KeySym) const override; MCSection *getStaticDtorSection(unsigned Priority, const MCSymbol *KeySym) const override; - - void emitLinkerFlagsForGlobal(raw_ostream &OS, - const GlobalValue *GV) const override; }; class TargetLoweringObjectFileWasm : public TargetLoweringObjectFile { @@ -187,9 +181,6 @@ const TargetMachine &TM) const override; }; -void emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV, - const Triple &TT, Mangler &Mangler); - } // end namespace llvm #endif // LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H Index: llvm/include/llvm/IR/GlobalValue.h =================================================================== --- llvm/include/llvm/IR/GlobalValue.h +++ llvm/include/llvm/IR/GlobalValue.h @@ -66,21 +66,14 @@ ProtectedVisibility ///< The GV is protected }; - /// @brief Storage classes of global values for PE targets. - enum DLLStorageClassTypes { - DefaultStorageClass = 0, - DLLImportStorageClass = 1, ///< Function to be imported from DLL - DLLExportStorageClass = 2 ///< Function to be accessible from DLL. - }; - protected: GlobalValue(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps, LinkageTypes Linkage, const Twine &Name, unsigned AddressSpace) : Constant(PointerType::get(Ty, AddressSpace), VTy, Ops, NumOps), ValueType(Ty), Linkage(Linkage), Visibility(DefaultVisibility), - UnnamedAddrVal(unsigned(UnnamedAddr::None)), - DllStorageClass(DefaultStorageClass), ThreadLocal(NotThreadLocal), - HasLLVMReservedName(false), IntID((Intrinsic::ID)0U), Parent(nullptr) { + UnnamedAddrVal(unsigned(UnnamedAddr::None)), DllImport(false), + ThreadLocal(NotThreadLocal), HasLLVMReservedName(false), + IntID((Intrinsic::ID)0U), Parent(nullptr) { setName(Name); } @@ -93,7 +86,7 @@ unsigned Linkage : 4; // The linkage of this global unsigned Visibility : 2; // The visibility style of this global unsigned UnnamedAddrVal : 2; // This value's address is not significant - unsigned DllStorageClass : 2; // DLL storage class + unsigned DllImport : 1; unsigned ThreadLocal : 3; // Is this symbol "Thread Local", if so, what is // the desired model? @@ -241,16 +234,12 @@ return static_cast(ThreadLocal); } - DLLStorageClassTypes getDLLStorageClass() const { - return DLLStorageClassTypes(DllStorageClass); - } - bool hasDLLImportStorageClass() const { - return DllStorageClass == DLLImportStorageClass; + bool isDLLImport() const { + return DllImport; } - bool hasDLLExportStorageClass() const { - return DllStorageClass == DLLExportStorageClass; - } - void setDLLStorageClass(DLLStorageClassTypes C) { DllStorageClass = C; } + void setDLLImport(bool b) { DllImport = b; } + + void addDLLExportFlag(); bool hasSection() const { return !getSection().empty(); } StringRef getSection() const; Index: llvm/include/llvm/Target/TargetLoweringObjectFile.h =================================================================== --- llvm/include/llvm/Target/TargetLoweringObjectFile.h +++ llvm/include/llvm/Target/TargetLoweringObjectFile.h @@ -70,10 +70,9 @@ virtual void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM, const MCSymbol *Sym) const; - /// Emit the module flags that the platform cares about. - virtual void emitModuleFlags(MCStreamer &Streamer, - ArrayRef Flags, - const TargetMachine &TM) const {} + /// Emit the module-level metadata that the platform cares about. + virtual void emitModuleMetadata(MCStreamer &Streamer, Module &M, + const TargetMachine &TM) const {} /// Given a constant with the SectionKind, return a section that it should be /// placed in. @@ -181,9 +180,6 @@ return nullptr; } - virtual void emitLinkerFlagsForGlobal(raw_ostream &OS, - const GlobalValue *GV) const {} - protected: virtual MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, Index: llvm/lib/AsmParser/LLLexer.cpp =================================================================== --- llvm/lib/AsmParser/LLLexer.cpp +++ llvm/lib/AsmParser/LLLexer.cpp @@ -503,7 +503,6 @@ KEYWORD(weak_odr); KEYWORD(appending); KEYWORD(dllimport); - KEYWORD(dllexport); KEYWORD(common); KEYWORD(default); KEYWORD(hidden); Index: llvm/lib/AsmParser/LLParser.h =================================================================== --- llvm/lib/AsmParser/LLParser.h +++ llvm/lib/AsmParser/LLParser.h @@ -231,9 +231,8 @@ bool ParseOptionalParamAttrs(AttrBuilder &B); bool ParseOptionalReturnAttrs(AttrBuilder &B); bool ParseOptionalLinkage(unsigned &Linkage, bool &HasLinkage, - unsigned &Visibility, unsigned &DLLStorageClass); + unsigned &Visibility, bool &DLLImport); void ParseOptionalVisibility(unsigned &Visibility); - void ParseOptionalDLLStorageClass(unsigned &DLLStorageClass); bool ParseOptionalCallingConv(unsigned &CC); bool ParseOptionalAlignment(unsigned &Alignment); bool ParseOptionalDerefAttrBytes(lltok::Kind AttrKind, uint64_t &Bytes); @@ -271,13 +270,12 @@ bool ParseUnnamedGlobal(); bool ParseNamedGlobal(); bool ParseGlobal(const std::string &Name, LocTy Loc, unsigned Linkage, - bool HasLinkage, unsigned Visibility, - unsigned DLLStorageClass, + bool HasLinkage, unsigned Visibility, bool DLLImport, GlobalVariable::ThreadLocalMode TLM, GlobalVariable::UnnamedAddr UnnamedAddr); bool parseIndirectSymbol(const std::string &Name, LocTy Loc, unsigned Linkage, unsigned Visibility, - unsigned DLLStorageClass, + bool DLLImport, GlobalVariable::ThreadLocalMode TLM, GlobalVariable::UnnamedAddr UnnamedAddr); bool parseComdat(); Index: llvm/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/lib/AsmParser/LLParser.cpp +++ llvm/lib/AsmParser/LLParser.cpp @@ -507,20 +507,20 @@ return true; } - bool HasLinkage; - unsigned Linkage, Visibility, DLLStorageClass; + bool HasLinkage, DLLImport; + unsigned Linkage, Visibility; GlobalVariable::ThreadLocalMode TLM; GlobalVariable::UnnamedAddr UnnamedAddr; - if (ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) || + if (ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLImport) || ParseOptionalThreadLocal(TLM) || ParseOptionalUnnamedAddr(UnnamedAddr)) return true; if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc) return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility, - DLLStorageClass, TLM, UnnamedAddr); + DLLImport, TLM, UnnamedAddr); return parseIndirectSymbol(Name, NameLoc, Linkage, Visibility, - DLLStorageClass, TLM, UnnamedAddr); + DLLImport, TLM, UnnamedAddr); } /// ParseNamedGlobal: @@ -533,21 +533,21 @@ std::string Name = Lex.getStrVal(); Lex.Lex(); - bool HasLinkage; - unsigned Linkage, Visibility, DLLStorageClass; + bool HasLinkage, DLLImport; + unsigned Linkage, Visibility; GlobalVariable::ThreadLocalMode TLM; GlobalVariable::UnnamedAddr UnnamedAddr; if (ParseToken(lltok::equal, "expected '=' in global variable") || - ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) || + ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLImport) || ParseOptionalThreadLocal(TLM) || ParseOptionalUnnamedAddr(UnnamedAddr)) return true; if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc) return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility, - DLLStorageClass, TLM, UnnamedAddr); + DLLImport, TLM, UnnamedAddr); return parseIndirectSymbol(Name, NameLoc, Linkage, Visibility, - DLLStorageClass, TLM, UnnamedAddr); + DLLImport, TLM, UnnamedAddr); } bool LLParser::parseComdat() { @@ -716,7 +716,7 @@ /// bool LLParser::parseIndirectSymbol( const std::string &Name, LocTy NameLoc, unsigned L, unsigned Visibility, - unsigned DLLStorageClass, GlobalVariable::ThreadLocalMode TLM, + bool DLLImport, GlobalVariable::ThreadLocalMode TLM, GlobalVariable::UnnamedAddr UnnamedAddr) { bool IsAlias; if (Lex.getKind() == lltok::kw_alias) @@ -806,7 +806,7 @@ Aliasee, /*Parent*/ nullptr)); GA->setThreadLocalMode(TLM); GA->setVisibility((GlobalValue::VisibilityTypes)Visibility); - GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); + GA->setDLLImport(DLLImport); GA->setUnnamedAddr(UnnamedAddr); if (Name.empty()) @@ -851,7 +851,7 @@ /// bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, unsigned Linkage, bool HasLinkage, - unsigned Visibility, unsigned DLLStorageClass, + unsigned Visibility, bool DLLImport, GlobalVariable::ThreadLocalMode TLM, GlobalVariable::UnnamedAddr UnnamedAddr) { if (!isValidVisibilityForLinkage(Visibility, Linkage)) @@ -927,7 +927,7 @@ GV->setConstant(IsConstant); GV->setLinkage((GlobalValue::LinkageTypes)Linkage); GV->setVisibility((GlobalValue::VisibilityTypes)Visibility); - GV->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); + GV->setDLLImport(DLLImport); GV->setExternallyInitialized(IsExternallyInitialized); GV->setThreadLocalMode(TLM); GV->setUnnamedAddr(UnnamedAddr); @@ -1590,12 +1590,12 @@ /// ::= 'external' bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage, unsigned &Visibility, - unsigned &DLLStorageClass) { + bool &DLLImport) { Res = parseOptionalLinkageAux(Lex.getKind(), HasLinkage); if (HasLinkage) Lex.Lex(); ParseOptionalVisibility(Visibility); - ParseOptionalDLLStorageClass(DLLStorageClass); + DLLImport = EatIfPresent(lltok::kw_dllimport); return false; } @@ -1623,26 +1623,6 @@ Lex.Lex(); } -/// ParseOptionalDLLStorageClass -/// ::= /*empty*/ -/// ::= 'dllimport' -/// ::= 'dllexport' -/// -void LLParser::ParseOptionalDLLStorageClass(unsigned &Res) { - switch (Lex.getKind()) { - default: - Res = GlobalValue::DefaultStorageClass; - return; - case lltok::kw_dllimport: - Res = GlobalValue::DLLImportStorageClass; - break; - case lltok::kw_dllexport: - Res = GlobalValue::DLLExportStorageClass; - break; - } - Lex.Lex(); -} - /// ParseOptionalCallingConv /// ::= /*empty*/ /// ::= 'ccc' @@ -4635,13 +4615,13 @@ unsigned Linkage; unsigned Visibility; - unsigned DLLStorageClass; + bool DLLImport; AttrBuilder RetAttrs; unsigned CC; bool HasLinkage; Type *RetType = nullptr; LocTy RetTypeLoc = Lex.getLoc(); - if (ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) || + if (ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLImport) || ParseOptionalCallingConv(CC) || ParseOptionalReturnAttrs(RetAttrs) || ParseType(RetType, RetTypeLoc, true /*void allowed*/)) return true; @@ -4816,7 +4796,7 @@ Fn->setLinkage((GlobalValue::LinkageTypes)Linkage); Fn->setVisibility((GlobalValue::VisibilityTypes)Visibility); - Fn->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); + Fn->setDLLImport(DLLImport); Fn->setCallingConv(CC); Fn->setAttributes(PAL); Fn->setUnnamedAddr(UnnamedAddr); Index: llvm/lib/AsmParser/LLToken.h =================================================================== --- llvm/lib/AsmParser/LLToken.h +++ llvm/lib/AsmParser/LLToken.h @@ -53,7 +53,6 @@ kw_weak_odr, kw_appending, kw_dllimport, - kw_dllexport, kw_common, kw_available_externally, kw_default, Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -453,6 +453,11 @@ /// which Metadata blocks are deferred. std::vector DeferredMetadataInfo; + /// This vector stores the list of globals with the historical dllexport + /// storage class. We need to create metadata for each of them after we + /// materialize the metadata. + std::vector DeferredDLLExportedGlobals; + /// These are basic blocks forward-referenced by block addresses. They are /// inserted lazily into functions when they're loaded. The basic block ID is /// its index into the vector. @@ -499,6 +504,9 @@ void setStripDebugInfo() override; private: + void upgradeDLLStorageClass(GlobalValue *GV, unsigned Val); + void upgradeDLLImportExportLinkage(GlobalValue *GV, unsigned Val); + std::vector IdentifiedStructTypes; StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name); StructType *createIdentifiedStructType(LLVMContext &Context); @@ -818,13 +826,12 @@ } } -static GlobalValue::DLLStorageClassTypes -getDecodedDLLStorageClass(unsigned Val) { +void BitcodeReader::upgradeDLLStorageClass(GlobalValue *GV, unsigned Val) { switch (Val) { default: // Map unknown values to default. - case 0: return GlobalValue::DefaultStorageClass; - case 1: return GlobalValue::DLLImportStorageClass; - case 2: return GlobalValue::DLLExportStorageClass; + case 0: break; + case 1: GV->setDLLImport(true); break; + case 2: DeferredDLLExportedGlobals.push_back(GV); break; } } @@ -974,10 +981,11 @@ return FMF; } -static void upgradeDLLImportExportLinkage(GlobalValue *GV, unsigned Val) { +void BitcodeReader::upgradeDLLImportExportLinkage(GlobalValue *GV, + unsigned Val) { switch (Val) { - case 5: GV->setDLLStorageClass(GlobalValue::DLLImportStorageClass); break; - case 6: GV->setDLLStorageClass(GlobalValue::DLLExportStorageClass); break; + case 5: GV->setDLLImport(true); break; + case 6: DeferredDLLExportedGlobals.push_back(GV); break; } } @@ -2501,6 +2509,14 @@ if (Error Err = MDLoader->parseModuleMetadata()) return Err; } + if (Metadata *Val = TheModule->getModuleFlag("Linker Options")) { + NamedMDNode *LinkerOpts = + TheModule->getOrInsertNamedMetadata("llvm.linker.options"); + for (const MDOperand &MDOptions : cast(Val)->operands()) + LinkerOpts->addOperand(cast(MDOptions)); + } + for (auto *GV : DeferredDLLExportedGlobals) + GV->addDLLExportFlag(); DeferredMetadataInfo.clear(); return Error::success(); } @@ -2897,7 +2913,7 @@ NewGV->setUnnamedAddr(UnnamedAddr); if (Record.size() > 10) - NewGV->setDLLStorageClass(getDecodedDLLStorageClass(Record[10])); + upgradeDLLStorageClass(NewGV, Record[10]); else upgradeDLLImportExportLinkage(NewGV, RawLinkage); @@ -2972,7 +2988,7 @@ FunctionPrologues.push_back(std::make_pair(Func, Record[10]-1)); if (Record.size() > 11) - Func->setDLLStorageClass(getDecodedDLLStorageClass(Record[11])); + upgradeDLLStorageClass(Func, Record[11]); else upgradeDLLImportExportLinkage(Func, RawLinkage); @@ -3047,7 +3063,7 @@ NewGA->setVisibility(getDecodedVisibility(Record[VisInd])); } if (OpNum != Record.size()) - NewGA->setDLLStorageClass(getDecodedDLLStorageClass(Record[OpNum++])); + upgradeDLLStorageClass(NewGA, Linkage); else upgradeDLLImportExportLinkage(NewGA, Linkage); if (OpNum != Record.size()) Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -990,15 +990,6 @@ llvm_unreachable("Invalid visibility"); } -static unsigned getEncodedDLLStorageClass(const GlobalValue &GV) { - switch (GV.getDLLStorageClass()) { - case GlobalValue::DefaultStorageClass: return 0; - case GlobalValue::DLLImportStorageClass: return 1; - case GlobalValue::DLLExportStorageClass: return 2; - } - llvm_unreachable("Invalid DLL storage class"); -} - static unsigned getEncodedThreadLocalMode(const GlobalValue &GV) { switch (GV.getThreadLocalMode()) { case GlobalVariable::NotThreadLocal: return 0; @@ -1198,14 +1189,12 @@ if (GV.isThreadLocal() || GV.getVisibility() != GlobalValue::DefaultVisibility || GV.getUnnamedAddr() != GlobalValue::UnnamedAddr::None || - GV.isExternallyInitialized() || - GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass || - GV.hasComdat()) { + GV.isExternallyInitialized() || GV.isDLLImport() || GV.hasComdat()) { Vals.push_back(getEncodedVisibility(GV)); Vals.push_back(getEncodedThreadLocalMode(GV)); Vals.push_back(getEncodedUnnamedAddr(GV)); Vals.push_back(GV.isExternallyInitialized()); - Vals.push_back(getEncodedDLLStorageClass(GV)); + Vals.push_back(GV.isDLLImport()); Vals.push_back(GV.hasComdat() ? VE.getComdatID(GV.getComdat()) : 0); } else { AbbrevToUse = SimpleGVarAbbrev; @@ -1232,7 +1221,7 @@ Vals.push_back(getEncodedUnnamedAddr(F)); Vals.push_back(F.hasPrologueData() ? (VE.getValueID(F.getPrologueData()) + 1) : 0); - Vals.push_back(getEncodedDLLStorageClass(F)); + Vals.push_back(F.isDLLImport()); Vals.push_back(F.hasComdat() ? VE.getComdatID(F.getComdat()) : 0); Vals.push_back(F.hasPrefixData() ? (VE.getValueID(F.getPrefixData()) + 1) : 0); @@ -1253,7 +1242,7 @@ Vals.push_back(VE.getValueID(A.getAliasee())); Vals.push_back(getEncodedLinkage(A)); Vals.push_back(getEncodedVisibility(A)); - Vals.push_back(getEncodedDLLStorageClass(A)); + Vals.push_back(A.isDLLImport()); Vals.push_back(getEncodedThreadLocalMode(A)); Vals.push_back(getEncodedUnnamedAddr(A)); unsigned AbbrevToUse = 0; Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1243,11 +1243,7 @@ const TargetLoweringObjectFile &TLOF = getObjFileLowering(); - // Emit module flags. - SmallVector ModuleFlags; - M.getModuleFlagsMetadata(ModuleFlags); - if (!ModuleFlags.empty()) - TLOF.emitModuleFlags(*OutStreamer, ModuleFlags, TM); + TLOF.emitModuleMetadata(*OutStreamer, M, TM); if (TM.getTargetTriple().isOSBinFormatELF()) { MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo(); Index: llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -158,7 +158,7 @@ addConstantValue(*VariableDIE, /*Unsigned=*/true, Expr->getElement(1)); // We cannot describe the location of dllimport'd variables: the // computation of their address requires loads from the IAT. - } else if ((Global && !Global->hasDLLImportStorageClass()) || AllConstant) { + } else if ((Global && !Global->isDLLImport()) || AllConstant) { if (!Loc) { Loc = new (DIEValueAllocator) DIELoc; DwarfExpr = llvm::make_unique(*Asm, *this, *Loc); Index: llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1042,7 +1042,7 @@ else if (GlobalValue *GV = mdconst::dyn_extract(Val)) { // We cannot describe the location of dllimport'd entities: the // computation of their address requires loads from the IAT. - if (!GV->hasDLLImportStorageClass()) { + if (!GV->isDLLImport()) { // For declaration non-type template parameters (such as global values // and functions) DIELoc *Loc = new (DIEValueAllocator) DIELoc; Index: llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp =================================================================== --- llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -551,15 +551,24 @@ } } -/// emitModuleFlags - Perform code emission for module flags. -void TargetLoweringObjectFileMachO::emitModuleFlags( - MCStreamer &Streamer, ArrayRef ModuleFlags, - const TargetMachine &TM) const { +void TargetLoweringObjectFileMachO::emitModuleMetadata( + MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { + // Emit the linker options if present. + if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { + for (const auto &Option : LinkerOptions->operands()) { + SmallVector StrOptions; + for (const auto &Piece : cast(Option)->operands()) + StrOptions.push_back(cast(Piece)->getString()); + Streamer.EmitLinkerOptions(StrOptions); + } + } + unsigned VersionVal = 0; unsigned ImageInfoFlags = 0; - MDNode *LinkerOptions = nullptr; StringRef SectionVal; + SmallVector ModuleFlags; + M.getModuleFlagsMetadata(ModuleFlags); for (const auto &MFE : ModuleFlags) { // Ignore flags with 'Require' behavior. if (MFE.Behavior == Module::Require) @@ -578,18 +587,6 @@ ImageInfoFlags |= mdconst::extract(Val)->getZExtValue(); } else if (Key == "Objective-C Image Info Section") { SectionVal = cast(Val)->getString(); - } else if (Key == "Linker Options") { - LinkerOptions = cast(Val); - } - } - - // Emit the linker options if present. - if (LinkerOptions) { - for (const auto &Option : LinkerOptions->operands()) { - SmallVector StrOptions; - for (const auto &Piece : cast(Option)->operands()) - StrOptions.push_back(cast(Piece)->getString()); - Streamer.EmitLinkerOptions(StrOptions); } } @@ -970,37 +967,6 @@ return 0; } -void llvm::emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV, - const Triple &TT, Mangler &Mangler) { - if (!GV->hasDLLExportStorageClass() || GV->isDeclaration()) - return; - - if (TT.isKnownWindowsMSVCEnvironment()) - OS << " /EXPORT:"; - else - OS << " -export:"; - - if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) { - std::string Flag; - raw_string_ostream FlagOS(Flag); - Mangler.getNameWithPrefix(FlagOS, GV, false); - FlagOS.flush(); - if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix()) - OS << Flag.substr(1); - else - OS << Flag; - } else { - Mangler.getNameWithPrefix(OS, GV, false); - } - - if (!GV->getValueType()->isFunctionTy()) { - if (TT.isKnownWindowsMSVCEnvironment()) - OS << ",DATA"; - else - OS << ",data"; - } -} - MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { int Selection = 0; @@ -1137,30 +1103,23 @@ COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); } -void TargetLoweringObjectFileCOFF::emitModuleFlags( - MCStreamer &Streamer, ArrayRef ModuleFlags, - const TargetMachine &TM) const { - MDNode *LinkerOptions = nullptr; - - for (const auto &MFE : ModuleFlags) { - StringRef Key = MFE.Key->getString(); - if (Key == "Linker Options") - LinkerOptions = cast(MFE.Val); - } +void TargetLoweringObjectFileCOFF::emitModuleMetadata( + MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { + NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options"); + if (!LinkerOptions) + return; - if (LinkerOptions) { - // Emit the linker options to the linker .drectve section. According to the - // spec, this section is a space-separated string containing flags for - // linker. - MCSection *Sec = getDrectveSection(); - Streamer.SwitchSection(Sec); - for (const auto &Option : LinkerOptions->operands()) { - for (const auto &Piece : cast(Option)->operands()) { - // Lead with a space for consistency with our dllexport implementation. - std::string Directive(" "); - Directive.append(cast(Piece)->getString()); - Streamer.EmitBytes(Directive); - } + // Emit the linker options to the linker .drectve section. According to the + // spec, this section is a space-separated string containing flags for + // linker. + MCSection *Sec = getDrectveSection(); + Streamer.SwitchSection(Sec); + for (const auto &Option : LinkerOptions->operands()) { + for (const auto &Piece : cast(Option)->operands()) { + // Lead with a space for consistency with our dllexport implementation. + std::string Directive(" "); + Directive.append(cast(Piece)->getString()); + Streamer.EmitBytes(Directive); } } } @@ -1202,11 +1161,6 @@ cast(StaticDtorSection), KeySym, 0); } -void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal( - raw_ostream &OS, const GlobalValue *GV) const { - emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler()); -} - //===----------------------------------------------------------------------===// // Wasm //===----------------------------------------------------------------------===// Index: llvm/lib/IR/AsmWriter.cpp =================================================================== --- llvm/lib/IR/AsmWriter.cpp +++ llvm/lib/IR/AsmWriter.cpp @@ -2405,15 +2405,6 @@ } } -static void PrintDLLStorageClass(GlobalValue::DLLStorageClassTypes SCT, - formatted_raw_ostream &Out) { - switch (SCT) { - case GlobalValue::DefaultStorageClass: break; - case GlobalValue::DLLImportStorageClass: Out << "dllimport "; break; - case GlobalValue::DLLExportStorageClass: Out << "dllexport "; break; - } -} - static void PrintThreadLocalModel(GlobalVariable::ThreadLocalMode TLM, formatted_raw_ostream &Out) { switch (TLM) { @@ -2476,7 +2467,8 @@ Out << getLinkagePrintName(GV->getLinkage()); PrintVisibility(GV->getVisibility(), Out); - PrintDLLStorageClass(GV->getDLLStorageClass(), Out); + if (GV->isDLLImport()) + Out << "dllimport "; PrintThreadLocalModel(GV->getThreadLocalMode(), Out); StringRef UA = getUnnamedAddrEncoding(GV->getUnnamedAddr()); if (!UA.empty()) @@ -2518,7 +2510,8 @@ Out << getLinkagePrintName(GIS->getLinkage()); PrintVisibility(GIS->getVisibility(), Out); - PrintDLLStorageClass(GIS->getDLLStorageClass(), Out); + if (GIS->isDLLImport()) + Out << "dllimport "; PrintThreadLocalModel(GIS->getThreadLocalMode(), Out); StringRef UA = getUnnamedAddrEncoding(GIS->getUnnamedAddr()); if (!UA.empty()) @@ -2637,7 +2630,8 @@ Out << getLinkagePrintName(F->getLinkage()); PrintVisibility(F->getVisibility(), Out); - PrintDLLStorageClass(F->getDLLStorageClass(), Out); + if (F->isDLLImport()) + Out << "dllimport "; // Print the calling convention. if (F->getCallingConv() != CallingConv::C) { Index: llvm/lib/IR/Constants.cpp =================================================================== --- llvm/lib/IR/Constants.cpp +++ llvm/lib/IR/Constants.cpp @@ -395,7 +395,7 @@ bool Constant::isDLLImportDependent() const { auto DLLImportPredicate = [](const GlobalValue *GV) { - return GV->hasDLLImportStorageClass(); + return GV->isDLLImport(); }; return ConstHasGlobalValuePredicate(this, DLLImportPredicate); } Index: llvm/lib/IR/Core.cpp =================================================================== --- llvm/lib/IR/Core.cpp +++ llvm/lib/IR/Core.cpp @@ -1561,13 +1561,15 @@ } LLVMDLLStorageClass LLVMGetDLLStorageClass(LLVMValueRef Global) { - return static_cast( - unwrap(Global)->getDLLStorageClass()); + return unwrap(Global)->isDLLImport() ? LLVMDLLImportStorageClass + : LLVMDefaultStorageClass; } void LLVMSetDLLStorageClass(LLVMValueRef Global, LLVMDLLStorageClass Class) { - unwrap(Global)->setDLLStorageClass( - static_cast(Class)); + auto *GV = unwrap(Global); + if (Class == LLVMDLLExportStorageClass) + GV->addDLLExportFlag(); + GV->setDLLImport(Class == LLVMDLLImportStorageClass); } LLVMBool LLVMHasUnnamedAddr(LLVMValueRef Global) { Index: llvm/lib/IR/Globals.cpp =================================================================== --- llvm/lib/IR/Globals.cpp +++ llvm/lib/IR/Globals.cpp @@ -20,6 +20,7 @@ #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" #include "llvm/Support/Error.h" @@ -66,7 +67,7 @@ void GlobalValue::copyAttributesFrom(const GlobalValue *Src) { setVisibility(Src->getVisibility()); setUnnamedAddr(Src->getUnnamedAddr()); - setDLLStorageClass(Src->getDLLStorageClass()); + setDLLImport(Src->isDLLImport()); } unsigned GlobalValue::getAlignment() const { @@ -83,6 +84,43 @@ return cast(this)->getAlignment(); } +void GlobalValue::addDLLExportFlag() { + Triple TT(getParent()->getTargetTriple()); + Mangler Mang; + + std::string Flag; + raw_string_ostream OS(Flag); + if (TT.isKnownWindowsMSVCEnvironment()) + OS << "/EXPORT:"; + else + OS << "-export:"; + + if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) { + std::string Flag; + raw_string_ostream FlagOS(Flag); + Mang.getNameWithPrefix(FlagOS, this, false); + FlagOS.flush(); + if (Flag[0] == getParent()->getDataLayout().getGlobalPrefix()) + OS << Flag.substr(1); + else + OS << Flag; + } else { + Mang.getNameWithPrefix(OS, this, false); + } + + if (!getValueType()->isFunctionTy()) { + if (TT.isKnownWindowsMSVCEnvironment()) + OS << ",DATA"; + else + OS << ",data"; + } + + getParent() + ->getOrInsertNamedMetadata("llvm.linker.options") + ->addOperand( + MDNode::get(getContext(), {MDString::get(getContext(), OS.str())})); +} + void GlobalObject::setAlignment(unsigned Align) { assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); assert(Align <= MaximumAlignment && Index: llvm/lib/IR/Verifier.cpp =================================================================== --- llvm/lib/IR/Verifier.cpp +++ llvm/lib/IR/Verifier.cpp @@ -649,7 +649,7 @@ } } - Assert(!GV.hasDLLImportStorageClass() || + Assert(!GV.isDLLImport() || (GV.isDeclaration() && GV.hasExternalLinkage()) || GV.hasAvailableExternallyLinkage(), "Global is marked as dllimport, but not external", &GV); @@ -2126,7 +2126,7 @@ Assert(false, "Invalid user of intrinsic instruction!", U); } - Assert(!F.hasDLLImportStorageClass() || + Assert(!F.isDLLImport() || (F.isDeclaration() && F.hasExternalLinkage()) || F.hasAvailableExternallyLinkage(), "Function is marked as dllimport, but not external.", &F); Index: llvm/lib/LTO/LTO.cpp =================================================================== --- llvm/lib/LTO/LTO.cpp +++ llvm/lib/LTO/LTO.cpp @@ -382,20 +382,13 @@ std::unique_ptr &M = Mod.Mod; if (auto E = M->materializeMetadata()) return std::move(E); - if (Metadata *Val = M->getModuleFlag("Linker Options")) { - MDNode *LinkerOptions = cast(Val); - for (const MDOperand &MDOptions : LinkerOptions->operands()) + if (NamedMDNode *LinkerOptions = M->getNamedMetadata("llvm.linker.options")) { + for (MDNode *MDOptions : LinkerOptions->operands()) for (const MDOperand &MDOption : cast(MDOptions)->operands()) LOS << " " << cast(MDOption)->getString(); } } - // Synthesize export flags for symbols with dllexport storage. - const Triple TT(Mods[0].Mod->getTargetTriple()); - Mangler M; - for (const ModuleSymbolTable::Symbol &Sym : SymTab.symbols()) - if (auto *GV = Sym.dyn_cast()) - emitLinkerFlagsForGlobalCOFF(LOS, GV, TT, M); LOS.flush(); return LinkerOpts; } Index: llvm/lib/LTO/LTOModule.cpp =================================================================== --- llvm/lib/LTO/LTOModule.cpp +++ llvm/lib/LTO/LTOModule.cpp @@ -637,10 +637,10 @@ raw_string_ostream OS(LinkerOpts); // Linker Options - if (Metadata *Val = getModule().getModuleFlag("Linker Options")) { - MDNode *LinkerOptions = cast(Val); + if (NamedMDNode *LinkerOptions = + getModule().getNamedMetadata("llvm.linker.options")) { for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) { - MDNode *MDOptions = cast(LinkerOptions->getOperand(i)); + MDNode *MDOptions = LinkerOptions->getOperand(i); for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) { MDString *MDOption = cast(MDOptions->getOperand(ii)); OS << " " << MDOption->getString(); @@ -648,16 +648,5 @@ } } - // Globals - we only need to do this for COFF. - const Triple TT(_target->getTargetTriple()); - if (!TT.isOSBinFormatCOFF()) - return; - Mangler M; - for (const NameAndAttributes &Sym : _symbols) { - if (!Sym.symbol) - continue; - emitLinkerFlagsForGlobalCOFF(OS, Sym.symbol, TT, M); - } - // Add other interesting metadata here. } Index: llvm/lib/Linker/LinkModules.cpp =================================================================== --- llvm/lib/Linker/LinkModules.cpp +++ llvm/lib/Linker/LinkModules.cpp @@ -260,7 +260,7 @@ if (SrcIsDeclaration) { // If Src is external or if both Src & Dest are external.. Just link the // external globals, we aren't adding anything. - if (Src.hasDLLImportStorageClass()) { + if (Src.isDLLImport()) { // If one of GVs is marked as DLLImport, result should be dllimport'ed. LinkFromSrc = DestIsDeclaration; return false; Index: llvm/lib/Object/ModuleSymbolTable.cpp =================================================================== --- llvm/lib/Object/ModuleSymbolTable.cpp +++ llvm/lib/Object/ModuleSymbolTable.cpp @@ -220,7 +220,7 @@ } auto *GV = S.get(); - if (GV->hasDLLImportStorageClass()) + if (GV->isDLLImport()) OS << "__imp_"; Mang.getNameWithPrefix(OS, GV, false); Index: llvm/lib/Target/ARM/ARMAsmPrinter.cpp =================================================================== --- llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -553,29 +553,6 @@ OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); } - if (TT.isOSBinFormatCOFF()) { - const auto &TLOF = - static_cast(getObjFileLowering()); - - std::string Flags; - raw_string_ostream OS(Flags); - - for (const auto &Function : M) - TLOF.emitLinkerFlagsForGlobal(OS, &Function); - for (const auto &Global : M.globals()) - TLOF.emitLinkerFlagsForGlobal(OS, &Global); - for (const auto &Alias : M.aliases()) - TLOF.emitLinkerFlagsForGlobal(OS, &Alias); - - OS.flush(); - - // Output collected flags - if (!Flags.empty()) { - OutStreamer->SwitchSection(TLOF.getDrectveSection()); - OutStreamer->EmitBytes(Flags); - } - } - // The last attribute to be emitted is ABI_optimization_goals MCTargetStreamer &TS = *OutStreamer->getTargetStreamer(); ARMTargetStreamer &ATS = static_cast(TS); Index: llvm/lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- llvm/lib/Target/ARM/ARMISelLowering.cpp +++ llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -2059,12 +2059,12 @@ } else if (Subtarget->isTargetCOFF()) { assert(Subtarget->isTargetWindows() && "Windows is the only supported COFF target"); - unsigned TargetFlags = GV->hasDLLImportStorageClass() + unsigned TargetFlags = GV->isDLLImport() ? ARMII::MO_DLLIMPORT : ARMII::MO_NO_FLAG; Callee = DAG.getTargetGlobalAddress(GV, dl, PtrVt, /*Offset=*/0, TargetFlags); - if (GV->hasDLLImportStorageClass()) + if (GV->isDLLImport()) Callee = DAG.getLoad(PtrVt, dl, DAG.getEntryNode(), DAG.getNode(ARMISD::Wrapper, dl, PtrVt, Callee), @@ -3234,7 +3234,7 @@ const GlobalValue *GV = cast(Op)->getGlobal(); const ARMII::TOF TargetFlags = - (GV->hasDLLImportStorageClass() ? ARMII::MO_DLLIMPORT : ARMII::MO_NO_FLAG); + (GV->isDLLImport() ? ARMII::MO_DLLIMPORT : ARMII::MO_NO_FLAG); EVT PtrVT = getPointerTy(DAG.getDataLayout()); SDValue Result; SDLoc DL(Op); @@ -3246,7 +3246,7 @@ Result = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, DAG.getTargetGlobalAddress(GV, DL, PtrVT, /*Offset=*/0, TargetFlags)); - if (GV->hasDLLImportStorageClass()) + if (GV->isDLLImport()) Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Result, MachinePointerInfo::getGOT(DAG.getMachineFunction())); return Result; Index: llvm/lib/Target/TargetMachine.cpp =================================================================== --- llvm/lib/Target/TargetMachine.cpp +++ llvm/lib/Target/TargetMachine.cpp @@ -124,7 +124,7 @@ const Triple &TT = getTargetTriple(); // DLLImport explicitly marks the GV as external. - if (GV && GV->hasDLLImportStorageClass()) + if (GV && GV->isDLLImport()) return false; // Every other GV is local on COFF. Index: llvm/lib/Target/X86/X86AsmPrinter.cpp =================================================================== --- llvm/lib/Target/X86/X86AsmPrinter.cpp +++ llvm/lib/Target/X86/X86AsmPrinter.cpp @@ -619,30 +619,8 @@ OutStreamer->EmitSymbolAttribute(S, MCSA_Global); } - if (TT.isOSBinFormatCOFF()) { - const TargetLoweringObjectFileCOFF &TLOFCOFF = - static_cast(getObjFileLowering()); - - std::string Flags; - raw_string_ostream FlagsOS(Flags); - - for (const auto &Function : M) - TLOFCOFF.emitLinkerFlagsForGlobal(FlagsOS, &Function); - for (const auto &Global : M.globals()) - TLOFCOFF.emitLinkerFlagsForGlobal(FlagsOS, &Global); - for (const auto &Alias : M.aliases()) - TLOFCOFF.emitLinkerFlagsForGlobal(FlagsOS, &Alias); - - FlagsOS.flush(); - - // Output collected flags. - if (!Flags.empty()) { - OutStreamer->SwitchSection(TLOFCOFF.getDrectveSection()); - OutStreamer->EmitBytes(Flags); - } - + if (TT.isOSBinFormatCOFF()) SM.serializeToStackMapSection(); - } if (TT.isOSBinFormatELF()) { SM.serializeToStackMapSection(); Index: llvm/lib/Target/X86/X86FastISel.cpp =================================================================== --- llvm/lib/Target/X86/X86FastISel.cpp +++ llvm/lib/Target/X86/X86FastISel.cpp @@ -1101,7 +1101,7 @@ return false; // Can't handle DLL Import. - if (GV->hasDLLImportStorageClass()) + if (GV->isDLLImport()) return false; // Can't handle TLS. Index: llvm/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/lib/Target/X86/X86ISelLowering.cpp +++ llvm/lib/Target/X86/X86ISelLowering.cpp @@ -3739,7 +3739,7 @@ // We should use extra load for direct calls to dllimported functions in // non-JIT mode. const GlobalValue *GV = G->getGlobal(); - if (!GV->hasDLLImportStorageClass()) { + if (!GV->isDLLImport()) { unsigned char OpFlags = Subtarget.classifyGlobalFunctionReference(GV); Callee = DAG.getTargetGlobalAddress( Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp =================================================================== --- llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -2365,7 +2365,7 @@ Target->takeName(&*J); Target->setLinkage(J->getLinkage()); Target->setVisibility(J->getVisibility()); - Target->setDLLStorageClass(J->getDLLStorageClass()); + Target->setDLLImport(J->isDLLImport()); if (Used.usedErase(&*J)) Used.usedInsert(Target); Index: llvm/lib/Transforms/IPO/Internalize.cpp =================================================================== --- llvm/lib/Transforms/IPO/Internalize.cpp +++ llvm/lib/Transforms/IPO/Internalize.cpp @@ -98,10 +98,6 @@ if (GV.hasAvailableExternallyLinkage()) return true; - // Assume that dllexported symbols are referenced elsewhere - if (GV.hasDLLExportStorageClass()) - return true; - // Already local, has nothing to do. if (GV.hasLocalLinkage()) return false; Index: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1980,7 +1980,6 @@ // Set meaningful attributes for indicator symbol. ODRIndicatorSym->setVisibility(NewGlobal->getVisibility()); - ODRIndicatorSym->setDLLStorageClass(NewGlobal->getDLLStorageClass()); ODRIndicatorSym->setAlignment(1); ODRIndicator = ODRIndicatorSym; InstrumentedGlobal = GA; Index: llvm/lib/Transforms/Utils/Evaluator.cpp =================================================================== --- llvm/lib/Transforms/Utils/Evaluator.cpp +++ llvm/lib/Transforms/Utils/Evaluator.cpp @@ -50,7 +50,7 @@ // Simple global addresses are supported, do not allow dllimport or // thread-local globals. if (auto *GV = dyn_cast(C)) - return !GV->hasDLLImportStorageClass() && !GV->isThreadLocal(); + return !GV->isDLLImport() && !GV->isThreadLocal(); // Simple integer, undef, constant aggregate zero, etc are all supported. if (C->getNumOperands() == 0 || isa(C))