diff options
author | Chris Lattner <sabre@nondot.org> | 2010-01-15 19:28:38 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-01-15 19:28:38 +0000 |
commit | b4307b33705ef9e660db640b2f70d6246aa51165 (patch) | |
tree | 9e5e2dfb75bf69750dcd137e935b3b90fab31b0b | |
parent | 1f19f0f31dace5d145fecbe1f0f3fea4fb9ae813 (diff) | |
download | external_llvm-b4307b33705ef9e660db640b2f70d6246aa51165.zip external_llvm-b4307b33705ef9e660db640b2f70d6246aa51165.tar.gz external_llvm-b4307b33705ef9e660db640b2f70d6246aa51165.tar.bz2 |
extend MCAsmParser::ParseExpression and ParseParenExpression
to return range information for subexpressions. Use this to
provide range info for several new X86Operands.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93534 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/MC/MCAsmParser.h | 8 | ||||
-rw-r--r-- | lib/MC/MCAsmParser.cpp | 15 | ||||
-rw-r--r-- | lib/Target/X86/AsmParser/X86AsmParser.cpp | 31 | ||||
-rw-r--r-- | tools/llvm-mc/AsmParser.cpp | 46 | ||||
-rw-r--r-- | tools/llvm-mc/AsmParser.h | 12 |
5 files changed, 70 insertions, 42 deletions
diff --git a/include/llvm/MC/MCAsmParser.h b/include/llvm/MC/MCAsmParser.h index d530093..a3c10f9 100644 --- a/include/llvm/MC/MCAsmParser.h +++ b/include/llvm/MC/MCAsmParser.h @@ -55,15 +55,17 @@ public: /// @param Res - The value of the expression. The result is undefined /// on error. /// @result - False on success. - virtual bool ParseExpression(const MCExpr *&Res) = 0; - + virtual bool ParseExpression(const MCExpr *&Res, + SMLoc &StartLoc, SMLoc &EndLoc) = 0; + bool ParseExpression(const MCExpr *&Res); + /// ParseParenExpression - Parse an arbitrary expression, assuming that an /// initial '(' has already been consumed. /// /// @param Res - The value of the expression. The result is undefined /// on error. /// @result - False on success. - virtual bool ParseParenExpression(const MCExpr *&Res) = 0; + virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; /// ParseAbsoluteExpression - Parse an expression which must evaluate to an /// absolute value. diff --git a/lib/MC/MCAsmParser.cpp b/lib/MC/MCAsmParser.cpp index 2287e89..b58d6d4 100644 --- a/lib/MC/MCAsmParser.cpp +++ b/lib/MC/MCAsmParser.cpp @@ -8,7 +8,8 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCAsmParser.h" - +#include "llvm/MC/MCParsedAsmOperand.h" +#include "llvm/Support/SourceMgr.h" using namespace llvm; MCAsmParser::MCAsmParser() { @@ -16,3 +17,15 @@ MCAsmParser::MCAsmParser() { MCAsmParser::~MCAsmParser() { } + +bool MCAsmParser::ParseExpression(const MCExpr *&Res) { + SMLoc L; + return ParseExpression(Res, L, L); +} + + +/// getStartLoc - Get the location of the first token of this operand. +SMLoc MCParsedAsmOperand::getStartLoc() const { return SMLoc(); } +SMLoc MCParsedAsmOperand::getEndLoc() const { return SMLoc(); } + + diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 8ccfc8f..7539528 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -201,8 +201,8 @@ struct X86Operand : public MCParsedAsmOperand { Inst.addOperand(MCOperand::CreateReg(getMemSegReg())); } - static X86Operand *CreateToken(StringRef Str) { - X86Operand *Res = new X86Operand(Token); + static X86Operand *CreateToken(StringRef Str, SMLoc Loc) { + X86Operand *Res = new X86Operand(Token, Loc, Loc); Res->Tok.Data = Str.data(); Res->Tok.Length = Str.size(); return Res; @@ -214,8 +214,8 @@ struct X86Operand : public MCParsedAsmOperand { return Res; } - static X86Operand *CreateImm(const MCExpr *Val) { - X86Operand *Res = new X86Operand(Immediate); + static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){ + X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc); Res->Imm.Val = Val; return Res; } @@ -281,9 +281,10 @@ X86Operand *X86ATTAsmParser::ParseOperand() { // $42 -> immediate. getLexer().Lex(); const MCExpr *Val; - if (getParser().ParseExpression(Val)) + SMLoc Start, End; + if (getParser().ParseExpression(Val, Start, End)) return 0; - return X86Operand::CreateImm(Val); + return X86Operand::CreateImm(Val, Start, End); } } } @@ -299,14 +300,15 @@ X86Operand *X86ATTAsmParser::ParseMemOperand() { // it. const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext()); if (getLexer().isNot(AsmToken::LParen)) { - if (getParser().ParseExpression(Disp)) return 0; + SMLoc ExprStart, ExprEnd; + if (getParser().ParseExpression(Disp, ExprStart, ExprEnd)) return 0; // After parsing the base expression we could either have a parenthesized // memory address or not. If not, return now. If so, eat the (. if (getLexer().isNot(AsmToken::LParen)) { // Unless we have a segment register, treat this as an immediate. if (SegReg == 0) - return X86Operand::CreateImm(Disp); + return X86Operand::CreateImm(Disp, ExprStart, ExprEnd); return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1); } @@ -315,14 +317,17 @@ X86Operand *X86ATTAsmParser::ParseMemOperand() { } else { // Okay, we have a '('. We don't know if this is an expression or not, but // so we have to eat the ( to see beyond it. + SMLoc LParenLoc = getLexer().getTok().getLoc(); getLexer().Lex(); // Eat the '('. if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) { // Nothing to do here, fall into the code below with the '(' part of the // memory operand consumed. } else { + SMLoc ExprEnd; + // It must be an parenthesized expression, parse it now. - if (getParser().ParseParenExpression(Disp)) + if (getParser().ParseParenExpression(Disp, ExprEnd)) return 0; // After parsing the base expression we could either have a parenthesized @@ -330,7 +335,7 @@ X86Operand *X86ATTAsmParser::ParseMemOperand() { if (getLexer().isNot(AsmToken::LParen)) { // Unless we have a segment register, treat this as an immediate. if (SegReg == 0) - return X86Operand::CreateImm(Disp); + return X86Operand::CreateImm(Disp, LParenLoc, ExprEnd); return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1); } @@ -414,15 +419,15 @@ bool X86ATTAsmParser:: ParseInstruction(const StringRef &Name, SMLoc NameLoc, SmallVectorImpl<MCParsedAsmOperand*> &Operands) { - Operands.push_back(X86Operand::CreateToken(Name)); + Operands.push_back(X86Operand::CreateToken(Name, NameLoc)); - SMLoc Loc = getLexer().getTok().getLoc(); if (getLexer().isNot(AsmToken::EndOfStatement)) { // Parse '*' modifier. if (getLexer().is(AsmToken::Star)) { + SMLoc Loc = getLexer().getTok().getLoc(); + Operands.push_back(X86Operand::CreateToken("*", Loc)); getLexer().Lex(); // Eat the star. - Operands.push_back(X86Operand::CreateToken("*")); } // Read the first operand. diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp index 2eb75a7..4e03646 100644 --- a/tools/llvm-mc/AsmParser.cpp +++ b/tools/llvm-mc/AsmParser.cpp @@ -29,11 +29,6 @@ #include "llvm/Target/TargetAsmParser.h" using namespace llvm; -/// getStartLoc - Get the location of the first token of this operand. -SMLoc MCParsedAsmOperand::getStartLoc() const { return SMLoc(); } -SMLoc MCParsedAsmOperand::getEndLoc() const { return SMLoc(); } - - // Mach-O section uniquing. // // FIXME: Figure out where this should live, it should be shared by @@ -193,10 +188,11 @@ void AsmParser::EatToEndOfStatement() { /// /// parenexpr ::= expr) /// -bool AsmParser::ParseParenExpr(const MCExpr *&Res) { +bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) { if (ParseExpression(Res)) return true; if (Lexer.isNot(AsmToken::RParen)) return TokError("expected ')' in parentheses expression"); + EndLoc = Lexer.getLoc(); Lexer.Lex(); return false; } @@ -217,13 +213,13 @@ MCSymbol *AsmParser::CreateSymbol(StringRef Name) { /// primaryexpr ::= symbol /// primaryexpr ::= number /// primaryexpr ::= ~,+,- primaryexpr -bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res) { +bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { switch (Lexer.getKind()) { default: return TokError("unknown token in expression"); case AsmToken::Exclaim: Lexer.Lex(); // Eat the operator. - if (ParsePrimaryExpr(Res)) + if (ParsePrimaryExpr(Res, EndLoc)) return true; Res = MCUnaryExpr::CreateLNot(Res, getContext()); return false; @@ -231,6 +227,7 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res) { case AsmToken::Identifier: { // This is a symbol reference. MCSymbol *Sym = CreateSymbol(Lexer.getTok().getIdentifier()); + EndLoc = Lexer.getLoc(); Lexer.Lex(); // Eat identifier. // If this is an absolute variable reference, substitute it now to preserve @@ -246,32 +243,38 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res) { } case AsmToken::Integer: Res = MCConstantExpr::Create(Lexer.getTok().getIntVal(), getContext()); + EndLoc = Lexer.getLoc(); Lexer.Lex(); // Eat token. return false; case AsmToken::LParen: Lexer.Lex(); // Eat the '('. - return ParseParenExpr(Res); + return ParseParenExpr(Res, EndLoc); case AsmToken::Minus: Lexer.Lex(); // Eat the operator. - if (ParsePrimaryExpr(Res)) + if (ParsePrimaryExpr(Res, EndLoc)) return true; Res = MCUnaryExpr::CreateMinus(Res, getContext()); return false; case AsmToken::Plus: Lexer.Lex(); // Eat the operator. - if (ParsePrimaryExpr(Res)) + if (ParsePrimaryExpr(Res, EndLoc)) return true; Res = MCUnaryExpr::CreatePlus(Res, getContext()); return false; case AsmToken::Tilde: Lexer.Lex(); // Eat the operator. - if (ParsePrimaryExpr(Res)) + if (ParsePrimaryExpr(Res, EndLoc)) return true; Res = MCUnaryExpr::CreateNot(Res, getContext()); return false; } } +bool AsmParser::ParseExpression(const MCExpr *&Res) { + SMLoc L; + return ParseExpression(Res, L, L); +} + /// ParseExpression - Parse an expression and return it. /// /// expr ::= expr +,- expr -> lowest. @@ -279,14 +282,16 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res) { /// expr ::= expr *,/,%,<<,>> expr -> highest. /// expr ::= primaryexpr /// -bool AsmParser::ParseExpression(const MCExpr *&Res) { +bool AsmParser::ParseExpression(const MCExpr *&Res, + SMLoc &StartLoc, SMLoc &EndLoc) { + StartLoc = Lexer.getLoc(); Res = 0; - return ParsePrimaryExpr(Res) || - ParseBinOpRHS(1, Res); + return ParsePrimaryExpr(Res, EndLoc) || + ParseBinOpRHS(1, Res, EndLoc); } -bool AsmParser::ParseParenExpression(const MCExpr *&Res) { - if (ParseParenExpr(Res)) +bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) { + if (ParseParenExpr(Res, EndLoc)) return true; return false; @@ -381,7 +386,8 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K, /// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'. /// Res contains the LHS of the expression on input. -bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res) { +bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, + SMLoc &EndLoc) { while (1) { MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add; unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind); @@ -395,14 +401,14 @@ bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res) { // Eat the next primary expression. const MCExpr *RHS; - if (ParsePrimaryExpr(RHS)) return true; + if (ParsePrimaryExpr(RHS, EndLoc)) return true; // If BinOp binds less tightly with RHS than the operator after RHS, let // the pending operator take RHS as its LHS. MCBinaryExpr::Opcode Dummy; unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy); if (TokPrec < NextTokPrec) { - if (ParseBinOpRHS(Precedence+1, RHS)) return true; + if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true; } // Merge LHS and RHS according to operator. diff --git a/tools/llvm-mc/AsmParser.h b/tools/llvm-mc/AsmParser.h index 171dfcd..63bac59 100644 --- a/tools/llvm-mc/AsmParser.h +++ b/tools/llvm-mc/AsmParser.h @@ -79,8 +79,10 @@ public: virtual void Warning(SMLoc L, const Twine &Meg); virtual bool Error(SMLoc L, const Twine &Msg); - virtual bool ParseExpression(const MCExpr *&Res); - virtual bool ParseParenExpression(const MCExpr *&Res); + bool ParseExpression(const MCExpr *&Res); + virtual bool ParseExpression(const MCExpr *&Res, + SMLoc &StartLoc, SMLoc &EndLoc); + virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc); virtual bool ParseAbsoluteExpression(int64_t &Res); /// } @@ -105,9 +107,9 @@ private: bool ParseAssignment(const StringRef &Name); - bool ParsePrimaryExpr(const MCExpr *&Res); - bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res); - bool ParseParenExpr(const MCExpr *&Res); + bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc); + bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc); + bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc); /// ParseIdentifier - Parse an identifier or string (as a quoted identifier) /// and set \arg Res to the identifier contents. |