mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-25 20:59:51 +00:00
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
This commit is contained in:
parent
1f19f0f31d
commit
b4307b3370
@ -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.
|
||||
|
@ -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(); }
|
||||
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user