mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-15 07:39:31 +00:00
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:
parent
fba7cf4b44
commit
836cf5d129
@ -55,15 +55,17 @@ public:
|
|||||||
/// @param Res - The value of the expression. The result is undefined
|
/// @param Res - The value of the expression. The result is undefined
|
||||||
/// on error.
|
/// on error.
|
||||||
/// @result - False on success.
|
/// @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
|
/// ParseParenExpression - Parse an arbitrary expression, assuming that an
|
||||||
/// initial '(' has already been consumed.
|
/// initial '(' has already been consumed.
|
||||||
///
|
///
|
||||||
/// @param Res - The value of the expression. The result is undefined
|
/// @param Res - The value of the expression. The result is undefined
|
||||||
/// on error.
|
/// on error.
|
||||||
/// @result - False on success.
|
/// @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
|
/// ParseAbsoluteExpression - Parse an expression which must evaluate to an
|
||||||
/// absolute value.
|
/// absolute value.
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/MC/MCAsmParser.h"
|
#include "llvm/MC/MCAsmParser.h"
|
||||||
|
#include "llvm/MC/MCParsedAsmOperand.h"
|
||||||
|
#include "llvm/Support/SourceMgr.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
MCAsmParser::MCAsmParser() {
|
MCAsmParser::MCAsmParser() {
|
||||||
@ -16,3 +17,15 @@ MCAsmParser::MCAsmParser() {
|
|||||||
|
|
||||||
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()));
|
Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
|
||||||
}
|
}
|
||||||
|
|
||||||
static X86Operand *CreateToken(StringRef Str) {
|
static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
|
||||||
X86Operand *Res = new X86Operand(Token);
|
X86Operand *Res = new X86Operand(Token, Loc, Loc);
|
||||||
Res->Tok.Data = Str.data();
|
Res->Tok.Data = Str.data();
|
||||||
Res->Tok.Length = Str.size();
|
Res->Tok.Length = Str.size();
|
||||||
return Res;
|
return Res;
|
||||||
@ -214,8 +214,8 @@ struct X86Operand : public MCParsedAsmOperand {
|
|||||||
return Res;
|
return Res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static X86Operand *CreateImm(const MCExpr *Val) {
|
static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
|
||||||
X86Operand *Res = new X86Operand(Immediate);
|
X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
|
||||||
Res->Imm.Val = Val;
|
Res->Imm.Val = Val;
|
||||||
return Res;
|
return Res;
|
||||||
}
|
}
|
||||||
@ -281,9 +281,10 @@ X86Operand *X86ATTAsmParser::ParseOperand() {
|
|||||||
// $42 -> immediate.
|
// $42 -> immediate.
|
||||||
getLexer().Lex();
|
getLexer().Lex();
|
||||||
const MCExpr *Val;
|
const MCExpr *Val;
|
||||||
if (getParser().ParseExpression(Val))
|
SMLoc Start, End;
|
||||||
|
if (getParser().ParseExpression(Val, Start, End))
|
||||||
return 0;
|
return 0;
|
||||||
return X86Operand::CreateImm(Val);
|
return X86Operand::CreateImm(Val, Start, End);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -299,14 +300,15 @@ X86Operand *X86ATTAsmParser::ParseMemOperand() {
|
|||||||
// it.
|
// it.
|
||||||
const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
|
const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
|
||||||
if (getLexer().isNot(AsmToken::LParen)) {
|
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
|
// After parsing the base expression we could either have a parenthesized
|
||||||
// memory address or not. If not, return now. If so, eat the (.
|
// memory address or not. If not, return now. If so, eat the (.
|
||||||
if (getLexer().isNot(AsmToken::LParen)) {
|
if (getLexer().isNot(AsmToken::LParen)) {
|
||||||
// Unless we have a segment register, treat this as an immediate.
|
// Unless we have a segment register, treat this as an immediate.
|
||||||
if (SegReg == 0)
|
if (SegReg == 0)
|
||||||
return X86Operand::CreateImm(Disp);
|
return X86Operand::CreateImm(Disp, ExprStart, ExprEnd);
|
||||||
return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
|
return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,14 +317,17 @@ X86Operand *X86ATTAsmParser::ParseMemOperand() {
|
|||||||
} else {
|
} else {
|
||||||
// Okay, we have a '('. We don't know if this is an expression or not, but
|
// 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.
|
// so we have to eat the ( to see beyond it.
|
||||||
|
SMLoc LParenLoc = getLexer().getTok().getLoc();
|
||||||
getLexer().Lex(); // Eat the '('.
|
getLexer().Lex(); // Eat the '('.
|
||||||
|
|
||||||
if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
|
if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
|
||||||
// Nothing to do here, fall into the code below with the '(' part of the
|
// Nothing to do here, fall into the code below with the '(' part of the
|
||||||
// memory operand consumed.
|
// memory operand consumed.
|
||||||
} else {
|
} else {
|
||||||
|
SMLoc ExprEnd;
|
||||||
|
|
||||||
// It must be an parenthesized expression, parse it now.
|
// It must be an parenthesized expression, parse it now.
|
||||||
if (getParser().ParseParenExpression(Disp))
|
if (getParser().ParseParenExpression(Disp, ExprEnd))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// After parsing the base expression we could either have a parenthesized
|
// After parsing the base expression we could either have a parenthesized
|
||||||
@ -330,7 +335,7 @@ X86Operand *X86ATTAsmParser::ParseMemOperand() {
|
|||||||
if (getLexer().isNot(AsmToken::LParen)) {
|
if (getLexer().isNot(AsmToken::LParen)) {
|
||||||
// Unless we have a segment register, treat this as an immediate.
|
// Unless we have a segment register, treat this as an immediate.
|
||||||
if (SegReg == 0)
|
if (SegReg == 0)
|
||||||
return X86Operand::CreateImm(Disp);
|
return X86Operand::CreateImm(Disp, LParenLoc, ExprEnd);
|
||||||
return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
|
return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,15 +419,15 @@ bool X86ATTAsmParser::
|
|||||||
ParseInstruction(const StringRef &Name, SMLoc NameLoc,
|
ParseInstruction(const StringRef &Name, SMLoc NameLoc,
|
||||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
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)) {
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||||
|
|
||||||
// Parse '*' modifier.
|
// Parse '*' modifier.
|
||||||
if (getLexer().is(AsmToken::Star)) {
|
if (getLexer().is(AsmToken::Star)) {
|
||||||
|
SMLoc Loc = getLexer().getTok().getLoc();
|
||||||
|
Operands.push_back(X86Operand::CreateToken("*", Loc));
|
||||||
getLexer().Lex(); // Eat the star.
|
getLexer().Lex(); // Eat the star.
|
||||||
Operands.push_back(X86Operand::CreateToken("*"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the first operand.
|
// Read the first operand.
|
||||||
|
@ -29,11 +29,6 @@
|
|||||||
#include "llvm/Target/TargetAsmParser.h"
|
#include "llvm/Target/TargetAsmParser.h"
|
||||||
using namespace llvm;
|
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.
|
// Mach-O section uniquing.
|
||||||
//
|
//
|
||||||
// FIXME: Figure out where this should live, it should be shared by
|
// FIXME: Figure out where this should live, it should be shared by
|
||||||
@ -193,10 +188,11 @@ void AsmParser::EatToEndOfStatement() {
|
|||||||
///
|
///
|
||||||
/// parenexpr ::= expr)
|
/// parenexpr ::= expr)
|
||||||
///
|
///
|
||||||
bool AsmParser::ParseParenExpr(const MCExpr *&Res) {
|
bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
|
||||||
if (ParseExpression(Res)) return true;
|
if (ParseExpression(Res)) return true;
|
||||||
if (Lexer.isNot(AsmToken::RParen))
|
if (Lexer.isNot(AsmToken::RParen))
|
||||||
return TokError("expected ')' in parentheses expression");
|
return TokError("expected ')' in parentheses expression");
|
||||||
|
EndLoc = Lexer.getLoc();
|
||||||
Lexer.Lex();
|
Lexer.Lex();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -217,13 +213,13 @@ MCSymbol *AsmParser::CreateSymbol(StringRef Name) {
|
|||||||
/// primaryexpr ::= symbol
|
/// primaryexpr ::= symbol
|
||||||
/// primaryexpr ::= number
|
/// primaryexpr ::= number
|
||||||
/// primaryexpr ::= ~,+,- primaryexpr
|
/// primaryexpr ::= ~,+,- primaryexpr
|
||||||
bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res) {
|
bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
|
||||||
switch (Lexer.getKind()) {
|
switch (Lexer.getKind()) {
|
||||||
default:
|
default:
|
||||||
return TokError("unknown token in expression");
|
return TokError("unknown token in expression");
|
||||||
case AsmToken::Exclaim:
|
case AsmToken::Exclaim:
|
||||||
Lexer.Lex(); // Eat the operator.
|
Lexer.Lex(); // Eat the operator.
|
||||||
if (ParsePrimaryExpr(Res))
|
if (ParsePrimaryExpr(Res, EndLoc))
|
||||||
return true;
|
return true;
|
||||||
Res = MCUnaryExpr::CreateLNot(Res, getContext());
|
Res = MCUnaryExpr::CreateLNot(Res, getContext());
|
||||||
return false;
|
return false;
|
||||||
@ -231,6 +227,7 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res) {
|
|||||||
case AsmToken::Identifier: {
|
case AsmToken::Identifier: {
|
||||||
// This is a symbol reference.
|
// This is a symbol reference.
|
||||||
MCSymbol *Sym = CreateSymbol(Lexer.getTok().getIdentifier());
|
MCSymbol *Sym = CreateSymbol(Lexer.getTok().getIdentifier());
|
||||||
|
EndLoc = Lexer.getLoc();
|
||||||
Lexer.Lex(); // Eat identifier.
|
Lexer.Lex(); // Eat identifier.
|
||||||
|
|
||||||
// If this is an absolute variable reference, substitute it now to preserve
|
// 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:
|
case AsmToken::Integer:
|
||||||
Res = MCConstantExpr::Create(Lexer.getTok().getIntVal(), getContext());
|
Res = MCConstantExpr::Create(Lexer.getTok().getIntVal(), getContext());
|
||||||
|
EndLoc = Lexer.getLoc();
|
||||||
Lexer.Lex(); // Eat token.
|
Lexer.Lex(); // Eat token.
|
||||||
return false;
|
return false;
|
||||||
case AsmToken::LParen:
|
case AsmToken::LParen:
|
||||||
Lexer.Lex(); // Eat the '('.
|
Lexer.Lex(); // Eat the '('.
|
||||||
return ParseParenExpr(Res);
|
return ParseParenExpr(Res, EndLoc);
|
||||||
case AsmToken::Minus:
|
case AsmToken::Minus:
|
||||||
Lexer.Lex(); // Eat the operator.
|
Lexer.Lex(); // Eat the operator.
|
||||||
if (ParsePrimaryExpr(Res))
|
if (ParsePrimaryExpr(Res, EndLoc))
|
||||||
return true;
|
return true;
|
||||||
Res = MCUnaryExpr::CreateMinus(Res, getContext());
|
Res = MCUnaryExpr::CreateMinus(Res, getContext());
|
||||||
return false;
|
return false;
|
||||||
case AsmToken::Plus:
|
case AsmToken::Plus:
|
||||||
Lexer.Lex(); // Eat the operator.
|
Lexer.Lex(); // Eat the operator.
|
||||||
if (ParsePrimaryExpr(Res))
|
if (ParsePrimaryExpr(Res, EndLoc))
|
||||||
return true;
|
return true;
|
||||||
Res = MCUnaryExpr::CreatePlus(Res, getContext());
|
Res = MCUnaryExpr::CreatePlus(Res, getContext());
|
||||||
return false;
|
return false;
|
||||||
case AsmToken::Tilde:
|
case AsmToken::Tilde:
|
||||||
Lexer.Lex(); // Eat the operator.
|
Lexer.Lex(); // Eat the operator.
|
||||||
if (ParsePrimaryExpr(Res))
|
if (ParsePrimaryExpr(Res, EndLoc))
|
||||||
return true;
|
return true;
|
||||||
Res = MCUnaryExpr::CreateNot(Res, getContext());
|
Res = MCUnaryExpr::CreateNot(Res, getContext());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AsmParser::ParseExpression(const MCExpr *&Res) {
|
||||||
|
SMLoc L;
|
||||||
|
return ParseExpression(Res, L, L);
|
||||||
|
}
|
||||||
|
|
||||||
/// ParseExpression - Parse an expression and return it.
|
/// ParseExpression - Parse an expression and return it.
|
||||||
///
|
///
|
||||||
/// expr ::= expr +,- expr -> lowest.
|
/// expr ::= expr +,- expr -> lowest.
|
||||||
@ -279,14 +282,16 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res) {
|
|||||||
/// expr ::= expr *,/,%,<<,>> expr -> highest.
|
/// expr ::= expr *,/,%,<<,>> expr -> highest.
|
||||||
/// expr ::= primaryexpr
|
/// expr ::= primaryexpr
|
||||||
///
|
///
|
||||||
bool AsmParser::ParseExpression(const MCExpr *&Res) {
|
bool AsmParser::ParseExpression(const MCExpr *&Res,
|
||||||
|
SMLoc &StartLoc, SMLoc &EndLoc) {
|
||||||
|
StartLoc = Lexer.getLoc();
|
||||||
Res = 0;
|
Res = 0;
|
||||||
return ParsePrimaryExpr(Res) ||
|
return ParsePrimaryExpr(Res, EndLoc) ||
|
||||||
ParseBinOpRHS(1, Res);
|
ParseBinOpRHS(1, Res, EndLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AsmParser::ParseParenExpression(const MCExpr *&Res) {
|
bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
|
||||||
if (ParseParenExpr(Res))
|
if (ParseParenExpr(Res, EndLoc))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -381,7 +386,8 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K,
|
|||||||
|
|
||||||
/// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
|
/// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
|
||||||
/// Res contains the LHS of the expression on input.
|
/// 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) {
|
while (1) {
|
||||||
MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
|
MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
|
||||||
unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
|
unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
|
||||||
@ -395,14 +401,14 @@ bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res) {
|
|||||||
|
|
||||||
// Eat the next primary expression.
|
// Eat the next primary expression.
|
||||||
const MCExpr *RHS;
|
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
|
// If BinOp binds less tightly with RHS than the operator after RHS, let
|
||||||
// the pending operator take RHS as its LHS.
|
// the pending operator take RHS as its LHS.
|
||||||
MCBinaryExpr::Opcode Dummy;
|
MCBinaryExpr::Opcode Dummy;
|
||||||
unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
|
unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
|
||||||
if (TokPrec < NextTokPrec) {
|
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.
|
// Merge LHS and RHS according to operator.
|
||||||
|
@ -79,8 +79,10 @@ public:
|
|||||||
virtual void Warning(SMLoc L, const Twine &Meg);
|
virtual void Warning(SMLoc L, const Twine &Meg);
|
||||||
virtual bool Error(SMLoc L, const Twine &Msg);
|
virtual bool Error(SMLoc L, const Twine &Msg);
|
||||||
|
|
||||||
virtual bool ParseExpression(const MCExpr *&Res);
|
bool ParseExpression(const MCExpr *&Res);
|
||||||
virtual bool ParseParenExpression(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);
|
virtual bool ParseAbsoluteExpression(int64_t &Res);
|
||||||
|
|
||||||
/// }
|
/// }
|
||||||
@ -105,9 +107,9 @@ private:
|
|||||||
|
|
||||||
bool ParseAssignment(const StringRef &Name);
|
bool ParseAssignment(const StringRef &Name);
|
||||||
|
|
||||||
bool ParsePrimaryExpr(const MCExpr *&Res);
|
bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc);
|
||||||
bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res);
|
bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
|
||||||
bool ParseParenExpr(const MCExpr *&Res);
|
bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
|
||||||
|
|
||||||
/// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
|
/// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
|
||||||
/// and set \arg Res to the identifier contents.
|
/// and set \arg Res to the identifier contents.
|
||||||
|
Loading…
Reference in New Issue
Block a user