diff options
author | Daniel Dunbar <daniel@zuster.org> | 2013-01-18 01:25:48 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2013-01-18 01:25:48 +0000 |
commit | cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86 (patch) | |
tree | a15dec96a85a567f8f4e96b8c6d30f76f4c42cfc | |
parent | bfdcc70d34f9c2bf3d4815c6d29fd43f01db8b76 (diff) | |
download | external_llvm-cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86.zip external_llvm-cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86.tar.gz external_llvm-cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86.tar.bz2 |
[MC/Mach-O] Add AsmParser support for .linker_option directive.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172778 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/MC/MCStreamer.h | 5 | ||||
-rw-r--r-- | lib/MC/MCAsmStreamer.cpp | 10 | ||||
-rw-r--r-- | lib/MC/MCParser/DarwinAsmParser.cpp | 30 | ||||
-rw-r--r-- | test/MC/MachO/linker-option-1.s | 21 |
4 files changed, 66 insertions, 0 deletions
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 904b930..c6246e1 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -20,6 +20,7 @@ #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCWin64EH.h" #include "llvm/Support/DataTypes.h" +#include <string> namespace llvm { class MCAsmBackend; @@ -255,6 +256,10 @@ namespace llvm { /// EmitAssemblerFlag - Note in the output the specified @p Flag. virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0; + /// EmitLinkerOptions - Emit the given list @p Options of strings as linker + /// options into the output. + virtual void EmitLinkerOptions(ArrayRef<std::string> Kind) {} + /// EmitDataRegion - Note in the output the specified region @p Kind. virtual void EmitDataRegion(MCDataRegionType Kind) {} diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index dd5112c..88a7d33 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -145,6 +145,7 @@ public: virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol); virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); + virtual void EmitLinkerOptions(ArrayRef<std::string> Options); virtual void EmitDataRegion(MCDataRegionType Kind); virtual void EmitThumbFunc(MCSymbol *Func); @@ -375,6 +376,15 @@ void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { EmitEOL(); } +void MCAsmStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) { + assert(!Options.empty() && "At least one option is required!"); + OS << "\t.linker_option \"" << Options[0] << '"'; + for (ArrayRef<std::string>::iterator it = Options.begin() + 1, + ie = Options.end(); it != ie; ++it) { + OS << ", " << '"' << *it << '"'; + } +} + void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) { MCContext &Ctx = getContext(); const MCAsmInfo &MAI = Ctx.getAsmInfo(); diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp index 7fda7ac..9029c6d 100644 --- a/lib/MC/MCParser/DarwinAsmParser.cpp +++ b/lib/MC/MCParser/DarwinAsmParser.cpp @@ -87,6 +87,8 @@ public: AddDirectiveHandler< &DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers>( ".lazy_symbol_pointer"); + AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveLinkerOption>( + ".linker_option"); AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral16>( ".literal16"); AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral4>( @@ -163,6 +165,7 @@ public: bool ParseDirectiveDesc(StringRef, SMLoc); bool ParseDirectiveDumpOrLoad(StringRef, SMLoc); bool ParseDirectiveLsym(StringRef, SMLoc); + bool ParseDirectiveLinkerOption(StringRef, SMLoc); bool ParseDirectiveSection(StringRef, SMLoc); bool ParseDirectivePushSection(StringRef, SMLoc); bool ParseDirectivePopSection(StringRef, SMLoc); @@ -435,6 +438,33 @@ bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive, return Warning(IDLoc, "ignoring directive .load for now"); } +/// ParseDirectiveLinkerOption +/// ::= .linker_option "string" ( , "string" )* +bool DarwinAsmParser::ParseDirectiveLinkerOption(StringRef IDVal, SMLoc) { + SmallVector<std::string, 4> Args; + for (;;) { + if (getLexer().isNot(AsmToken::String)) + return TokError("expected string in '" + Twine(IDVal) + "' directive"); + + std::string Data; + if (getParser().ParseEscapedString(Data)) + return true; + + Args.push_back(Data); + + Lex(); + if (getLexer().is(AsmToken::EndOfStatement)) + break; + + if (getLexer().isNot(AsmToken::Comma)) + return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); + Lex(); + } + + getStreamer().EmitLinkerOptions(Args); + return false; +} + /// ParseDirectiveLsym /// ::= .lsym identifier , expression bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) { diff --git a/test/MC/MachO/linker-option-1.s b/test/MC/MachO/linker-option-1.s new file mode 100644 index 0000000..a01cab7 --- /dev/null +++ b/test/MC/MachO/linker-option-1.s @@ -0,0 +1,21 @@ +// RUN: not llvm-mc -triple x86_64-apple-darwin10 %s 2> %t.err > %t +// RUN: FileCheck --check-prefix=CHECK-OUTPUT < %t %s +// RUN: FileCheck --check-prefix=CHECK-ERROR < %t.err %s + +// CHECK-OUTPUT: .linker_option "a" +.linker_option "a" +// CHECK-OUTPUT: .linker_option "a", "b" +.linker_option "a", "b" +// CHECK-OUTPUT-NOT: .linker_option +// CHECK-ERROR: expected string in '.linker_option' directive +// CHECK-ERROR: .linker_option 10 +// CHECK-ERROR: ^ +.linker_option 10 +// CHECK-ERROR: expected string in '.linker_option' directive +// CHECK-ERROR: .linker_option "a", +// CHECK-ERROR: ^ +.linker_option "a", +// CHECK-ERROR: unexpected token in '.linker_option' directive +// CHECK-ERROR: .linker_option "a" "b" +// CHECK-ERROR: ^ +.linker_option "a" "b" |