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

Reid Kleckner rnk at google.com
Mon Oct 21 15:37:05 PDT 2013


Reverted in r193123, since I wasn't sure how to fix it.


On Mon, Oct 21, 2013 at 3:00 PM, Reid Kleckner <rnk at google.com> wrote:

> 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/bed1a312/attachment.html>


More information about the cfe-commits mailing list