Add support for polymorphic matchers. Use runtime type checking to determine the right polymorphic overload to use.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184558 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp
index 839c447..8df0274 100644
--- a/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -2250,10 +2250,9 @@
 }
 
 AST_POLYMORPHIC_MATCHER_P(
-    polymorphicHas, internal::Matcher<Decl>, AMatcher) {
-  TOOLING_COMPILE_ASSERT((llvm::is_same<NodeType, Decl>::value) ||
-                         (llvm::is_same<NodeType, Stmt>::value),
-                         assert_node_type_is_accessible);
+    polymorphicHas,
+    AST_POLYMORPHIC_SUPPORTED_TYPES_2(Decl, Stmt),
+    internal::Matcher<Decl>, AMatcher) {
   return Finder->matchesChildOf(
       Node, AMatcher, Builder,
       ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
diff --git a/unittests/ASTMatchers/Dynamic/ParserTest.cpp b/unittests/ASTMatchers/Dynamic/ParserTest.cpp
index d7973c9..e6b04e0 100644
--- a/unittests/ASTMatchers/Dynamic/ParserTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/ParserTest.cpp
@@ -52,6 +52,7 @@
   virtual ast_type_traits::ASTNodeKind getSupportedKind() const {
     return ast_type_traits::ASTNodeKind();
   }
+
 private:
   uint64_t ID;
   std::string BoundID;
@@ -75,15 +76,16 @@
     Errors.push_back(Error.ToStringFull());
   }
 
-  DynTypedMatcher *actOnMatcherExpression(StringRef MatcherName,
-                                          const SourceRange &NameRange,
-                                          StringRef BindID,
-                                          ArrayRef<ParserValue> Args,
-                                          Diagnostics *Error) {
+  MatcherList actOnMatcherExpression(StringRef MatcherName,
+                                     const SourceRange &NameRange,
+                                     StringRef BindID,
+                                     ArrayRef<ParserValue> Args,
+                                     Diagnostics *Error) {
     MatcherInfo ToStore = { MatcherName, NameRange, Args, BindID };
     Matchers.push_back(ToStore);
     DummyDynTypedMatcher Matcher(ExpectedMatchers[MatcherName]);
-    return Matcher.tryBind(BindID);
+    OwningPtr<DynTypedMatcher> Out(Matcher.tryBind(BindID));
+    return *Out;
   }
 
   struct MatcherInfo {
@@ -146,9 +148,9 @@
   }
 
   EXPECT_EQ(1ULL, Sema.Values.size());
-  EXPECT_EQ(ExpectedFoo, Sema.Values[0].getMatcher().getID());
-  EXPECT_EQ("Yo!", static_cast<const DummyDynTypedMatcher &>(
-                       Sema.Values[0].getMatcher()).boundID());
+  EXPECT_EQ(ExpectedFoo, Sema.Values[0].getMatchers().matchers()[0]->getID());
+  EXPECT_EQ("Yo!", static_cast<const DummyDynTypedMatcher *>(
+                       Sema.Values[0].getMatchers().matchers()[0])->boundID());
 
   EXPECT_EQ(3ULL, Sema.Matchers.size());
   const MockSema::MatcherInfo Bar = Sema.Matchers[0];
@@ -167,8 +169,10 @@
   EXPECT_EQ("Foo", Foo.MatcherName);
   EXPECT_TRUE(matchesRange(Foo.NameRange, 1, 2, 2, 12));
   EXPECT_EQ(2ULL, Foo.Args.size());
-  EXPECT_EQ(ExpectedBar, Foo.Args[0].Value.getMatcher().getID());
-  EXPECT_EQ(ExpectedBaz, Foo.Args[1].Value.getMatcher().getID());
+  EXPECT_EQ(ExpectedBar,
+            Foo.Args[0].Value.getMatchers().matchers()[0]->getID());
+  EXPECT_EQ(ExpectedBaz,
+            Foo.Args[1].Value.getMatchers().matchers()[0]->getID());
   EXPECT_EQ("Yo!", Foo.BoundID);
 }
 
@@ -176,11 +180,14 @@
 
 TEST(ParserTest, FullParserTest) {
   OwningPtr<DynTypedMatcher> VarDecl(Parser::parseMatcherExpression(
-      "varDecl(hasInitializer(binaryOperator(hasLHS(integerLiteral()))))",
+      "varDecl(hasInitializer(binaryOperator(hasLHS(integerLiteral()),"
+      "                                      hasOperatorName(\"+\"))))",
       NULL));
   Matcher<Decl> M = Matcher<Decl>::constructFrom(*VarDecl);
   EXPECT_TRUE(matches("int x = 1 + false;", M));
   EXPECT_FALSE(matches("int x = true + 1;", M));
+  EXPECT_FALSE(matches("int x = 1 - false;", M));
+  EXPECT_FALSE(matches("int x = true - 1;", M));
 
   OwningPtr<DynTypedMatcher> HasParameter(Parser::parseMatcherExpression(
       "functionDecl(hasParameter(1, hasName(\"x\")))", NULL));
@@ -242,6 +249,9 @@
   EXPECT_EQ("1:1: Error building matcher isArrow.\n"
             "1:1: Matcher does not support binding.",
             ParseWithError("isArrow().bind(\"foo\")"));
+  EXPECT_EQ("Input value has unresolved overloaded type: "
+            "Matcher<DoStmt|ForStmt|WhileStmt>",
+            ParseMatcherWithError("hasBody(stmt())"));
 }
 
 }  // end anonymous namespace
