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/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