<div dir="ltr">This isn't working with MSVC 2012:<div><a href="http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/5646/steps/build_clang/logs/stdio">http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/5646/steps/build_clang/logs/stdio</a><br>
</div><div><br></div><div><div>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'</div>
</div><div><br></div><div>This is found while instantiating Optional<DynTypedMatcher>.</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Oct 21, 2013 at 11:40 AM, Samuel Benzaquen <span dir="ltr"><<a href="mailto:sbenza@google.com" target="_blank">sbenza@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: sbenza<br>
Date: Mon Oct 21 13:40:51 2013<br>
New Revision: 193100<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=193100&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=193100&view=rev</a><br>
Log:<br>
Refactor DynTypedMatcher into a value type class, just like Matcher<T>.<br>
<br>
Summary:<br>
Refactor DynTypedMatcher into a value type class, just like Matcher<T>.<br>
This simplifies its usage and removes the virtual hierarchy from Matcher<T>.<br>
It also enables planned changes to replace MatcherInteface<T>.<br>
Too many instantiaions of this class hierarchy has been causing Registry.cpp.o to bloat in size and number of symbols.<br>
<br>
Reviewers: klimek<br>
<br>
CC: cfe-commits, revane<br>
<br>
Differential Revision: <a href="http://llvm-reviews.chandlerc.com/D1661" target="_blank">http://llvm-reviews.chandlerc.com/D1661</a><br>
<br>
Modified:<br>
cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h<br>
cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h<br>
cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h<br>
cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h<br>
cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp<br>
cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp<br>
cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h<br>
cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp<br>
cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp<br>
cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp<br>
cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp<br>
<br>
Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h?rev=193100&r1=193099&r2=193100&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h?rev=193100&r1=193099&r2=193100&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h (original)<br>
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h Mon Oct 21 13:40:51 2013<br>
@@ -162,7 +162,7 @@ public:<br>
private:<br>
/// \brief For each \c DynTypedMatcher a \c MatchCallback that will be called<br>
/// when it matches.<br>
- std::vector<std::pair<const internal::DynTypedMatcher*, MatchCallback*> ><br>
+ std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> ><br>
MatcherCallbackPairs;<br>
<br>
/// \brief Called when parsing is done.<br>
<br>
Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=193100&r1=193099&r2=193100&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=193100&r1=193099&r2=193100&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original)<br>
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Mon Oct 21 13:40:51 2013<br>
@@ -36,12 +36,13 @@<br>
#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H<br>
<br>
#include "clang/AST/ASTTypeTraits.h"<br>
-#include "clang/AST/DeclCXX.h"<br>
#include "clang/AST/Decl.h"<br>
+#include "clang/AST/DeclCXX.h"<br>
#include "clang/AST/ExprCXX.h"<br>
-#include "clang/AST/StmtCXX.h"<br>
#include "clang/AST/Stmt.h"<br>
+#include "clang/AST/StmtCXX.h"<br>
#include "clang/AST/Type.h"<br>
+#include "llvm/ADT/Optional.h"<br>
#include "llvm/ADT/VariadicFunction.h"<br>
#include "llvm/Support/type_traits.h"<br>
#include <map><br>
@@ -200,38 +201,6 @@ private:<br>
}<br>
};<br>
<br>
-/// \brief Base class for all matchers that works on a \c DynTypedNode.<br>
-///<br>
-/// Matcher implementations will check whether the \c DynTypedNode is<br>
-/// convertible into the respecitve types and then do the actual match<br>
-/// on the actual node, or return false if it is not convertible.<br>
-class DynTypedMatcher {<br>
-public:<br>
- virtual ~DynTypedMatcher();<br>
-<br>
- /// \brief Returns true if the matcher matches the given \c DynNode.<br>
- virtual bool matches(const ast_type_traits::DynTypedNode DynNode,<br>
- ASTMatchFinder *Finder,<br>
- BoundNodesTreeBuilder *Builder) const = 0;<br>
-<br>
- /// \brief Makes a copy of this matcher object.<br>
- virtual DynTypedMatcher *clone() const = 0;<br>
-<br>
- /// \brief Returns a unique ID for the matcher.<br>
- virtual uint64_t getID() const = 0;<br>
-<br>
- /// \brief Bind the specified \p ID to the matcher.<br>
- /// \return A new matcher with the \p ID bound to it if this matcher supports<br>
- /// binding. Otherwise, returns NULL. Returns NULL by default.<br>
- virtual DynTypedMatcher* tryBind(StringRef ID) const;<br>
-<br>
- /// \brief Returns the type this matcher works on.<br>
- ///<br>
- /// \c matches() will always return false unless the node passed is of this<br>
- /// or a derived type.<br>
- virtual ast_type_traits::ASTNodeKind getSupportedKind() const = 0;<br>
-};<br>
-<br>
/// \brief Wrapper of a MatcherInterface<T> *that allows copying.<br>
///<br>
/// A Matcher<Base> can be used anywhere a Matcher<Derived> is<br>
@@ -241,7 +210,7 @@ public:<br>
/// operator rather than a type hierarchy to be able to templatize the<br>
/// type hierarchy instead of spelling it out.<br>
template <typename T><br>
-class Matcher : public DynTypedMatcher {<br>
+class Matcher {<br>
public:<br>
/// \brief Takes ownership of the provided implementation pointer.<br>
explicit Matcher(MatcherInterface<T> *Implementation)<br>
@@ -267,35 +236,6 @@ public:<br>
llvm::is_same<TypeT, Type>::value >::type* = 0)<br>
: Implementation(new TypeToQualType<TypeT>(Other)) {}<br>
<br>
- /// \brief Returns \c true if the passed DynTypedMatcher can be converted<br>
- /// to a \c Matcher<T>.<br>
- ///<br>
- /// This method verifies that the underlying matcher in \c Other can process<br>
- /// nodes of types T.<br>
- static bool canConstructFrom(const DynTypedMatcher &Other) {<br>
- return Other.getSupportedKind()<br>
- .isBaseOf(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());<br>
- }<br>
-<br>
- /// \brief Construct a Matcher<T> interface around the dynamic matcher<br>
- /// \c Other.<br>
- ///<br>
- /// This method asserts that canConstructFrom(Other) is \c true. Callers<br>
- /// should call canConstructFrom(Other) first to make sure that Other is<br>
- /// compatible with T.<br>
- static Matcher<T> constructFrom(const DynTypedMatcher &Other) {<br>
- assert(canConstructFrom(Other));<br>
- return constructFromUnsafe(Other);<br>
- }<br>
-<br>
- /// \brief Same as constructFrom(), but does not check that the underlying<br>
- /// matcher can handle a value of T.<br>
- ///<br>
- /// If it is not compatible, then this matcher will never match anything.<br>
- static Matcher<T> constructFromUnsafe(const DynTypedMatcher &Other) {<br>
- return Matcher<T>(new WrappedMatcher(Other));<br>
- }<br>
-<br>
/// \brief Forwards the call to the underlying MatcherInterface<T> pointer.<br>
bool matches(const T &Node,<br>
ASTMatchFinder *Finder,<br>
@@ -316,23 +256,6 @@ public:<br>
return reinterpret_cast<uint64_t>(Implementation.getPtr());<br>
}<br>
<br>
- /// \brief Returns the type this matcher works on.<br>
- ast_type_traits::ASTNodeKind getSupportedKind() const {<br>
- return ast_type_traits::ASTNodeKind::getFromNodeKind<T>();<br>
- }<br>
-<br>
- /// \brief Returns whether the matcher matches on the given \c DynNode.<br>
- virtual bool matches(const ast_type_traits::DynTypedNode DynNode,<br>
- ASTMatchFinder *Finder,<br>
- BoundNodesTreeBuilder *Builder) const {<br>
- const T *Node = DynNode.get<T>();<br>
- if (!Node) return false;<br>
- return matches(*Node, Finder, Builder);<br>
- }<br>
-<br>
- /// \brief Makes a copy of this matcher object.<br>
- virtual Matcher<T> *clone() const { return new Matcher<T>(*this); }<br>
-<br>
/// \brief Allows the conversion of a \c Matcher<Type> to a \c<br>
/// Matcher<QualType>.<br>
///<br>
@@ -375,23 +298,6 @@ private:<br>
const Matcher<Base> From;<br>
};<br>
<br>
- /// \brief Simple MatcherInterface<T> wrapper around a DynTypedMatcher.<br>
- class WrappedMatcher : public MatcherInterface<T> {<br>
- public:<br>
- explicit WrappedMatcher(const DynTypedMatcher &Matcher)<br>
- : Inner(Matcher.clone()) {}<br>
- virtual ~WrappedMatcher() {}<br>
-<br>
- bool matches(const T &Node, ASTMatchFinder *Finder,<br>
- BoundNodesTreeBuilder *Builder) const {<br>
- return Inner->matches(ast_type_traits::DynTypedNode::create(Node), Finder,<br>
- Builder);<br>
- }<br>
-<br>
- private:<br>
- const OwningPtr<DynTypedMatcher> Inner;<br>
- };<br>
-<br>
IntrusiveRefCntPtr< MatcherInterface<T> > Implementation;<br>
}; // class Matcher<br>
<br>
@@ -402,15 +308,160 @@ inline Matcher<T> makeMatcher(MatcherInt<br>
return Matcher<T>(Implementation);<br>
}<br>
<br>
+template <typename T> class BindableMatcher;<br>
+<br>
+/// \brief Matcher that works on a \c DynTypedNode.<br>
+///<br>
+/// It is constructed from a \c Matcher<T> object and redirects most calls to<br>
+/// underlying matcher.<br>
+/// It checks whether the \c DynTypedNode is convertible into the type of the<br>
+/// underlying matcher and then do the actual match on the actual node, or<br>
+/// return false if it is not convertible.<br>
+class DynTypedMatcher {<br>
+public:<br>
+ /// \brief Construct from a \c Matcher<T>. Copies the matcher.<br>
+ template <typename T><br>
+ DynTypedMatcher(const Matcher<T> &M)<br>
+ : Storage(new TypedMatcherStorage<T>(M, false)) {}<br>
+<br>
+ /// \brief Construct from a bindable \c Matcher<T>. Copies the matcher.<br>
+ ///<br>
+ /// This version enables \c tryBind() on the \c DynTypedMatcher.<br>
+ template <typename T><br>
+ DynTypedMatcher(const BindableMatcher<T> &M)<br>
+ : Storage(new TypedMatcherStorage<T>(M, true)) {}<br>
+<br>
+ /// \brief Returns true if the matcher matches the given \c DynNode.<br>
+ bool matches(const ast_type_traits::DynTypedNode DynNode,<br>
+ ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const {<br>
+ return Storage->matches(DynNode, Finder, Builder);<br>
+ }<br>
+<br>
+ /// \brief Bind the specified \p ID to the matcher.<br>
+ /// \return A new matcher with the \p ID bound to it if this matcher supports<br>
+ /// binding. Otherwise, returns an empty \c Optional<>.<br>
+ llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const {<br>
+ return Storage->tryBind(ID);<br>
+ }<br>
+<br>
+ /// \brief Returns a unique \p ID for the matcher.<br>
+ uint64_t getID() const { return Storage->getID(); }<br>
+<br>
+ /// \brief Returns the type this matcher works on.<br>
+ ///<br>
+ /// \c matches() will always return false unless the node passed is of this<br>
+ /// or a derived type.<br>
+ ast_type_traits::ASTNodeKind getSupportedKind() const {<br>
+ return Storage->getSupportedKind();<br>
+ }<br>
+<br>
+ /// \brief Returns \c true if the passed \c DynTypedMatcher can be converted<br>
+ /// to a \c Matcher<T>.<br>
+ ///<br>
+ /// This method verifies that the underlying matcher in \c Other can process<br>
+ /// nodes of types T.<br>
+ template <typename T> bool canConvertTo() const {<br>
+ return getSupportedKind().isBaseOf(<br>
+ ast_type_traits::ASTNodeKind::getFromNodeKind<T>());<br>
+ }<br>
+<br>
+ /// \brief Construct a \c Matcher<T> interface around the dynamic matcher.<br>
+ ///<br>
+ /// This method asserts that \c canConvertTo() is \c true. Callers<br>
+ /// should call \c canConvertTo() first to make sure that \c this is<br>
+ /// compatible with T.<br>
+ template <typename T> Matcher<T> convertTo() const {<br>
+ assert(canConvertTo<T>());<br>
+ return unconditionalConvertTo<T>();<br>
+ }<br>
+<br>
+ /// \brief Same as \c convertTo(), but does not check that the underlying<br>
+ /// matcher can handle a value of T.<br>
+ ///<br>
+ /// If it is not compatible, then this matcher will never match anything.<br>
+ template <typename T> Matcher<T> unconditionalConvertTo() const {<br>
+ return Matcher<T>(new WrappedMatcher<T>(*this));<br>
+ }<br>
+<br>
+private:<br>
+ class MatcherStorage : public RefCountedBaseVPTR {<br>
+ public:<br>
+ MatcherStorage(ast_type_traits::ASTNodeKind SupportedKind, uint64_t ID)<br>
+ : SupportedKind(SupportedKind), ID(ID) {}<br>
+ virtual ~MatcherStorage();<br>
+<br>
+ virtual bool matches(const ast_type_traits::DynTypedNode DynNode,<br>
+ ASTMatchFinder *Finder,<br>
+ BoundNodesTreeBuilder *Builder) const = 0;<br>
+<br>
+ virtual llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const = 0;<br>
+<br>
+ ast_type_traits::ASTNodeKind getSupportedKind() const {<br>
+ return SupportedKind;<br>
+ }<br>
+<br>
+ uint64_t getID() const { return ID; }<br>
+<br>
+ private:<br>
+ const ast_type_traits::ASTNodeKind SupportedKind;<br>
+ const uint64_t ID;<br>
+ };<br>
+<br>
+ template <typename T> class TypedMatcherStorage : public MatcherStorage {<br>
+ public:<br>
+ TypedMatcherStorage(const Matcher<T> &Other, bool AllowBind)<br>
+ : MatcherStorage(ast_type_traits::ASTNodeKind::getFromNodeKind<T>(),<br>
+ Other.getID()),<br>
+ InnerMatcher(Other), AllowBind(AllowBind) {}<br>
+<br>
+ bool matches(const ast_type_traits::DynTypedNode DynNode,<br>
+ ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const<br>
+ LLVM_OVERRIDE {<br>
+ if (const T *Node = DynNode.get<T>()) {<br>
+ return InnerMatcher.matches(*Node, Finder, Builder);<br>
+ }<br>
+ return false;<br>
+ }<br>
+<br>
+ llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const LLVM_OVERRIDE {<br>
+ if (!AllowBind)<br>
+ return llvm::Optional<DynTypedMatcher>();<br>
+ return DynTypedMatcher(BindableMatcher<T>(InnerMatcher).bind(ID));<br>
+ }<br>
+<br>
+ private:<br>
+ const Matcher<T> InnerMatcher;<br>
+ const bool AllowBind;<br>
+ };<br>
+<br>
+ /// \brief Simple MatcherInterface<T> wrapper around a DynTypedMatcher.<br>
+ template <typename T> class WrappedMatcher;<br>
+<br>
+ IntrusiveRefCntPtr<const MatcherStorage> Storage;<br>
+};<br>
+<br>
+template <typename T><br>
+class DynTypedMatcher::WrappedMatcher : public MatcherInterface<T> {<br>
+public:<br>
+ explicit WrappedMatcher(const DynTypedMatcher &Matcher) : Inner(Matcher) {}<br>
+ virtual ~WrappedMatcher() {}<br>
+<br>
+ bool matches(const T &Node, ASTMatchFinder *Finder,<br>
+ BoundNodesTreeBuilder *Builder) const {<br>
+ return Inner.matches(ast_type_traits::DynTypedNode::create(Node), Finder,<br>
+ Builder);<br>
+ }<br>
+<br>
+private:<br>
+ const DynTypedMatcher Inner;<br>
+};<br>
+<br>
/// \brief Specialization of the conversion functions for QualType.<br>
///<br>
/// These specializations provide the Matcher<Type>->Matcher<QualType><br>
/// conversion that the static API does.<br>
-template <><br>
-inline bool<br>
-Matcher<QualType>::canConstructFrom(const DynTypedMatcher &Other) {<br>
- ast_type_traits::ASTNodeKind SourceKind = Other.getSupportedKind();<br>
- // We support implicit conversion from Matcher<Type> to Matcher<QualType><br>
+template <> inline bool DynTypedMatcher::canConvertTo<QualType>() const {<br>
+ const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();<br>
return SourceKind.isSame(<br>
ast_type_traits::ASTNodeKind::getFromNodeKind<Type>()) ||<br>
SourceKind.isSame(<br>
@@ -418,16 +469,15 @@ Matcher<QualType>::canConstructFrom(cons<br>
}<br>
<br>
template <><br>
-inline Matcher<QualType><br>
-Matcher<QualType>::constructFrom(const DynTypedMatcher &Other) {<br>
- assert(canConstructFrom(Other));<br>
- ast_type_traits::ASTNodeKind SourceKind = Other.getSupportedKind();<br>
+inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const {<br>
+ assert(canConvertTo<QualType>());<br>
+ const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();<br>
if (SourceKind.isSame(<br>
ast_type_traits::ASTNodeKind::getFromNodeKind<Type>())) {<br>
// We support implicit conversion from Matcher<Type> to Matcher<QualType><br>
- return Matcher<Type>::constructFrom(Other);<br>
+ return unconditionalConvertTo<Type>();<br>
}<br>
- return makeMatcher(new WrappedMatcher(Other));<br>
+ return unconditionalConvertTo<QualType>();<br>
}<br>
<br>
/// \brief Finds the first node in a range that matches the given matcher.<br>
@@ -973,16 +1023,6 @@ public:<br>
Matcher<T> bind(StringRef ID) const {<br>
return Matcher<T>(new IdMatcher<T>(ID, *this));<br>
}<br>
-<br>
- /// \brief Makes a copy of this matcher object.<br>
- virtual BindableMatcher<T>* clone() const {<br>
- return new BindableMatcher<T>(*this);<br>
- }<br>
-<br>
- /// \brief Bind the specified \c ID to the matcher.<br>
- virtual Matcher<T>* tryBind(StringRef ID) const {<br>
- return new Matcher<T>(bind(ID));<br>
- }<br>
};<br>
<br>
/// \brief Matches nodes of type T that have child nodes of type ChildT for<br>
@@ -1075,8 +1115,7 @@ private:<br>
/// matchers as an array of DynTypedMatcher.<br>
typedef bool (*VariadicOperatorFunction)(<br>
const ast_type_traits::DynTypedNode DynNode, ASTMatchFinder *Finder,<br>
- BoundNodesTreeBuilder *Builder,<br>
- ArrayRef<const DynTypedMatcher *> InnerMatchers);<br>
+ BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);<br>
<br>
/// \brief \c MatcherInterface<T> implementation for an variadic operator.<br>
template <typename T><br>
@@ -1086,14 +1125,10 @@ public:<br>
ArrayRef<const Matcher<T> *> InputMatchers)<br>
: Func(Func) {<br>
for (size_t i = 0, e = InputMatchers.size(); i != e; ++i) {<br>
- InnerMatchers.push_back(new Matcher<T>(*InputMatchers[i]));<br>
+ InnerMatchers.push_back(*InputMatchers[i]);<br>
}<br>
}<br>
<br>
- ~VariadicOperatorMatcherInterface() {<br>
- llvm::DeleteContainerPointers(InnerMatchers);<br>
- }<br>
-<br>
virtual bool matches(const T &Node, ASTMatchFinder *Finder,<br>
BoundNodesTreeBuilder *Builder) const {<br>
return Func(ast_type_traits::DynTypedNode::create(Node), Finder, Builder,<br>
@@ -1102,7 +1137,7 @@ public:<br>
<br>
private:<br>
const VariadicOperatorFunction Func;<br>
- std::vector<const DynTypedMatcher *> InnerMatchers;<br>
+ std::vector<DynTypedMatcher> InnerMatchers;<br>
};<br>
<br>
/// \brief "No argument" placeholder to use as template paratemers.<br>
@@ -1196,24 +1231,24 @@ struct VariadicOperatorMatcherFunc {<br>
/// @}<br>
<br>
/// \brief Matches nodes for which all provided matchers match.<br>
-bool<br>
-AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,<br>
- ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,<br>
- ArrayRef<const DynTypedMatcher *> InnerMatchers);<br>
+bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,<br>
+ ASTMatchFinder *Finder,<br>
+ BoundNodesTreeBuilder *Builder,<br>
+ ArrayRef<DynTypedMatcher> InnerMatchers);<br>
<br>
/// \brief Matches nodes for which at least one of the provided matchers<br>
/// matches, but doesn't stop at the first match.<br>
-bool<br>
-EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,<br>
- ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,<br>
- ArrayRef<const DynTypedMatcher *> InnerMatchers);<br>
+bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,<br>
+ ASTMatchFinder *Finder,<br>
+ BoundNodesTreeBuilder *Builder,<br>
+ ArrayRef<DynTypedMatcher> InnerMatchers);<br>
<br>
/// \brief Matches nodes for which at least one of the provided matchers<br>
/// matches.<br>
-bool<br>
-AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,<br>
- ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,<br>
- ArrayRef<const DynTypedMatcher *> InnerMatchers);<br>
+bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,<br>
+ ASTMatchFinder *Finder,<br>
+ BoundNodesTreeBuilder *Builder,<br>
+ ArrayRef<DynTypedMatcher> InnerMatchers);<br>
<br>
/// \brief Creates a Matcher<T> that matches if all inner matchers match.<br>
template<typename T><br>
@@ -1232,8 +1267,8 @@ BindableMatcher<T> makeAllOfComposite(<br>
template<typename T, typename InnerT><br>
BindableMatcher<T> makeDynCastAllOfComposite(<br>
ArrayRef<const Matcher<InnerT> *> InnerMatchers) {<br>
- return BindableMatcher<T>(<br>
- Matcher<T>::constructFromUnsafe(makeAllOfComposite(InnerMatchers)));<br>
+ return BindableMatcher<T>(DynTypedMatcher(makeAllOfComposite(InnerMatchers))<br>
+ .unconditionalConvertTo<T>());<br>
}<br>
<br>
/// \brief Matches nodes of type T that have at least one descendant node of<br>
<br>
Modified: cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h?rev=193100&r1=193099&r2=193100&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h?rev=193100&r1=193099&r2=193100&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h (original)<br>
+++ cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h Mon Oct 21 13:40:51 2013<br>
@@ -37,6 +37,7 @@<br>
#include "clang/ASTMatchers/Dynamic/VariantValue.h"<br>
#include "clang/Basic/LLVM.h"<br>
#include "llvm/ADT/ArrayRef.h"<br>
+#include "llvm/ADT/Optional.h"<br>
#include "llvm/ADT/StringRef.h"<br>
<br>
namespace clang {<br>
@@ -92,11 +93,12 @@ public:<br>
///<br>
/// \param MatcherCode The matcher expression to parse.<br>
///<br>
- /// \return The matcher object constructed, or NULL if an error occurred.<br>
- // In that case, \c Error will contain a description of the error.<br>
+ /// \return The matcher object constructed, or an empty Optional if an error<br>
+ /// occurred.<br>
+ /// In that case, \c Error will contain a description of the error.<br>
/// The caller takes ownership of the DynTypedMatcher object returned.<br>
- static DynTypedMatcher *parseMatcherExpression(StringRef MatcherCode,<br>
- Diagnostics *Error);<br>
+ static llvm::Optional<DynTypedMatcher><br>
+ parseMatcherExpression(StringRef MatcherCode, Diagnostics *Error);<br>
<br>
/// \brief Parse a matcher expression.<br>
///<br>
@@ -104,13 +106,12 @@ public:<br>
///<br>
/// \param S The Sema instance that will help the parser<br>
/// construct the matchers.<br>
- /// \return The matcher object constructed by the processor, or NULL<br>
- /// if an error occurred. In that case, \c Error will contain a<br>
+ /// \return The matcher object constructed by the processor, or an empty<br>
+ /// Optional if an error occurred. In that case, \c Error will contain a<br>
/// description of the error.<br>
/// The caller takes ownership of the DynTypedMatcher object returned.<br>
- static DynTypedMatcher *parseMatcherExpression(StringRef MatcherCode,<br>
- Sema *S,<br>
- Diagnostics *Error);<br>
+ static llvm::Optional<DynTypedMatcher><br>
+ parseMatcherExpression(StringRef MatcherCode, Sema *S, Diagnostics *Error);<br>
<br>
/// \brief Parse an expression, creating matchers from the registry.<br>
///<br>
<br>
Modified: cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h?rev=193100&r1=193099&r2=193100&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h?rev=193100&r1=193099&r2=193100&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h (original)<br>
+++ cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h Mon Oct 21 13:40:51 2013<br>
@@ -22,6 +22,7 @@<br>
#include "clang/ASTMatchers/ASTMatchers.h"<br>
#include "clang/ASTMatchers/ASTMatchersInternal.h"<br>
#include "llvm/ADT/IntrusiveRefCntPtr.h"<br>
+#include "llvm/ADT/Optional.h"<br>
#include "llvm/ADT/Twine.h"<br>
#include "llvm/Support/type_traits.h"<br>
<br>
@@ -62,7 +63,7 @@ class VariantMatcher {<br>
class Payload : public RefCountedBaseVPTR {<br>
public:<br>
virtual ~Payload();<br>
- virtual bool getSingleMatcher(const DynTypedMatcher *&Out) const = 0;<br>
+ virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;<br>
virtual std::string getTypeAsString() const = 0;<br>
virtual void makeTypedMatcher(MatcherOps &Ops) const = 0;<br>
};<br>
@@ -77,8 +78,7 @@ public:<br>
/// \brief Clones the provided matchers.<br>
///<br>
/// They should be the result of a polymorphic matcher.<br>
- static VariantMatcher<br>
- PolymorphicMatcher(ArrayRef<const DynTypedMatcher *> Matchers);<br>
+ static VariantMatcher PolymorphicMatcher(ArrayRef<DynTypedMatcher> Matchers);<br>
<br>
/// \brief Creates a 'variadic' operator matcher.<br>
///<br>
@@ -95,10 +95,10 @@ public:<br>
<br>
/// \brief Return a single matcher, if there is no ambiguity.<br>
///<br>
- /// \returns \c true, and set Out to the matcher, if there is only one<br>
- /// matcher. \c false, if the underlying matcher is a polymorphic matcher with<br>
- /// more than one representation.<br>
- bool getSingleMatcher(const DynTypedMatcher *&Out) const;<br>
+ /// \returns the matcher, if there is only one matcher. An empty Optional, if<br>
+ /// the underlying matcher is a polymorphic matcher with more than one<br>
+ /// representation.<br>
+ llvm::Optional<DynTypedMatcher> getSingleMatcher() const;<br>
<br>
/// \brief Determines if the contained matcher can be converted to<br>
/// \c Matcher<T>.<br>
@@ -146,11 +146,11 @@ private:<br>
typedef ast_matchers::internal::Matcher<T> MatcherT;<br>
<br>
virtual bool canConstructFrom(const DynTypedMatcher &Matcher) const {<br>
- return MatcherT::canConstructFrom(Matcher);<br>
+ return Matcher.canConvertTo<T>();<br>
}<br>
<br>
virtual void constructFrom(const DynTypedMatcher& Matcher) {<br>
- Out.reset(new MatcherT(MatcherT::constructFrom(Matcher)));<br>
+ Out.reset(new MatcherT(Matcher.convertTo<T>()));<br>
}<br>
<br>
virtual void constructVariadicOperator(<br>
@@ -173,7 +173,9 @@ private:<br>
new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(<br>
Func, ArrayRef<const MatcherT *>(InnerArgs, NumArgs))));<br>
}<br>
- std::for_each(InnerArgs, InnerArgs + NumArgs, llvm::deleter<MatcherT>);<br>
+ for (size_t i = 0; i != NumArgs; ++i) {<br>
+ delete InnerArgs[i];<br>
+ }<br>
delete[] InnerArgs;<br>
}<br>
<br>
<br>
Modified: cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp?rev=193100&r1=193099&r2=193100&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp?rev=193100&r1=193099&r2=193100&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp (original)<br>
+++ cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp Mon Oct 21 13:40:51 2013<br>
@@ -295,25 +295,26 @@ private:<br>
class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,<br>
public ASTMatchFinder {<br>
public:<br>
- MatchASTVisitor(std::vector<std::pair<const internal::DynTypedMatcher*,<br>
- MatchCallback*> > *MatcherCallbackPairs)<br>
- : MatcherCallbackPairs(MatcherCallbackPairs),<br>
- ActiveASTContext(NULL) {<br>
- }<br>
+ MatchASTVisitor(<br>
+ std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> > *<br>
+ MatcherCallbackPairs)<br>
+ : MatcherCallbackPairs(MatcherCallbackPairs), ActiveASTContext(NULL) {}<br>
<br>
void onStartOfTranslationUnit() {<br>
- for (std::vector<std::pair<const internal::DynTypedMatcher*,<br>
- MatchCallback*> >::const_iterator<br>
- I = MatcherCallbackPairs->begin(), E = MatcherCallbackPairs->end();<br>
+ for (std::vector<std::pair<internal::DynTypedMatcher,<br>
+ MatchCallback *> >::const_iterator<br>
+ I = MatcherCallbackPairs->begin(),<br>
+ E = MatcherCallbackPairs->end();<br>
I != E; ++I) {<br>
I->second->onStartOfTranslationUnit();<br>
}<br>
}<br>
<br>
void onEndOfTranslationUnit() {<br>
- for (std::vector<std::pair<const internal::DynTypedMatcher*,<br>
- MatchCallback*> >::const_iterator<br>
- I = MatcherCallbackPairs->begin(), E = MatcherCallbackPairs->end();<br>
+ for (std::vector<std::pair<internal::DynTypedMatcher,<br>
+ MatchCallback *> >::const_iterator<br>
+ I = MatcherCallbackPairs->begin(),<br>
+ E = MatcherCallbackPairs->end();<br>
I != E; ++I) {<br>
I->second->onEndOfTranslationUnit();<br>
}<br>
@@ -450,12 +451,13 @@ public:<br>
// Matches all registered matchers on the given node and calls the<br>
// result callback for every node that matches.<br>
void match(const ast_type_traits::DynTypedNode& Node) {<br>
- for (std::vector<std::pair<const internal::DynTypedMatcher*,<br>
- MatchCallback*> >::const_iterator<br>
- I = MatcherCallbackPairs->begin(), E = MatcherCallbackPairs->end();<br>
+ for (std::vector<std::pair<internal::DynTypedMatcher,<br>
+ MatchCallback *> >::const_iterator<br>
+ I = MatcherCallbackPairs->begin(),<br>
+ E = MatcherCallbackPairs->end();<br>
I != E; ++I) {<br>
BoundNodesTreeBuilder Builder;<br>
- if (I->first->matches(Node, this, &Builder)) {<br>
+ if (I->first.matches(Node, this, &Builder)) {<br>
MatchVisitor Visitor(ActiveASTContext, I->second);<br>
Builder.visitMatches(&Visitor);<br>
}<br>
@@ -603,8 +605,8 @@ private:<br>
return false;<br>
}<br>
<br>
- std::vector<std::pair<const internal::DynTypedMatcher*,<br>
- MatchCallback*> > *const MatcherCallbackPairs;<br>
+ std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> > *const<br>
+ MatcherCallbackPairs;<br>
ASTContext *ActiveASTContext;<br>
<br>
// Maps a canonical type to its TypedefDecls.<br>
@@ -743,11 +745,10 @@ bool MatchASTVisitor::TraverseNestedName<br>
class MatchASTConsumer : public ASTConsumer {<br>
public:<br>
MatchASTConsumer(<br>
- std::vector<std::pair<const internal::DynTypedMatcher*,<br>
- MatchCallback*> > *MatcherCallbackPairs,<br>
- MatchFinder::ParsingDoneTestCallback *ParsingDone)<br>
- : Visitor(MatcherCallbackPairs),<br>
- ParsingDone(ParsingDone) {}<br>
+ std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> > *<br>
+ MatcherCallbackPairs,<br>
+ MatchFinder::ParsingDoneTestCallback *ParsingDone)<br>
+ : Visitor(MatcherCallbackPairs), ParsingDone(ParsingDone) {}<br>
<br>
private:<br>
virtual void HandleTranslationUnit(ASTContext &Context) {<br>
@@ -778,49 +779,36 @@ MatchFinder::ParsingDoneTestCallback::~P<br>
<br>
MatchFinder::MatchFinder() : ParsingDone(NULL) {}<br>
<br>
-MatchFinder::~MatchFinder() {<br>
- for (std::vector<std::pair<const internal::DynTypedMatcher*,<br>
- MatchCallback*> >::const_iterator<br>
- It = MatcherCallbackPairs.begin(), End = MatcherCallbackPairs.end();<br>
- It != End; ++It) {<br>
- delete It->first;<br>
- }<br>
-}<br>
+MatchFinder::~MatchFinder() {}<br>
<br>
void MatchFinder::addMatcher(const DeclarationMatcher &NodeMatch,<br>
MatchCallback *Action) {<br>
- MatcherCallbackPairs.push_back(std::make_pair(<br>
- new internal::Matcher<Decl>(NodeMatch), Action));<br>
+ MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));<br>
}<br>
<br>
void MatchFinder::addMatcher(const TypeMatcher &NodeMatch,<br>
MatchCallback *Action) {<br>
- MatcherCallbackPairs.push_back(std::make_pair(<br>
- new internal::Matcher<QualType>(NodeMatch), Action));<br>
+ MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));<br>
}<br>
<br>
void MatchFinder::addMatcher(const StatementMatcher &NodeMatch,<br>
MatchCallback *Action) {<br>
- MatcherCallbackPairs.push_back(std::make_pair(<br>
- new internal::Matcher<Stmt>(NodeMatch), Action));<br>
+ MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));<br>
}<br>
<br>
void MatchFinder::addMatcher(const NestedNameSpecifierMatcher &NodeMatch,<br>
MatchCallback *Action) {<br>
- MatcherCallbackPairs.push_back(std::make_pair(<br>
- new NestedNameSpecifierMatcher(NodeMatch), Action));<br>
+ MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));<br>
}<br>
<br>
void MatchFinder::addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch,<br>
MatchCallback *Action) {<br>
- MatcherCallbackPairs.push_back(std::make_pair(<br>
- new NestedNameSpecifierLocMatcher(NodeMatch), Action));<br>
+ MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));<br>
}<br>
<br>
void MatchFinder::addMatcher(const TypeLocMatcher &NodeMatch,<br>
MatchCallback *Action) {<br>
- MatcherCallbackPairs.push_back(std::make_pair(<br>
- new TypeLocMatcher(NodeMatch), Action));<br>
+ MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));<br>
}<br>
<br>
ASTConsumer *MatchFinder::newASTConsumer() {<br>
<br>
Modified: cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp?rev=193100&r1=193099&r2=193100&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp?rev=193100&r1=193099&r2=193100&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp (original)<br>
+++ cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp Mon Oct 21 13:40:51 2013<br>
@@ -26,25 +26,23 @@ void BoundNodesTreeBuilder::visitMatches<br>
}<br>
}<br>
<br>
+DynTypedMatcher::MatcherStorage::~MatcherStorage() {}<br>
+<br>
void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) {<br>
for (unsigned i = 0, e = Other.Bindings.size(); i != e; ++i) {<br>
Bindings.push_back(Other.Bindings[i]);<br>
}<br>
}<br>
<br>
-DynTypedMatcher::~DynTypedMatcher() {}<br>
-<br>
-DynTypedMatcher *DynTypedMatcher::tryBind(StringRef ID) const { return NULL; }<br>
-<br>
bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,<br>
ASTMatchFinder *Finder,<br>
BoundNodesTreeBuilder *Builder,<br>
- ArrayRef<const DynTypedMatcher *> InnerMatchers) {<br>
+ ArrayRef<DynTypedMatcher> InnerMatchers) {<br>
// allOf leads to one matcher for each alternative in the first<br>
// matcher combined with each alternative in the second matcher.<br>
// Thus, we can reuse the same Builder.<br>
for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {<br>
- if (!InnerMatchers[i]->matches(DynNode, Finder, Builder))<br>
+ if (!InnerMatchers[i].matches(DynNode, Finder, Builder))<br>
return false;<br>
}<br>
return true;<br>
@@ -53,12 +51,12 @@ bool AllOfVariadicOperator(const ast_typ<br>
bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,<br>
ASTMatchFinder *Finder,<br>
BoundNodesTreeBuilder *Builder,<br>
- ArrayRef<const DynTypedMatcher *> InnerMatchers) {<br>
+ ArrayRef<DynTypedMatcher> InnerMatchers) {<br>
BoundNodesTreeBuilder Result;<br>
bool Matched = false;<br>
for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {<br>
BoundNodesTreeBuilder BuilderInner(*Builder);<br>
- if (InnerMatchers[i]->matches(DynNode, Finder, &BuilderInner)) {<br>
+ if (InnerMatchers[i].matches(DynNode, Finder, &BuilderInner)) {<br>
Matched = true;<br>
Result.addMatch(BuilderInner);<br>
}<br>
@@ -70,10 +68,10 @@ bool EachOfVariadicOperator(const ast_ty<br>
bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,<br>
ASTMatchFinder *Finder,<br>
BoundNodesTreeBuilder *Builder,<br>
- ArrayRef<const DynTypedMatcher *> InnerMatchers) {<br>
+ ArrayRef<DynTypedMatcher> InnerMatchers) {<br>
for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {<br>
BoundNodesTreeBuilder Result = *Builder;<br>
- if (InnerMatchers[i]->matches(DynNode, Finder, &Result)) {<br>
+ if (InnerMatchers[i].matches(DynNode, Finder, &Result)) {<br>
*Builder = Result;<br>
return true;<br>
}<br>
<br>
Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h?rev=193100&r1=193099&r2=193100&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h?rev=193100&r1=193099&r2=193100&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h (original)<br>
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h Mon Oct 21 13:40:51 2013<br>
@@ -167,15 +167,13 @@ private:<br>
/// out of the polymorphic object.<br>
template <class PolyMatcher><br>
static void mergePolyMatchers(const PolyMatcher &Poly,<br>
- std::vector<const DynTypedMatcher *> &Out,<br>
+ std::vector<DynTypedMatcher> &Out,<br>
ast_matchers::internal::EmptyTypeList) {}<br>
<br>
template <class PolyMatcher, class TypeList><br>
static void mergePolyMatchers(const PolyMatcher &Poly,<br>
- std::vector<const DynTypedMatcher *> &Out,<br>
- TypeList) {<br>
- Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly)<br>
- .clone());<br>
+ std::vector<DynTypedMatcher> &Out, TypeList) {<br>
+ Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly));<br>
mergePolyMatchers(Poly, Out, typename TypeList::tail());<br>
}<br>
<br>
@@ -193,10 +191,9 @@ template <typename T><br>
static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher,<br>
typename T::ReturnTypes * =<br>
NULL) {<br>
- std::vector<const DynTypedMatcher *> Matchers;<br>
+ std::vector<DynTypedMatcher> Matchers;<br>
mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes());<br>
VariantMatcher Out = VariantMatcher::PolymorphicMatcher(Matchers);<br>
- llvm::DeleteContainerPointers(Matchers);<br>
return Out;<br>
}<br>
<br>
<br>
Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp?rev=193100&r1=193099&r2=193100&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp?rev=193100&r1=193099&r2=193100&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp (original)<br>
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp Mon Oct 21 13:40:51 2013<br>
@@ -390,29 +390,29 @@ bool Parser::parseExpression(StringRef C<br>
return true;<br>
}<br>
<br>
-DynTypedMatcher *Parser::parseMatcherExpression(StringRef Code,<br>
- Diagnostics *Error) {<br>
+llvm::Optional<DynTypedMatcher><br>
+Parser::parseMatcherExpression(StringRef Code, Diagnostics *Error) {<br>
RegistrySema S;<br>
return parseMatcherExpression(Code, &S, Error);<br>
}<br>
<br>
-DynTypedMatcher *Parser::parseMatcherExpression(StringRef Code,<br>
- Parser::Sema *S,<br>
- Diagnostics *Error) {<br>
+llvm::Optional<DynTypedMatcher><br>
+Parser::parseMatcherExpression(StringRef Code, Parser::Sema *S,<br>
+ Diagnostics *Error) {<br>
VariantValue Value;<br>
if (!parseExpression(Code, S, &Value, Error))<br>
- return NULL;<br>
+ return llvm::Optional<DynTypedMatcher>();<br>
if (!Value.isMatcher()) {<br>
Error->addError(SourceRange(), Error->ET_ParserNotAMatcher);<br>
- return NULL;<br>
+ return llvm::Optional<DynTypedMatcher>();<br>
}<br>
- const DynTypedMatcher *Result;<br>
- if (!Value.getMatcher().getSingleMatcher(Result)) {<br>
+ llvm::Optional<DynTypedMatcher> Result =<br>
+ Value.getMatcher().getSingleMatcher();<br>
+ if (!Result.hasValue()) {<br>
Error->addError(SourceRange(), Error->ET_ParserOverloadedType)<br>
<< Value.getTypeAsString();<br>
- return NULL;<br>
}<br>
- return Result->clone();<br>
+ return Result;<br>
}<br>
<br>
} // namespace dynamic<br>
<br>
Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp?rev=193100&r1=193099&r2=193100&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp?rev=193100&r1=193099&r2=193100&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp (original)<br>
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp Mon Oct 21 13:40:51 2013<br>
@@ -329,10 +329,10 @@ VariantMatcher Registry::constructBoundM<br>
VariantMatcher Out = constructMatcher(MatcherName, NameRange, Args, Error);<br>
if (Out.isNull()) return Out;<br>
<br>
- const DynTypedMatcher *Result;<br>
- if (Out.getSingleMatcher(Result)) {<br>
- OwningPtr<DynTypedMatcher> Bound(Result->tryBind(BindID));<br>
- if (Bound) {<br>
+ llvm::Optional<DynTypedMatcher> Result = Out.getSingleMatcher();<br>
+ if (Result.hasValue()) {<br>
+ llvm::Optional<DynTypedMatcher> Bound = Result->tryBind(BindID);<br>
+ if (Bound.hasValue()) {<br>
return VariantMatcher::SingleMatcher(*Bound);<br>
}<br>
}<br>
<br>
Modified: cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp?rev=193100&r1=193099&r2=193100&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp?rev=193100&r1=193099&r2=193100&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp (original)<br>
+++ cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp Mon Oct 21 13:40:51 2013<br>
@@ -26,44 +26,37 @@ VariantMatcher::Payload::~Payload() {}<br>
<br>
class VariantMatcher::SinglePayload : public VariantMatcher::Payload {<br>
public:<br>
- SinglePayload(const DynTypedMatcher &Matcher) : Matcher(Matcher.clone()) {}<br>
+ SinglePayload(const DynTypedMatcher &Matcher) : Matcher(Matcher) {}<br>
<br>
- virtual bool getSingleMatcher(const DynTypedMatcher *&Out) const {<br>
- Out = Matcher.get();<br>
- return true;<br>
+ virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {<br>
+ return Matcher;<br>
}<br>
<br>
virtual std::string getTypeAsString() const {<br>
- return (Twine("Matcher<") + Matcher->getSupportedKind().asStringRef() + ">")<br>
+ return (Twine("Matcher<") + Matcher.getSupportedKind().asStringRef() + ">")<br>
.str();<br>
}<br>
<br>
virtual void makeTypedMatcher(MatcherOps &Ops) const {<br>
- if (Ops.canConstructFrom(*Matcher))<br>
- Ops.constructFrom(*Matcher);<br>
+ if (Ops.canConstructFrom(Matcher))<br>
+ Ops.constructFrom(Matcher);<br>
}<br>
<br>
private:<br>
- OwningPtr<const DynTypedMatcher> Matcher;<br>
+ const DynTypedMatcher Matcher;<br>
};<br>
<br>
class VariantMatcher::PolymorphicPayload : public VariantMatcher::Payload {<br>
public:<br>
- PolymorphicPayload(ArrayRef<const DynTypedMatcher *> MatchersIn) {<br>
- for (size_t i = 0, e = MatchersIn.size(); i != e; ++i) {<br>
- Matchers.push_back(MatchersIn[i]->clone());<br>
- }<br>
- }<br>
+ PolymorphicPayload(ArrayRef<DynTypedMatcher> MatchersIn)<br>
+ : Matchers(MatchersIn) {}<br>
<br>
- virtual ~PolymorphicPayload() {<br>
- llvm::DeleteContainerPointers(Matchers);<br>
- }<br>
+ virtual ~PolymorphicPayload() {}<br>
<br>
- virtual bool getSingleMatcher(const DynTypedMatcher *&Out) const {<br>
+ virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {<br>
if (Matchers.size() != 1)<br>
- return false;<br>
- Out = Matchers[0];<br>
- return true;<br>
+ return llvm::Optional<DynTypedMatcher>();<br>
+ return Matchers[0];<br>
}<br>
<br>
virtual std::string getTypeAsString() const {<br>
@@ -71,7 +64,7 @@ public:<br>
for (size_t i = 0, e = Matchers.size(); i != e; ++i) {<br>
if (i != 0)<br>
Inner += "|";<br>
- Inner += Matchers[i]->getSupportedKind().asStringRef();<br>
+ Inner += Matchers[i].getSupportedKind().asStringRef();<br>
}<br>
return (Twine("Matcher<") + Inner + ">").str();<br>
}<br>
@@ -79,17 +72,17 @@ public:<br>
virtual void makeTypedMatcher(MatcherOps &Ops) const {<br>
const DynTypedMatcher *Found = NULL;<br>
for (size_t i = 0, e = Matchers.size(); i != e; ++i) {<br>
- if (Ops.canConstructFrom(*Matchers[i])) {<br>
+ if (Ops.canConstructFrom(Matchers[i])) {<br>
if (Found)<br>
return;<br>
- Found = Matchers[i];<br>
+ Found = &Matchers[i];<br>
}<br>
}<br>
if (Found)<br>
Ops.constructFrom(*Found);<br>
}<br>
<br>
- std::vector<const DynTypedMatcher *> Matchers;<br>
+ const std::vector<DynTypedMatcher> Matchers;<br>
};<br>
<br>
class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload {<br>
@@ -98,8 +91,8 @@ public:<br>
ArrayRef<VariantMatcher> Args)<br>
: Func(Func), Args(Args) {}<br>
<br>
- virtual bool getSingleMatcher(const DynTypedMatcher *&Out) const {<br>
- return false;<br>
+ virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {<br>
+ return llvm::Optional<DynTypedMatcher>();<br>
}<br>
<br>
virtual std::string getTypeAsString() const {<br>
@@ -128,7 +121,7 @@ VariantMatcher VariantMatcher::SingleMat<br>
}<br>
<br>
VariantMatcher<br>
-VariantMatcher::PolymorphicMatcher(ArrayRef<const DynTypedMatcher *> Matchers) {<br>
+VariantMatcher::PolymorphicMatcher(ArrayRef<DynTypedMatcher> Matchers) {<br>
return VariantMatcher(new PolymorphicPayload(Matchers));<br>
}<br>
<br>
@@ -138,9 +131,8 @@ VariantMatcher VariantMatcher::VariadicO<br>
return VariantMatcher(new VariadicOpPayload(Func, Args));<br>
}<br>
<br>
-bool VariantMatcher::getSingleMatcher(const DynTypedMatcher *&Out) const {<br>
- if (Value) return Value->getSingleMatcher(Out);<br>
- return false;<br>
+llvm::Optional<DynTypedMatcher> VariantMatcher::getSingleMatcher() const {<br>
+ return Value ? Value->getSingleMatcher() : llvm::Optional<DynTypedMatcher>();<br>
}<br>
<br>
void VariantMatcher::reset() { Value.reset(); }<br>
<br>
Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp?rev=193100&r1=193099&r2=193100&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp?rev=193100&r1=193099&r2=193100&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp (original)<br>
+++ cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp Mon Oct 21 13:40:51 2013<br>
@@ -21,51 +21,14 @@ namespace ast_matchers {<br>
namespace dynamic {<br>
namespace {<br>
<br>
-class DummyDynTypedMatcher : public DynTypedMatcher {<br>
-public:<br>
- DummyDynTypedMatcher(uint64_t ID) : ID(ID) {}<br>
- DummyDynTypedMatcher(uint64_t ID, StringRef BoundID)<br>
- : ID(ID), BoundID(BoundID) {}<br>
-<br>
- typedef ast_matchers::internal::ASTMatchFinder ASTMatchFinder;<br>
- typedef ast_matchers::internal::BoundNodesTreeBuilder BoundNodesTreeBuilder;<br>
- virtual bool matches(const ast_type_traits::DynTypedNode DynNode,<br>
- ASTMatchFinder *Finder,<br>
- BoundNodesTreeBuilder *Builder) const {<br>
- return false;<br>
- }<br>
-<br>
- /// \brief Makes a copy of this matcher object.<br>
- virtual DynTypedMatcher *clone() const {<br>
- return new DummyDynTypedMatcher(*this);<br>
- }<br>
-<br>
- /// \brief Returns a unique ID for the matcher.<br>
- virtual uint64_t getID() const { return ID; }<br>
-<br>
- virtual DynTypedMatcher* tryBind(StringRef BoundID) const {<br>
- return new DummyDynTypedMatcher(ID, BoundID);<br>
- }<br>
-<br>
- StringRef boundID() const { return BoundID; }<br>
-<br>
- virtual ast_type_traits::ASTNodeKind getSupportedKind() const {<br>
- return ast_type_traits::ASTNodeKind();<br>
- }<br>
-<br>
-private:<br>
- uint64_t ID;<br>
- std::string BoundID;<br>
-};<br>
-<br>
class MockSema : public Parser::Sema {<br>
public:<br>
virtual ~MockSema() {}<br>
<br>
uint64_t expectMatcher(StringRef MatcherName) {<br>
- uint64_t ID = ExpectedMatchers.size() + 1;<br>
- ExpectedMatchers[MatcherName] = ID;<br>
- return ID;<br>
+ ast_matchers::internal::Matcher<Stmt> M = stmt();<br>
+ ExpectedMatchers.insert(std::make_pair(MatcherName, M));<br>
+ return M.getID();<br>
}<br>
<br>
void parse(StringRef Code) {<br>
@@ -83,9 +46,8 @@ public:<br>
Diagnostics *Error) {<br>
MatcherInfo ToStore = { MatcherName, NameRange, Args, BindID };<br>
Matchers.push_back(ToStore);<br>
- DummyDynTypedMatcher Matcher(ExpectedMatchers[MatcherName]);<br>
- OwningPtr<DynTypedMatcher> Out(Matcher.tryBind(BindID));<br>
- return VariantMatcher::SingleMatcher(*Out);<br>
+ return VariantMatcher::SingleMatcher(<br>
+ ExpectedMatchers.find(MatcherName)->second);<br>
}<br>
<br>
struct MatcherInfo {<br>
@@ -98,7 +60,8 @@ public:<br>
std::vector<std::string> Errors;<br>
std::vector<VariantValue> Values;<br>
std::vector<MatcherInfo> Matchers;<br>
- llvm::StringMap<uint64_t> ExpectedMatchers;<br>
+ std::map<std::string, ast_matchers::internal::Matcher<Stmt> ><br>
+ ExpectedMatchers;<br>
};<br>
<br>
TEST(ParserTest, ParseUnsigned) {<br>
@@ -137,10 +100,11 @@ bool matchesRange(const SourceRange &Ran<br>
Range.Start.Column == StartColumn && Range.End.Column == EndColumn;<br>
}<br>
<br>
-const DynTypedMatcher *getSingleMatcher(const VariantValue &Value) {<br>
- const DynTypedMatcher *Out;<br>
- EXPECT_TRUE(Value.getMatcher().getSingleMatcher(Out));<br>
- return Out;<br>
+llvm::Optional<DynTypedMatcher> getSingleMatcher(const VariantValue &Value) {<br>
+ llvm::Optional<DynTypedMatcher> Result =<br>
+ Value.getMatcher().getSingleMatcher();<br>
+ EXPECT_TRUE(Result.hasValue());<br>
+ return Result;<br>
}<br>
<br>
TEST(ParserTest, ParseMatcher) {<br>
@@ -155,8 +119,6 @@ TEST(ParserTest, ParseMatcher) {<br>
<br>
EXPECT_EQ(1ULL, Sema.Values.size());<br>
EXPECT_EQ(ExpectedFoo, getSingleMatcher(Sema.Values[0])->getID());<br>
- EXPECT_EQ("Yo!", static_cast<const DummyDynTypedMatcher *>(<br>
- getSingleMatcher(Sema.Values[0]))->boundID());<br>
<br>
EXPECT_EQ(3ULL, Sema.Matchers.size());<br>
const MockSema::MatcherInfo Bar = Sema.Matchers[0];<br>
@@ -184,27 +146,28 @@ using ast_matchers::internal::Matcher;<br>
<br>
TEST(ParserTest, FullParserTest) {<br>
Diagnostics Error;<br>
- OwningPtr<DynTypedMatcher> VarDecl(Parser::parseMatcherExpression(<br>
+ llvm::Optional<DynTypedMatcher> VarDecl(Parser::parseMatcherExpression(<br>
"varDecl(hasInitializer(binaryOperator(hasLHS(integerLiteral()),"<br>
" hasOperatorName(\"+\"))))",<br>
&Error));<br>
EXPECT_EQ("", Error.toStringFull());<br>
- Matcher<Decl> M = Matcher<Decl>::constructFrom(*VarDecl);<br>
+ Matcher<Decl> M = VarDecl->unconditionalConvertTo<Decl>();<br>
EXPECT_TRUE(matches("int x = 1 + false;", M));<br>
EXPECT_FALSE(matches("int x = true + 1;", M));<br>
EXPECT_FALSE(matches("int x = 1 - false;", M));<br>
EXPECT_FALSE(matches("int x = true - 1;", M));<br>
<br>
- OwningPtr<DynTypedMatcher> HasParameter(Parser::parseMatcherExpression(<br>
+ llvm::Optional<DynTypedMatcher> HasParameter(Parser::parseMatcherExpression(<br>
"functionDecl(hasParameter(1, hasName(\"x\")))", &Error));<br>
EXPECT_EQ("", Error.toStringFull());<br>
- M = Matcher<Decl>::constructFrom(*HasParameter);<br>
+ M = HasParameter->unconditionalConvertTo<Decl>();<br>
<br>
EXPECT_TRUE(matches("void f(int a, int x);", M));<br>
EXPECT_FALSE(matches("void f(int x, int a);", M));<br>
<br>
- EXPECT_TRUE(Parser::parseMatcherExpression(<br>
- "hasInitializer(\n binaryOperator(hasLHS(\"A\")))", &Error) == NULL);<br>
+ EXPECT_TRUE(!Parser::parseMatcherExpression(<br>
+ "hasInitializer(\n binaryOperator(hasLHS(\"A\")))",<br>
+ &Error).hasValue());<br>
EXPECT_EQ("1:1: Error parsing argument 1 for matcher hasInitializer.\n"<br>
"2:5: Error parsing argument 1 for matcher binaryOperator.\n"<br>
"2:20: Error building matcher hasLHS.\n"<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>