From f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Thu, 12 Aug 2010 00:55:38 +0000 Subject: [PATCH] MC/AsmParser: Push the burdon of emitting diagnostics about unmatched instructions onto the target specific parser, which can do a better job. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@110889 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetAsmParser.h | 6 ++++- lib/MC/MCParser/AsmParser.cpp | 10 ++------ lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 11 ++++++-- lib/Target/X86/AsmParser/X86AsmParser.cpp | 31 ++++++++++++++--------- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/include/llvm/Target/TargetAsmParser.h b/include/llvm/Target/TargetAsmParser.h index 4d37ad3d75d..5830d1f99f5 100644 --- a/include/llvm/Target/TargetAsmParser.h +++ b/include/llvm/Target/TargetAsmParser.h @@ -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 &Operands, + MatchInstruction(SMLoc IDLoc, + const SmallVectorImpl &Operands, MCInst &Inst) = 0; }; diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 016f8f96a36..87a4a886bc8 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -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 diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 6932afbdb41..14592b0709f 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -80,9 +80,16 @@ private: bool ParseDirectiveSyntax(SMLoc L); - bool MatchInstruction(const SmallVectorImpl &Operands, + bool MatchInstruction(SMLoc IDLoc, + const SmallVectorImpl &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 diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 874a38ad0ed..01d2b415fa1 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -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 &Operands, + bool MatchInstruction(SMLoc IDLoc, + const SmallVectorImpl &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 +X86ATTAsmParser::MatchInstruction(SMLoc IDLoc, + const SmallVectorImpl &Operands, MCInst &Inst) { + assert(!Operands.empty() && "Unexpect empty operand list!"); + + X86Operand *Op = static_cast(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(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 return false; // Otherwise, the match failed. + + // FIXME: We should give nicer diagnostics about the exact failure. + Error(IDLoc, "unrecognized instruction"); + return true; }