njames93 updated this revision to Diff 255258.
njames93 added a comment.

- Remove format artefacts


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77499/new/

https://reviews.llvm.org/D77499

Files:
  clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h
  clang/lib/ASTMatchers/Dynamic/CMakeLists.txt
  clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp
  clang/lib/ASTMatchers/Dynamic/Marshallers.cpp
  clang/lib/ASTMatchers/Dynamic/Marshallers.h

Index: clang/lib/ASTMatchers/Dynamic/Marshallers.h
===================================================================
--- clang/lib/ASTMatchers/Dynamic/Marshallers.h
+++ clang/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -29,6 +29,7 @@
 #include "clang/Basic/OpenMPKinds.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSwitch.h"
@@ -64,6 +65,10 @@
   static ArgKind getKind() {
     return ArgKind(ArgKind::AK_String);
   }
+
+  static llvm::Optional<std::string> getBestGuess(const VariantValue &) {
+    return llvm::None;
+  }
 };
 
 template <>
@@ -82,6 +87,10 @@
   static ArgKind getKind() {
     return ArgKind(ASTNodeKind::getFromNodeKind<T>());
   }
+
+  static llvm::Optional<std::string> getBestGuess(const VariantValue &) {
+    return llvm::None;
+  }
 };
 
 template <> struct ArgTypeTraits<bool> {
@@ -94,6 +103,10 @@
   static ArgKind getKind() {
     return ArgKind(ArgKind::AK_Boolean);
   }
+
+  static llvm::Optional<std::string> getBestGuess(const VariantValue &) {
+    return llvm::None;
+  }
 };
 
 template <> struct ArgTypeTraits<double> {
@@ -106,6 +119,10 @@
   static ArgKind getKind() {
     return ArgKind(ArgKind::AK_Double);
   }
+
+  static llvm::Optional<std::string> getBestGuess(const VariantValue &) {
+    return llvm::None;
+  }
 };
 
 template <> struct ArgTypeTraits<unsigned> {
@@ -118,6 +135,10 @@
   static ArgKind getKind() {
     return ArgKind(ArgKind::AK_Unsigned);
   }
+
+  static llvm::Optional<std::string> getBestGuess(const VariantValue &) {
+    return llvm::None;
+  }
 };
 
 template <> struct ArgTypeTraits<attr::Kind> {
@@ -141,6 +162,8 @@
   static ArgKind getKind() {
     return ArgKind(ArgKind::AK_String);
   }
+
+  static llvm::Optional<std::string> getBestGuess(const VariantValue &Value);
 };
 
 template <> struct ArgTypeTraits<CastKind> {
@@ -164,6 +187,8 @@
   static ArgKind getKind() {
     return ArgKind(ArgKind::AK_String);
   }
+
+  static llvm::Optional<std::string> getBestGuess(const VariantValue &Value);
 };
 
 template <> struct ArgTypeTraits<OpenMPClauseKind> {
@@ -186,6 +211,8 @@
   }
 
   static ArgKind getKind() { return ArgKind(ArgKind::AK_String); }
+
+  static llvm::Optional<std::string> getBestGuess(const VariantValue &Value);
 };
 
 /// Matcher descriptor interface.
@@ -319,7 +346,7 @@
 /// polymorphic matcher. For the former, we just construct the VariantMatcher.
 /// For the latter, we instantiate all the possible Matcher<T> of the poly
 /// matcher.
-static VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) {
+inline VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) {
   return VariantMatcher::SingleMatcher(Matcher);
 }
 
@@ -496,9 +523,16 @@
 
 #define CHECK_ARG_TYPE(index, type)                                            \
   if (!ArgTypeTraits<type>::is(Args[index].Value)) {                           \
-    Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType)         \
-        << (index + 1) << ArgTypeTraits<type>::getKind().asString()            \
-        << Args[index].Value.getTypeAsString();                                \
+    if (llvm::Optional<std::string> BestGuess =                                \
+            ArgTypeTraits<type>::getBestGuess(Args[index].Value)) {            \
+      Error->addError(Args[index].Range,                                       \
+                      Error->ET_RegistryUnknownEnumWithReplace)                \
+          << index + 1 << Args[index].Value.getString() << *BestGuess;         \
+    } else {                                                                   \
+      Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType)       \
+          << (index + 1) << ArgTypeTraits<type>::getKind().asString()          \
+          << Args[index].Value.getTypeAsString();                              \
+    }                                                                          \
     return VariantMatcher();                                                   \
   }
 
