Add support for eachOf/allOf/anyOf variadic matchers in the dynamic layer.

Summary:
Add support for eachOf/allOf/anyOf variadic matchers in the dynamic layer.
These function require some late binding behavior for the type conversions, thus changes in VariadicValue's MatcherList.
Second try. This time with a fix for C++11 builds.

Reviewers: klimek

CC: cfe-commits, revane

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@189500 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/unittests/ASTMatchers/Dynamic/ParserTest.cpp b/unittests/ASTMatchers/Dynamic/ParserTest.cpp
index 71b0f87..9116ab8 100644
--- a/unittests/ASTMatchers/Dynamic/ParserTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/ParserTest.cpp
@@ -137,9 +137,9 @@
          Range.Start.Column == StartColumn && Range.End.Column == EndColumn;
 }
 
-const DynTypedMatcher *getSingleMatcher(const VariantValue &value) {
+const DynTypedMatcher *getSingleMatcher(const VariantValue &Value) {
   const DynTypedMatcher *Out;
-  EXPECT_TRUE(value.getMatcher().getSingleMatcher(Out));
+  EXPECT_TRUE(Value.getMatcher().getSingleMatcher(Out));
   return Out;
 }
 
diff --git a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
index 55490a5..874a4f3 100644
--- a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
@@ -261,6 +261,33 @@
   EXPECT_FALSE(matches("void foo() { if (true) return; }", S));
 }
 
+TEST_F(RegistryTest, VariadicOp) {
+  Matcher<Decl> D = constructMatcher(
+      "anyOf", constructMatcher("recordDecl"),
+      constructMatcher("namedDecl",
+                       constructMatcher("hasName", std::string("foo"))))
+      .getTypedMatcher<Decl>();
+
+  EXPECT_TRUE(matches("void foo(){}", D));
+  EXPECT_TRUE(matches("struct Foo{};", D));
+  EXPECT_FALSE(matches("int i = 0;", D));
+
+  D = constructMatcher(
+      "allOf", constructMatcher("recordDecl"),
+      constructMatcher(
+          "namedDecl",
+          constructMatcher("anyOf",
+                           constructMatcher("hasName", std::string("Foo")),
+                           constructMatcher("hasName", std::string("Bar")))))
+      .getTypedMatcher<Decl>();
+
+  EXPECT_FALSE(matches("void foo(){}", D));
+  EXPECT_TRUE(matches("struct Foo{};", D));
+  EXPECT_FALSE(matches("int i = 0;", D));
+  EXPECT_TRUE(matches("class Bar{};", D));
+  EXPECT_FALSE(matches("class OtherBar{};", D));
+}
+
 TEST_F(RegistryTest, Errors) {
   // Incorrect argument count.
   OwningPtr<Diagnostics> Error(new Diagnostics());
@@ -285,6 +312,24 @@
   EXPECT_EQ("Incorrect type for arg 2. (Expected = Matcher<CXXRecordDecl>) != "
             "(Actual = Matcher<FunctionDecl>)",
             Error->toString());
+
+  // Bad argument type with variadic.
+  Error.reset(new Diagnostics());
+  EXPECT_TRUE(constructMatcher("anyOf", std::string(), Error.get()).isNull());
+  EXPECT_EQ(
+      "Incorrect type for arg 1. (Expected = Matcher<>) != (Actual = String)",
+      Error->toString());
+  Error.reset(new Diagnostics());
+  EXPECT_TRUE(constructMatcher(
+      "recordDecl",
+      constructMatcher("allOf",
+                       constructMatcher("isDerivedFrom", std::string("FOO")),
+                       constructMatcher("isArrow")),
+      Error.get()).isNull());
+  EXPECT_EQ("Incorrect type for arg 1. "
+            "(Expected = Matcher<CXXRecordDecl>) != "
+            "(Actual = Matcher<CXXRecordDecl>&Matcher<MemberExpr>)",
+            Error->toString());
 }
 
 } // end anonymous namespace