diff --git a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
index fd6eaef..357a371 100644
--- a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
@@ -38,25 +38,23 @@
 
   template <class T>
   Matcher<T> constructMatcher(StringRef MatcherName, Diagnostics *Error) {
-    OwningPtr<DynTypedMatcher> Out(
-        Registry::constructMatcher(MatcherName, SourceRange(), Args(), Error));
-    return Matcher<T>::constructFrom(*Out);
+    return Registry::constructMatcher(MatcherName, SourceRange(), Args(), Error)
+        .getTypedMatcher<T>();
   }
 
   template <class T>
   Matcher<T> constructMatcher(StringRef MatcherName, const VariantValue &Arg1,
                               Diagnostics *Error) {
-    OwningPtr<DynTypedMatcher> Out(Registry::constructMatcher(
-        MatcherName, SourceRange(), Args(Arg1), Error));
-    return Matcher<T>::constructFrom(*Out);
+    return Registry::constructMatcher(MatcherName, SourceRange(), Args(Arg1),
+                                      Error).getTypedMatcher<T>();
   }
 
   template <class T>
   Matcher<T> constructMatcher(StringRef MatcherName, const VariantValue &Arg1,
                               const VariantValue &Arg2, Diagnostics *Error) {
-    OwningPtr<DynTypedMatcher> Out(Registry::constructMatcher(
-        MatcherName, SourceRange(), Args(Arg1, Arg2), Error));
-    return Matcher<T>::constructFrom(*Out);
+    return Registry::constructMatcher(MatcherName, SourceRange(),
+                                      Args(Arg1, Arg2), Error)
+        .getTypedMatcher<T>();
   }
 };
 
@@ -115,34 +113,57 @@
   EXPECT_FALSE(matches("void f(int x, int a);", HasParameter));
 }
 
