Resubmit "Refactor DynTypedMatcher into a value type class, just like Matcher<T>."
authorSamuel Benzaquen <sbenza@google.com>
Tue, 29 Oct 2013 14:37:15 +0000 (14:37 +0000)
committerSamuel Benzaquen <sbenza@google.com>
Tue, 29 Oct 2013 14:37:15 +0000 (14:37 +0000)
Summary: This resubmits r193100, plus a fix for a breakage with MSVC.

Reviewers: klimek, rnk

CC: cfe-commits, revane
Differential Revision: http://llvm-reviews.chandlerc.com/D2005

llvm-svn: 193613

clang/include/clang/ASTMatchers/ASTMatchFinder.h
clang/include/clang/ASTMatchers/ASTMatchersInternal.h
clang/include/clang/ASTMatchers/Dynamic/Parser.h
clang/include/clang/ASTMatchers/Dynamic/VariantValue.h
clang/lib/ASTMatchers/ASTMatchFinder.cpp
clang/lib/ASTMatchers/ASTMatchersInternal.cpp
clang/lib/ASTMatchers/Dynamic/Marshallers.h
clang/lib/ASTMatchers/Dynamic/Parser.cpp
clang/lib/ASTMatchers/Dynamic/Registry.cpp
clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp

index d2b71d3..8817d3e 100644 (file)
@@ -162,7 +162,7 @@ public:
 private:
   /// \brief For each \c DynTypedMatcher a \c MatchCallback that will be called
   /// when it matches.
-  std::vector<std::pair<const internal::DynTypedMatcher*, MatchCallback*> >
+  std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> >
     MatcherCallbackPairs;
 
   /// \brief Called when parsing is done.
index 26ebc97..3d07825 100644 (file)
 #define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H
 
 #include "clang/AST/ASTTypeTraits.h"
-#include "clang/AST/DeclCXX.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprCXX.h"
-#include "clang/AST/StmtCXX.h"
 #include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
 #include "clang/AST/Type.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/VariadicFunction.h"
 #include "llvm/Support/type_traits.h"
 #include <map>
@@ -200,38 +201,6 @@ private:
   }
 };
 
-/// \brief Base class for all matchers that works on a \c DynTypedNode.
-///
-/// Matcher implementations will check whether the \c DynTypedNode is
-/// convertible into the respecitve types and then do the actual match
-/// on the actual node, or return false if it is not convertible.
-class DynTypedMatcher {
-public:
-  virtual ~DynTypedMatcher();
-
-  /// \brief Returns true if the matcher matches the given \c DynNode.
-  virtual bool matches(const ast_type_traits::DynTypedNode DynNode,
-                       ASTMatchFinder *Finder,
-                       BoundNodesTreeBuilder *Builder) const = 0;
-
-  /// \brief Makes a copy of this matcher object.
-  virtual DynTypedMatcher *clone() const = 0;
-
-  /// \brief Returns a unique ID for the matcher.
-  virtual uint64_t getID() const = 0;
-
-  /// \brief Bind the specified \p ID to the matcher.
-  /// \return A new matcher with the \p ID bound to it if this matcher supports
-  ///   binding. Otherwise, returns NULL. Returns NULL by default.
-  virtual DynTypedMatcher* tryBind(StringRef ID) const;
-
-  /// \brief Returns the type this matcher works on.
-  ///
-  /// \c matches() will always return false unless the node passed is of this
-  /// or a derived type.
-  virtual ast_type_traits::ASTNodeKind getSupportedKind() const = 0;
-};
-
 /// \brief Wrapper of a MatcherInterface<T> *that allows copying.
 ///
 /// A Matcher<Base> can be used anywhere a Matcher<Derived> is
@@ -241,7 +210,7 @@ public:
 /// operator rather than a type hierarchy to be able to templatize the
 /// type hierarchy instead of spelling it out.
 template <typename T>
-class Matcher : public DynTypedMatcher {
+class Matcher {
 public:
   /// \brief Takes ownership of the provided implementation pointer.
   explicit Matcher(MatcherInterface<T> *Implementation)
@@ -267,35 +236,6 @@ public:
             llvm::is_same<TypeT, Type>::value >::type* = 0)
       : Implementation(new TypeToQualType<TypeT>(Other)) {}
 
-  /// \brief Returns \c true if the passed DynTypedMatcher can be converted
-  ///   to a \c Matcher<T>.
-  ///
-  /// This method verifies that the underlying matcher in \c Other can process
-  /// nodes of types T.
-  static bool canConstructFrom(const DynTypedMatcher &Other) {
-    return Other.getSupportedKind()
-        .isBaseOf(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
-  }
-
-  /// \brief Construct a Matcher<T> interface around the dynamic matcher
-  ///   \c Other.
-  ///
-  /// This method asserts that canConstructFrom(Other) is \c true. Callers
-  /// should call canConstructFrom(Other) first to make sure that Other is
-  /// compatible with T.
-  static Matcher<T> constructFrom(const DynTypedMatcher &Other) {
-    assert(canConstructFrom(Other));
-    return constructFromUnsafe(Other);
-  }
-
-  /// \brief Same as constructFrom(), but does not check that the underlying
-  ///   matcher can handle a value of T.
-  ///
-  /// If it is not compatible, then this matcher will never match anything.
-  static Matcher<T> constructFromUnsafe(const DynTypedMatcher &Other) {
-    return Matcher<T>(new WrappedMatcher(Other));
-  }
-
   /// \brief Forwards the call to the underlying MatcherInterface<T> pointer.
   bool matches(const T &Node,
                ASTMatchFinder *Finder,
@@ -316,23 +256,6 @@ public:
     return reinterpret_cast<uint64_t>(Implementation.getPtr());
   }
 
-  /// \brief Returns the type this matcher works on.
-  ast_type_traits::ASTNodeKind getSupportedKind() const {
-    return ast_type_traits::ASTNodeKind::getFromNodeKind<T>();
-  }
-
-  /// \brief Returns whether the matcher matches on the given \c DynNode.
-  virtual bool matches(const ast_type_traits::DynTypedNode DynNode,
-                       ASTMatchFinder *Finder,
-                       BoundNodesTreeBuilder *Builder) const {
-    const T *Node = DynNode.get<T>();
-    if (!Node) return false;
-    return matches(*Node, Finder, Builder);
-  }
-
-  /// \brief Makes a copy of this matcher object.
-  virtual Matcher<T> *clone() const { return new Matcher<T>(*this); }
-
   /// \brief Allows the conversion of a \c Matcher<Type> to a \c
   /// Matcher<QualType>.
   ///
@@ -375,23 +298,6 @@ private:
     const Matcher<Base> From;
   };
 
-  /// \brief Simple MatcherInterface<T> wrapper around a DynTypedMatcher.
-  class WrappedMatcher : public MatcherInterface<T> {
-  public:
-    explicit WrappedMatcher(const DynTypedMatcher &Matcher)
-        : Inner(Matcher.clone()) {}
-    virtual ~WrappedMatcher() {}
-
-    bool matches(const T &Node, ASTMatchFinder *Finder,
-                 BoundNodesTreeBuilder *Builder) const {
-      return Inner->matches(ast_type_traits::DynTypedNode::create(Node), Finder,
-                            Builder);
-    }
-
-  private:
-    const OwningPtr<DynTypedMatcher> Inner;
-  };
-
   IntrusiveRefCntPtr< MatcherInterface<T> > Implementation;
 };  // class Matcher
 
