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/MCParser | |
| 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/MCParser')
| -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); | 

