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 | e297b9f5069fc6b49ff78e7dd2cc4abb858ba829 (patch) | |
tree | 2b94a274a39354eb4b6e520d6631a0ac7e002156 /llvm/lib/MC | |
parent | 62c18b088122822cf70a375866ce45dfc4aae2c8 (diff) | |
download | bcm5719-llvm-e297b9f5069fc6b49ff78e7dd2cc4abb858ba829.tar.gz bcm5719-llvm-e297b9f5069fc6b49ff78e7dd2cc4abb858ba829.zip |
AsmParser: Add support for .ifc and .ifnc directives.
Based on a patch from PaX Team.
llvm-svn: 156706
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index b0491e79fe8..d6f9236077e 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/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); |