From: Hal Finkel Date: Sat, 16 Dec 2017 02:42:18 +0000 (+0000) Subject: [PowerPC, AsmParser] Enable the mnemonic spell corrector X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4f44d46023205f082762e21f2503cff164028eee;p=llvm [PowerPC, AsmParser] Enable the mnemonic spell corrector r307148 added an assembly mnemonic spelling correction support and enabled it on ARM. This enables that support on PowerPC as well. Patch by Dmitry Venikov, thanks! Differential Revision: https://reviews.llvm.org/D40552 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320911 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp index 2fbf51007c3..d6db354e021 100644 --- a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp +++ b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp @@ -393,6 +393,10 @@ public: /// getEndLoc - Get the location of the last token of this operand. SMLoc getEndLoc() const override { return EndLoc; } + /// getLocRange - Get the range between the first and last token of this + /// operand. + SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); } + /// isPPC64 - True if this operand is for an instruction in 64-bit mode. bool isPPC64() const { return IsPPC64; } @@ -1268,6 +1272,9 @@ void PPCAsmParser::ProcessInstruction(MCInst &Inst, } } +static std::string PPCMnemonicSpellCheck(StringRef S, uint64_t FBS, + unsigned VariantID = 0); + bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, @@ -1283,8 +1290,13 @@ bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return false; case Match_MissingFeature: return Error(IDLoc, "instruction use requires an option to be enabled"); - case Match_MnemonicFail: - return Error(IDLoc, "unrecognized instruction mnemonic"); + case Match_MnemonicFail: { + uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); + std::string Suggestion = PPCMnemonicSpellCheck( + ((PPCOperand &)*Operands[0]).getToken(), FBS); + return Error(IDLoc, "invalid instruction" + Suggestion, + ((PPCOperand &)*Operands[0]).getLocRange()); + } case Match_InvalidOperand: { SMLoc ErrorLoc = IDLoc; if (ErrorInfo != ~0ULL) { @@ -1920,6 +1932,7 @@ extern "C" void LLVMInitializePowerPCAsmParser() { #define GET_REGISTER_MATCHER #define GET_MATCHER_IMPLEMENTATION +#define GET_MNEMONIC_SPELL_CHECKER #include "PPCGenAsmMatcher.inc" // Define this matcher function after the auto-generated include so we diff --git a/test/MC/PowerPC/invalid-instructions-spellcheck.s b/test/MC/PowerPC/invalid-instructions-spellcheck.s new file mode 100644 index 00000000000..cbf761f83fd --- /dev/null +++ b/test/MC/PowerPC/invalid-instructions-spellcheck.s @@ -0,0 +1,44 @@ +# RUN: not llvm-mc -triple powerpc-unknown-unknown < %s 2>&1 | FileCheck %s + +# This tests the mnemonic spell checker. + +# First check what happens when an instruction is omitted: + +%r1, %r2, %r3 + +# CHECK: error: unexpected token at start of statement +# CHECK-NEXT: %r1, %r2, %r3 +# CHECK-NEXT: ^ + +# We don't want to see a suggestion here; the edit distance is too large to +# give sensible suggestions: + +aaaaaaaaaaaaaaa %r1, %r2, %r3 + +# CHECK: error: invalid instruction +# CHECK-NEXT: aaaaaaaaaaaaaaa %r1, %r2, %r3 +# CHECK-NEXT: ^ + +# Check that we get one suggestion: 'vmaxfpg' is 1 edit away, i.e. an deletion. + +vmaxfpg %r1, %r2 + +# CHECK: error: invalid instruction, did you mean: vmaxfp? +# CHECK-NEXT: vmaxfpg %r1, %r2 +# CHECK-NEXT: ^ + +# Check edit distance 1 and 2, just insertions: + +xsnmsubad %r1, %r2 + +# CHECK: error: invalid instruction, did you mean: xsmsubadp, xsnmsubadp? +# CHECK-NEXT: xsnmsubad %r1, %r2 +# CHECK-NEXT: ^ + +# Check an instruction that is 2 edits away, and also has a lot of candidates: + +adXd %r1, %r2, %r3 + +# CHECK: error: invalid instruction, did you mean: add, addc, adde, addi, fadd? +# CHECK-NEXT: adXd %r1, %r2, %r3 +# CHECK-NEXT: ^