1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 20:23:11 +01: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

llvm-svn: 305227
This commit is contained in:
Peter Collingbourne 2017-06-12 20:10:48 +00:00
parent 87969b4f1e
commit 54103de7c1
18 changed files with 113 additions and 114 deletions

View File

@ -5352,40 +5352,6 @@ Some important flag interactions:
- A module with ``Objective-C Garbage Collection`` set to 0 cannot be - A module with ``Objective-C Garbage Collection`` set to 0 cannot be
merged with a module with ``Objective-C GC Only`` set to 6. 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 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} !0 = !{i32 1, !"short_wchar", i32 1}
!1 = !{i32 1, !"short_enum", i32 0} !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: .. _intrinsicglobalvariables:
Intrinsic Global Variables Intrinsic Global Variables

View File

@ -42,9 +42,8 @@ public:
~TargetLoweringObjectFileELF() override = default; ~TargetLoweringObjectFileELF() override = default;
/// Emit Obj-C garbage collection and linker options. /// Emit Obj-C garbage collection and linker options.
void emitModuleFlags(MCStreamer &Streamer, void emitModuleMetadata(MCStreamer &Streamer, Module &M,
ArrayRef<Module::ModuleFlagEntry> ModuleFlags, const TargetMachine &TM) const override;
const TargetMachine &TM) const override;
void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM, void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM,
const MCSymbol *Sym) const override; const MCSymbol *Sym) const override;
@ -99,9 +98,8 @@ public:
void Initialize(MCContext &Ctx, const TargetMachine &TM) override; void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
/// Emit the module flags that specify the garbage collection information. /// Emit the module flags that specify the garbage collection information.
void emitModuleFlags(MCStreamer &Streamer, void emitModuleMetadata(MCStreamer &Streamer, Module &M,
ArrayRef<Module::ModuleFlagEntry> ModuleFlags, const TargetMachine &TM) const override;
const TargetMachine &TM) const override;
MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
const TargetMachine &TM) const override; const TargetMachine &TM) const override;
@ -155,9 +153,8 @@ public:
const TargetMachine &TM) const override; const TargetMachine &TM) const override;
/// Emit Obj-C garbage collection and linker options. /// Emit Obj-C garbage collection and linker options.
void emitModuleFlags(MCStreamer &Streamer, void emitModuleMetadata(MCStreamer &Streamer, Module &M,
ArrayRef<Module::ModuleFlagEntry> ModuleFlags, const TargetMachine &TM) const override;
const TargetMachine &TM) const override;
MCSection *getStaticCtorSection(unsigned Priority, MCSection *getStaticCtorSection(unsigned Priority,
const MCSymbol *KeySym) const override; const MCSymbol *KeySym) const override;

View File

@ -158,7 +158,7 @@ public:
private: private:
/// Parse metadata from the module /// 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(); void parseMetadata();
/// Parse the symbols from the module and model-level ASM and add them to /// Parse the symbols from the module and model-level ASM and add them to

View File

@ -70,10 +70,9 @@ public:
virtual void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM, virtual void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM,
const MCSymbol *Sym) const; const MCSymbol *Sym) const;
/// Emit the module flags that the platform cares about. /// Emit the module-level metadata that the platform cares about.
virtual void emitModuleFlags(MCStreamer &Streamer, virtual void emitModuleMetadata(MCStreamer &Streamer, Module &M,
ArrayRef<Module::ModuleFlagEntry> Flags, const TargetMachine &TM) const {}
const TargetMachine &TM) const {}
/// Given a constant with the SectionKind, return a section that it should be /// Given a constant with the SectionKind, return a section that it should be
/// placed in. /// placed in.

View File

@ -2608,6 +2608,16 @@ Error BitcodeReader::materializeMetadata() {
if (Error Err = MDLoader->parseModuleMetadata()) if (Error Err = MDLoader->parseModuleMetadata())
return Err; 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(); DeferredMetadataInfo.clear();
return Error::success(); return Error::success();
} }

View File