+TEST_F(RegistryTest, PolymorphicMatchers) {
+  const MatcherList IsDefinition =
+      Registry::constructMatcher("isDefinition", SourceRange(), Args(), NULL);
+  Matcher<Decl> Var = constructMatcher<Decl>("varDecl", IsDefinition, NULL);
+  Matcher<Decl> Class =
+      constructMatcher<Decl>("recordDecl", IsDefinition, NULL);
+  Matcher<Decl> Func =
+      constructMatcher<Decl>("functionDecl", IsDefinition, NULL);
+  EXPECT_TRUE(matches("int a;", Var));
+  EXPECT_FALSE(matches("extern int a;", Var));
+  EXPECT_TRUE(matches("class A {};", Class));
+  EXPECT_FALSE(matches("class A;", Class));
+  EXPECT_TRUE(matches("void f(){};", Func));
+  EXPECT_FALSE(matches("void f();", Func));
+
+  Matcher<Decl> Anything = constructMatcher<Decl>("anything", NULL);
+  Matcher<Decl> RecordDecl =
+      constructMatcher<Decl>("recordDecl", Anything, NULL);
+
+  EXPECT_TRUE(matches("int a;", Anything));
+  EXPECT_TRUE(matches("class A {};", Anything));
+  EXPECT_TRUE(matches("void f(){};", Anything));
+  EXPECT_FALSE(matches("int a;", RecordDecl));
+  EXPECT_TRUE(matches("class A {};", RecordDecl));
+  EXPECT_FALSE(matches("void f(){};", RecordDecl));
+}
+
 TEST_F(RegistryTest, Errors) {
   // Incorrect argument count.
   OwningPtr<Diagnostics> Error(new Diagnostics());
-  EXPECT_TRUE(NULL ==
-              Registry::constructMatcher("hasInitializer", SourceRange(),
-                                         Args(), Error.get()));
+  EXPECT_TRUE(Registry::constructMatcher("hasInitializer", SourceRange(),
+                                         Args(), Error.get()).empty());
   EXPECT_EQ("Incorrect argument count. (Expected = 1) != (Actual = 0)",
             Error->ToString());
   Error.reset(new Diagnostics());
-  EXPECT_TRUE(NULL ==
-              Registry::constructMatcher("isArrow", SourceRange(),
-                                         Args(std::string()), Error.get()));
+  EXPECT_TRUE(Registry::constructMatcher(
+      "isArrow", SourceRange(), Args(std::string()), Error.get()).empty());
   EXPECT_EQ("Incorrect argument count. (Expected = 0) != (Actual = 1)",
             Error->ToString());
 
   // Bad argument type
   Error.reset(new Diagnostics());
-  EXPECT_TRUE(NULL ==
-              Registry::constructMatcher("ofClass", SourceRange(),
-                                         Args(std::string()), Error.get()));
+  EXPECT_TRUE(Registry::constructMatcher(
+      "ofClass", SourceRange(), Args(std::string()), Error.get()).empty());
   EXPECT_EQ("Incorrect type for arg 1. (Expected = Matcher<CXXRecordDecl>) != "
             "(Actual = String)",
             Error->ToString());
   Error.reset(new Diagnostics());
-  EXPECT_TRUE(NULL ==
-              Registry::constructMatcher(
-                  "recordDecl", SourceRange(),
-                  Args(recordDecl(), parameterCountIs(3)), Error.get()));
+  EXPECT_TRUE(Registry::constructMatcher(
+      "recordDecl", SourceRange(), Args(recordDecl(), parameterCountIs(3)),
+      Error.get()).empty());
   EXPECT_EQ("Incorrect type for arg 2. (Expected = Matcher<CXXRecordDecl>) != "
             "(Actual = Matcher<FunctionDecl>)",
             Error->ToString());
diff --git a/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp b/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp
index c941672..625f70b 100644
--- a/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp
@@ -27,9 +27,9 @@
   EXPECT_EQ(kUnsigned, Value.getUnsigned());
 
   EXPECT_FALSE(Value.isString());
-  EXPECT_FALSE(Value.isMatcher());
-  EXPECT_FALSE(Value.hasTypedMatcher<clang::Decl>());
-  EXPECT_FALSE(Value.hasTypedMatcher<clang::UnaryOperator>());
+  EXPECT_FALSE(Value.isMatchers());
+  EXPECT_FALSE(Value.hasTypedMatcher<Decl>());
+  EXPECT_FALSE(Value.hasTypedMatcher<UnaryOperator>());
 }
 
 TEST(VariantValueTest, String) {
@@ -41,9 +41,7 @@
   EXPECT_EQ("String", Value.getTypeAsString());
 
   EXPECT_FALSE(Value.isUnsigned());
-  EXPECT_FALSE(Value.isMatcher());
-  EXPECT_FALSE(Value.hasTypedMatcher<clang::Decl>());
-  EXPECT_FALSE(Value.hasTypedMatcher<clang::UnaryOperator>());
+  EXPECT_FALSE(Value.isMatchers());
 }
 
 TEST(VariantValueTest, DynTypedMatcher) {
@@ -52,25 +50,25 @@
   EXPECT_FALSE(Value.isUnsigned());
   EXPECT_FALSE(Value.isString());
 
-  EXPECT_TRUE(Value.isMatcher());
-  EXPECT_FALSE(Value.hasTypedMatcher<clang::Decl>());
-  EXPECT_TRUE(Value.hasTypedMatcher<clang::UnaryOperator>());
+  EXPECT_TRUE(Value.isMatchers());
+  EXPECT_FALSE(Value.hasTypedMatcher<Decl>());
+  EXPECT_TRUE(Value.hasTypedMatcher<UnaryOperator>());
   EXPECT_EQ("Matcher<Stmt>", Value.getTypeAsString());
 
   // Can only convert to compatible matchers.
   Value = recordDecl();
-  EXPECT_TRUE(Value.isMatcher());
-  EXPECT_TRUE(Value.hasTypedMatcher<clang::Decl>());
-  EXPECT_FALSE(Value.hasTypedMatcher<clang::UnaryOperator>());
+  EXPECT_TRUE(Value.isMatchers());
+  EXPECT_TRUE(Value.hasTypedMatcher<Decl>());
+  EXPECT_FALSE(Value.hasTypedMatcher<UnaryOperator>());
   EXPECT_EQ("Matcher<Decl>", Value.getTypeAsString());
 
   Value = ignoringImpCasts(expr());
-  EXPECT_TRUE(Value.isMatcher());
-  EXPECT_FALSE(Value.hasTypedMatcher<clang::Decl>());
-  EXPECT_FALSE(Value.hasTypedMatcher<clang::Stmt>());
-  EXPECT_TRUE(Value.hasTypedMatcher<clang::Expr>());
-  EXPECT_TRUE(Value.hasTypedMatcher<clang::IntegerLiteral>());
-  EXPECT_FALSE(Value.hasTypedMatcher<clang::GotoStmt>());
+  EXPECT_TRUE(Value.isMatchers());
+  EXPECT_FALSE(Value.hasTypedMatcher<Decl>());
+  EXPECT_FALSE(Value.hasTypedMatcher<Stmt>());
+  EXPECT_TRUE(Value.hasTypedMatcher<Expr>());
+  EXPECT_TRUE(Value.hasTypedMatcher<IntegerLiteral>());
+  EXPECT_FALSE(Value.hasTypedMatcher<GotoStmt>());
   EXPECT_EQ("Matcher<Expr>", Value.getTypeAsString());
 }
 
