extend MCAsmParser::ParseExpression and ParseParenExpression

to return range information for subexpressions.  Use this to
provide range info for several new X86Operands.

llvm-svn: 93534
This commit is contained in:
Chris Lattner 2010-01-15 19:28:38 +00:00
parent fba7cf4b44
commit 836cf5d129
5 changed files with 70 additions and 42 deletions

View File

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

View File

@ -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(); }

View File

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

View File

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

View File

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