@@ -402,15 +308,168 @@ inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
   return Matcher<T>(Implementation);
 }
 
+template <typename T> class BindableMatcher;
+
+/// \brief Matcher that works on a \c DynTypedNode.
+///
+/// It is constructed from a \c Matcher<T> object and redirects most calls to
+/// underlying matcher.
+/// It checks whether the \c DynTypedNode is convertible into the type of the
+/// underlying matcher and then do the actual match on the actual node, or
+/// return false if it is not convertible.
+class DynTypedMatcher {
+public:
+  /// \brief Construct from a \c Matcher<T>. Copies the matcher.
+  template <typename T> inline DynTypedMatcher(const Matcher<T> &M);
+
+  /// \brief Construct from a bindable \c Matcher<T>. Copies the matcher.
+  ///
+  /// This version enables \c tryBind() on the \c DynTypedMatcher.
+  template <typename T> inline DynTypedMatcher(const BindableMatcher<T> &M);
+
+  /// \brief Returns true if the matcher matches the given \c DynNode.
+  bool matches(const ast_type_traits::DynTypedNode DynNode,
+               ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const {
+    return Storage->matches(DynNode, Finder, Builder);
+  }
+
+  /// \brief Bind the specified \p ID to the matcher.
+  /// \return A new matcher with the \p ID bound to it if this matcher supports
+  ///   binding. Otherwise, returns an empty \c Optional<>.
+  llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const {
+    return Storage->tryBind(ID);
+  }
+
+  /// \brief Returns a unique \p ID for the matcher.
+  uint64_t getID() const { return Storage->getID(); }
+
+  /// \brief Returns the type this matcher works on.
+  ///
+  /// \c matches() will always return false unless the node passed is of this
+  /// or a derived type.
+  ast_type_traits::ASTNodeKind getSupportedKind() const {
+    return Storage->getSupportedKind();
+  }
+
+  /// \brief Returns \c true if the passed \c DynTypedMatcher can be converted
+  ///   to a \c Matcher<T>.
+  ///
+  /// This method verifies that the underlying matcher in \c Other can process
+  /// nodes of types T.
+  template <typename T> bool canConvertTo() const {
+    return getSupportedKind().isBaseOf(
+        ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
+  }
+
+  /// \brief Construct a \c Matcher<T> interface around the dynamic matcher.
+  ///
+  /// This method asserts that \c canConvertTo() is \c true. Callers
+  /// should call \c canConvertTo() first to make sure that \c this is
+  /// compatible with T.
+  template <typename T> Matcher<T> convertTo() const {
+    assert(canConvertTo<T>());
+    return unconditionalConvertTo<T>();
+  }
+
+  /// \brief Same as \c convertTo(), but does not check that the underlying
+  ///   matcher can handle a value of T.
+  ///
+  /// If it is not compatible, then this matcher will never match anything.
+  template <typename T> Matcher<T> unconditionalConvertTo() const {
+    return Matcher<T>(new WrappedMatcher<T>(*this));
+  }
+
+private:
+  class MatcherStorage : public RefCountedBaseVPTR {
+  public:
+    MatcherStorage(ast_type_traits::ASTNodeKind SupportedKind, uint64_t ID)
+        : SupportedKind(SupportedKind), ID(ID) {}
+    virtual ~MatcherStorage();
+
+    virtual bool matches(const ast_type_traits::DynTypedNode DynNode,
+                         ASTMatchFinder *Finder,
+                         BoundNodesTreeBuilder *Builder) const = 0;
+
+    virtual llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const = 0;
+
+    ast_type_traits::ASTNodeKind getSupportedKind() const {
+      return SupportedKind;
+    }
+
+    uint64_t getID() const { return ID; }
+
+  private:
+    const ast_type_traits::ASTNodeKind SupportedKind;
+    const uint64_t ID;
+  };
+
+  /// \brief Typed implementation of \c MatcherStorage.
+  template <typename T> class TypedMatcherStorage;
+
+  /// \brief Simple MatcherInterface<T> wrapper around a DynTypedMatcher.
+  template <typename T> class WrappedMatcher;
+
+  IntrusiveRefCntPtr<const MatcherStorage> Storage;
+};
+
+template <typename T>
+class DynTypedMatcher::TypedMatcherStorage : public MatcherStorage {
+public:
+  TypedMatcherStorage(const Matcher<T> &Other, bool AllowBind)
+      : MatcherStorage(ast_type_traits::ASTNodeKind::getFromNodeKind<T>(),
+                       Other.getID()),
+        InnerMatcher(Other), AllowBind(AllowBind) {}
+
+  bool matches(const ast_type_traits::DynTypedNode DynNode,
+               ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const
+      LLVM_OVERRIDE {
+    if (const T *Node = DynNode.get<T>()) {
+      return InnerMatcher.matches(*Node, Finder, Builder);
+    }
+    return false;
+  }
+
+  llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const LLVM_OVERRIDE {
+    if (!AllowBind)
+      return llvm::Optional<DynTypedMatcher>();
+    return DynTypedMatcher(BindableMatcher<T>(InnerMatcher).bind(ID));
+  }
+
+private:
+  const Matcher<T> InnerMatcher;
+  const bool AllowBind;
+};
+
+template <typename T>
+inline DynTypedMatcher::DynTypedMatcher(const Matcher<T> &M)
+    : Storage(new TypedMatcherStorage<T>(M, false)) {}
+
+template <typename T>
+inline DynTypedMatcher::DynTypedMatcher(const BindableMatcher<T> &M)
+    : Storage(new TypedMatcherStorage<T>(M, true)) {}
+
+template <typename T>
+class DynTypedMatcher::WrappedMatcher : public MatcherInterface<T> {
+public:
+  explicit WrappedMatcher(const DynTypedMatcher &Matcher) : Inner(Matcher) {}
+  virtual ~WrappedMatcher() {}
+
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const {
+    return Inner.matches(ast_type_traits::DynTypedNode::create(Node), Finder,
+                         Builder);
+  }
+
+private:
+  const DynTypedMatcher Inner;
+};
+
 /// \brief Specialization of the conversion functions for QualType.
 ///
 /// These specializations provide the Matcher<Type>->Matcher<QualType>
 /// conversion that the static API does.
-template <>
-inline bool
-Matcher<QualType>::canConstructFrom(const DynTypedMatcher &Other) {
-  ast_type_traits::ASTNodeKind SourceKind = Other.getSupportedKind();
-  // We support implicit conversion from Matcher<Type> to Matcher<QualType>
+template <> inline bool DynTypedMatcher::canConvertTo<QualType>() const {
+  const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();
   return SourceKind.isSame(
              ast_type_traits::ASTNodeKind::getFromNodeKind<Type>()) ||
          SourceKind.isSame(
@@ -418,16 +477,15 @@ Matcher<QualType>::canConstructFrom(const DynTypedMatcher &Other) {
 }
 
 template <>
-inline Matcher<QualType>
-Matcher<QualType>::constructFrom(const DynTypedMatcher &Other) {
-  assert(canConstructFrom(Other));
-  ast_type_traits::ASTNodeKind SourceKind = Other.getSupportedKind();
+inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const {
+  assert(canConvertTo<QualType>());
+  const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();
   if (SourceKind.isSame(
           ast_type_traits::ASTNodeKind::getFromNodeKind<Type>())) {
     // We support implicit conversion from Matcher<Type> to Matcher<QualType>
-    return Matcher<Type>::constructFrom(Other);
+    return unconditionalConvertTo<Type>();
   }
-  return makeMatcher(new WrappedMatcher(Other));
+  return unconditionalConvertTo<QualType>();
 }
 
 /// \brief Finds the first node in a range that matches the given matcher.
@@ -973,16 +1031,6 @@ public:
   Matcher<T> bind(StringRef ID) const {
     return Matcher<T>(new IdMatcher<T>(ID, *this));
   }
-
-  /// \brief Makes a copy of this matcher object.
-  virtual BindableMatcher<T>* clone() const {
-    return new BindableMatcher<T>(*this);
-  }
-
-  /// \brief Bind the specified \c ID to the matcher.
-  virtual Matcher<T>* tryBind(StringRef ID) const {
-    return new Matcher<T>(bind(ID));
-  }
 };
 
 /// \brief Matches nodes of type T that have child nodes of type ChildT for
@@ -1075,8 +1123,7 @@ private:
 ///   matchers as an array of DynTypedMatcher.
 typedef bool (*VariadicOperatorFunction)(
     const ast_type_traits::DynTypedNode DynNode, ASTMatchFinder *Finder,
-    BoundNodesTreeBuilder *Builder,
-    ArrayRef<const DynTypedMatcher *> InnerMatchers);
+    BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);
 
 /// \brief \c MatcherInterface<T> implementation for an variadic operator.
 template <typename T>
@@ -1086,14 +1133,10 @@ public:
                                    ArrayRef<const Matcher<T> *> InputMatchers)
       : Func(Func) {
     for (size_t i = 0, e = InputMatchers.size(); i != e; ++i) {
-      InnerMatchers.push_back(new Matcher<T>(*InputMatchers[i]));
+      InnerMatchers.push_back(*InputMatchers[i]);
     }
   }
 
-  ~VariadicOperatorMatcherInterface() {
-    llvm::DeleteContainerPointers(InnerMatchers);
-  }
-
   virtual bool matches(const T &Node, ASTMatchFinder *Finder,
                        BoundNodesTreeBuilder *Builder) const {
     return Func(ast_type_traits::DynTypedNode::create(Node), Finder, Builder,
@@ -1102,7 +1145,7 @@ public:
 
 private:
   const VariadicOperatorFunction Func;
-  std::vector<const DynTypedMatcher *> InnerMatchers;
+  std::vector<DynTypedMatcher> InnerMatchers;
 };
 
 /// \brief "No argument" placeholder to use as template paratemers.
@@ -1196,24 +1239,24 @@ struct VariadicOperatorMatcherFunc {
 /// @}
 
 /// \brief Matches nodes for which all provided matchers match.
-bool
-AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
-                      ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
-                      ArrayRef<const DynTypedMatcher *> InnerMatchers);
+bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+                           ASTMatchFinder *Finder,
+                           BoundNodesTreeBuilder *Builder,
+                           ArrayRef<DynTypedMatcher> InnerMatchers);
 
 /// \brief Matches nodes for which at least one of the provided matchers
 /// matches, but doesn't stop at the first match.
-bool
-EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
-                       ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
-                       ArrayRef<const DynTypedMatcher *> InnerMatchers);
+bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+                            ASTMatchFinder *Finder,
+                            BoundNodesTreeBuilder *Builder,
+                            ArrayRef<DynTypedMatcher> InnerMatchers);
 
 /// \brief Matches nodes for which at least one of the provided matchers
 /// matches.
-bool
-AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
-                      ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
-                      ArrayRef<const DynTypedMatcher *> InnerMatchers);
+bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+                           ASTMatchFinder *Finder,
+                           BoundNodesTreeBuilder *Builder,
+                           ArrayRef<DynTypedMatcher> InnerMatchers);
 
 /// \brief Creates a Matcher<T> that matches if all inner matchers match.
 template<typename T>