@@ -79,31 +77,31 @@
   EXPECT_TRUE(Value.isString());
   EXPECT_EQ("A", Value.getString());
   EXPECT_FALSE(Value.isUnsigned());
-  EXPECT_FALSE(Value.isMatcher());
+  EXPECT_FALSE(Value.isMatchers());
   EXPECT_EQ("String", Value.getTypeAsString());
 
   Value = recordDecl();
   EXPECT_FALSE(Value.isUnsigned());
   EXPECT_FALSE(Value.isString());
-  EXPECT_TRUE(Value.isMatcher());
-  EXPECT_TRUE(Value.hasTypedMatcher<clang::Decl>());
-  EXPECT_FALSE(Value.hasTypedMatcher<clang::UnaryOperator>());
+  EXPECT_TRUE(Value.isMatchers());
+  EXPECT_TRUE(Value.hasTypedMatcher<Decl>());
+  EXPECT_FALSE(Value.hasTypedMatcher<UnaryOperator>());
   EXPECT_EQ("Matcher<Decl>", Value.getTypeAsString());
 
   Value = 17;
   EXPECT_TRUE(Value.isUnsigned());
   EXPECT_EQ(17U, Value.getUnsigned());
-  EXPECT_FALSE(Value.isMatcher());
+  EXPECT_FALSE(Value.isMatchers());
   EXPECT_FALSE(Value.isString());
 
   Value = VariantValue();
   EXPECT_FALSE(Value.isUnsigned());
   EXPECT_FALSE(Value.isString());
-  EXPECT_FALSE(Value.isMatcher());
+  EXPECT_FALSE(Value.isMatchers());
   EXPECT_EQ("Nothing", Value.getTypeAsString());
 }
 
-TEST(GenericValueTest, Matcher) {
+TEST(VariantValueTest, Matcher) {
   EXPECT_TRUE(matches("class X {};", VariantValue(recordDecl(hasName("X")))
                                          .getTypedMatcher<Decl>()));
   EXPECT_TRUE(
@@ -117,13 +115,15 @@
   // do this test when building with MSVC because its debug C runtime prints the
   // assertion failure message as a wide string, which gtest doesn't understand.
   EXPECT_DEATH(VariantValue(varDecl()).getTypedMatcher<Stmt>(),
-               "canConstructFrom");
+               "hasTypedMatcher");
 #endif
 
   EXPECT_FALSE(
       matches("int x;", VariantValue(functionDecl()).getTypedMatcher<Decl>()));
-  EXPECT_FALSE(matches("int foo() { return 1 + 1; }",
-                       VariantValue(declRefExpr()).getTypedMatcher<Stmt>()));
+  EXPECT_FALSE(
+      matches("int foo() { return 1 + 1; }",
+
+              VariantValue(declRefExpr()).getTypedMatcher<Stmt>()));
 }
 
 } // end anonymous namespace