[llvm] [RISCV] Report all near-miss reasons in the AsmParser (PR #205721)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 25 16:49:43 PDT 2026


================
@@ -1460,350 +1473,376 @@ bool RISCVAsmParser::generateImmOutOfRangeError(
   return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
 }
 
-bool RISCVAsmParser::generateImmOutOfRangeError(
-    OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
-    const Twine &Msg = "immediate must be an integer in the range") {
-  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
-  return generateImmOutOfRangeError(ErrorLoc, Lower, Upper, Msg);
-}
-
-bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
-                                             OperandVector &Operands,
-                                             MCStreamer &Out,
-                                             uint64_t &ErrorInfo,
-                                             bool MatchingInlineAsm) {
-  MCInst Inst;
-  FeatureBitset MissingFeatures;
-
-  auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
-                                     MatchingInlineAsm);
-  switch (Result) {
-  default:
-    break;
-  case Match_Success:
-    if (validateInstruction(Inst, Operands))
-      return true;
-    return processInstruction(Inst, IDLoc, Operands, Out);
-  case Match_MissingFeature: {
-    assert(MissingFeatures.any() && "Unknown missing features!");
-    bool FirstFeature = true;
-    std::string Msg = "instruction requires the following:";
-    for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
-      if (MissingFeatures[i]) {
-        Msg += FirstFeature ? " " : ", ";
-        Msg += getSubtargetFeatureName(i);
-        FirstFeature = false;
-      }
-    }
-    return Error(IDLoc, Msg);
-  }
-  case Match_MnemonicFail: {
-    FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
-    std::string Suggestion = RISCVMnemonicSpellCheck(
-        ((RISCVOperand &)*Operands[0]).getToken(), FBS, 0);
-    return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);
-  }
-  case Match_InvalidOperand: {
-    SMLoc ErrorLoc = IDLoc;
-    if (ErrorInfo != ~0ULL) {
-      if (ErrorInfo >= Operands.size())
-        return Error(ErrorLoc, "too few operands for instruction");
-
-      ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
-      if (ErrorLoc == SMLoc())
-        ErrorLoc = IDLoc;
-    }
-    return Error(ErrorLoc, "invalid operand for instruction");
-  }
-  }
-
-  // Handle the case when the error message is of specific type
-  // other than the generic Match_InvalidOperand, and the
-  // corresponding operand is missing.
-  if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
-    SMLoc ErrorLoc = IDLoc;
-    if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.size())
-      return Error(ErrorLoc, "too few operands for instruction");
-  }
+// Some diagnostics need to vary with subtarget features, so they are handled
+// here. For example, several immediate ranges depend on whether the target is
+// RV32 or RV64.
+std::string RISCVAsmParser::getCustomOperandDiag(unsigned MatchError) {
+  auto Range = [](int64_t Lower, int64_t Upper,
+                  StringRef Msg = "immediate must be an integer in the range") {
+    return (Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]").str();
+  };
 
-  switch (Result) {
+  switch (MatchError) {
   default:
-    break;
+    // For all other operand diagnostics, use the static string generated by
+    // TableGen from the DiagnosticString field, if any.
+    if (const char *Diag = getMatchKindDiag((RISCVMatchResultTy)MatchError))
+      return Diag;
+    return std::string();
   case Match_InvalidImmXLenLI:
-    if (isRV64()) {
-      SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
-      return Error(ErrorLoc, "operand must be a constant 64-bit integer");
-    }
-    return generateImmOutOfRangeError(Operands, ErrorInfo,
-                                      std::numeric_limits<int32_t>::min(),
-                                      std::numeric_limits<uint32_t>::max());
+    if (isRV64())
+      return "operand must be a constant 64-bit integer";
+    return Range(std::numeric_limits<int32_t>::min(),
+                 std::numeric_limits<uint32_t>::max());
   case Match_InvalidImmXLenLI_Restricted:
-    if (isRV64()) {
-      SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
-      return Error(ErrorLoc, "operand either must be a constant 64-bit integer "
-                             "or a bare symbol name");
-    }
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
-        std::numeric_limits<uint32_t>::max(),
-        "operand either must be a bare symbol name or an immediate integer in "
-        "the range");
+    if (isRV64())
+      return "operand either must be a constant 64-bit integer "
+             "or a bare symbol name";
+    return Range(std::numeric_limits<int32_t>::min(),
+                 std::numeric_limits<uint32_t>::max(),
+                 "operand either must be a bare symbol name or an immediate "
+                 "integer in the range");
   case Match_InvalidUImmLog2XLen:
     if (isRV64())
-      return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
+      return Range(0, (1 << 6) - 1);
+    return Range(0, (1 << 5) - 1);
   case Match_InvalidUImmLog2XLenNonZero:
     if (isRV64())
-      return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
+      return Range(1, (1 << 6) - 1);
+    return Range(1, (1 << 5) - 1);
   case Match_InvalidUImm1:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
+    return Range(0, (1 << 1) - 1);
   case Match_InvalidUImm2:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
+    return Range(0, (1 << 2) - 1);
   case Match_InvalidUImm2Lsb0:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 2,
-                                      "immediate must be one of");
+    return Range(0, 2, "immediate must be one of");
   case Match_InvalidUImm3:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
+    return Range(0, (1 << 3) - 1);
   case Match_InvalidUImm4:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
+    return Range(0, (1 << 4) - 1);
   case Match_InvalidUImm4Plus1:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
+    return Range(1, (1 << 4));
   case Match_InvalidUImm5:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
+    return Range(0, (1 << 5) - 1);
   case Match_InvalidUImm5NonZero:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
+    return Range(1, (1 << 5) - 1);
   case Match_InvalidUImm5GT3:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1);
