AsmParser: add support for .end directive
authorSaleem Abdulrasool <compnerd@compnerd.org>
Wed, 18 Dec 2013 02:53:03 +0000 (02:53 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Wed, 18 Dec 2013 02:53:03 +0000 (02:53 +0000)
The .end directive indicates the end of the file.  No further instructions are
processed after a .end directive is encountered.

One potential (glaringly obvious) optimisation that could be pursued here is to
extend MCAsmParser with a DiscardRemainder method to avoid processing lexemes to
the end of the file.  It was unclear at this point if that would be worth
adding, and could easily be added in a follow on change.

Signed-off-by: Saleem Abdulrasool <compnerd@compnerd.org>
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197547 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/MCParser/AsmParser.cpp
test/MC/AsmParser/directive_end-2.s [new file with mode: 0644]
test/MC/AsmParser/directive_end.s [new file with mode: 0644]

index a336cb97c66ce8b44eac78be6338ecafe20b8895..35f38a2a87c44412b37507a84690848a2cb1d3f7 100644 (file)
@@ -358,7 +358,8 @@ private:
     DK_CFI_RESTORE, DK_CFI_ESCAPE, DK_CFI_SIGNAL_FRAME, DK_CFI_UNDEFINED,
     DK_CFI_REGISTER, DK_CFI_WINDOW_SAVE,
     DK_MACROS_ON, DK_MACROS_OFF, DK_MACRO, DK_ENDM, DK_ENDMACRO, DK_PURGEM,
-    DK_SLEB128, DK_ULEB128
+    DK_SLEB128, DK_ULEB128,
+    DK_END
   };
 
   /// \brief Maps directive name --> DirectiveKind enum, for
@@ -464,6 +465,9 @@ private:
   // "align"
   bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);
 
+  // "end"
+  bool parseDirectiveEnd(SMLoc DirectiveLoc);
+
   void initializeDirectiveKindMap();
 };
 }
@@ -1508,6 +1512,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
       return parseDirectiveEndMacro(IDVal);
     case DK_PURGEM:
       return parseDirectivePurgeMacro(IDLoc);
+    case DK_END:
+      return parseDirectiveEnd(IDLoc);
     }
 
     return Error(IDLoc, "unknown directive");
@@ -3743,6 +3749,20 @@ bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
   return false;
 }
 
+/// parseDirectiveEnd
+/// ::= .end
+bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
+  if (getLexer().isNot(AsmToken::EndOfStatement))
+    return TokError("unexpected token in '.end' directive");
+
+  Lex();
+
+  while (Lexer.isNot(AsmToken::Eof))
+    Lex();
+
+  return false;
+}
+
 /// parseDirectiveEndIf
 /// ::= .endif
 bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
@@ -3828,6 +3848,7 @@ void AsmParser::initializeDirectiveKindMap() {
   DirectiveKindMap[".ifnotdef"] = DK_IFNOTDEF;
   DirectiveKindMap[".elseif"] = DK_ELSEIF;
   DirectiveKindMap[".else"] = DK_ELSE;
+  DirectiveKindMap[".end"] = DK_END;
   DirectiveKindMap[".endif"] = DK_ENDIF;
   DirectiveKindMap[".skip"] = DK_SKIP;
   DirectiveKindMap[".space"] = DK_SPACE;
diff --git a/test/MC/AsmParser/directive_end-2.s b/test/MC/AsmParser/directive_end-2.s
new file mode 100644 (file)
index 0000000..96188da
--- /dev/null
@@ -0,0 +1,14 @@
+# RUN: llvm-mc -triple i386-unknown-unknown %s -I %p -filetype obj -o - \
+# RUN:   | llvm-readobj -t | FileCheck %s
+
+rock:
+    movl $42, %eax
+
+.include "directive_end.s"
+
+hard_place:
+    movl $42, %ebx
+
+# CHECK: Symbol {
+# CHECK:   Name: rock
+# CHECK-NOT:   Name: hard_place
diff --git a/test/MC/AsmParser/directive_end.s b/test/MC/AsmParser/directive_end.s
new file mode 100644 (file)
index 0000000..ec43cad
--- /dev/null
@@ -0,0 +1,11 @@
+# RUN: llvm-mc -triple i386-unknown-unknown %s -filetype obj -o - \
+# RUN:   | llvm-readobj -t | FileCheck %s
+
+       .end
+
+its_a_tarp:
+       int $0x3
+
+# CHECK: Symbol {
+# CHECK-NOT:   Name: its_a_tarp
+