From 896fe7d2bc844386470a6e0bd039bfc329924645 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Tue, 18 Jul 2017 09:17:00 +0000 Subject: [PATCH] [SystemZ, AsmParser] Enable the mnemonic spell corrector. This enables the suggestions of other mnemonics when invalid ones are specified. Review: Ulrich Weigand git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308280 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp | 15 +++++- test/MC/SystemZ/invalid-instructions-spellcheck.s | 66 +++++++++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 test/MC/SystemZ/invalid-instructions-spellcheck.s diff --git a/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp index ee23692ad1d..33680789ee0 100644 --- a/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp +++ b/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp @@ -275,6 +275,10 @@ public: SMLoc getEndLoc() const override { return EndLoc; } void print(raw_ostream &OS) const override; + /// getLocRange - Get the range between the first and last token of this + /// operand. + SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); } + // Used by the TableGen code to add particular types of operand // to an instruction. void addRegOperands(MCInst &Inst, unsigned N) const { @@ -1164,6 +1168,8 @@ bool SystemZAsmParser::parseOperand(OperandVector &Operands, return false; } +std::string SystemZMnemonicSpellCheck(StringRef S, uint64_t FBS); + bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, @@ -1209,8 +1215,13 @@ bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return Error(ErrorLoc, "invalid operand for instruction"); } - case Match_MnemonicFail: - return Error(IDLoc, "invalid instruction"); + case Match_MnemonicFail: { + uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); + std::string Suggestion = SystemZMnemonicSpellCheck( + ((SystemZOperand &)*Operands[0]).getToken(), FBS); + return Error(IDLoc, "invalid instruction" + Suggestion, + ((SystemZOperand &)*Operands[0]).getLocRange()); + } } llvm_unreachable("Unexpected match type"); diff --git a/test/MC/SystemZ/invalid-instructions-spellcheck.s b/test/MC/SystemZ/invalid-instructions-spellcheck.s new file mode 100644 index 00000000000..e77b99d9a38 --- /dev/null +++ b/test/MC/SystemZ/invalid-instructions-spellcheck.s @@ -0,0 +1,66 @@ +# RUN: not llvm-mc -triple=systemz -mcpu=z13 -show-encoding < %s 2>&1 | FileCheck %s +# RUN: not llvm-mc -triple=systemz -mcpu=zEC12 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ZEC12 + +# 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: 'cpdt' is 1 edit away, i.e. an deletion. + + cpdtX %r1, 0(4, %r15), 0 + +#CHECK: error: invalid instruction, did you mean: cpdt +#CHECK-NEXT: cpdtX %r1, 0(4, %r15), 0 +#CHECK-NEXT: ^ + +# Check edit distance 1 and 2 + + ltTr %r1, %r2 + +# CHECK: error: invalid instruction, did you mean: lr, lt, ltdr, ltdtr, lter, ltgr, ltr, ltxr, ltxtr, tr, trtr? +# CHECK-NEXT: ltTr %r1, %r2 +# CHECK-NEXT: ^ + +# Check edit distance 1 and 2, just insertions: + + begin 0, 65292 + +# CHECK: error: invalid instruction, did you mean: tbegin, tbeginc? +# CHECK-NEXT: begin 0, 65292 +# CHECK-NEXT: ^ + +# Check an instruction that is 2 edits away, and also has a lot of candidates: + + adt %r1, 244(%r15) + +# CHECK: error: invalid instruction, did you mean: a, ad, adb, adr, adtr, adtra, d, lat, mad, qadtr? +# CHECK-NEXT: adt %r1, 244(%r15) +# CHECK-NEXT: ^ + +# Here it is checked that we don't suggest instructions that are not supported. +# For example, in pre-z13 mode we don't want to see suggestions for vector instructions. + + vlvggp %v1, %r2, %r3 + +# CHECK-ZEC12: error: invalid instruction +# CHECK-ZEC12: vlvggp +# CHECK-ZEC12: ^ + +# CHECK: error: invalid instruction, did you mean: vlvg, vlvgg, vlvgp? +# CHECK-NEXT: vlvggp %v1, %r2, %r3 +# CHECK-NEXT: ^ -- 2.11.0