AsmParser: Add support for .ifb and .ifnb directives.

Based on a patch from PaX Team.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156705 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer 2012-05-12 11:18:42 +00:00
parent 1cce5bf8ef
commit a3dd0eb93c
2 changed files with 96 additions and 0 deletions

View 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);

67
test/MC/AsmParser/ifb.s Normal file
View File

@ -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