@@ -1232,8 +1275,8 @@ BindableMatcher<T> makeAllOfComposite(
 template<typename T, typename InnerT>
 BindableMatcher<T> makeDynCastAllOfComposite(
     ArrayRef<const Matcher<InnerT> *> InnerMatchers) {
-  return BindableMatcher<T>(
-      Matcher<T>::constructFromUnsafe(makeAllOfComposite(InnerMatchers)));
+  return BindableMatcher<T>(DynTypedMatcher(makeAllOfComposite(InnerMatchers))
+                                .unconditionalConvertTo<T>());
 }
 
 /// \brief Matches nodes of type T that have at least one descendant node of
index 3759f63..bb6ac76 100644 (file)
@@ -37,6 +37,7 @@
 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringRef.h"
 
 namespace clang {
@@ -92,11 +93,12 @@ public:
   ///
   /// \param MatcherCode The matcher expression to parse.
   ///
-  /// \return The matcher object constructed, or NULL if an error occurred.
-  //    In that case, \c Error will contain a description of the error.
+  /// \return The matcher object constructed, or an empty Optional if an error
+  ///   occurred.
+  ///   In that case, \c Error will contain a description of the error.
   ///   The caller takes ownership of the DynTypedMatcher object returned.
-  static DynTypedMatcher *parseMatcherExpression(StringRef MatcherCode,
-                                                 Diagnostics *Error);
+  static llvm::Optional<DynTypedMatcher>
+  parseMatcherExpression(StringRef MatcherCode, Diagnostics *Error);
 
   /// \brief Parse a matcher expression.
   ///
@@ -104,13 +106,12 @@ public:
   ///
   /// \param S The Sema instance that will help the parser
   ///   construct the matchers.
-  /// \return The matcher object constructed by the processor, or NULL
-  ///   if an error occurred. In that case, \c Error will contain a
+  /// \return The matcher object constructed by the processor, or an empty
+  ///   Optional if an error occurred. In that case, \c Error will contain a
   ///   description of the error.
   ///   The caller takes ownership of the DynTypedMatcher object returned.
-  static DynTypedMatcher *parseMatcherExpression(StringRef MatcherCode,
-                                                 Sema *S,
-                                                 Diagnostics *Error);
+  static llvm::Optional<DynTypedMatcher>
+  parseMatcherExpression(StringRef MatcherCode, Sema *S, Diagnostics *Error);
 
   /// \brief Parse an expression, creating matchers from the registry.
   ///
index 9d7e4e1..b9bc017 100644 (file)
@@ -22,6 +22,7 @@
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/ASTMatchers/ASTMatchersInternal.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/type_traits.h"
 
@@ -62,7 +63,7 @@ class VariantMatcher {
   class Payload : public RefCountedBaseVPTR {
   public:
     virtual ~Payload();
-    virtual bool getSingleMatcher(const DynTypedMatcher *&Out) const = 0;
+    virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
     virtual std::string getTypeAsString() const = 0;
     virtual void makeTypedMatcher(MatcherOps &Ops) const = 0;
   };
@@ -77,8 +78,7 @@ public:
   /// \brief Clones the provided matchers.
   ///
   /// They should be the result of a polymorphic matcher.
-  static VariantMatcher
-  PolymorphicMatcher(ArrayRef<const DynTypedMatcher *> Matchers);
+  static VariantMatcher PolymorphicMatcher(ArrayRef<DynTypedMatcher> Matchers);
 
   /// \brief Creates a 'variadic' operator matcher.
   ///
@@ -95,10 +95,10 @@ public:
 
   /// \brief Return a single matcher, if there is no ambiguity.
   ///
-  /// \returns \c true, and set Out to the matcher, if there is only one
-  /// matcher. \c false, if the underlying matcher is a polymorphic matcher with
-  /// more than one representation.
-  bool getSingleMatcher(const DynTypedMatcher *&Out) const;
+  /// \returns the matcher, if there is only one matcher. An empty Optional, if
+  /// the underlying matcher is a polymorphic matcher with more than one
+  /// representation.
+  llvm::Optional<DynTypedMatcher> getSingleMatcher() const;
 
   /// \brief Determines if the contained matcher can be converted to
   ///   \c Matcher<T>.
@@ -146,11 +146,11 @@ private:
     typedef ast_matchers::internal::Matcher<T> MatcherT;
 
     virtual bool canConstructFrom(const DynTypedMatcher &Matcher) const {
-      return MatcherT::canConstructFrom(Matcher);
+      return Matcher.canConvertTo<T>();
     }
 
     virtual void constructFrom(const DynTypedMatcher& Matcher) {
-      Out.reset(new MatcherT(MatcherT::constructFrom(Matcher)));
+      Out.reset(new MatcherT(Matcher.convertTo<T>()));
     }
 
     virtual void constructVariadicOperator(
@@ -173,7 +173,9 @@ private:
             new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(
                 Func, ArrayRef<const MatcherT *>(InnerArgs, NumArgs))));
       }
-      std::for_each(InnerArgs, InnerArgs + NumArgs, llvm::deleter<MatcherT>);
+      for (size_t i = 0; i != NumArgs; ++i) {
+        delete InnerArgs[i];
+      }
       delete[] InnerArgs;
     }
 
