MC/AsmParser: Push the burdon of emitting diagnostics about unmatched

instructions onto the target specific parser, which can do a better job.

llvm-svn: 110889
This commit is contained in:
Daniel Dunbar 2010-08-12 00:55:38 +00:00
parent 167b9d7f30
commit 2ecc3bb4f7
4 changed files with 35 additions and 23 deletions

View File

@ -73,8 +73,12 @@ public:
/// MatchInstruction - Recognize a series of operands of a parsed instruction
/// as an actual MCInst. This returns false and fills in Inst on success and
/// returns true on failure to match.
///
/// On failure, the target parser is responsible for emitting a diagnostic
/// explaining the match failure.
virtual bool
MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MatchInstruction(SMLoc IDLoc,
const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCInst &Inst) = 0;
};

View File

@ -934,17 +934,11 @@ bool AsmParser::ParseStatement() {
// If parsing succeeded, match the instruction.
if (!HadError) {
MCInst Inst;
if (!getTargetParser().MatchInstruction(ParsedOperands, Inst)) {
if (!getTargetParser().MatchInstruction(IDLoc, ParsedOperands, Inst)) {
// Emit the instruction on success.
Out.EmitInstruction(Inst);
} else {
// Otherwise emit a diagnostic about the match failure and set the error
// flag.
//
// FIXME: We should give nicer diagnostics about the exact failure.
Error(IDLoc, "unrecognized instruction");
} else
HadError = true;
}
}
// If there was no error, consume the end-of-statement token. Otherwise this

View File

@ -80,9 +80,16 @@ private:
bool ParseDirectiveSyntax(SMLoc L);
bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
bool MatchInstruction(SMLoc IDLoc,
const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCInst &Inst) {
return MatchInstructionImpl(Operands, Inst);
if (!MatchInstructionImpl(Operands, Inst))
return false;
// FIXME: We should give nicer diagnostics about the exact failure.
Error(IDLoc, "unrecognized instruction");
return true;
}
/// @name Auto-generated Match Functions

View File

@ -10,6 +10,7 @@
#include "llvm/Target/TargetAsmParser.h"
#include "X86.h"
#include "X86Subtarget.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
@ -50,7 +51,8 @@ private:
bool ParseDirectiveWord(unsigned Size, SMLoc L);
bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
bool MatchInstruction(SMLoc IDLoc,
const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCInst &Inst);
/// @name Auto-generated Matcher Functions
@ -871,31 +873,32 @@ bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
return false;
}
bool
X86ATTAsmParser::MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*>
X86ATTAsmParser::MatchInstruction(SMLoc IDLoc,
const SmallVectorImpl<MCParsedAsmOperand*>
&Operands,
MCInst &Inst) {
assert(!Operands.empty() && "Unexpect empty operand list!");
X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
assert(Op->isToken() && "Leading operand should always be a mnemonic!");
// First, try a direct match.
if (!MatchInstructionImpl(Operands, Inst))
return false;
// Ignore anything which is obviously not a suffix match.
if (Operands.size() == 0)
return true;
X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
if (!Op->isToken() || Op->getToken().size() > 15)
return true;
// FIXME: Ideally, we would only attempt suffix matches for things which are
// valid prefixes, and we could just infer the right unambiguous
// type. However, that requires substantially more matcher support than the
// following hack.
// Change the operand to point to a temporary token.
char Tmp[16];
StringRef Base = Op->getToken();
memcpy(Tmp, Base.data(), Base.size());
Op->setTokenValue(StringRef(Tmp, Base.size() + 1));
SmallString<16> Tmp;
Tmp += Base;
Tmp += ' ';
Op->setTokenValue(Tmp.str());
// Check for the various suffix matches.
Tmp[Base.size()] = 'b';
@ -917,6 +920,10 @@ X86ATTAsmParser::MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*>
return false;
// Otherwise, the match failed.
// FIXME: We should give nicer diagnostics about the exact failure.
Error(IDLoc, "unrecognized instruction");
return true;
}