Refactor "MatcherList" into "VariantMatcher" and abstract the notion of a list of matchers for the polymorphic case.

Summary:
Refactor "MatcherList" into "VariantMatcher" and abstract the notion of a list of matchers for the polymorphic case.
This work is to support future changes needed for eachOf/allOf/anyOf matchers. We will add a new type on VariantMatcher.

Reviewers: klimek

CC: cfe-commits, revane

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188272 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/ASTMatchers/Dynamic/VariantValue.cpp b/lib/ASTMatchers/Dynamic/VariantValue.cpp
index 79c5c8e..a8fd7c6 100644
--- a/lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ b/lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -15,25 +15,38 @@
 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
 
 #include "clang/Basic/LLVM.h"
+#include "llvm/ADT/STLExtras.h"
 
 namespace clang {
 namespace ast_matchers {
 namespace dynamic {
 
-MatcherList::MatcherList() : List() {}
+VariantMatcher::VariantMatcher() : List() {}
 
-MatcherList::MatcherList(const DynTypedMatcher &Matcher)
-    : List(1, Matcher.clone()) {}
-
-MatcherList::MatcherList(const MatcherList& Other) {
+VariantMatcher::VariantMatcher(const VariantMatcher& Other) {
   *this = Other;
 }
 
-MatcherList::~MatcherList() {
+VariantMatcher VariantMatcher::SingleMatcher(const DynTypedMatcher &Matcher) {
+  VariantMatcher Out;
+  Out.List.push_back(Matcher.clone());
+  return Out;
+}
+
+VariantMatcher
+VariantMatcher::PolymorphicMatcher(ArrayRef<const DynTypedMatcher *> Matchers) {
+  VariantMatcher Out;
+  for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
+    Out.List.push_back(Matchers[i]->clone());
+  }
+  return Out;
+}
+
+VariantMatcher::~VariantMatcher() {
   reset();
 }
 
-MatcherList &MatcherList::operator=(const MatcherList &Other) {
+VariantMatcher &VariantMatcher::operator=(const VariantMatcher &Other) {
   if (this == &Other) return *this;
   reset();
   for (size_t i = 0, e = Other.List.size(); i != e; ++i) {
@@ -42,18 +55,17 @@
   return *this;
 }
 
-void MatcherList::add(const DynTypedMatcher &Matcher) {
-  List.push_back(Matcher.clone());
+bool VariantMatcher::getSingleMatcher(const DynTypedMatcher *&Out) const {
+  if (List.size() != 1) return false;
+  Out = List[0];
+  return true;
 }
 
-void MatcherList::reset() {
-  for (size_t i = 0, e = List.size(); i != e; ++i) {
-    delete List[i];
-  }
-  List.resize(0);
+void VariantMatcher::reset() {
+  llvm::DeleteContainerPointers(List);
 }
 
-std::string MatcherList::getTypeAsString() const {
+std::string VariantMatcher::getTypeAsString() const {
   std::string Inner;
   for (size_t I = 0, E = List.size(); I != E; ++I) {
     if (I != 0) Inner += "|";
@@ -62,6 +74,18 @@
   return (Twine("Matcher<") + Inner + ">").str();
 }
 
+const DynTypedMatcher *VariantMatcher::getTypedMatcher(
+    bool (*CanConstructCallback)(const DynTypedMatcher &)) const {
+  const DynTypedMatcher *Out = NULL;
+  for (size_t i = 0, e = List.size(); i != e; ++i) {
+    if (CanConstructCallback(*List[i])) {
+      if (Out) return NULL;
+      Out = List[i];
+    }
+  }
+  return Out;
+}
+
 VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) {
   *this = Other;
 }
@@ -74,12 +98,8 @@
   setString(String);
 }
 
-VariantValue::VariantValue(const DynTypedMatcher &Matcher) : Type(VT_Nothing) {
-  setMatchers(MatcherList(Matcher));
-}
-
-VariantValue::VariantValue(const MatcherList &Matchers) : Type(VT_Nothing) {
-  setMatchers(Matchers);
+VariantValue::VariantValue(const VariantMatcher &Matcher) : Type(VT_Nothing) {
+  setMatcher(Matcher);
 }
 
 VariantValue::~VariantValue() { reset(); }
@@ -94,8 +114,8 @@
   case VT_String:
     setString(Other.getString());
     break;
-  case VT_Matchers:
-    setMatchers(Other.getMatchers());
+  case VT_Matcher:
+    setMatcher(Other.getMatcher());
     break;
   case VT_Nothing:
     Type = VT_Nothing;
@@ -109,8 +129,8 @@
   case VT_String:
     delete Value.String;
     break;
-  case VT_Matchers:
-    delete Value.Matchers;
+  case VT_Matcher:
+    delete Value.Matcher;
     break;
   // Cases that do nothing.
   case VT_Unsigned:
@@ -150,25 +170,25 @@
   Value.String = new std::string(NewValue);
 }
 
-bool VariantValue::isMatchers() const {
-  return Type == VT_Matchers;
+bool VariantValue::isMatcher() const {
+  return Type == VT_Matcher;
 }
 
-const MatcherList &VariantValue::getMatchers() const {
-  assert(isMatchers());
-  return *Value.Matchers;
+const VariantMatcher &VariantValue::getMatcher() const {
+  assert(isMatcher());
+  return *Value.Matcher;
 }
 
-void VariantValue::setMatchers(const MatcherList &NewValue) {
+void VariantValue::setMatcher(const VariantMatcher &NewValue) {
   reset();
-  Type = VT_Matchers;
-  Value.Matchers = new MatcherList(NewValue);
+  Type = VT_Matcher;
+  Value.Matcher = new VariantMatcher(NewValue);
 }
 
 std::string VariantValue::getTypeAsString() const {
   switch (Type) {
   case VT_String: return "String";
-  case VT_Matchers: return getMatchers().getTypeAsString();
+  case VT_Matcher: return getMatcher().getTypeAsString();
   case VT_Unsigned: return "Unsigned";
   case VT_Nothing: return "Nothing";
   }