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/lib/ASTMatchers/Dynamic/VariantValue.cpp b/lib/ASTMatchers/Dynamic/VariantValue.cpp
index 912858f..79c5c8e 100644
--- a/lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ b/lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -20,6 +20,48 @@
 namespace ast_matchers {
 namespace dynamic {
 
+MatcherList::MatcherList() : List() {}
+
+MatcherList::MatcherList(const DynTypedMatcher &Matcher)
+    : List(1, Matcher.clone()) {}
+
+MatcherList::MatcherList(const MatcherList& Other) {
+  *this = Other;
+}
+
+MatcherList::~MatcherList() {
+  reset();
+}
+
+MatcherList &MatcherList::operator=(const MatcherList &Other) {
+  if (this == &Other) return *this;
+  reset();
+  for (size_t i = 0, e = Other.List.size(); i != e; ++i) {
+    List.push_back(Other.List[i]->clone());
+  }
+  return *this;
+}
+
+void MatcherList::add(const DynTypedMatcher &Matcher) {
+  List.push_back(Matcher.clone());
+}
+
+void MatcherList::reset() {
+  for (size_t i = 0, e = List.size(); i != e; ++i) {
+    delete List[i];
+  }
+  List.resize(0);
+}
+
+std::string MatcherList::getTypeAsString() const {
+  std::string Inner;
+  for (size_t I = 0, E = List.size(); I != E; ++I) {
+    if (I != 0) Inner += "|";
+    Inner += List[I]->getSupportedKind().asStringRef();
+  }
+  return (Twine("Matcher<") + Inner + ">").str();
+}
+
 VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) {
   *this = Other;
 }
@@ -33,7 +75,11 @@
 }
 
 VariantValue::VariantValue(const DynTypedMatcher &Matcher) : Type(VT_Nothing) {
-  setMatcher(Matcher);
+  setMatchers(MatcherList(Matcher));
+}
+
+VariantValue::VariantValue(const MatcherList &Matchers) : Type(VT_Nothing) {
+  setMatchers(Matchers);
 }
 
 VariantValue::~VariantValue() { reset(); }
@@ -48,8 +94,8 @@
   case VT_String:
     setString(Other.getString());
     break;
-  case VT_Matcher:
-    setMatcher(Other.getMatcher());
+  case VT_Matchers:
+    setMatchers(Other.getMatchers());
     break;
   case VT_Nothing:
     Type = VT_Nothing;
@@ -63,8 +109,8 @@
   case VT_String:
     delete Value.String;
     break;
-  case VT_Matcher:
-    delete Value.Matcher;
+  case VT_Matchers:
+    delete Value.Matchers;
     break;
   // Cases that do nothing.
   case VT_Unsigned:
@@ -104,33 +150,25 @@
   Value.String = new std::string(NewValue);
 }
 
-bool VariantValue::isMatcher() const {
-  return Type == VT_Matcher;
+bool VariantValue::isMatchers() const {
+  return Type == VT_Matchers;
 }
 
-const DynTypedMatcher &VariantValue::getMatcher() const {
-  assert(isMatcher());
-  return *Value.Matcher;
+const MatcherList &VariantValue::getMatchers() const {
+  assert(isMatchers());
+  return *Value.Matchers;
 }
 
-void VariantValue::setMatcher(const DynTypedMatcher &NewValue) {
+void VariantValue::setMatchers(const MatcherList &NewValue) {
   reset();
-  Type = VT_Matcher;
-  Value.Matcher = NewValue.clone();
-}
-
-void VariantValue::takeMatcher(DynTypedMatcher *NewValue) {
-  reset();
-  Type = VT_Matcher;
-  Value.Matcher = NewValue;
+  Type = VT_Matchers;
+  Value.Matchers = new MatcherList(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_Matchers: return getMatchers().getTypeAsString();
   case VT_Unsigned: return "Unsigned";
   case VT_Nothing: return "Nothing";
   }