Add support for Adaptative matchers on the dynamic registry.

Summary:
Add support for Adaptative matchers on the dynamic registry.
Each adaptative matcher is created with a function template. We instantiate the function N times, one for each possible From type and apply the techniques used on argument overloaded and polymorphic matchers to add them to the registry.

Reviewers: klimek

CC: cfe-commits, revane

Differential Revision: http://llvm-reviews.chandlerc.com/D1201

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@187044 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
index e69017e..7f49b6a 100644
--- a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
@@ -222,6 +222,37 @@
   EXPECT_FALSE(matches("struct Foo { Foo() : bar(1) {} int bar; };", CtorDecl));
 }
 
+TEST_F(RegistryTest, Adaptative) {
+  Matcher<Decl> D = constructMatcher(
+      "recordDecl",
+      constructMatcher(
+          "has",
+          constructMatcher("recordDecl",
+                           constructMatcher("hasName", std::string("X")))))
+      .getTypedMatcher<Decl>();
+  EXPECT_TRUE(matches("class X {};", D));
+  EXPECT_TRUE(matches("class Y { class X {}; };", D));
+  EXPECT_FALSE(matches("class Y { class Z {}; };", D));
+
+  Matcher<Stmt> S = constructMatcher(
+      "forStmt",
+      constructMatcher(
+          "hasDescendant",
+          constructMatcher("varDecl",
+                           constructMatcher("hasName", std::string("X")))))
+      .getTypedMatcher<Stmt>();
+  EXPECT_TRUE(matches("void foo() { for(int X;;); }", S));
+  EXPECT_TRUE(matches("void foo() { for(;;) { int X; } }", S));
+  EXPECT_FALSE(matches("void foo() { for(;;); }", S));
+  EXPECT_FALSE(matches("void foo() { if (int X = 0){} }", S));
+
+  S = constructMatcher(
+      "compoundStmt", constructMatcher("hasParent", constructMatcher("ifStmt")))
+      .getTypedMatcher<Stmt>();
+  EXPECT_TRUE(matches("void foo() { if (true) { int x = 42; } }", S));
+  EXPECT_FALSE(matches("void foo() { if (true) return; }", S));
+}
+
 TEST_F(RegistryTest, Errors) {
   // Incorrect argument count.
   OwningPtr<Diagnostics> Error(new Diagnostics());