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

llvm-svn: 188272
diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h
index 9f1cfe3..abd5d40 100644
--- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h
+++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -26,6 +26,7 @@
 #include "clang/ASTMatchers/Dynamic/Diagnostics.h"
 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
 #include "clang/Basic/LLVM.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/type_traits.h"
 
 namespace clang {
@@ -82,9 +83,9 @@
 class MatcherCreateCallback {
 public:
   virtual ~MatcherCreateCallback() {}
-  virtual MatcherList run(const SourceRange &NameRange,
-                          ArrayRef<ParserValue> Args,
-                          Diagnostics *Error) const = 0;
+  virtual VariantMatcher run(const SourceRange &NameRange,
+                             ArrayRef<ParserValue> Args,
+                             Diagnostics *Error) const = 0;
 };
 
 /// \brief Simple callback implementation. Marshaller and function are provided.
@@ -99,10 +100,10 @@
   /// FIXME: Use void(*)() as FuncType on this interface to remove the template
   /// argument of this class. The marshaller can cast the function pointer back
   /// to the original type.
-  typedef MatcherList (*MarshallerType)(FuncType, StringRef,
-                                        const SourceRange &,
-                                        ArrayRef<ParserValue>,
-                                        Diagnostics *);
+  typedef VariantMatcher (*MarshallerType)(FuncType, StringRef,
+                                           const SourceRange &,
+                                           ArrayRef<ParserValue>,
+                                           Diagnostics *);
 
   /// \param Marshaller Function to unpack the arguments and call \c Func
   /// \param Func Matcher construct function. This is the function that
@@ -111,8 +112,8 @@
                                      StringRef MatcherName)
       : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName.str()) {}
 