@ -1286,11 +1286,7 @@ bool AsmPrinter::doFinalization(Module &M) {
const TargetLoweringObjectFile &TLOF = getObjFileLowering(); const TargetLoweringObjectFile &TLOF = getObjFileLowering();
// Emit module flags. TLOF.emitModuleMetadata(*OutStreamer, M, TM);
SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
M.getModuleFlagsMetadata(ModuleFlags);
if (!ModuleFlags.empty())
TLOF.emitModuleFlags(*OutStreamer, ModuleFlags, TM);
if (TM.getTargetTriple().isOSBinFormatELF()) { if (TM.getTargetTriple().isOSBinFormatELF()) {
MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>(); MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();

View File

@ -61,9 +61,11 @@
using namespace llvm; using namespace llvm;
using namespace dwarf; using namespace dwarf;
static void GetObjCImageInfo(ArrayRef<Module::ModuleFlagEntry> ModuleFlags, static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags,
unsigned &Version, unsigned &Flags,
StringRef &Section) { StringRef &Section) {
SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
M.getModuleFlagsMetadata(ModuleFlags);
for (const auto &MFE: ModuleFlags) { for (const auto &MFE: ModuleFlags) {
// Ignore flags with 'Require' behaviour. // Ignore flags with 'Require' behaviour.
if (MFE.Behavior == Module::Require) if (MFE.Behavior == Module::Require)
@ -88,14 +90,13 @@ static void GetObjCImageInfo(ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
// ELF // ELF
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
void TargetLoweringObjectFileELF::emitModuleFlags( void TargetLoweringObjectFileELF::emitModuleMetadata(
MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, MCStreamer &Streamer, Module &M, const TargetMachine &TM) const {
const TargetMachine &TM) const {
unsigned Version = 0; unsigned Version = 0;
unsigned Flags = 0; unsigned Flags = 0;
StringRef Section; StringRef Section;
GetObjCImageInfo(ModuleFlags, Version, Flags, Section); GetObjCImageInfo(M, Version, Flags, Section);
if (Section.empty()) if (Section.empty())
return; return;
@ -618,20 +619,10 @@ void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx,
} }
} }
/// emitModuleFlags - Perform code emission for module flags. void TargetLoweringObjectFileMachO::emitModuleMetadata(
void TargetLoweringObjectFileMachO::emitModuleFlags( MCStreamer &Streamer, Module &M, const TargetMachine &TM) const {
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);
}
// Emit the linker options if present. // Emit the linker options if present.
if (LinkerOptions) { if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
for (const auto &Option : LinkerOptions->operands()) { for (const auto &Option : LinkerOptions->operands()) {
SmallVector<std::string, 4> StrOptions; SmallVector<std::string, 4> StrOptions;
for (const auto &Piece : cast<MDNode>(Option)->operands()) for (const auto &Piece : cast<MDNode>(Option)->operands())
@ -643,7 +634,8 @@ void TargetLoweringObjectFileMachO::emitModuleFlags(
unsigned VersionVal = 0; unsigned VersionVal = 0;
unsigned ImageInfoFlags = 0; unsigned ImageInfoFlags = 0;
StringRef SectionVal; 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. // The section is mandatory. If we don't have it, then we don't have GC info.
if (SectionVal.empty()) if (SectionVal.empty())
@ -1159,18 +1151,9 @@ MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(
COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
} }
void TargetLoweringObjectFileCOFF::emitModuleFlags( void TargetLoweringObjectFileCOFF::emitModuleMetadata(
MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, MCStreamer &Streamer, Module &M, const TargetMachine &TM) const {
const TargetMachine &TM) const { if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
MDNode *LinkerOptions = nullptr;
for (const auto &MFE : ModuleFlags) {
StringRef Key = MFE.Key->getString();
if (Key == "Linker Options")
LinkerOptions = cast<MDNode>(MFE.Val);
}
if (LinkerOptions) {
// Emit the linker options to the linker .drectve section. According to the // Emit the linker options to the linker .drectve section. According to the
// spec, this section is a space-separated string containing flags for // spec, this section is a space-separated string containing flags for
// linker. // linker.
@ -1190,7 +1173,7 @@ void TargetLoweringObjectFileCOFF::emitModuleFlags(
unsigned Flags = 0; unsigned Flags = 0;
StringRef Section; StringRef Section;
GetObjCImageInfo(ModuleFlags, Version, Flags, Section); GetObjCImageInfo(M, Version, Flags, Section);
if (Section.empty()) if (Section.empty())
return; return;

View File

@ -1330,6 +1330,14 @@ Verifier::visitModuleFlag(const MDNode *Op,
= mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(2)); = mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(2));
Assert(Value, "wchar_size metadata requires constant integer argument"); 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. /// Return true if this attribute kind only applies to functions.

View File

@ -637,10 +637,10 @@ void LTOModule::parseMetadata() {
raw_string_ostream OS(LinkerOpts); raw_string_ostream OS(LinkerOpts);
// Linker Options // Linker Options
if (Metadata *Val = getModule().getModuleFlag("Linker Options")) { if (NamedMDNode *LinkerOptions =
MDNode *LinkerOptions = cast<MDNode>(Val); getModule().getNamedMetadata("llvm.linker.options")) {
for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) { 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) { for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) {
MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii)); MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii));
OS << " " << MDOption->getString(); OS << " " << MDOption->getString();

View File

@ -109,9 +109,9 @@ Error Builder::addModule(Module *M) {
if (TT.isOSBinFormatCOFF()) { if (TT.isOSBinFormatCOFF()) {
if (auto E = M->materializeMetadata()) if (auto E = M->materializeMetadata())
return E; return E;
if (Metadata *Val = M->getModuleFlag("Linker Options")) { if (NamedMDNode *LinkerOptions =
MDNode *LinkerOptions = cast<MDNode>(Val); M->getNamedMetadata("llvm.linker.options")) {
for (const MDOperand &MDOptions : LinkerOptions->operands()) for (MDNode *MDOptions : LinkerOptions->operands())
for (const MDOperand &MDOption : cast<MDNode>(MDOptions)->operands()) for (const MDOperand &MDOption : cast<MDNode>(MDOptions)->operands())
COFFLinkerOptsOS << " " << cast<MDString>(MDOption)->getString(); COFFLinkerOptsOS << " " << cast<MDString>(MDOption)->getString();
} }

View 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}

View File

@ -65,7 +65,7 @@ attributes #1 = { nounwind readnone }
!llvm.dbg.cu = !{!2, !11} !llvm.dbg.cu = !{!2, !11}
!llvm.ident = !{!13, !13} !llvm.ident = !{!13, !13}
!llvm.module.flags = !{!14, !18, !19, !20} !llvm.module.flags = !{!18, !19, !20}
!0 = !DIGlobalVariableExpression(var: !1) !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) !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) !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") !12 = !DIFile(filename: "b.cpp", directory: "C:\5Csrc\5Cllvm-project\5Cbuild", checksumkind: CSK_MD5, checksum: "9cfd390d8827beab36769147bb037abc")
!13 = !{!"clang version 5.0.0 "} !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} !18 = !{i32 2, !"CodeView", i32 1}
!19 = !{i32 2, !"Debug Info Version", i32 3} !19 = !{i32 2, !"Debug Info Version", i32 3}
!20 = !{i32 1, !"PIC Level", i32 2} !20 = !{i32 1, !"PIC Level", i32 2}

View File

@ -39,12 +39,11 @@ define void @main(i32* %i.i) !dbg !16 {
ret void ret void
} }
!llvm.module.flags = !{!0, !1, !2} !llvm.module.flags = !{!0, !1}
!llvm.dbg.cu = !{!4} !llvm.dbg.cu = !{!4}
!0 = !{i32 2, !"CodeView", i32 1} !0 = !{i32 2, !"CodeView", i32 1}
!1 = !{i32 2, !"Debug Info Version", i32 3} !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) !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") !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 = !DILocation(line: 302, column: 9, scope: !7, inlinedAt: !15)

View File

@ -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" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
; CHECK-NOT: linker opts: ; CHECK-NOT: linker opts:
!0 = !{i32 6, !"Linker Options", !{!{!"/include:foo"}}} !0 = !{!"/include:foo"}
!llvm.module.flags = !{ !0 } !llvm.linker.options = !{ !0 }
@g1 = global i32 0 @g1 = global i32 0

View File

@ -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" source_filename = "src.c"
; CHECK: linker opts: /include:foo ; CHECK: linker opts: /include:foo
!0 = !{i32 6, !"Linker Options", !{!{!"/include:foo"}}} !0 = !{!"/include:foo"}
!llvm.module.flags = !{ !0 } !llvm.linker.options = !{ !0 }
; CHECK: D------X _fun ; CHECK: D------X _fun
define i32 @fun() { define i32 @fun() {

View File

@ -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" } 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.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !7, !8} !llvm.module.flags = !{!7, !8}
!llvm.ident = !{!9} !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) !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 ; CHECK-NOT: .short 4412 # Record kind: S_COMPILE3
!1 = !DIFile(filename: "D:\5Csrc\5Cscopes\5Cfoo.cpp", directory: "D:\5Csrc\5Cscopes\5Cclang") !1 = !DIFile(filename: "D:\5Csrc\5Cscopes\5Cfoo.cpp", directory: "D:\5Csrc\5Cscopes\5Cclang")
!2 = !{} !2 = !{}
!3 = !{i32 6, !"Linker Options", !4}
!4 = !{!5, !6}
!5 = !{!"/DEFAULTLIB:libcmtd.lib"}
!6 = !{!"/DEFAULTLIB:oldnames.lib"}
!7 = !{i32 2, !"CodeView", i32 1} !7 = !{i32 2, !"CodeView", i32 1}
!8 = !{i32 2, !"Debug Info Version", i32 3} !8 = !{i32 2, !"Debug Info Version", i32 3}
!9 = !{!"clang version 4.0.0 "} !9 = !{!"clang version 4.0.0 "}

View File

@ -1,8 +1,10 @@
; RUN: llc -O0 -mtriple=i386-pc-win32 -filetype=asm -o - %s | FileCheck %s ; 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"}}} !0 = !{!"/DEFAULTLIB:msvcrt.lib"}
!1 = !{!"/DEFAULTLIB:msvcrt.lib", !"/DEFAULTLIB:secur32.lib"}
!llvm.module.flags = !{ !0 } !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() { define dllexport void @foo() {
ret void ret void

View File

@ -27,6 +27,7 @@
; CHECK-OBJ: ] ; CHECK-OBJ: ]
; CHECK-OBJ: } ; CHECK-OBJ: }
!0 = !{i32 6, !"Linker Options", !{!{!"-lz"}, !{!"-framework", !"Cocoa"}, !{!"-lmath"}}} !0 = !{!"-lz"}
!1 = !{!"-framework", !"Cocoa"}
!llvm.module.flags = !{ !0 } !2 = !{!"-lmath"}
!llvm.linker.options = !{!0, !1, !2}