mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-26 21:20:37 +00:00
IR: Replace the "Linker Options" module flag with "llvm.linker.options" named metadata.
The new metadata is easier to manipulate than module flags. Differential Revision: https://reviews.llvm.org/D31349 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305227 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fd2310ef5b
commit
9283a09c18
@ -5352,40 +5352,6 @@ Some important flag interactions:
|
||||
- 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 @@ enum is the smallest type which can represent all of its values::
|
||||
!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
|
||||
|
@ -42,9 +42,8 @@ public:
|
||||
~TargetLoweringObjectFileELF() override = default;
|
||||
|
||||
/// Emit Obj-C garbage collection and linker options.
|
||||
void emitModuleFlags(MCStreamer &Streamer,
|
||||
ArrayRef<Module::ModuleFlagEntry> 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 @@ public:
|
||||
void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
|
||||
|
||||
/// Emit the module flags that specify the garbage collection information.
|
||||
void emitModuleFlags(MCStreamer &Streamer,
|
||||
ArrayRef<Module::ModuleFlagEntry> 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 @@ public:
|
||||
const TargetMachine &TM) const override;
|
||||
|
||||
/// Emit Obj-C garbage collection and linker options.
|
||||
void emitModuleFlags(MCStreamer &Streamer,
|
||||
ArrayRef<Module::ModuleFlagEntry> 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;
|
||||
|
@ -158,7 +158,7 @@ public:
|
||||
|
||||
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
|
||||
|
@ -70,10 +70,9 @@ public:
|
||||
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<Module::ModuleFlagEntry> 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.
|
||||
|
@ -2608,6 +2608,16 @@ Error BitcodeReader::materializeMetadata() {
|
||||
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<MDNode>(Val)->operands())
|
||||
LinkerOpts->addOperand(cast<MDNode>(MDOptions));
|
||||
}
|
||||
|
||||
DeferredMetadataInfo.clear();
|
||||
return Error::success();
|
||||
}
|
||||
|
@ -1286,11 +1286,7 @@ bool AsmPrinter::doFinalization(Module &M) {
|
||||
|
||||
const TargetLoweringObjectFile &TLOF = getObjFileLowering();
|
||||
|
||||
// Emit module flags.
|
||||
SmallVector<Module::ModuleFlagEntry, 8> 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<MachineModuleInfoELF>();
|
||||
|
@ -61,9 +61,11 @@
|
||||
using namespace llvm;
|
||||
using namespace dwarf;
|
||||
|
||||
static void GetObjCImageInfo(ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
|
||||
unsigned &Version, unsigned &Flags,
|
||||
static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags,
|
||||
StringRef &Section) {
|
||||
SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
|
||||
M.getModuleFlagsMetadata(ModuleFlags);
|
||||
|
||||
for (const auto &MFE: ModuleFlags) {
|
||||
// Ignore flags with 'Require' behaviour.
|
||||
if (MFE.Behavior == Module::Require)
|
||||
@ -88,14 +90,13 @@ static void GetObjCImageInfo(ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
|
||||
// ELF
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void TargetLoweringObjectFileELF::emitModuleFlags(
|
||||
MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> 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 @@ void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx,
|
||||
}
|
||||
}
|
||||
|
||||
/// emitModuleFlags - Perform code emission for module flags.
|
||||
void TargetLoweringObjectFileMachO::emitModuleFlags(
|
||||
MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
|
||||
const TargetMachine &TM) const {
|
||||
MDNode *LinkerOptions = nullptr;
|
||||
|
||||
for (const auto &MFE : ModuleFlags) {
|
||||
StringRef Key = MFE.Key->getString();
|
||||
if (Key == "Linker Options")
|
||||
LinkerOptions = cast<MDNode>(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<std::string, 4> StrOptions;
|
||||
for (const auto &Piece : cast<MDNode>(Option)->operands())
|
||||
@ -643,7 +634,8 @@ void TargetLoweringObjectFileMachO::emitModuleFlags(
|
||||
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 @@ MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(
|
||||
COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
|
||||
}
|
||||
|
||||
void TargetLoweringObjectFileCOFF::emitModuleFlags(
|
||||
MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
|
||||
const TargetMachine &TM) const {
|
||||
MDNode *LinkerOptions = nullptr;
|
||||
|
||||
for (const auto &MFE : ModuleFlags) {
|
||||
StringRef Key = MFE.Key->getString();
|
||||
if (Key == "Linker Options")
|
||||
LinkerOptions = cast<MDNode>(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 @@ void TargetLoweringObjectFileCOFF::emitModuleFlags(
|
||||
unsigned Flags = 0;
|
||||
StringRef Section;
|
||||
|
||||
GetObjCImageInfo(ModuleFlags, Version, Flags, Section);
|
||||
GetObjCImageInfo(M, Version, Flags, Section);
|
||||
if (Section.empty())
|
||||
return;
|
||||
|
||||
|
@ -1330,6 +1330,14 @@ Verifier::visitModuleFlag(const MDNode *Op,
|
||||
= mdconst::dyn_extract_or_null<ConstantInt>(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.
|
||||
|
@ -637,10 +637,10 @@ void LTOModule::parseMetadata() {
|
||||
raw_string_ostream OS(LinkerOpts);
|
||||
|
||||
// Linker Options
|
||||
if (Metadata *Val = getModule().getModuleFlag("Linker Options")) {
|
||||
MDNode *LinkerOptions = cast<MDNode>(Val);
|
||||
if (NamedMDNode *LinkerOptions =
|
||||
getModule().getNamedMetadata("llvm.linker.options")) {
|
||||
for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) {
|
||||
MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i));
|
||||
MDNode *MDOptions = LinkerOptions->getOperand(i);
|
||||
for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) {
|
||||
MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii));
|
||||
OS << " " << MDOption->getString();
|
||||
|
@ -109,9 +109,9 @@ Error Builder::addModule(Module *M) {
|
||||
if (TT.isOSBinFormatCOFF()) {
|
||||
if (auto E = M->materializeMetadata())
|
||||
return E;
|
||||
if (Metadata *Val = M->getModuleFlag("Linker Options")) {
|
||||
MDNode *LinkerOptions = cast<MDNode>(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<MDNode>(MDOptions)->operands())
|
||||
COFFLinkerOptsOS << " " << cast<MDString>(MDOption)->getString();
|
||||
}
|
||||
|
15
test/Bitcode/upgrade-linker-options.ll
Normal file
15
test/Bitcode/upgrade-linker-options.ll
Normal file
@ -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}
|
@ -65,7 +65,7 @@ attributes #1 = { nounwind readnone }
|
||||
|
||||
!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 @@ attributes #1 = { nounwind readnone }
|
||||
!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}
|
||||
|
@ -39,12 +39,11 @@ define void @main(i32* %i.i) !dbg !16 {
|
||||
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)
|
||||
|
@ -6,8 +6,8 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||
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
|
||||
|
||||
|
@ -9,8 +9,8 @@ target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
|
||||
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() {
|
||||
|
@ -13,7 +13,7 @@ entry:
|
||||
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 @@ attributes #0 = { nounwind sspstrong "correctly-rounded-divide-sqrt-fp-math"="fa
|
||||
; 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 "}
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
|
Loading…
Reference in New Issue
Block a user