Enhancements for the DynTypedMatcher system.
- Added conversion routines and checks in Matcher<T> that take a DynTypedMatcher.
- Added type information on the error messages for the marshallers.
- Allows future work on Polymorphic/overloaded matchers. We should be
  able to disambiguate at runtime and choose the appropriate overload.

llvm-svn: 184429
diff --git a/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp b/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp
index 79c9389..6b1d660 100644
--- a/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp
@@ -36,7 +36,7 @@
   case Diagnostics::ET_RegistryWrongArgCount:
     return "Incorrect argument count. (Expected = $0) != (Actual = $1)";
   case Diagnostics::ET_RegistryWrongArgType:
-    return "Incorrect type on function $0 for arg $1.";
+    return "Incorrect type for arg $0. (Expected = $1) != (Actual = $2)";
   case Diagnostics::ET_RegistryNotBindable:
     return "Matcher does not support binding.";
 
diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h
index 4ba33b8..aceddc9 100644
--- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h
+++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -42,6 +42,7 @@
 };
 
 template <> struct ArgTypeTraits<std::string> {
+  static StringRef asString() { return "String"; }
   static bool is(const VariantValue &Value) { return Value.isString(); }
   static const std::string &get(const VariantValue &Value) {
     return Value.getString();
@@ -49,13 +50,21 @@
 };
 
 template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T> > {
-  static bool is(const VariantValue &Value) { return Value.isMatcher(); }
+  static std::string asString() {
+    return (Twine("Matcher<") +
+            ast_type_traits::ASTNodeKind::getFromNodeKind<T>().asStringRef() +
+            ">").str();
+  }
+  static bool is(const VariantValue &Value) {
+    return Value.hasTypedMatcher<T>();
+  }
   static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {
     return Value.getTypedMatcher<T>();
   }
 };
 
 template <> struct ArgTypeTraits<unsigned> {
+  static std::string asString() { return "Unsigned"; }
   static bool is(const VariantValue &Value) { return Value.isUnsigned(); }
   static unsigned get(const VariantValue &Value) {
     return Value.getUnsigned();
@@ -147,7 +156,8 @@
 #define CHECK_ARG_TYPE(index, type)                                            \
   if (!ArgTypeTraits<type>::is(Args[index].Value)) {                           \
     Error->pushErrorFrame(Args[index].Range, Error->ET_RegistryWrongArgType)   \
-        << MatcherName << (index + 1);                                         \
+        << (index + 1) << ArgTypeTraits<type>::asString()                      \
+        << Args[index].Value.getTypeAsString();                                \
     return NULL;                                                               \
   }
 
@@ -201,14 +211,16 @@
 
   bool HasError = false;
   for (size_t i = 0, e = Args.size(); i != e; ++i) {
-    if (!Args[i].Value.isTypedMatcher<DerivedType>()) {
-      Error->pushErrorFrame(Args[i].Range, Error->ET_RegistryWrongArgType)
-          << MatcherName << (i + 1);
+    typedef ArgTypeTraits<DerivedMatcherType> DerivedTraits;
+    const ParserValue &Arg = Args[i];
+    const VariantValue &Value = Arg.Value;
+    if (!DerivedTraits::is(Value)) {
+      Error->pushErrorFrame(Arg.Range, Error->ET_RegistryWrongArgType)
+          << (i + 1) << DerivedTraits::asString() << Value.getTypeAsString();
       HasError = true;
       break;
     }
-    InnerArgs[i] =
-        new DerivedMatcherType(Args[i].Value.getTypedMatcher<DerivedType>());
+    InnerArgs[i] = new DerivedMatcherType(DerivedTraits::get(Value));
   }
 
   DynTypedMatcher *Out = NULL;
diff --git a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
index 6fcbe7f..912858f 100644
--- a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -14,6 +14,8 @@
 
 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
 
+#include "clang/Basic/LLVM.h"
+
 namespace clang {
 namespace ast_matchers {
 namespace dynamic {
@@ -123,6 +125,18 @@
   Value.Matcher = NewValue;
 }
 
+std::string VariantValue::getTypeAsString() const {
+  switch (Type) {
+  case VT_String: return "String";
+  case VT_Matcher:
+    return (Twine("Matcher<") + getMatcher().getSupportedKind().asStringRef() +
+            ">").str();
+  case VT_Unsigned: return "Unsigned";
+  case VT_Nothing: return "Nothing";
+  }
+  llvm_unreachable("Invalid Type");
+}
+
 } // end namespace dynamic
 } // end namespace ast_matchers
 } // end namespace clang