aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2013-01-18 01:25:48 +0000
committerDaniel Dunbar <daniel@zuster.org>2013-01-18 01:25:48 +0000
commitcddd236e8a5acb80e9a0e79dc63f6cfaa8205b86 (patch)
treea15dec96a85a567f8f4e96b8c6d30f76f4c42cfc
parentbfdcc70d34f9c2bf3d4815c6d29fd43f01db8b76 (diff)
downloadexternal_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.h5
-rw-r--r--lib/MC/MCAsmStreamer.cpp10
-rw-r--r--lib/MC/MCParser/DarwinAsmParser.cpp30
-rw-r--r--test/MC/MachO/linker-option-1.s21
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"