-  MatcherList run(const SourceRange &NameRange, ArrayRef<ParserValue> Args,
-                  Diagnostics *Error) const {
+  VariantMatcher run(const SourceRange &NameRange, ArrayRef<ParserValue> Args,
+                     Diagnostics *Error) const {
     return Marshaller(Func, MatcherName, NameRange, Args, Error);
   }
 
@@ -131,16 +132,16 @@
 /// object file.
 class FreeFuncMatcherCreateCallback : public MatcherCreateCallback {
 public:
-  typedef MatcherList (*RunFunc)(StringRef MatcherName,
-                                 const SourceRange &NameRange,
-                                 ArrayRef<ParserValue> Args,
-                                 Diagnostics *Error);
+  typedef VariantMatcher (*RunFunc)(StringRef MatcherName,
+                                    const SourceRange &NameRange,
+                                    ArrayRef<ParserValue> Args,
+                                    Diagnostics *Error);
 
   FreeFuncMatcherCreateCallback(RunFunc Func, StringRef MatcherName)
       : Func(Func), MatcherName(MatcherName.str()) {}
 
-  MatcherList run(const SourceRange &NameRange, ArrayRef<ParserValue> Args,
-                  Diagnostics *Error) const {
+  VariantMatcher run(const SourceRange &NameRange, ArrayRef<ParserValue> Args,
+                     Diagnostics *Error) const {
     return Func(MatcherName, NameRange, Args, Error);
   }
 
@@ -154,7 +155,7 @@
   if (Args.size() != count) {                                                  \
     Error->addError(NameRange, Error->ET_RegistryWrongArgCount)                \
         << count << Args.size();                                               \
-    return MatcherList();                                                      \
+    return VariantMatcher();                                                   \
   }
 
 #define CHECK_ARG_TYPE(index, type)                                            \
@@ -162,76 +163,80 @@
     Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType)         \
         << (index + 1) << ArgTypeTraits<type>::asString()                      \
         << Args[index].Value.getTypeAsString();                                \
-    return MatcherList();                                                      \
+    return VariantMatcher();                                                   \
   }
 
 /// \brief Helper methods to extract and merge all possible typed matchers
 /// out of the polymorphic object.
 template <class PolyMatcher>
-static void mergePolyMatchers(const PolyMatcher &Poly, MatcherList *Out,
+static void mergePolyMatchers(const PolyMatcher &Poly,
+                              std::vector<const DynTypedMatcher *> &Out,
                               ast_matchers::internal::EmptyTypeList) {}
 
 template <class PolyMatcher, class TypeList>
-static void mergePolyMatchers(const PolyMatcher &Poly, MatcherList *Out,
+static void mergePolyMatchers(const PolyMatcher &Poly,
+                              std::vector<const DynTypedMatcher *> &Out,
                               TypeList) {
-  Out->add(ast_matchers::internal::Matcher<typename TypeList::head>(Poly));
+  Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly)
+                    .clone());
   mergePolyMatchers(Poly, Out, typename TypeList::tail());
 }
 
-/// \brief Convert the return values of the functions into a MatcherList.
+/// \brief Convert the return values of the functions into a VariantMatcher.
 ///
 /// There are 2 cases right now: The return value is a Matcher<T> or is a
-/// polymorphic matcher. For the former, we just construct the MatcherList. For
-/// the latter, we instantiate all the possible Matcher<T> of the poly matcher.
+/// polymorphic matcher. For the former, we just construct the VariantMatcher.
+/// For the latter, we instantiate all the possible Matcher<T> of the poly
+/// matcher.
 template <typename T>
-static MatcherList
-outvalueToMatcherList(const ast_matchers::internal::Matcher<T> &Matcher) {
-  return MatcherList(Matcher);
+static VariantMatcher
+outvalueToVariantMatcher(const ast_matchers::internal::Matcher<T> &Matcher) {
+  return VariantMatcher::SingleMatcher(Matcher);
 }
 
 template <typename T>
-static MatcherList
-outvalueToMatcherList(const T& PolyMatcher, typename T::ReturnTypes* = NULL) {
-  MatcherList Matchers;
-  mergePolyMatchers(PolyMatcher, &Matchers, typename T::ReturnTypes());
-  return Matchers;
+static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher,
+                                               typename T::ReturnTypes * =
+                                                   NULL) {
+  std::vector<const DynTypedMatcher *> Matchers;
+  mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes());
+  VariantMatcher Out = VariantMatcher::PolymorphicMatcher(Matchers);
+  llvm::DeleteContainerPointers(Matchers);
+  return Out;
 }
 
 /// \brief 0-arg marshaller function.
 template <typename ReturnType>
-static MatcherList matcherMarshall0(ReturnType (*Func)(),
-                                    StringRef MatcherName,
-                                    const SourceRange &NameRange,
-                                    ArrayRef<ParserValue> Args,
-                                    Diagnostics *Error) {
+static VariantMatcher
+matcherMarshall0(ReturnType (*Func)(), StringRef MatcherName,
+                 const SourceRange &NameRange, ArrayRef<ParserValue> Args,
+                 Diagnostics *Error) {
   CHECK_ARG_COUNT(0);
-  return outvalueToMatcherList(Func());
+  return outvalueToVariantMatcher(Func());
 }
 
 /// \brief 1-arg marshaller function.
 template <typename ReturnType, typename ArgType1>
-static MatcherList matcherMarshall1(ReturnType (*Func)(ArgType1),
-                                    StringRef MatcherName,
-                                    const SourceRange &NameRange,
-                                    ArrayRef<ParserValue> Args,
-                                    Diagnostics *Error) {
+static VariantMatcher
+matcherMarshall1(ReturnType (*Func)(ArgType1), StringRef MatcherName,
+                 const SourceRange &NameRange, ArrayRef<ParserValue> Args,
+                 Diagnostics *Error) {
   CHECK_ARG_COUNT(1);
   CHECK_ARG_TYPE(0, ArgType1);
-  return outvalueToMatcherList(
+  return outvalueToVariantMatcher(
       Func(ArgTypeTraits<ArgType1>::get(Args[0].Value)));
 }
 
 /// \brief 2-arg marshaller function.
 template <typename ReturnType, typename ArgType1, typename ArgType2>
-static MatcherList matcherMarshall2(ReturnType (*Func)(ArgType1, ArgType2),
-                                    StringRef MatcherName,
-                                    const SourceRange &NameRange,
-                                    ArrayRef<ParserValue> Args,
-                                    Diagnostics *Error) {
+static VariantMatcher
+matcherMarshall2(ReturnType (*Func)(ArgType1, ArgType2), StringRef MatcherName,
+                 const SourceRange &NameRange, ArrayRef<ParserValue> Args,
+                 Diagnostics *Error) {
   CHECK_ARG_COUNT(2);
   CHECK_ARG_TYPE(0, ArgType1);
   CHECK_ARG_TYPE(1, ArgType2);
-  return outvalueToMatcherList(
+  return outvalueToVariantMatcher(
       Func(ArgTypeTraits<ArgType1>::get(Args[0].Value),
            ArgTypeTraits<ArgType2>::get(Args[1].Value)));
 }
@@ -242,10 +247,10 @@
 /// \brief Variadic marshaller function.
 template <typename ResultT, typename ArgT,
           ResultT (*Func)(ArrayRef<const ArgT *>)>
-MatcherList variadicMatcherCreateCallback(StringRef MatcherName,
-                                          const SourceRange &NameRange,
-                                          ArrayRef<ParserValue> Args,
-                                          Diagnostics *Error) {
+VariantMatcher
+variadicMatcherCreateCallback(StringRef MatcherName,
+                              const SourceRange &NameRange,
+                              ArrayRef<ParserValue> Args, Diagnostics *Error) {
   ArgT **InnerArgs = new ArgT *[Args.size()]();
 
   bool HasError = false;
@@ -262,9 +267,9 @@
     InnerArgs[i] = new ArgT(ArgTraits::get(Value));
   }
 
-  MatcherList Out;
+  VariantMatcher Out;
   if (!HasError) {
-    Out = outvalueToMatcherList(
+    Out = outvalueToVariantMatcher(
         Func(ArrayRef<const ArgT *>(InnerArgs, Args.size())));
   }
 
diff --git a/clang/lib/ASTMatchers/Dynamic/Parser.cpp b/clang/lib/ASTMatchers/Dynamic/Parser.cpp
index 54424ce..37e6c10 100644
--- a/clang/lib/ASTMatchers/Dynamic/Parser.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Parser.cpp
@@ -311,9 +311,9 @@
                            NameToken.Text, NameToken.Range);
   SourceRange MatcherRange = NameToken.Range;
   MatcherRange.End = EndToken.Range.End;
-  MatcherList Result = S->actOnMatcherExpression(
+  VariantMatcher Result = S->actOnMatcherExpression(
       NameToken.Text, MatcherRange, BindID, Args, Error);
-  if (Result.empty()) return false;
+  if (Result.isNull()) return false;
 
   *Value = Result;
   return true;
@@ -358,11 +358,11 @@
 class RegistrySema : public Parser::Sema {
 public:
   virtual ~RegistrySema() {}
-  MatcherList actOnMatcherExpression(StringRef MatcherName,
-                                     const SourceRange &NameRange,
-                                     StringRef BindID,
-                                     ArrayRef<ParserValue> Args,
-                                     Diagnostics *Error) {
+  VariantMatcher actOnMatcherExpression(StringRef MatcherName,
+                                        const SourceRange &NameRange,
+                                        StringRef BindID,
+                                        ArrayRef<ParserValue> Args,
+                                        Diagnostics *Error) {
     if (BindID.empty()) {
       return Registry::constructMatcher(MatcherName, NameRange, Args, Error);
     } else {
@@ -402,16 +402,17 @@
   VariantValue Value;
   if (!parseExpression(Code, S, &Value, Error))
     return NULL;
-  if (!Value.isMatchers()) {
+  if (!Value.isMatcher()) {
     Error->addError(SourceRange(), Error->ET_ParserNotAMatcher);
     return NULL;
   }
-  if (Value.getMatchers().matchers().size() != 1) {
+  const DynTypedMatcher *Result;
+  if (!Value.getMatcher().getSingleMatcher(Result)) {
     Error->addError(SourceRange(), Error->ET_ParserOverloadedType)
         << Value.getTypeAsString();
     return NULL;
   }
-  return Value.getMatchers().matchers()[0]->clone();
+  return Result->clone();
 }
 
 }  // namespace dynamic
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index e0c7280..47957c7 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -63,25 +63,25 @@
       delete Overloads[i];
   }
 
-  virtual MatcherList run(const SourceRange &NameRange,
-                          ArrayRef<ParserValue> Args,
-                          Diagnostics *Error) const {
-    std::vector<MatcherList> Constructed;
+  virtual VariantMatcher run(const SourceRange &NameRange,
+                             ArrayRef<ParserValue> Args,
+                             Diagnostics *Error) const {
+    std::vector<VariantMatcher> Constructed;
     Diagnostics::OverloadContext Ctx(Error);
     for (size_t i = 0, e = Overloads.size(); i != e; ++i) {
-      MatcherList SubMatcher = Overloads[i]->run(NameRange, Args, Error);
-      if (!SubMatcher.empty()) {
+      VariantMatcher SubMatcher = Overloads[i]->run(NameRange, Args, Error);
+      if (!SubMatcher.isNull()) {
         Constructed.push_back(SubMatcher);
       }
     }
 
-    if (Constructed.empty()) return MatcherList();  // No overload matched.
+    if (Constructed.empty()) return VariantMatcher();  // No overload matched.
     // We ignore the errors if any matcher succeeded.
     Ctx.revertErrors();
     if (Constructed.size() > 1) {
       // More than one constructed. It is ambiguous.
       Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload);
-      return MatcherList();
+      return VariantMatcher();
     }
     return Constructed[0];
   }
@@ -405,38 +405,38 @@
 } // anonymous namespace
 
 // static
-MatcherList Registry::constructMatcher(StringRef MatcherName,
-                                       const SourceRange &NameRange,
-                                       ArrayRef<ParserValue> Args,
-                                       Diagnostics *Error) {
+VariantMatcher Registry::constructMatcher(StringRef MatcherName,
+                                          const SourceRange &NameRange,
+                                          ArrayRef<ParserValue> Args,
+                                          Diagnostics *Error) {
   ConstructorMap::const_iterator it =
       RegistryData->constructors().find(MatcherName);
   if (it == RegistryData->constructors().end()) {
     Error->addError(NameRange, Error->ET_RegistryNotFound) << MatcherName;
-    return MatcherList();
+    return VariantMatcher();
   }
 
   return it->second->run(NameRange, Args, Error);
 }
 
 // static
-MatcherList Registry::constructBoundMatcher(StringRef MatcherName,
-                                            const SourceRange &NameRange,
-                                            StringRef BindID,
-                                            ArrayRef<ParserValue> Args,
-                                            Diagnostics *Error) {
-  MatcherList Out = constructMatcher(MatcherName, NameRange, Args, Error);
-  if (Out.empty()) return Out;
+VariantMatcher Registry::constructBoundMatcher(StringRef MatcherName,
+                                               const SourceRange &NameRange,
+                                               StringRef BindID,
+                                               ArrayRef<ParserValue> Args,
+                                               Diagnostics *Error) {
+  VariantMatcher Out = constructMatcher(MatcherName, NameRange, Args, Error);
+  if (Out.isNull()) return Out;
 
-  ArrayRef<const DynTypedMatcher*> Matchers = Out.matchers();
-  if (Matchers.size() == 1) {
-    OwningPtr<DynTypedMatcher> Bound(Matchers[0]->tryBind(BindID));
+  const DynTypedMatcher *Result;
+  if (Out.getSingleMatcher(Result)) {
+    OwningPtr<DynTypedMatcher> Bound(Result->tryBind(BindID));
     if (Bound) {
-      return *Bound;
+      return VariantMatcher::SingleMatcher(*Bound);
     }
   }
   Error->addError(NameRange, Error->ET_RegistryNotBindable);
-  return MatcherList();
+  return VariantMatcher();
 }
 
 }  // namespace dynamic
diff --git a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
index 79c5c8e..a8fd7c6 100644
--- a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ b/clang/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";
   }