+    return Range(4, (1 << 5) - 1);
   case Match_InvalidUImm5Plus1:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
+    return Range(1, (1 << 5));
   case Match_InvalidUImm5GE6Plus1:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 6, (1 << 5));
-  case Match_InvalidUImm5Slist: {
-    SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
-    return Error(ErrorLoc,
-                 "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31");
-  }
+    return Range(6, (1 << 5));
+  case Match_InvalidUImm5Slist:
+    return "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31";
   case Match_InvalidUImm6:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
+    return Range(0, (1 << 6) - 1);
   case Match_InvalidUImm6Plus1:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
+    return Range(1, (1 << 6));
   case Match_InvalidUImm7:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
+    return Range(0, (1 << 7) - 1);
   case Match_InvalidUImm8:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
+    return Range(0, (1 << 8) - 1);
   case Match_InvalidUImm8GE32:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 32, (1 << 8) - 1);
+    return Range(32, (1 << 8) - 1);
   case Match_InvalidSImm5:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),
-                                      (1 << 4) - 1);
+    return Range(-(1 << 4), (1 << 4) - 1);
   case Match_InvalidSImm5NonZero:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, -(1 << 4), (1 << 4) - 1,
-        "immediate must be non-zero in the range");
+    return Range(-(1 << 4), (1 << 4) - 1,
+                 "immediate must be non-zero in the range");
   case Match_InvalidSImm6:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
-                                      (1 << 5) - 1);
+    return Range(-(1 << 5), (1 << 5) - 1);
   case Match_InvalidSImm6NonZero:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
-        "immediate must be non-zero in the range");
+    return Range(-(1 << 5), (1 << 5) - 1,
+                 "immediate must be non-zero in the range");
   case Match_InvalidCLUIImm:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, 1, (1 << 5) - 1,
-        "immediate must be in [0xfffe0, 0xfffff] or");
+    return Range(1, (1 << 5) - 1, "immediate must be in [0xfffe0, 0xfffff] or");
   case Match_InvalidUImm5Lsb0:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, 0, (1 << 5) - 2,
-        "immediate must be a multiple of 2 bytes in the range");
+    return Range(0, (1 << 5) - 2,
+                 "immediate must be a multiple of 2 bytes in the range");
   case Match_InvalidUImm6Lsb0:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, 0, (1 << 6) - 2,
-        "immediate must be a multiple of 2 bytes in the range");
+    return Range(0, (1 << 6) - 2,
+                 "immediate must be a multiple of 2 bytes in the range");
   case Match_InvalidUImm7Lsb00:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, 0, (1 << 7) - 4,