Index: clang/lib/ASTMatchers/Dynamic/Marshallers.cpp
===================================================================
--- /dev/null
+++ clang/lib/ASTMatchers/Dynamic/Marshallers.cpp
@@ -0,0 +1,91 @@
+#include "Marshallers.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+
+static llvm::Optional<std::string>
+getBestGuess(llvm::StringRef Search, llvm::ArrayRef<llvm::StringRef> Allowed,
+             llvm::StringRef DropPrefix = "", unsigned MaxEditDistance = 3) {
+  if (MaxEditDistance != -1u) {
+    ++MaxEditDistance;
+  }
+  llvm::StringRef Res;
+  for (const llvm::StringRef &Item : Allowed) {
+    if (Item.equals_lower(Search)) {
+      if (Item.equals(Search))
+        return Item.str();
+      MaxEditDistance = 1;
+      Res = Item;
+      continue;
+    }
+    unsigned Distance = Item.edit_distance(Search);
+    if (Distance < MaxEditDistance) {
+      MaxEditDistance = Distance;
+      Res = Item;
+    }
+  }
+  if (!Res.empty())
+    return Res.str();
+  if (!DropPrefix.empty()) {
+    --MaxEditDistance; // Treat dropping the prefix as 1 edit
+    for (const llvm::StringRef &Item : Allowed) {
+      auto NoPrefix = Item;
+      if (!NoPrefix.consume_front(DropPrefix))
+        continue;
+      if (NoPrefix.equals_lower(Search)) {
+        if (NoPrefix.equals(Search))
+          return Item.str();
+        MaxEditDistance = 1;
+        Res = Item;
+        continue;
+      }
+      unsigned Distance = NoPrefix.edit_distance(Search);
+      if (Distance < MaxEditDistance) {
+        MaxEditDistance = Distance;
+        Res = Item;
+      }
+    }
+    if (!Res.empty())
+      return Res.str();
+  }
+  return llvm::None;
+}
+
+llvm::Optional<std::string>
+clang::ast_matchers::dynamic::internal::ArgTypeTraits<
+    clang::attr::Kind>::getBestGuess(const VariantValue &Value) {
+  static constexpr llvm::StringRef Allowed[] = {
+#define ATTR(X) "attr::" #X,
+#include "clang/Basic/AttrList.inc"
+  };
+  if (Value.isString())
+    return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed),
+                          "attr::");
+  return llvm::None;
+}
+
+llvm::Optional<std::string>
+clang::ast_matchers::dynamic::internal::ArgTypeTraits<
+    clang::CastKind>::getBestGuess(const VariantValue &Value) {
+  static constexpr llvm::StringRef Allowed[] = {
+#define CAST_OPERATION(Name) #Name,
+#include "clang/AST/OperationKinds.def"
+  };
+  if (Value.isString())
+    return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed));
+  return llvm::None;
+}
+
+llvm::Optional<std::string>
+clang::ast_matchers::dynamic::internal::ArgTypeTraits<
+    clang::OpenMPClauseKind>::getBestGuess(const VariantValue &Value) {
+  static constexpr llvm::StringRef Allowed[] = {
+#define OPENMP_CLAUSE(TextualSpelling, Class) "OMPC_" #TextualSpelling,
+#include "clang/Basic/OpenMPKinds.def"
+  };
+  if (Value.isString())
+    return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed),
+                          "OMPC_");
+  return llvm::None;
+}
Index: clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp
===================================================================
--- clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp
+++ clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp
@@ -98,6 +98,8 @@
     return "Ambiguous matcher overload.";
   case Diagnostics::ET_RegistryValueNotFound:
     return "Value not found: $0";
+  case Diagnostics::ET_RegistryUnknownEnumWithReplace:
+    return "Unknown value '$1' for arg $0; did you mean '$2'";
 
   case Diagnostics::ET_ParserStringError:
     return "Error parsing string token: <$0>";
Index: clang/lib/ASTMatchers/Dynamic/CMakeLists.txt
===================================================================
--- clang/lib/ASTMatchers/Dynamic/CMakeLists.txt
+++ clang/lib/ASTMatchers/Dynamic/CMakeLists.txt
@@ -14,6 +14,7 @@
   VariantValue.cpp
   Parser.cpp
   Registry.cpp
+  Marshallers.cpp
 
   LINK_LIBS
   clangAST
Index: clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h
===================================================================
--- clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h
+++ clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h
@@ -65,6 +65,7 @@
     ET_RegistryNotBindable = 4,
     ET_RegistryAmbiguousOverload = 5,
     ET_RegistryValueNotFound = 6,
+    ET_RegistryUnknownEnumWithReplace = 7,
 
     ET_ParserStringError = 100,
     ET_ParserNoOpenParen = 101,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to