AsmParser: Add support for .ifb and .ifnb directives.
authorBenjamin Kramer <benny.kra@googlemail.com>
Sat, 12 May 2012 11:18:42 +0000 (11:18 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sat, 12 May 2012 11:18:42 +0000 (11:18 +0000)
Based on a patch from PaX Team.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156705 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 25419916c71ee20ce6f6d7373071b85219069d8c..b0491e79fe8b7d7284526f90adae0458f44df42a 100644 (file)
@@ -245,6 +245,8 @@ private:
   bool ParseDirectiveIncbin(); // ".incbin"
 
   bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if"
+  // ".ifb" or ".ifnb", depending on ExpectBlank.
+  bool ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank);
   // ".ifdef" or ".ifndef", depending on expect_defined
   bool ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);
   bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif"
@@ -1042,6 +1044,10 @@ bool AsmParser::ParseStatement() {
   // example.
   if (IDVal == ".if")
     return ParseDirectiveIf(IDLoc);
+  if (IDVal == ".ifb")
+    return ParseDirectiveIfb(IDLoc, true);
+  if (IDVal == ".ifnb")
+    return ParseDirectiveIfb(IDLoc, false);
   if (IDVal == ".ifdef")
     return ParseDirectiveIfdef(IDLoc, true);
   if (IDVal == ".ifndef" || IDVal == ".ifnotdef")
@@ -2313,6 +2319,29 @@ bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
   return false;
 }
 
+/// ParseDirectiveIfb
+/// ::= .ifb string
+bool AsmParser::ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
+  TheCondStack.push_back(TheCondState);
+  TheCondState.TheCond = AsmCond::IfCond;
+
+  if(TheCondState.Ignore) {
+    EatToEndOfStatement();
+  } else {
+    StringRef Str = ParseStringToEndOfStatement();
+
+    if (getLexer().isNot(AsmToken::EndOfStatement))
+      return TokError("unexpected token in '.ifb' directive");
+
+    Lex();
+
+    TheCondState.CondMet = ExpectBlank == Str.empty();
+    TheCondState.Ignore = !TheCondState.CondMet;
+  }
+
+  return false;
+}
+
 bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
   StringRef Name;
   TheCondStack.push_back(TheCondState);
diff --git a/test/MC/AsmParser/ifb.s b/test/MC/AsmParser/ifb.s
new file mode 100644 (file)
index 0000000..48d69f4
--- /dev/null
@@ -0,0 +1,67 @@
+# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
+
+defined:
+
+# CHECK-NOT: .byte 0
+# CHECK: .byte 1
+.ifb
+       .byte 1
+.else
+       .byte 0
+.endif
+
+# CHECK-NOT: .byte 0
+# CHECK: .byte 1
+.ifb defined
+       .byte 0
+.else
+       .byte 1
+.endif
+
+# CHECK-NOT: .byte 0
+# CHECK: .byte 1
+.ifb undefined
+       .byte 0
+.else
+       .byte 1
+.endif
+
+# CHECK-NOT: .byte 0
+# CHECK: .byte 1
+.ifb ""
+       .byte 0
+.else
+       .byte 1
+.endif
+
+# CHECK-NOT: .byte 0
+# CHECK: .byte 1
+.ifnb
+       .byte 0
+.else
+       .byte 1
+.endif
+
+# CHECK-NOT: .byte 0
+# CHECK: .byte 1
+.ifnb defined
+       .byte 1
+.else
+       .byte 0
+.endif
+
+# CHECK-NOT: .byte 0
+# CHECK: .byte 1
+.ifnb undefined
+       .byte 1
+.else
+       .byte 0
+.endif
+
+# CHECK-NOT: .byte 0
+# CHECK: .byte 1
+.ifnb ""
+       .byte 1
+.else
+       .byte 0
+.endif