-        "immediate must be a multiple of 4 bytes in the range");
+    return Range(0, (1 << 7) - 4,
+                 "immediate must be a multiple of 4 bytes in the range");
   case Match_InvalidUImm8Lsb00:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, 0, (1 << 8) - 4,
-        "immediate must be a multiple of 4 bytes in the range");
+    return Range(0, (1 << 8) - 4,
+                 "immediate must be a multiple of 4 bytes in the range");
   case Match_InvalidUImm8Lsb000:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, 0, (1 << 8) - 8,
-        "immediate must be a multiple of 8 bytes in the range");
+    return Range(0, (1 << 8) - 8,
+                 "immediate must be a multiple of 8 bytes in the range");
   case Match_InvalidUImm9:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 9) - 1,
-                                      "immediate offset must be in the range");
+    return Range(0, (1 << 9) - 1, "immediate offset must be in the range");
   case Match_InvalidBareSImm9Lsb0:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
-        "immediate must be a multiple of 2 bytes in the range");
+    return Range(-(1 << 8), (1 << 8) - 2,
+                 "immediate must be a multiple of 2 bytes in the range");
   case Match_InvalidUImm9Lsb000:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, 0, (1 << 9) - 8,
-        "immediate must be a multiple of 8 bytes in the range");
+    return Range(0, (1 << 9) - 8,
+                 "immediate must be a multiple of 8 bytes in the range");
   case Match_InvalidSImm8PLI_B:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
-                                      (1 << 8) - 1);
+    return Range(-(1 << 7), (1 << 8) - 1);
   case Match_InvalidSImm10:
   case Match_InvalidSImm10PLI_H:
   case Match_InvalidSImm10PLI_W:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
-                                      (1 << 9) - 1);
+    return Range(-(1 << 9), (1 << 9) - 1);
   case Match_InvalidSImm10PLUI:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
-                                      (1 << 10) - 1);
+    return Range(-(1 << 9), (1 << 10) - 1);
   case Match_InvalidUImm10Lsb00NonZero:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, 4, (1 << 10) - 4,
-        "immediate must be a multiple of 4 bytes in the range");
+    return Range(4, (1 << 10) - 4,
+                 "immediate must be a multiple of 4 bytes in the range");
   case Match_InvalidSImm10Lsb0000NonZero:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
+    return Range(
+        -(1 << 9), (1 << 9) - 16,
         "immediate must be a multiple of 16 bytes and non-zero in the range");
   case Match_InvalidSImm11:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 10),
-                                      (1 << 10) - 1);
+    return Range(-(1 << 10), (1 << 10) - 1);
   case Match_InvalidBareSImm11Lsb0:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,
-        "immediate must be a multiple of 2 bytes in the range");
+    return Range(-(1 << 10), (1 << 10) - 2,
+                 "immediate must be a multiple of 2 bytes in the range");
   case Match_InvalidUImm10:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
+    return Range(0, (1 << 10) - 1);
   case Match_InvalidUImm11:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
+    return Range(0, (1 << 11) - 1);
   case Match_InvalidUImm14Lsb00:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, 0, (1 << 14) - 4,
-        "immediate must be a multiple of 4 bytes in the range");
+    return Range(0, (1 << 14) - 4,
+                 "immediate must be a multiple of 4 bytes in the range");
   case Match_InvalidUImm16NonZero:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16) - 1);
+    return Range(1, (1 << 16) - 1);
   case Match_InvalidSImm12:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
-                                      (1 << 11) - 1);
+    return Range(-(1 << 11), (1 << 11) - 1);
   case Match_InvalidSImm12LO:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
-        "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo specifier or an "
-        "integer in the range");
+    return Range(-(1 << 11), (1 << 11) - 1,
+                 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo "
+                 "specifier or an integer in the range");
   case Match_InvalidBareSImm12Lsb0:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
-        "immediate must be a multiple of 2 bytes in the range");
+    return Range(-(1 << 11), (1 << 11) - 2,
+                 "immediate must be a multiple of 2 bytes in the range");
   case Match_InvalidSImm12Lsb00000:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32,
