diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2012-05-12 11:18:51 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2012-05-12 11:18:51 +0000 |
commit | dec06ef43114ca0f7e5a616ca7437be6e98ea0b3 (patch) | |
tree | ebe42dbadcd2da110eac2bc6a7fe2d7e63d1a69e /lib/MC | |
parent | a3dd0eb93c764905dac919851bca12517e7e8757 (diff) | |
download | external_llvm-dec06ef43114ca0f7e5a616ca7437be6e98ea0b3.zip external_llvm-dec06ef43114ca0f7e5a616ca7437be6e98ea0b3.tar.gz external_llvm-dec06ef43114ca0f7e5a616ca7437be6e98ea0b3.tar.bz2 |
AsmParser: Add support for .ifc and .ifnc directives.
Based on a patch from PaX Team.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156706 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index b0491e7..d6f9236 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -209,6 +209,10 @@ private: /// will be either the EndOfStatement or EOF. StringRef ParseStringToEndOfStatement(); + /// \brief Parse until the end of a statement or a comma is encountered, + /// return the contents from the current token up to the end or comma. + StringRef ParseStringToComma(); + bool ParseAssignment(StringRef Name, bool allow_redef); bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc); @@ -247,6 +251,8 @@ private: bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if" // ".ifb" or ".ifnb", depending on ExpectBlank. bool ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank); + // ".ifc" or ".ifnc", depending on ExpectEqual. + bool ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual); // ".ifdef" or ".ifndef", depending on expect_defined bool ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined); bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif" @@ -604,6 +610,18 @@ StringRef AsmParser::ParseStringToEndOfStatement() { return StringRef(Start, End - Start); } +StringRef AsmParser::ParseStringToComma() { + const char *Start = getTok().getLoc().getPointer(); + + while (Lexer.isNot(AsmToken::EndOfStatement) && + Lexer.isNot(AsmToken::Comma) && + Lexer.isNot(AsmToken::Eof)) + Lex(); + + const char *End = getTok().getLoc().getPointer(); + return StringRef(Start, End - Start); +} + /// ParseParenExpr - Parse a paren expression and return it. /// NOTE: This assumes the leading '(' has already been consumed. /// @@ -1048,6 +1066,10 @@ bool AsmParser::ParseStatement() { return ParseDirectiveIfb(IDLoc, true); if (IDVal == ".ifnb") return ParseDirectiveIfb(IDLoc, false); + if (IDVal == ".ifc") + return ParseDirectiveIfc(IDLoc, true); + if (IDVal == ".ifnc") + return ParseDirectiveIfc(IDLoc, false); if (IDVal == ".ifdef") return ParseDirectiveIfdef(IDLoc, true); if (IDVal == ".ifndef" || IDVal == ".ifnotdef") @@ -2342,6 +2364,38 @@ bool AsmParser::ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) { return false; } +/// ParseDirectiveIfc +/// ::= .ifc string1, string2 +bool AsmParser::ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) { + TheCondStack.push_back(TheCondState); + TheCondState.TheCond = AsmCond::IfCond; + + if(TheCondState.Ignore) { + EatToEndOfStatement(); + } else { + StringRef Str1 = ParseStringToComma(); + + if (getLexer().isNot(AsmToken::Comma)) + return TokError("unexpected token in '.ifc' directive"); + + Lex(); + + StringRef Str2 = ParseStringToEndOfStatement(); + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in '.ifc' directive"); + + Lex(); + + TheCondState.CondMet = ExpectEqual == (Str1 == Str2); + TheCondState.Ignore = !TheCondState.CondMet; + } + + return false; +} + +/// ParseDirectiveIfdef +/// ::= .ifdef symbol bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { StringRef Name; TheCondStack.push_back(TheCondState); |