r193100 - Refactor DynTypedMatcher into a value type class, just like Matcher<T>.

Reid Kleckner rnk at google.com
Mon Oct 21 15:00:06 PDT 2013


This isn't working with MSVC 2012:
http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/5646/steps/build_clang/logs/stdio

E:\bb-win7\ninja-clang-i686-msc17-R\llvm-project\llvm\include\llvm/Support/AlignOf.h(175)
: error C2079: 'llvm::detail::AlignerImpl<T1,T2,T3,T4,T5,T6,T7>::t1' uses
undefined class 'clang::ast_matchers::internal::DynTypedMatcher'

This is found while instantiating Optional<DynTypedMatcher>.


On Mon, Oct 21, 2013 at 11:40 AM, Samuel Benzaquen <sbenza at google.com>wrote:

> Author: sbenza
> Date: Mon Oct 21 13:40:51 2013
> New Revision: 193100
>
> URL: http://llvm.org/viewvc/llvm-project?rev=193100&view=rev
> Log:
> Refactor DynTypedMatcher into a value type class, just like Matcher<T>.
>
> Summary:
> Refactor DynTypedMatcher into a value type class, just like Matcher<T>.
> This simplifies its usage and removes the virtual hierarchy from
> Matcher<T>.
> It also enables planned changes to replace MatcherInteface<T>.
> Too many instantiaions of this class hierarchy has been causing
> Registry.cpp.o to bloat in size and number of symbols.
>
> Reviewers: klimek
>
> CC: cfe-commits, revane
>
> Differential Revision: http://llvm-reviews.chandlerc.com/D1661
>
> Modified:
>     cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h
>     cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
>     cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h
>     cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h
>     cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp
>     cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
>     cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h
>     cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp
>     cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
>     cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp
>     cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp
>
> Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h?rev=193100&r1=193099&r2=193100&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h (original)
> +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h Mon Oct 21
> 13:40:51 2013
> @@ -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.
>
> Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=193100&r1=193099&r2=193100&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original)
> +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Mon Oct 21
> 13:40:51 2013
> @@ -36,12 +36,13 @@
>  #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,160 @@ inline Matcher<T> makeMatcher(MatcherInt
>    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>
> +  DynTypedMatcher(const Matcher<T> &M)
> +      : Storage(new TypedMatcherStorage<T>(M, false)) {}
> +
> +  /// \brief Construct from a bindable \c Matcher<T>. Copies the matcher.
> +  ///
> +  /// This version enables \c tryBind() on the \c DynTypedMatcher.
> +  template <typename T>
> +  DynTypedMatcher(const BindableMatcher<T> &M)
> +      : Storage(new TypedMatcherStorage<T>(M, true)) {}
> +
> +  /// \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;
> +  };
> +
> +  template <typename T> class 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;
> +  };
> +
> +  /// \brief Simple MatcherInterface<T> wrapper around a DynTypedMatcher.
> +  template <typename T> class WrappedMatcher;
> +
> +  IntrusiveRefCntPtr<const MatcherStorage> Storage;
> +};
> +
> +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 +469,15 @@ Matcher<QualType>::canConstructFrom(cons
>  }
>
>  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 +1023,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 +1115,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 +1125,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 +1137,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 +1231,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 +1267,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
>
> Modified: cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h?rev=193100&r1=193099&r2=193100&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h (original)
> +++ cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h Mon Oct 21
> 13:40:51 2013
> @@ -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.
>    ///
>
> Modified: cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h?rev=193100&r1=193099&r2=193100&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h (original)
> +++ cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h Mon Oct 21
> 13:40:51 2013
> @@ -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;
>      }
>
>
> Modified: cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp?rev=193100&r1=193099&r2=193100&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp (original)
> +++ cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp Mon Oct 21 13:40:51 2013
> @@ -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::TraverseNestedName
>  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::~P
>
>  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() {
>
> Modified: cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp?rev=193100&r1=193099&r2=193100&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp (original)
> +++ cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp Mon Oct 21 13:40:51
> 2013
> @@ -26,25 +26,23 @@ void BoundNodesTreeBuilder::visitMatches
>    }
>  }
>
> +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_typ
>  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_ty
>  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;
>      }
>
> Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h?rev=193100&r1=193099&r2=193100&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h (original)
> +++ cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h Mon Oct 21 13:40:51
> 2013
> @@ -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;
>  }
>
>
> Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp?rev=193100&r1=193099&r2=193100&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp (original)
> +++ cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp Mon Oct 21 13:40:51 2013
> @@ -390,29 +390,29 @@ bool Parser::parseExpression(StringRef C
>    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
>
> Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp?rev=193100&r1=193099&r2=193100&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp (original)
> +++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp Mon Oct 21 13:40:51 2013
> @@ -329,10 +329,10 @@ VariantMatcher Registry::constructBoundM
>    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);
>      }
>    }
>
> Modified: cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp?rev=193100&r1=193099&r2=193100&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp (original)
> +++ cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp Mon Oct 21 13:40:51
> 2013
> @@ -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::SingleMat
>  }
>
>  VariantMatcher
> -VariantMatcher::PolymorphicMatcher(ArrayRef<const DynTypedMatcher *>
> Matchers) {
> +VariantMatcher::PolymorphicMatcher(ArrayRef<DynTypedMatcher> Matchers) {
>    return VariantMatcher(new PolymorphicPayload(Matchers));
>  }
>
> @@ -138,9 +131,8 @@ VariantMatcher VariantMatcher::VariadicO
>    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(); }
>
> Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp?rev=193100&r1=193099&r2=193100&view=diff
>
> ==============================================================================
> --- cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp (original)
> +++ cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp Mon Oct 21
> 13:40:51 2013
> @@ -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 &Ran
>           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"
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131021/afe95310/attachment.html>


More information about the cfe-commits mailing list