-        "immediate must be a multiple of 32 bytes in the range");
+    return Range(-(1 << 11), (1 << 11) - 32,
+                 "immediate must be a multiple of 32 bytes in the range");
   case Match_InvalidBareSImm13Lsb0:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
-        "immediate must be a multiple of 2 bytes in the range");
+    return Range(-(1 << 12), (1 << 12) - 2,
+                 "immediate must be a multiple of 2 bytes in the range");
   case Match_InvalidSImm16:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 15),
-                                      (1 << 15) - 1);
+    return Range(-(1 << 15), (1 << 15) - 1);
   case Match_InvalidSImm16NonZero:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
-        "immediate must be non-zero in the range");
+    return Range(-(1 << 15), (1 << 15) - 1,
+                 "immediate must be non-zero in the range");
   case Match_InvalidSImm20LI:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, -(1 << 19), (1 << 19) - 1,
-        "operand must be a symbol with a %qc.abs20 specifier or an integer "
-        " in the range");
+    return Range(-(1 << 19), (1 << 19) - 1,
+                 "operand must be a symbol with a %qc.abs20 specifier or an "
+                 "integer  in the range");
   case Match_InvalidUImm20LUI:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, 0, (1 << 20) - 1,
-        "operand must be a symbol with "
-        "%hi/%tprel_hi specifier or an integer in "
-        "the range");
+    return Range(0, (1 << 20) - 1,
+                 "operand must be a symbol with %hi/%tprel_hi specifier or an "
+                 "integer in the range");
   case Match_InvalidUImm20:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
+    return Range(0, (1 << 20) - 1);
   case Match_InvalidUImm20AUIPC:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, 0, (1 << 20) - 1,
+    return Range(
+        0, (1 << 20) - 1,
         "operand must be a symbol with a "
         "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
-        "or "
-        "an integer in the range");
+        "or an integer in the range");
   case Match_InvalidBareSImm21Lsb0:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
-        "immediate must be a multiple of 2 bytes in the range");
-  case Match_InvalidCSRSystemRegister: {
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
-                                      "operand must be a valid system register "
-                                      "name or an integer in the range");
-  }
+    return Range(-(1 << 20), (1 << 20) - 2,
+                 "immediate must be a multiple of 2 bytes in the range");
+  case Match_InvalidCSRSystemRegister:
+    return Range(0, (1 << 12) - 1,
+                 "operand must be a valid system register name or an integer "
+                 "in the range");
   case Match_InvalidImm5Zibi:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, -1, (1 << 5) - 1,
-        "immediate must be non-zero in the range");
-  case Match_InvalidVTypeI: {
-    SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
-    return generateVTypeError(ErrorLoc);
-  }
-  case Match_InvalidSImm5Plus1: {
-    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,
-                                      (1 << 4),
-                                      "immediate must be in the range");
-  }
+    return Range(-1, (1 << 5) - 1, "immediate must be non-zero in the range");
+  case Match_InvalidVTypeI:
+    return "operand must be "
+           "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]";
+  case Match_InvalidSImm5Plus1:
+    return Range(-(1 << 4) + 1, (1 << 4), "immediate must be in the range");
   case Match_InvalidSImm18:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 17),
-                                      (1 << 17) - 1);
+    return Range(-(1 << 17), (1 << 17) - 1);
   case Match_InvalidSImm18Lsb0:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,
-        "immediate must be a multiple of 2 bytes in the range");
+    return Range(-(1 << 17), (1 << 17) - 2,
+                 "immediate must be a multiple of 2 bytes in the range");
   case Match_InvalidSImm19Lsb00:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,
-        "immediate must be a multiple of 4 bytes in the range");
+    return Range(-(1 << 18), (1 << 18) - 4,
+                 "immediate must be a multiple of 4 bytes in the range");
   case Match_InvalidSImm20Lsb000:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,
-        "immediate must be a multiple of 8 bytes in the range");
+    return Range(-(1 << 19), (1 << 19) - 8,
+                 "immediate must be a multiple of 8 bytes in the range");
   case Match_InvalidSImm26:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
