Index: cfe/trunk/lib/CodeGen/CodeGenModule.h =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.h +++ cfe/trunk/lib/CodeGen/CodeGenModule.h @@ -429,7 +429,7 @@ llvm::SmallPtrSet EmittedModuleInitializers; /// \brief A vector of metadata strings. - SmallVector LinkerOptionsMetadata; + SmallVector LinkerOptionsMetadata; /// @name Cache for Objective-C runtime types /// @{ @@ -1058,13 +1058,14 @@ void RefreshTypeCacheForClass(const CXXRecordDecl *Class); - /// \brief Appends Opts to the "Linker Options" metadata value. + /// \brief Appends Opts to the "llvm.linker.options" metadata value. void AppendLinkerOptions(StringRef Opts); /// \brief Appends a detect mismatch command to the linker options. void AddDetectMismatch(StringRef Name, StringRef Value); - /// \brief Appends a dependent lib to the "Linker Options" metadata value. + /// \brief Appends a dependent lib to the "llvm.linker.options" metadata + /// value. void AddDependentLib(StringRef Lib); llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD); Index: cfe/trunk/lib/CodeGen/CodeGenModule.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp @@ -1243,7 +1243,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) { @@ -1331,7 +1331,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) @@ -1340,9 +1340,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() { Index: cfe/trunk/test/CodeGen/dependent-lib.c =================================================================== --- cfe/trunk/test/CodeGen/dependent-lib.c +++ cfe/trunk/test/CodeGen/dependent-lib.c @@ -3,14 +3,10 @@ // RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple x86_64-pc-win32 -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple i686-pc-linux -emit-llvm -o - | FileCheck -check-prefix LINUX %s -// CHECK: !llvm.module.flags = !{{{.*}}} -// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[link_opts:[0-9]+]]} -// CHECK: ![[link_opts]] = !{![[msvcrt:[0-9]+]]} +// CHECK: !llvm.linker.options = !{![[msvcrt:[0-9]+]]} // CHECK: ![[msvcrt]] = !{!"/DEFAULTLIB:msvcrt.lib"} -// LINUX: !llvm.module.flags = !{{{.*}}} -// LINUX: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[link_opts:[0-9]+]]} -// LINUX: ![[link_opts]] = !{![[msvcrt:[0-9]+]]} +// LINUX: !llvm.linker.options = !{![[msvcrt:[0-9]+]]} // LINUX: ![[msvcrt]] = !{!"-lmsvcrt"} int f(); Index: cfe/trunk/test/CodeGen/linker-option.c =================================================================== --- cfe/trunk/test/CodeGen/linker-option.c +++ cfe/trunk/test/CodeGen/linker-option.c @@ -1,8 +1,6 @@ // RUN: %clang_cc1 %s --linker-option=/include:foo -triple i686-pc-win32 -emit-llvm -o - | FileCheck %s -// CHECK: !llvm.module.flags = !{{{.*}}} -// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[link_opts:[0-9]+]]} -// CHECK: ![[link_opts]] = !{![[msvcrt:[0-9]+]]} +// CHECK: !llvm.linker.options = !{![[msvcrt:[0-9]+]]} // CHECK: ![[msvcrt]] = !{!"/include:foo"} int f(); Index: cfe/trunk/test/CodeGen/pragma-comment.c =================================================================== --- cfe/trunk/test/CodeGen/pragma-comment.c +++ cfe/trunk/test/CodeGen/pragma-comment.c @@ -14,9 +14,7 @@ #pragma comment(linker," /bar=" BAR) #pragma comment(linker," /foo=\"foo bar\"") -// CHECK: !llvm.module.flags = !{{{.*}}} -// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[link_opts:[0-9]+]]} -// CHECK: ![[link_opts]] = !{![[msvcrt:[0-9]+]], ![[kernel32:[0-9]+]], ![[USER32:[0-9]+]], ![[space:[0-9]+]], ![[bar:[0-9]+]], ![[foo:[0-9]+]]} +// CHECK: !llvm.linker.options = !{![[msvcrt:[0-9]+]], ![[kernel32:[0-9]+]], ![[USER32:[0-9]+]], ![[space:[0-9]+]], ![[bar:[0-9]+]], ![[foo:[0-9]+]]} // CHECK: ![[msvcrt]] = !{!"/DEFAULTLIB:msvcrt.lib"} // CHECK: ![[kernel32]] = !{!"/DEFAULTLIB:kernel32.lib"} // CHECK: ![[USER32]] = !{!"/DEFAULTLIB:USER32.LIB"} Index: cfe/trunk/test/CodeGen/pragma-detect_mismatch.c =================================================================== --- cfe/trunk/test/CodeGen/pragma-detect_mismatch.c +++ cfe/trunk/test/CodeGen/pragma-detect_mismatch.c @@ -6,8 +6,6 @@ #define BAR "2" #pragma detect_mismatch("test2", BAR) -// CHECK: !llvm.module.flags = !{{{.*}}} -// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[link_opts:[0-9]+]]} -// CHECK: ![[link_opts]] = !{![[test:[0-9]+]], ![[test2:[0-9]+]]} +// CHECK: !llvm.linker.options = !{![[test:[0-9]+]], ![[test2:[0-9]+]]} // CHECK: ![[test]] = !{!"/FAILIFMISMATCH:\22test=1\22"} // CHECK: ![[test2]] = !{!"/FAILIFMISMATCH:\22test2=2\22"} Index: cfe/trunk/test/CodeGenCXX/ms-thread_local.cpp =================================================================== --- cfe/trunk/test/CodeGenCXX/ms-thread_local.cpp +++ cfe/trunk/test/CodeGenCXX/ms-thread_local.cpp @@ -27,7 +27,5 @@ return c; } -// CHECK: !llvm.module.flags = !{{{.*}}} -// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[link_opts:[0-9]+]]} -// CHECK: ![[link_opts]] = !{![[dyn_tls_init:[0-9]+]]} +// CHECK: !llvm.linker.options = !{![[dyn_tls_init:[0-9]+]]} // CHECK: ![[dyn_tls_init]] = !{!"/include:___dyn_tls_init@12"} Index: cfe/trunk/test/CodeGenObjC/availability-cf-link-guard.m =================================================================== --- cfe/trunk/test/CodeGenObjC/availability-cf-link-guard.m +++ cfe/trunk/test/CodeGenObjC/availability-cf-link-guard.m @@ -37,9 +37,8 @@ // CHECK_NO_GUARD-NOT: __clang_at_available_requires_core_foundation_framework // CHECK_NO_GUARD-NOT: CFBundleGetVersionNumber -// CHECK_LINK_OPT: !"Linker Options", ![[OPTS:[0-9]+]] -// CHECK_LINK_OPT: ![[OPTS]] = !{![[FRAMEWORK:[0-9]+]] +// CHECK_LINK_OPT: !llvm.linker.options = !{![[FRAMEWORK:[0-9]+]] // CHECK_LINK_OPT: ![[FRAMEWORK]] = !{!"-framework", !"CoreFoundation"} -// CHECK_NO_GUARD-NOT: "Linker Options" +// CHECK_NO_GUARD-NOT: !llvm.linker.options // CHECK_NO_GUARD-NOT: CoreFoundation Index: cfe/trunk/test/Modules/autolink.m =================================================================== --- cfe/trunk/test/Modules/autolink.m +++ cfe/trunk/test/Modules/autolink.m @@ -36,9 +36,7 @@ // NOTE: "autolink_sub" is intentionally not linked. -// CHECK: !llvm.module.flags = !{{{.*}}} -// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[AUTOLINK_OPTIONS:[0-9]+]]} -// CHECK: ![[AUTOLINK_OPTIONS]] = !{![[AUTOLINK_PCH:[0-9]+]], ![[AUTOLINK_FRAMEWORK:[0-9]+]], ![[AUTOLINK:[0-9]+]], ![[DEPENDSONMODULE:[0-9]+]], ![[MODULE:[0-9]+]], ![[NOUMBRELLA:[0-9]+]]} +// CHECK: !llvm.linker.options = !{![[AUTOLINK_PCH:[0-9]+]], ![[AUTOLINK_FRAMEWORK:[0-9]+]], ![[AUTOLINK:[0-9]+]], ![[DEPENDSONMODULE:[0-9]+]], ![[MODULE:[0-9]+]], ![[NOUMBRELLA:[0-9]+]]} // CHECK: ![[AUTOLINK_PCH]] = !{!"{{(\\01|-l|/DEFAULTLIB:)}}autolink_from_pch{{(\.lib)?}}"} // CHECK: ![[AUTOLINK_FRAMEWORK]] = !{!"-framework", !"autolink_framework"} // CHECK: ![[AUTOLINK]] = !{!"{{(\\01|-l|/DEFAULTLIB:)}}autolink{{(\.lib)?}}"} @@ -47,4 +45,4 @@ // CHECK: ![[NOUMBRELLA]] = !{!"-framework", !"NoUmbrella"} // CHECK-AUTOLINK-DISABLED: !llvm.module.flags -// CHECK-AUTOLINK-DISABLED-NOT: "Linker Options" +// CHECK-AUTOLINK-DISABLED-NOT: !llvm.linker.options Index: cfe/trunk/test/Modules/autolinkTBD.m =================================================================== --- cfe/trunk/test/Modules/autolinkTBD.m +++ cfe/trunk/test/Modules/autolinkTBD.m @@ -8,10 +8,8 @@ return foo(); } -// CHECK: !llvm.module.flags = !{{{.*}}} -// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[AUTOLINK_OPTIONS:[0-9]+]]} -// CHECK: ![[AUTOLINK_OPTIONS]] = !{![[AUTOLINK_FRAMEWORK:[0-9]+]]} +// CHECK: !llvm.linker.options = !{![[AUTOLINK_FRAMEWORK:[0-9]+]]} // CHECK: ![[AUTOLINK_FRAMEWORK]] = !{!"-framework", !"AutolinkTBD"} // CHECK-AUTOLINK-DISABLED: !llvm.module.flags -// CHECK-AUTOLINK-DISABLED-NOT: "Linker Options" +// CHECK-AUTOLINK-DISABLED-NOT: !llvm.linker.options Index: cfe/trunk/test/Modules/module-impl-with-link.c =================================================================== --- cfe/trunk/test/Modules/module-impl-with-link.c +++ cfe/trunk/test/Modules/module-impl-with-link.c @@ -1,7 +1,6 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fmodule-name=Clib %s -I %S/Inputs/module-impl-with-link -emit-llvm -o - | FileCheck %s #include "foo.h" -// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[LINK_OPTIONS:[0-9]+]]} // Make sure we don't generate linker option for module Clib since this TU is // an implementation of Clib. -// CHECK: ![[LINK_OPTIONS]] = !{} +// CHECK: !llvm.linker.options = !{} Index: lld/trunk/test/COFF/Inputs/constant-export.ll =================================================================== --- lld/trunk/test/COFF/Inputs/constant-export.ll +++ lld/trunk/test/COFF/Inputs/constant-export.ll @@ -3,8 +3,5 @@ @__CFConstantStringClassReference = common global [32 x i32] zeroinitializer, align 4 -!llvm.module.flags = !{!0} - -!0 = !{i32 6, !"Linker Options", !1} -!1 = !{!2} -!2 = !{!" -export:___CFConstantStringClassReference,CONSTANT"} +!llvm.linker.options = !{!0} +!0 = !{!" -export:___CFConstantStringClassReference,CONSTANT"} Index: lld/trunk/test/COFF/include-lto.ll =================================================================== --- lld/trunk/test/COFF/include-lto.ll +++ lld/trunk/test/COFF/include-lto.ll @@ -17,8 +17,5 @@ ret i32 0 } -!llvm.module.flags = !{!0} - -!0 = !{i32 6, !"Linker Options", !1} -!1 = !{!2} -!2 = !{!"/INCLUDE:foo"} +!llvm.linker.options = !{!0} +!0 = !{!"/INCLUDE:foo"} Index: lld/trunk/test/COFF/lto-linker-opts.ll =================================================================== --- lld/trunk/test/COFF/lto-linker-opts.ll +++ lld/trunk/test/COFF/lto-linker-opts.ll @@ -4,8 +4,5 @@ target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc" -!llvm.module.flags = !{!0} - -!0 = !{i32 6, !"Linker Options", !1} -!1 = !{!2} -!2 = !{!"/DEFAULTLIB:ret42.lib"} +!llvm.linker.options = !{!0} +!0 = !{!"/DEFAULTLIB:ret42.lib"} Index: llvm/trunk/docs/LangRef.rst =================================================================== --- llvm/trunk/docs/LangRef.rst +++ llvm/trunk/docs/LangRef.rst @@ -5352,40 +5352,6 @@ - A module with ``Objective-C Garbage Collection`` set to 0 cannot be merged with a module with ``Objective-C GC Only`` set to 6. -Automatic Linker Flags Module Flags Metadata --------------------------------------------- - -Some targets support embedding flags to the linker inside individual object -files. Typically this is used in conjunction with language extensions which -allow source files to explicitly declare the libraries they depend on, and have -these automatically be transmitted to the linker via object files. - -These flags are encoded in the IR using metadata in the module flags section, -using the ``Linker Options`` key. The merge behavior for this flag is required -to be ``AppendUnique``, and the value for the key is expected to be a metadata -node which should be a list of other metadata nodes, each of which should be a -list of metadata strings defining linker options. - -For example, the following metadata section specifies two separate sets of -linker options, presumably to link against ``libz`` and the ``Cocoa`` -framework:: - - !0 = !{ i32 6, !"Linker Options", - !{ - !{ !"-lz" }, - !{ !"-framework", !"Cocoa" } } } - !llvm.module.flags = !{ !0 } - -The metadata encoding as lists of lists of options, as opposed to a collapsed -list of options, is chosen so that the IR encoding can use multiple option -strings to specify e.g., a single library, while still having that specifier be -preserved as an atomic element that can be recognized by a target specific -assembly writer or object file emitter. - -Each individual option is required to be either a valid option for the target's -linker, or an option that is reserved by the target specific assembly writer or -object file emitter. No other aspect of these options is defined by the IR. - C type width Module Flags Metadata ---------------------------------- @@ -5422,6 +5388,37 @@ !0 = !{i32 1, !"short_wchar", i32 1} !1 = !{i32 1, !"short_enum", i32 0} +Automatic Linker Flags Named Metadata +===================================== + +Some targets support embedding flags to the linker inside individual object +files. Typically this is used in conjunction with language extensions which +allow source files to explicitly declare the libraries they depend on, and have +these automatically be transmitted to the linker via object files. + +These flags are encoded in the IR using named metadata with the name +``!llvm.linker.options``. Each operand is expected to be a metadata node +which should be a list of other metadata nodes, each of which should be a +list of metadata strings defining linker options. + +For example, the following metadata section specifies two separate sets of +linker options, presumably to link against ``libz`` and the ``Cocoa`` +framework:: + + !0 = !{ !"-lz" }, + !1 = !{ !"-framework", !"Cocoa" } } } + !llvm.linker.options = !{ !0, !1 } + +The metadata encoding as lists of lists of options, as opposed to a collapsed +list of options, is chosen so that the IR encoding can use multiple option +strings to specify e.g., a single library, while still having that specifier be +preserved as an atomic element that can be recognized by a target specific +assembly writer or object file emitter. + +Each individual option is required to be either a valid option for the target's +linker, or an option that is reserved by the target specific assembly writer or +object file emitter. No other aspect of these options is defined by the IR. + .. _intrinsicglobalvariables: Intrinsic Global Variables Index: llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -42,9 +42,8 @@ ~TargetLoweringObjectFileELF() override = default; /// Emit Obj-C garbage collection and linker options. - void emitModuleFlags(MCStreamer &Streamer, - ArrayRef ModuleFlags, - const TargetMachine &TM) const override; + void emitModuleMetadata(MCStreamer &Streamer, Module &M, + const TargetMachine &TM) const override; void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM, const MCSymbol *Sym) const override; @@ -99,9 +98,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; @@ -155,9 +153,8 @@ const TargetMachine &TM) const override; /// Emit Obj-C garbage collection and linker options. - void emitModuleFlags(MCStreamer &Streamer, - ArrayRef ModuleFlags, - const TargetMachine &TM) const override; + void emitModuleMetadata(MCStreamer &Streamer, Module &M, + const TargetMachine &TM) const override; MCSection *getStaticCtorSection(unsigned Priority, const MCSymbol *KeySym) const override; Index: llvm/trunk/include/llvm/LTO/legacy/LTOModule.h =================================================================== --- llvm/trunk/include/llvm/LTO/legacy/LTOModule.h +++ llvm/trunk/include/llvm/LTO/legacy/LTOModule.h @@ -158,7 +158,7 @@ private: /// Parse metadata from the module - // FIXME: it only parses "Linker Options" metadata at the moment + // FIXME: it only parses "llvm.linker.options" metadata at the moment void parseMetadata(); /// Parse the symbols from the module and model-level ASM and add them to Index: llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h =================================================================== --- llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h +++ llvm/trunk/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. Index: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2608,6 +2608,16 @@ if (Error Err = MDLoader->parseModuleMetadata()) return Err; } + + // Upgrade "Linker Options" module flag to "llvm.linker.options" module-level + // metadata. + 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)); + } + DeferredMetadataInfo.clear(); return Error::success(); } Index: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1286,11 +1286,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/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp =================================================================== --- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -61,9 +61,11 @@ using namespace llvm; using namespace dwarf; -static void GetObjCImageInfo(ArrayRef ModuleFlags, - unsigned &Version, unsigned &Flags, +static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags, StringRef &Section) { + SmallVector ModuleFlags; + M.getModuleFlagsMetadata(ModuleFlags); + for (const auto &MFE: ModuleFlags) { // Ignore flags with 'Require' behaviour. if (MFE.Behavior == Module::Require) @@ -88,14 +90,13 @@ // ELF //===----------------------------------------------------------------------===// -void TargetLoweringObjectFileELF::emitModuleFlags( - MCStreamer &Streamer, ArrayRef ModuleFlags, - const TargetMachine &TM) const { +void TargetLoweringObjectFileELF::emitModuleMetadata( + MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { unsigned Version = 0; unsigned Flags = 0; StringRef Section; - GetObjCImageInfo(ModuleFlags, Version, Flags, Section); + GetObjCImageInfo(M, Version, Flags, Section); if (Section.empty()) return; @@ -618,20 +619,10 @@ } } -/// emitModuleFlags - Perform code emission for module flags. -void TargetLoweringObjectFileMachO::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 TargetLoweringObjectFileMachO::emitModuleMetadata( + MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { // Emit the linker options if present. - if (LinkerOptions) { + if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { for (const auto &Option : LinkerOptions->operands()) { SmallVector StrOptions; for (const auto &Piece : cast(Option)->operands()) @@ -643,7 +634,8 @@ unsigned VersionVal = 0; unsigned ImageInfoFlags = 0; StringRef SectionVal; - GetObjCImageInfo(ModuleFlags, VersionVal, ImageInfoFlags, SectionVal); + + GetObjCImageInfo(M, VersionVal, ImageInfoFlags, SectionVal); // The section is mandatory. If we don't have it, then we don't have GC info. if (SectionVal.empty()) @@ -1159,18 +1151,9 @@ 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); - } - - if (LinkerOptions) { +void TargetLoweringObjectFileCOFF::emitModuleMetadata( + MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { + if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { // Emit the linker options to the linker .drectve section. According to the // spec, this section is a space-separated string containing flags for // linker. @@ -1190,7 +1173,7 @@ unsigned Flags = 0; StringRef Section; - GetObjCImageInfo(ModuleFlags, Version, Flags, Section); + GetObjCImageInfo(M, Version, Flags, Section); if (Section.empty()) return; Index: llvm/trunk/lib/IR/Verifier.cpp =================================================================== --- llvm/trunk/lib/IR/Verifier.cpp +++ llvm/trunk/lib/IR/Verifier.cpp @@ -1330,6 +1330,14 @@ = mdconst::dyn_extract_or_null(Op->getOperand(2)); Assert(Value, "wchar_size metadata requires constant integer argument"); } + + if (ID->getString() == "Linker Options") { + // If the llvm.linker.options named metadata exists, we assume that the + // bitcode reader has upgraded the module flag. Otherwise the flag might + // have been created by a client directly. + Assert(M.getNamedMetadata("llvm.linker.options"), + "'Linker Options' named metadata no longer supported"); + } } /// Return true if this attribute kind only applies to functions. Index: llvm/trunk/lib/LTO/LTOModule.cpp =================================================================== --- llvm/trunk/lib/LTO/LTOModule.cpp +++ llvm/trunk/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(); Index: llvm/trunk/lib/Object/IRSymtab.cpp =================================================================== --- llvm/trunk/lib/Object/IRSymtab.cpp +++ llvm/trunk/lib/Object/IRSymtab.cpp @@ -109,9 +109,9 @@ if (TT.isOSBinFormatCOFF()) { if (auto E = M->materializeMetadata()) return 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()) COFFLinkerOptsOS << " " << cast(MDOption)->getString(); } Index: llvm/trunk/test/Bitcode/upgrade-linker-options.ll =================================================================== --- llvm/trunk/test/Bitcode/upgrade-linker-options.ll +++ llvm/trunk/test/Bitcode/upgrade-linker-options.ll @@ -0,0 +1,15 @@ +; RUN: llvm-as -disable-verify < %s | llvm-dis | FileCheck %s +; RUN: not llvm-as < %s 2>&1 | FileCheck --check-prefix=ERROR %s + +; CHECK: !llvm.linker.options = !{!2, !3} +; CHECK: !2 = !{!"/DEFAULTLIB:libcmtd.lib"} +; CHECK: !3 = !{!"/DEFAULTLIB:oldnames.lib"} + +; ERROR: 'Linker Options' named metadata no longer supported + +!0 = !{i32 6, !"Linker Options", !1} +!1 = !{!2, !3} +!2 = !{!"/DEFAULTLIB:libcmtd.lib"} +!3 = !{!"/DEFAULTLIB:oldnames.lib"} + +!llvm.module.flags = !{!0} Index: llvm/trunk/test/DebugInfo/COFF/array-odr-violation.ll =================================================================== --- llvm/trunk/test/DebugInfo/COFF/array-odr-violation.ll +++ llvm/trunk/test/DebugInfo/COFF/array-odr-violation.ll @@ -65,7 +65,7 @@ !llvm.dbg.cu = !{!2, !11} !llvm.ident = !{!13, !13} -!llvm.module.flags = !{!14, !18, !19, !20} +!llvm.module.flags = !{!18, !19, !20} !0 = !DIGlobalVariableExpression(var: !1) !1 = distinct !DIGlobalVariable(name: "a", linkageName: "\01?a@@3TYYSTYPE@@A", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true) @@ -81,10 +81,6 @@ !11 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !12, producer: "clang version 5.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4) !12 = !DIFile(filename: "b.cpp", directory: "C:\5Csrc\5Cllvm-project\5Cbuild", checksumkind: CSK_MD5, checksum: "9cfd390d8827beab36769147bb037abc") !13 = !{!"clang version 5.0.0 "} -!14 = !{i32 6, !"Linker Options", !15} -!15 = !{!16, !17} -!16 = !{!"/DEFAULTLIB:libcmt.lib"} -!17 = !{!"/DEFAULTLIB:oldnames.lib"} !18 = !{i32 2, !"CodeView", i32 1} !19 = !{i32 2, !"Debug Info Version", i32 3} !20 = !{i32 1, !"PIC Level", i32 2} Index: llvm/trunk/test/DebugInfo/COFF/inlining-same-name.ll =================================================================== --- llvm/trunk/test/DebugInfo/COFF/inlining-same-name.ll +++ llvm/trunk/test/DebugInfo/COFF/inlining-same-name.ll @@ -39,12 +39,11 @@ ret void } -!llvm.module.flags = !{!0, !1, !2} +!llvm.module.flags = !{!0, !1} !llvm.dbg.cu = !{!4} !0 = !{i32 2, !"CodeView", i32 1} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = !{i32 6, !"Linker Options", !{}} !4 = distinct !DICompileUnit(language: DW_LANG_D, file: !5, producer: "LDC (http://wiki.dlang.org/LDC)", isOptimized: false, runtimeVersion: 1, emissionKind: FullDebug) !5 = !DIFile(filename: "opover2.d", directory: "C:\5CLDC\5Cninja-ldc\5C..\5Cldc\5Ctests\5Cd2\5Cdmd-testsuite\5Crunnable") !6 = !DILocation(line: 302, column: 9, scope: !7, inlinedAt: !15) Index: llvm/trunk/test/LTO/Resolution/X86/symtab-elf.ll =================================================================== --- llvm/trunk/test/LTO/Resolution/X86/symtab-elf.ll +++ llvm/trunk/test/LTO/Resolution/X86/symtab-elf.ll @@ -6,8 +6,8 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" ; CHECK-NOT: linker opts: -!0 = !{i32 6, !"Linker Options", !{!{!"/include:foo"}}} -!llvm.module.flags = !{ !0 } +!0 = !{!"/include:foo"} +!llvm.linker.options = !{ !0 } @g1 = global i32 0 Index: llvm/trunk/test/LTO/Resolution/X86/symtab.ll =================================================================== --- llvm/trunk/test/LTO/Resolution/X86/symtab.ll +++ llvm/trunk/test/LTO/Resolution/X86/symtab.ll @@ -9,8 +9,8 @@ source_filename = "src.c" ; CHECK: linker opts: /include:foo -!0 = !{i32 6, !"Linker Options", !{!{!"/include:foo"}}} -!llvm.module.flags = !{ !0 } +!0 = !{!"/include:foo"} +!llvm.linker.options = !{ !0 } ; CHECK: D------X _fun define i32 @fun() { Index: llvm/trunk/test/MC/COFF/cv-compiler-info.ll =================================================================== --- llvm/trunk/test/MC/COFF/cv-compiler-info.ll +++ llvm/trunk/test/MC/COFF/cv-compiler-info.ll @@ -13,7 +13,7 @@ attributes #0 = { nounwind sspstrong "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } !llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!3, !7, !8} +!llvm.module.flags = !{!7, !8} !llvm.ident = !{!9} !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 4.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) @@ -35,10 +35,6 @@ ; CHECK-NOT: .short 4412 # Record kind: S_COMPILE3 !1 = !DIFile(filename: "D:\5Csrc\5Cscopes\5Cfoo.cpp", directory: "D:\5Csrc\5Cscopes\5Cclang") !2 = !{} -!3 = !{i32 6, !"Linker Options", !4} -!4 = !{!5, !6} -!5 = !{!"/DEFAULTLIB:libcmtd.lib"} -!6 = !{!"/DEFAULTLIB:oldnames.lib"} !7 = !{i32 2, !"CodeView", i32 1} !8 = !{i32 2, !"Debug Info Version", i32 3} !9 = !{!"clang version 4.0.0 "} Index: llvm/trunk/test/MC/COFF/linker-options.ll =================================================================== --- llvm/trunk/test/MC/COFF/linker-options.ll +++ llvm/trunk/test/MC/COFF/linker-options.ll @@ -1,8 +1,10 @@ ; RUN: llc -O0 -mtriple=i386-pc-win32 -filetype=asm -o - %s | FileCheck %s -!0 = !{i32 6, !"Linker Options", !{!{!"/DEFAULTLIB:msvcrt.lib"}, !{!"/DEFAULTLIB:msvcrt.lib", !"/DEFAULTLIB:secur32.lib"}, !{!"/DEFAULTLIB:\22C:\5Cpath to\5Casan_rt.lib\22"}, !{!"\22/with spaces\22"}}} - -!llvm.module.flags = !{ !0 } +!0 = !{!"/DEFAULTLIB:msvcrt.lib"} +!1 = !{!"/DEFAULTLIB:msvcrt.lib", !"/DEFAULTLIB:secur32.lib"} +!2 = !{!"/DEFAULTLIB:\22C:\5Cpath to\5Casan_rt.lib\22"} +!3 = !{!"\22/with spaces\22"} +!llvm.linker.options = !{!0, !1, !2, !3} define dllexport void @foo() { ret void Index: llvm/trunk/test/MC/MachO/linker-options.ll =================================================================== --- llvm/trunk/test/MC/MachO/linker-options.ll +++ llvm/trunk/test/MC/MachO/linker-options.ll @@ -27,6 +27,7 @@ ; CHECK-OBJ: ] ; CHECK-OBJ: } -!0 = !{i32 6, !"Linker Options", !{!{!"-lz"}, !{!"-framework", !"Cocoa"}, !{!"-lmath"}}} - -!llvm.module.flags = !{ !0 } +!0 = !{!"-lz"} +!1 = !{!"-framework", !"Cocoa"} +!2 = !{!"-lmath"} +!llvm.linker.options = !{!0, !1, !2}