index 78bd9be..fbb696f 100644 (file)
@@ -295,25 +295,26 @@ private:
 class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
                         public ASTMatchFinder {
 public:
-  MatchASTVisitor(std::vector<std::pair<const internal::DynTypedMatcher*,
-                                        MatchCallback*> > *MatcherCallbackPairs)
-     : MatcherCallbackPairs(MatcherCallbackPairs),
-       ActiveASTContext(NULL) {
-  }
+  MatchASTVisitor(
+      std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> > *
+          MatcherCallbackPairs)
+      : MatcherCallbackPairs(MatcherCallbackPairs), ActiveASTContext(NULL) {}
 
   void onStartOfTranslationUnit() {
-    for (std::vector<std::pair<const internal::DynTypedMatcher*,
-                               MatchCallback*> >::const_iterator
-             I = MatcherCallbackPairs->begin(), E = MatcherCallbackPairs->end();
+    for (std::vector<std::pair<internal::DynTypedMatcher,
+                               MatchCallback *> >::const_iterator
+             I = MatcherCallbackPairs->begin(),
+             E = MatcherCallbackPairs->end();
          I != E; ++I) {
       I->second->onStartOfTranslationUnit();
     }
   }
 
   void onEndOfTranslationUnit() {
-    for (std::vector<std::pair<const internal::DynTypedMatcher*,
-                               MatchCallback*> >::const_iterator
-             I = MatcherCallbackPairs->begin(), E = MatcherCallbackPairs->end();
+    for (std::vector<std::pair<internal::DynTypedMatcher,
+                               MatchCallback *> >::const_iterator
+             I = MatcherCallbackPairs->begin(),
+             E = MatcherCallbackPairs->end();
          I != E; ++I) {
       I->second->onEndOfTranslationUnit();
     }
@@ -450,12 +451,13 @@ public:
   // Matches all registered matchers on the given node and calls the
   // result callback for every node that matches.
   void match(const ast_type_traits::DynTypedNode& Node) {
-    for (std::vector<std::pair<const internal::DynTypedMatcher*,
-                               MatchCallback*> >::const_iterator
-             I = MatcherCallbackPairs->begin(), E = MatcherCallbackPairs->end();
+    for (std::vector<std::pair<internal::DynTypedMatcher,
+                               MatchCallback *> >::const_iterator
+             I = MatcherCallbackPairs->begin(),
+             E = MatcherCallbackPairs->end();
          I != E; ++I) {
       BoundNodesTreeBuilder Builder;
-      if (I->first->matches(Node, this, &Builder)) {
+      if (I->first.matches(Node, this, &Builder)) {
         MatchVisitor Visitor(ActiveASTContext, I->second);
         Builder.visitMatches(&Visitor);
       }
@@ -603,8 +605,8 @@ private:
     return false;
   }
 
-  std::vector<std::pair<const internal::DynTypedMatcher*,
-                        MatchCallback*> > *const MatcherCallbackPairs;
+  std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> > *const
+  MatcherCallbackPairs;
   ASTContext *ActiveASTContext;
 
   // Maps a canonical type to its TypedefDecls.
@@ -743,11 +745,10 @@ bool MatchASTVisitor::TraverseNestedNameSpecifierLoc(
 class MatchASTConsumer : public ASTConsumer {
 public:
   MatchASTConsumer(
-    std::vector<std::pair<const internal::DynTypedMatcher*,
-                          MatchCallback*> > *MatcherCallbackPairs,
-    MatchFinder::ParsingDoneTestCallback *ParsingDone)
-    : Visitor(MatcherCallbackPairs),
-      ParsingDone(ParsingDone) {}
+      std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> > *
+          MatcherCallbackPairs,
+      MatchFinder::ParsingDoneTestCallback *ParsingDone)
+      : Visitor(MatcherCallbackPairs), ParsingDone(ParsingDone) {}
 
 private:
   virtual void HandleTranslationUnit(ASTContext &Context) {
@@ -778,49 +779,36 @@ MatchFinder::ParsingDoneTestCallback::~ParsingDoneTestCallback() {}
 
 MatchFinder::MatchFinder() : ParsingDone(NULL) {}
 
-MatchFinder::~MatchFinder() {
-  for (std::vector<std::pair<const internal::DynTypedMatcher*,
-                             MatchCallback*> >::const_iterator
-           It = MatcherCallbackPairs.begin(), End = MatcherCallbackPairs.end();
-       It != End; ++It) {
-    delete It->first;
-  }
-}
+MatchFinder::~MatchFinder() {}
 
 void MatchFinder::addMatcher(const DeclarationMatcher &NodeMatch,
                              MatchCallback *Action) {
-  MatcherCallbackPairs.push_back(std::make_pair(
-    new internal::Matcher<Decl>(NodeMatch), Action));
+  MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
 }
 
 void MatchFinder::addMatcher(const TypeMatcher &NodeMatch,
                              MatchCallback *Action) {
-  MatcherCallbackPairs.push_back(std::make_pair(
-    new internal::Matcher<QualType>(NodeMatch), Action));
+  MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
 }
 
 void MatchFinder::addMatcher(const StatementMatcher &NodeMatch,
                              MatchCallback *Action) {
-  MatcherCallbackPairs.push_back(std::make_pair(
-    new internal::Matcher<Stmt>(NodeMatch), Action));
+  MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
 }
 
 void MatchFinder::addMatcher(const NestedNameSpecifierMatcher &NodeMatch,
                              MatchCallback *Action) {
-  MatcherCallbackPairs.push_back(std::make_pair(
-    new NestedNameSpecifierMatcher(NodeMatch), Action));
+  MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
 }
 
 void MatchFinder::addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch,
                              MatchCallback *Action) {
-  MatcherCallbackPairs.push_back(std::make_pair(
-    new NestedNameSpecifierLocMatcher(NodeMatch), Action));
+  MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
 }
 
 void MatchFinder::addMatcher(const TypeLocMatcher &NodeMatch,
                              MatchCallback *Action) {
-  MatcherCallbackPairs.push_back(std::make_pair(
-    new TypeLocMatcher(NodeMatch), Action));
+  MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
 }
 
 ASTConsumer *MatchFinder::newASTConsumer() {
index e746516..d15eb54 100644 (file)
@@ -26,25 +26,23 @@ void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {
   }
 }
 
+DynTypedMatcher::MatcherStorage::~MatcherStorage() {}
+
 void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) {
   for (unsigned i = 0, e = Other.Bindings.size(); i != e; ++i) {
     Bindings.push_back(Other.Bindings[i]);
   }
 }
 
-DynTypedMatcher::~DynTypedMatcher() {}
-
-DynTypedMatcher *DynTypedMatcher::tryBind(StringRef ID) const { return NULL; }
-
 bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
                            ASTMatchFinder *Finder,
                            BoundNodesTreeBuilder *Builder,
-                           ArrayRef<const DynTypedMatcher *> InnerMatchers) {
+                           ArrayRef<DynTypedMatcher> InnerMatchers) {
   // allOf leads to one matcher for each alternative in the first
   // matcher combined with each alternative in the second matcher.
   // Thus, we can reuse the same Builder.
   for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
-    if (!InnerMatchers[i]->matches(DynNode, Finder, Builder))
+    if (!InnerMatchers[i].matches(DynNode, Finder, Builder))
       return false;
   }
   return true;
@@ -53,12 +51,12 @@ bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
 bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
                             ASTMatchFinder *Finder,
                             BoundNodesTreeBuilder *Builder,
-                            ArrayRef<const DynTypedMatcher *> InnerMatchers) {
+                            ArrayRef<DynTypedMatcher> InnerMatchers) {
   BoundNodesTreeBuilder Result;
   bool Matched = false;
   for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
     BoundNodesTreeBuilder BuilderInner(*Builder);
-    if (InnerMatchers[i]->matches(DynNode, Finder, &BuilderInner)) {
+    if (InnerMatchers[i].matches(DynNode, Finder, &BuilderInner)) {
       Matched = true;
       Result.addMatch(BuilderInner);
     }
@@ -70,10 +68,10 @@ bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
 bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
                            ASTMatchFinder *Finder,
                            BoundNodesTreeBuilder *Builder,
-                           ArrayRef<const DynTypedMatcher *> InnerMatchers) {
+                           ArrayRef<DynTypedMatcher> InnerMatchers) {
   for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
     BoundNodesTreeBuilder Result = *Builder;
-    if (InnerMatchers[i]->matches(DynNode, Finder, &Result)) {
+    if (InnerMatchers[i].matches(DynNode, Finder, &Result)) {
       *Builder = Result;
       return true;
     }
index 0df9c8c..ae0c300 100644 (file)
@@ -167,15 +167,13 @@ private:
 /// out of the polymorphic object.
 template <class PolyMatcher>
 static void mergePolyMatchers(const PolyMatcher &Poly,
-                              std::vector<const DynTypedMatcher *> &Out,
+                              std::vector<DynTypedMatcher> &Out,
                               ast_matchers::internal::EmptyTypeList) {}
 
 template <class PolyMatcher, class TypeList>
 static void mergePolyMatchers(const PolyMatcher &Poly,
-                              std::vector<const DynTypedMatcher *> &Out,
-                              TypeList) {
-  Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly)
-                    .clone());
+                              std::vector<DynTypedMatcher> &Out, TypeList) {
+  Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly));
   mergePolyMatchers(Poly, Out, typename TypeList::tail());
 }
 
@@ -193,10 +191,9 @@ template <typename T>
 static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher,
                                                typename T::ReturnTypes * =
                                                    NULL) {
-  std::vector<const DynTypedMatcher *> Matchers;
+  std::vector<DynTypedMatcher> Matchers;
   mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes());
   VariantMatcher Out = VariantMatcher::PolymorphicMatcher(Matchers);
-  llvm::DeleteContainerPointers(Matchers);
   return Out;
 }
 
index 37e6c10..df9596e 100644 (file)
@@ -390,29 +390,29 @@ bool Parser::parseExpression(StringRef Code, Sema *S,
   return true;
 }
 
-DynTypedMatcher *Parser::parseMatcherExpression(StringRef Code,
-                                                Diagnostics *Error) {
+llvm::Optional<DynTypedMatcher>
+Parser::parseMatcherExpression(StringRef Code, Diagnostics *Error) {
   RegistrySema S;
   return parseMatcherExpression(Code, &S, Error);
 }
 
-DynTypedMatcher *Parser::parseMatcherExpression(StringRef Code,
-                                                Parser::Sema *S,
-                                                Diagnostics *Error) {
+llvm::Optional<DynTypedMatcher>
+Parser::parseMatcherExpression(StringRef Code, Parser::Sema *S,
+                               Diagnostics *Error) {
   VariantValue Value;
   if (!parseExpression(Code, S, &Value, Error))
-    return NULL;
+    return llvm::Optional<DynTypedMatcher>();
   if (!Value.isMatcher()) {
     Error->addError(SourceRange(), Error->ET_ParserNotAMatcher);
-    return NULL;
+    return llvm::Optional<DynTypedMatcher>();
   }
-  const DynTypedMatcher *Result;
-  if (!Value.getMatcher().getSingleMatcher(Result)) {
+  llvm::Optional<DynTypedMatcher> Result =
+      Value.getMatcher().getSingleMatcher();
+  if (!Result.hasValue()) {
     Error->addError(SourceRange(), Error->ET_ParserOverloadedType)
         << Value.getTypeAsString();
-    return NULL;
   }
-  return Result->clone();
+  return Result;
 }
 
 }  // namespace dynamic
index 3f8e7d4..3a17038 100644 (file)
@@ -329,10 +329,10 @@ VariantMatcher Registry::constructBoundMatcher(StringRef MatcherName,
   VariantMatcher Out = constructMatcher(MatcherName, NameRange, Args, Error);
   if (Out.isNull()) return Out;
 
-  const DynTypedMatcher *Result;
-  if (Out.getSingleMatcher(Result)) {
-    OwningPtr<DynTypedMatcher> Bound(Result->tryBind(BindID));
-    if (Bound) {
+  llvm::Optional<DynTypedMatcher> Result = Out.getSingleMatcher();
+  if (Result.hasValue()) {
+    llvm::Optional<DynTypedMatcher> Bound = Result->tryBind(BindID);
+    if (Bound.hasValue()) {
       return VariantMatcher::SingleMatcher(*Bound);
     }
   }
index c350d78..3e49e1b 100644 (file)
@@ -26,44 +26,37 @@ VariantMatcher::Payload::~Payload() {}
 
 class VariantMatcher::SinglePayload : public VariantMatcher::Payload {
 public:
-  SinglePayload(const DynTypedMatcher &Matcher) : Matcher(Matcher.clone()) {}
+  SinglePayload(const DynTypedMatcher &Matcher) : Matcher(Matcher) {}
 
-  virtual bool getSingleMatcher(const DynTypedMatcher *&Out) const {
-    Out = Matcher.get();
-    return true;
+  virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
+    return Matcher;
   }
 
   virtual std::string getTypeAsString() const {
-    return (Twine("Matcher<") + Matcher->getSupportedKind().asStringRef() + ">")
+    return (Twine("Matcher<") + Matcher.getSupportedKind().asStringRef() + ">")
         .str();
   }
 
   virtual void makeTypedMatcher(MatcherOps &Ops) const {
-    if (Ops.canConstructFrom(*Matcher))
-      Ops.constructFrom(*Matcher);
+    if (Ops.canConstructFrom(Matcher))
+      Ops.constructFrom(Matcher);
   }
 
 private:
-  OwningPtr<const DynTypedMatcher> Matcher;
+  const DynTypedMatcher Matcher;
 };
 
 class VariantMatcher::PolymorphicPayload : public VariantMatcher::Payload {
 public:
-  PolymorphicPayload(ArrayRef<const DynTypedMatcher *> MatchersIn) {
-    for (size_t i = 0, e = MatchersIn.size(); i != e; ++i) {
-      Matchers.push_back(MatchersIn[i]->clone());
-    }
-  }
+  PolymorphicPayload(ArrayRef<DynTypedMatcher> MatchersIn)
+      : Matchers(MatchersIn) {}
 
-  virtual ~PolymorphicPayload() {
-    llvm::DeleteContainerPointers(Matchers);
-  }
+  virtual ~PolymorphicPayload() {}
 
-  virtual bool getSingleMatcher(const DynTypedMatcher *&Out) const {
+  virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
     if (Matchers.size() != 1)
-      return false;
-    Out = Matchers[0];
-    return true;
+      return llvm::Optional<DynTypedMatcher>();
+    return Matchers[0];
   }
 
   virtual std::string getTypeAsString() const {
@@ -71,7 +64,7 @@ public:
     for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
       if (i != 0)
         Inner += "|";
-      Inner += Matchers[i]->getSupportedKind().asStringRef();
+      Inner += Matchers[i].getSupportedKind().asStringRef();
     }
     return (Twine("Matcher<") + Inner + ">").str();
   }
@@ -79,17 +72,17 @@ public:
   virtual void makeTypedMatcher(MatcherOps &Ops) const {
     const DynTypedMatcher *Found = NULL;
     for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
-      if (Ops.canConstructFrom(*Matchers[i])) {
+      if (Ops.canConstructFrom(Matchers[i])) {
         if (Found)
           return;
-        Found = Matchers[i];
+        Found = &Matchers[i];
       }
     }
     if (Found)
       Ops.constructFrom(*Found);
   }
 
-  std::vector<const DynTypedMatcher *> Matchers;
+  const std::vector<DynTypedMatcher> Matchers;
 };
 
 class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload {
@@ -98,8 +91,8 @@ public:
                     ArrayRef<VariantMatcher> Args)
       : Func(Func), Args(Args) {}
 
-  virtual bool getSingleMatcher(const DynTypedMatcher *&Out) const {
-    return false;
+  virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
+    return llvm::Optional<DynTypedMatcher>();
   }
 
   virtual std::string getTypeAsString() const {
@@ -128,7 +121,7 @@ VariantMatcher VariantMatcher::SingleMatcher(const DynTypedMatcher &Matcher) {
 }
 
 VariantMatcher
-VariantMatcher::PolymorphicMatcher(ArrayRef<const DynTypedMatcher *> Matchers) {
+VariantMatcher::PolymorphicMatcher(ArrayRef<DynTypedMatcher> Matchers) {
   return VariantMatcher(new PolymorphicPayload(Matchers));
 }
 
@@ -138,9 +131,8 @@ VariantMatcher VariantMatcher::VariadicOperatorMatcher(
   return VariantMatcher(new VariadicOpPayload(Func, Args));
 }
 
-bool VariantMatcher::getSingleMatcher(const DynTypedMatcher *&Out) const {
-  if (Value) return Value->getSingleMatcher(Out);
-  return false;
+llvm::Optional<DynTypedMatcher> VariantMatcher::getSingleMatcher() const {
+  return Value ? Value->getSingleMatcher() : llvm::Optional<DynTypedMatcher>();
 }
 
 void VariantMatcher::reset() { Value.reset(); }
index 9116ab8..f19ec51 100644 (file)
@@ -21,51 +21,14 @@ namespace ast_matchers {
 namespace dynamic {
 namespace {
 
-class DummyDynTypedMatcher : public DynTypedMatcher {
-public:
-  DummyDynTypedMatcher(uint64_t ID) : ID(ID) {}
-  DummyDynTypedMatcher(uint64_t ID, StringRef BoundID)
-      : ID(ID), BoundID(BoundID) {}
-
-  typedef ast_matchers::internal::ASTMatchFinder ASTMatchFinder;
-  typedef ast_matchers::internal::BoundNodesTreeBuilder BoundNodesTreeBuilder;
-  virtual bool matches(const ast_type_traits::DynTypedNode DynNode,
-                       ASTMatchFinder *Finder,
-                       BoundNodesTreeBuilder *Builder) const {
-    return false;
-  }
-
-  /// \brief Makes a copy of this matcher object.
-  virtual DynTypedMatcher *clone() const {
-    return new DummyDynTypedMatcher(*this);
-  }
-
-  /// \brief Returns a unique ID for the matcher.
-  virtual uint64_t getID() const { return ID; }
-
-  virtual DynTypedMatcher* tryBind(StringRef BoundID) const {
-    return new DummyDynTypedMatcher(ID, BoundID);
-  }
-
-  StringRef boundID() const { return BoundID; }
-
-  virtual ast_type_traits::ASTNodeKind getSupportedKind() const {
-    return ast_type_traits::ASTNodeKind();
-  }
-
-private:
-  uint64_t ID;
-  std::string BoundID;
-};
-
 class MockSema : public Parser::Sema {
 public:
   virtual ~MockSema() {}
 
   uint64_t expectMatcher(StringRef MatcherName) {
-    uint64_t ID = ExpectedMatchers.size() + 1;
-    ExpectedMatchers[MatcherName] = ID;
-    return ID;
+    ast_matchers::internal::Matcher<Stmt> M = stmt();
+    ExpectedMatchers.insert(std::make_pair(MatcherName, M));
+    return M.getID();
   }
 
   void parse(StringRef Code) {
@@ -83,9 +46,8 @@ public:
                                         Diagnostics *Error) {
     MatcherInfo ToStore = { MatcherName, NameRange, Args, BindID };
     Matchers.push_back(ToStore);
-    DummyDynTypedMatcher Matcher(ExpectedMatchers[MatcherName]);
-    OwningPtr<DynTypedMatcher> Out(Matcher.tryBind(BindID));
-    return VariantMatcher::SingleMatcher(*Out);
+    return VariantMatcher::SingleMatcher(
+        ExpectedMatchers.find(MatcherName)->second);
   }
 
   struct MatcherInfo {
@@ -98,7 +60,8 @@ public:
   std::vector<std::string> Errors;
   std::vector<VariantValue> Values;
   std::vector<MatcherInfo> Matchers;
-  llvm::StringMap<uint64_t> ExpectedMatchers;
+  std::map<std::string, ast_matchers::internal::Matcher<Stmt> >
+  ExpectedMatchers;
 };
 
 TEST(ParserTest, ParseUnsigned) {
@@ -137,10 +100,11 @@ bool matchesRange(const SourceRange &Range, unsigned StartLine,
          Range.Start.Column == StartColumn && Range.End.Column == EndColumn;
 }
 
-const DynTypedMatcher *getSingleMatcher(const VariantValue &Value) {
-  const DynTypedMatcher *Out;
-  EXPECT_TRUE(Value.getMatcher().getSingleMatcher(Out));
-  return Out;
+llvm::Optional<DynTypedMatcher> getSingleMatcher(const VariantValue &Value) {
+  llvm::Optional<DynTypedMatcher> Result =
+      Value.getMatcher().getSingleMatcher();
+  EXPECT_TRUE(Result.hasValue());
+  return Result;
 }
 
 TEST(ParserTest, ParseMatcher) {
@@ -155,8 +119,6 @@ TEST(ParserTest, ParseMatcher) {
 
   EXPECT_EQ(1ULL, Sema.Values.size());
   EXPECT_EQ(ExpectedFoo, getSingleMatcher(Sema.Values[0])->getID());
-  EXPECT_EQ("Yo!", static_cast<const DummyDynTypedMatcher *>(
-                       getSingleMatcher(Sema.Values[0]))->boundID());
 
   EXPECT_EQ(3ULL, Sema.Matchers.size());
   const MockSema::MatcherInfo Bar = Sema.Matchers[0];
@@ -184,27 +146,28 @@ using ast_matchers::internal::Matcher;
 
 TEST(ParserTest, FullParserTest) {
   Diagnostics Error;
-  OwningPtr<DynTypedMatcher> VarDecl(Parser::parseMatcherExpression(
+  llvm::Optional<DynTypedMatcher> VarDecl(Parser::parseMatcherExpression(
       "varDecl(hasInitializer(binaryOperator(hasLHS(integerLiteral()),"
       "                                      hasOperatorName(\"+\"))))",
       &Error));
   EXPECT_EQ("", Error.toStringFull());
-  Matcher<Decl> M = Matcher<Decl>::constructFrom(*VarDecl);
+  Matcher<Decl> M = VarDecl->unconditionalConvertTo<Decl>();
   EXPECT_TRUE(matches("int x = 1 + false;", M));
   EXPECT_FALSE(matches("int x = true + 1;", M));
   EXPECT_FALSE(matches("int x = 1 - false;", M));
   EXPECT_FALSE(matches("int x = true - 1;", M));
 
-  OwningPtr<DynTypedMatcher> HasParameter(Parser::parseMatcherExpression(
+  llvm::Optional<DynTypedMatcher> HasParameter(Parser::parseMatcherExpression(
       "functionDecl(hasParameter(1, hasName(\"x\")))", &Error));
   EXPECT_EQ("", Error.toStringFull());
-  M = Matcher<Decl>::constructFrom(*HasParameter);
+  M = HasParameter->unconditionalConvertTo<Decl>();
 
   EXPECT_TRUE(matches("void f(int a, int x);", M));
   EXPECT_FALSE(matches("void f(int x, int a);", M));
 
-  EXPECT_TRUE(Parser::parseMatcherExpression(
-      "hasInitializer(\n    binaryOperator(hasLHS(\"A\")))", &Error) == NULL);
+  EXPECT_TRUE(!Parser::parseMatcherExpression(
+                   "hasInitializer(\n    binaryOperator(hasLHS(\"A\")))",
+                   &Error).hasValue());
   EXPECT_EQ("1:1: Error parsing argument 1 for matcher hasInitializer.\n"
             "2:5: Error parsing argument 1 for matcher binaryOperator.\n"
             "2:20: Error building matcher hasLHS.\n"