diff options
Diffstat (limited to 'utils/TableGen/AsmMatcherEmitter.cpp')
-rw-r--r-- | utils/TableGen/AsmMatcherEmitter.cpp | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 0980e08f67f71..1f8e1b125889f 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -2222,7 +2222,7 @@ static void emitValidateOperandClass(AsmMatcherInfo &Info, OS << " switch (Operand.getReg()) {\n"; OS << " default: OpKind = InvalidMatchClass; break;\n"; for (const auto &RC : Info.RegisterClasses) - OS << " case " << Info.Target.getName() << "::" + OS << " case " << RC.first->getValueAsString("Namespace") << "::" << RC.first->getName() << ": OpKind = " << RC.second->Name << "; break;\n"; OS << " }\n"; @@ -2711,6 +2711,47 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, OS << "}\n\n"; } +static void emitMnemonicSpellChecker(raw_ostream &OS, CodeGenTarget &Target, + unsigned VariantCount) { + OS << "std::string " << Target.getName() << "MnemonicSpellCheck(StringRef S, uint64_t FBS) {\n"; + if (!VariantCount) + OS << " return \"\";"; + else { + OS << " const unsigned MaxEditDist = 2;\n"; + OS << " std::vector<StringRef> Candidates;\n"; + OS << " StringRef Prev = \"\";\n"; + OS << " auto End = std::end(MatchTable0);\n"; + OS << "\n"; + OS << " for (auto I = std::begin(MatchTable0); I < End; I++) {\n"; + OS << " // Ignore unsupported instructions.\n"; + OS << " if ((FBS & I->RequiredFeatures) != I->RequiredFeatures)\n"; + OS << " continue;\n"; + OS << "\n"; + OS << " StringRef T = I->getMnemonic();\n"; + OS << " // Avoid recomputing the edit distance for the same string.\n"; + OS << " if (T.equals(Prev))\n"; + OS << " continue;\n"; + OS << "\n"; + OS << " Prev = T;\n"; + OS << " unsigned Dist = S.edit_distance(T, false, MaxEditDist);\n"; + OS << " if (Dist <= MaxEditDist)\n"; + OS << " Candidates.push_back(T);\n"; + OS << " }\n"; + OS << "\n"; + OS << " if (Candidates.empty())\n"; + OS << " return \"\";\n"; + OS << "\n"; + OS << " std::string Res = \", did you mean: \";\n"; + OS << " unsigned i = 0;\n"; + OS << " for( ; i < Candidates.size() - 1; i++)\n"; + OS << " Res += Candidates[i].str() + \", \";\n"; + OS << " return Res + Candidates[i].str() + \"?\";\n"; + } + OS << "}\n"; + OS << "\n"; +} + + void AsmMatcherEmitter::run(raw_ostream &OS) { CodeGenTarget Target(Records); Record *AsmParser = Target.getAsmParser(); @@ -2948,7 +2989,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.str(); OS << " { " << StringTable.GetOrAddStringOffset(LenMnemonic, false) << " /* " << MI->Mnemonic << " */, " - << Target.getName() << "::" + << Target.getInstNamespace() << "::" << MI->getResultInst()->TheDef->getName() << ", " << MI->ConversionFnKind << ", "; @@ -2974,6 +3015,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "};\n\n"; } + emitMnemonicSpellChecker(OS, Target, VariantCount); + // Finally, build the match function. OS << "unsigned " << Target.getName() << ClassName << "::\n" << "MatchInstructionImpl(const OperandVector &Operands,\n"; |