-                                      (1 << 25) - 1);
+    return Range(-(1 << 25), (1 << 25) - 1);
   // HACK: See comment before `BareSymbolQC_E_LI` in RISCVInstrInfoXqci.td.
   case Match_InvalidBareSymbolQC_E_LI:
     [[fallthrough]];
   // END HACK
   case Match_InvalidBareSImm32:
-    return generateImmOutOfRangeError(Operands, ErrorInfo,
-                                      std::numeric_limits<int32_t>::min(),
-                                      std::numeric_limits<uint32_t>::max());
+    return Range(std::numeric_limits<int32_t>::min(),
+                 std::numeric_limits<uint32_t>::max());
   case Match_InvalidBareSImm32Lsb0:
-    return generateImmOutOfRangeError(
-        Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
-        std::numeric_limits<int32_t>::max() - 1,
-        "operand must be a multiple of 2 bytes in the range");
-  case Match_InvalidRnumArg: {
-    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
-  }
-  case Match_InvalidStackAdj: {
-    SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
-    return Error(
-        ErrorLoc,
-        "stack adjustment is invalid for this instruction and register list");
+    return Range(std::numeric_limits<int32_t>::min(),
+                 std::numeric_limits<int32_t>::max() - 1,
+                 "operand must be a multiple of 2 bytes in the range");
+  case Match_InvalidRnumArg:
+    return Range(0, 10);
+  case Match_InvalidStackAdj:
+    return "stack adjustment is invalid for this instruction and register "
+           "list";
+  case Match_InvalidYBNDSWImm:
+    return "immediate must be an integer in the range "
+           "[1, 255], a multiple of 8 in the range [256, 504], "
+           "or a multiple of 16 in the range [512, 4096]";
+  case Match_InvalidUImm7EqXLen:
+    return ("immediate must be an integer equal to XLEN (" +
+            Twine(isRV64() ? "64" : "32") + ")")
+        .str();
   }
-  case Match_InvalidYBNDSWImm: {
-    const SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
-    return Error(ErrorLoc, "immediate must be an integer in the range "
-                           "[1, 255], a multiple of 8 in the range [256, 504], "
-                           "or a multiple of 16 in the range [512, 4096]");
-  }
-  case Match_InvalidUImm7EqXLen: {
-    const SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
-    return Error(ErrorLoc, "immediate must be an integer equal to XLEN (" +
-                               Twine(isRV64() ? "64" : "32") + ")");
+}
+
+// Process the list of near-misses, throwing away ones we don't want to report
+// to the user, and converting the rest to a source location and string that
+// should be reported.
+void RISCVAsmParser::FilterNearMisses(
+    SmallVectorImpl<NearMissInfo> &NearMissesIn,
+    SmallVectorImpl<NearMissMessage> &NearMissesOut, SMLoc IDLoc,
+    OperandVector &Operands) {
+  // Record some information about near-misses that we have already seen, so
+  // that we can avoid reporting redundant ones.
+  std::multimap<unsigned, unsigned> OperandMissesSeen;
+  SmallSet<FeatureBitset, 4> FeatureMissesSeen;
+  bool ReportedTooFewOperands = false;
+
+  for (NearMissInfo &I : NearMissesIn) {
+    switch (I.getKind()) {
+    case NearMissInfo::NearMissOperand: {
+      SMLoc OperandLoc =
+          ((RISCVOperand &)*Operands[I.getOperandIndex()]).getStartLoc();
+      std::string OperandDiag = getCustomOperandDiag(I.getOperandError());
+
+      // If we have already emitted a message for a superclass on this operand,
+      // don't also report the sub-class.
+      unsigned DupCheckMatchClass =
+          OperandDiag.empty() ? ~0U : I.getOperandClass();
+      auto PrevReports = OperandMissesSeen.equal_range(I.getOperandIndex());
+      if (std::any_of(
+              PrevReports.first, PrevReports.second,
+              [DupCheckMatchClass](const std::pair<unsigned, unsigned> Pair) {
+                if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
+                  return Pair.second == DupCheckMatchClass;
+                else
----------------
topperc wrote:

No else after return

https://github.com/llvm/llvm-project/pull/205721


More information about the llvm-commits mailing list