r193123 - Revert "Refactor DynTypedMatcher into a value type class, just like Matcher<T>."
Reid Kleckner
reid at kleckner.net
Mon Oct 21 15:26:37 PDT 2013
Author: rnk
Date: Mon Oct 21 17:26:36 2013
New Revision: 193123
URL: http://llvm.org/viewvc/llvm-project?rev=193123&view=rev
Log:
Revert "Refactor DynTypedMatcher into a value type class, just like Matcher<T>."
This reverts commit r193100.
It was failing to compile with MSVC 2012 while instantiating
llvm::Optional<DynTypedMatcher>.
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=193123&r1=193122&r2=193123&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h Mon Oct 21 17:26:36 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<internal::DynTypedMatcher, MatchCallback *> >
+ std::vector<std::pair<const 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=193123&r1=193122&r2=193123&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Mon Oct 21 17:26:36 2013
@@ -36,13 +36,12 @@
#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H
#include "clang/AST/ASTTypeTraits.h"
-#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Decl.h"
#include "clang/AST/ExprCXX.h"
-#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
+#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/VariadicFunction.h"
#include "llvm/Support/type_traits.h"
#include <map>
@@ -201,6 +200,38 @@ 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
@@ -210,7 +241,7 @@ private:
/// operator rather than a type hierarchy to be able to templatize the
/// type hierarchy instead of spelling it out.
template <typename T>
-class Matcher {
+class Matcher : public DynTypedMatcher {
public:
/// \brief Takes ownership of the provided implementation pointer.
explicit Matcher(MatcherInterface<T> *Implementation)
@@ -236,6 +267,35 @@ 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,
@@ -256,6 +316,23 @@ 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>.
///
@@ -298,6 +375,23 @@ 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
@@ -308,160 +402,15 @@ 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 DynTypedMatcher::canConvertTo<QualType>() const {
- const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();
+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>
return SourceKind.isSame(
ast_type_traits::ASTNodeKind::getFromNodeKind<Type>()) ||
SourceKind.isSame(
@@ -469,15 +418,16 @@ template <> inline bool DynTypedMatcher:
}
template <>
-inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const {
- assert(canConvertTo<QualType>());
- const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();
+inline Matcher<QualType>
+Matcher<QualType>::constructFrom(const DynTypedMatcher &Other) {
+ assert(canConstructFrom(Other));
+ ast_type_traits::ASTNodeKind SourceKind = Other.getSupportedKind();
if (SourceKind.isSame(
ast_type_traits::ASTNodeKind::getFromNodeKind<Type>())) {
// We support implicit conversion from Matcher<Type> to Matcher<QualType>
- return unconditionalConvertTo<Type>();
+ return Matcher<Type>::constructFrom(Other);
}
- return unconditionalConvertTo<QualType>();
+ return makeMatcher(new WrappedMatcher(Other));
}
/// \brief Finds the first node in a range that matches the given matcher.
@@ -1023,6 +973,16 @@ 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
@@ -1115,7 +1075,8 @@ private:
/// matchers as an array of DynTypedMatcher.
typedef bool (*VariadicOperatorFunction)(
const ast_type_traits::DynTypedNode DynNode, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);
+ BoundNodesTreeBuilder *Builder,
+ ArrayRef<const DynTypedMatcher *> InnerMatchers);
/// \brief \c MatcherInterface<T> implementation for an variadic operator.
template <typename T>
@@ -1125,10 +1086,14 @@ public:
ArrayRef<const Matcher<T> *> InputMatchers)
: Func(Func) {
for (size_t i = 0, e = InputMatchers.size(); i != e; ++i) {
- InnerMatchers.push_back(*InputMatchers[i]);
+ InnerMatchers.push_back(new Matcher<T>(*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,
@@ -1137,7 +1102,7 @@ public:
private:
const VariadicOperatorFunction Func;
- std::vector<DynTypedMatcher> InnerMatchers;
+ std::vector<const DynTypedMatcher *> InnerMatchers;
};
/// \brief "No argument" placeholder to use as template paratemers.
@@ -1231,24 +1196,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<DynTypedMatcher> InnerMatchers);
+bool
+AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+ ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+ ArrayRef<const 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<DynTypedMatcher> InnerMatchers);
+bool
+EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+ ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+ ArrayRef<const 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<DynTypedMatcher> InnerMatchers);
+bool
+AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+ ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+ ArrayRef<const DynTypedMatcher *> InnerMatchers);
/// \brief Creates a Matcher<T> that matches if all inner matchers match.
template<typename T>
@@ -1267,8 +1232,8 @@ BindableMatcher<T> makeAllOfComposite(
template<typename T, typename InnerT>
BindableMatcher<T> makeDynCastAllOfComposite(
ArrayRef<const Matcher<InnerT> *> InnerMatchers) {
- return BindableMatcher<T>(DynTypedMatcher(makeAllOfComposite(InnerMatchers))
- .unconditionalConvertTo<T>());
+ return BindableMatcher<T>(
+ Matcher<T>::constructFromUnsafe(makeAllOfComposite(InnerMatchers)));
}
/// \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=193123&r1=193122&r2=193123&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h Mon Oct 21 17:26:36 2013
@@ -37,7 +37,6 @@
#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 {
@@ -93,12 +92,11 @@ public:
///
/// \param MatcherCode The matcher expression to parse.
///
- /// \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.
+ /// \return The matcher object constructed, or NULL 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 llvm::Optional<DynTypedMatcher>
- parseMatcherExpression(StringRef MatcherCode, Diagnostics *Error);
+ static DynTypedMatcher *parseMatcherExpression(StringRef MatcherCode,
+ Diagnostics *Error);
/// \brief Parse a matcher expression.
///
@@ -106,12 +104,13 @@ public:
///
/// \param S The Sema instance that will help the parser
/// construct the matchers.
- /// \return The matcher object constructed by the processor, or an empty
- /// Optional if an error occurred. In that case, \c Error will contain a
+ /// \return The matcher object constructed by the processor, or NULL
+ /// 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 llvm::Optional<DynTypedMatcher>
- parseMatcherExpression(StringRef MatcherCode, Sema *S, Diagnostics *Error);
+ static 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=193123&r1=193122&r2=193123&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h Mon Oct 21 17:26:36 2013
@@ -22,7 +22,6 @@
#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"
@@ -63,7 +62,7 @@ class VariantMatcher {
class Payload : public RefCountedBaseVPTR {
public:
virtual ~Payload();
- virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
+ virtual bool getSingleMatcher(const DynTypedMatcher *&Out) const = 0;
virtual std::string getTypeAsString() const = 0;
virtual void makeTypedMatcher(MatcherOps &Ops) const = 0;
};
@@ -78,7 +77,8 @@ public:
/// \brief Clones the provided matchers.
///
/// They should be the result of a polymorphic matcher.
- static VariantMatcher PolymorphicMatcher(ArrayRef<DynTypedMatcher> Matchers);
+ static VariantMatcher
+ PolymorphicMatcher(ArrayRef<const DynTypedMatcher *> Matchers);
/// \brief Creates a 'variadic' operator matcher.
///
@@ -95,10 +95,10 @@ public:
/// \brief Return a single matcher, if there is no ambiguity.
///
- /// \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;
+ /// \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;
/// \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 Matcher.canConvertTo<T>();
+ return MatcherT::canConstructFrom(Matcher);
}
virtual void constructFrom(const DynTypedMatcher& Matcher) {
- Out.reset(new MatcherT(Matcher.convertTo<T>()));
+ Out.reset(new MatcherT(MatcherT::constructFrom(Matcher)));
}
virtual void constructVariadicOperator(
@@ -173,9 +173,7 @@ private:
new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(
Func, ArrayRef<const MatcherT *>(InnerArgs, NumArgs))));
}
- for (size_t i = 0; i != NumArgs; ++i) {
- delete InnerArgs[i];
- }
+ std::for_each(InnerArgs, InnerArgs + NumArgs, llvm::deleter<MatcherT>);
delete[] InnerArgs;
}
Modified: cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp?rev=193123&r1=193122&r2=193123&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp Mon Oct 21 17:26:36 2013
@@ -295,26 +295,25 @@ private:
class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
public ASTMatchFinder {
public:
- MatchASTVisitor(
- std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> > *
- MatcherCallbackPairs)
- : MatcherCallbackPairs(MatcherCallbackPairs), ActiveASTContext(NULL) {}
+ MatchASTVisitor(std::vector<std::pair<const internal::DynTypedMatcher*,
+ MatchCallback*> > *MatcherCallbackPairs)
+ : MatcherCallbackPairs(MatcherCallbackPairs),
+ ActiveASTContext(NULL) {
+ }
void onStartOfTranslationUnit() {
- for (std::vector<std::pair<internal::DynTypedMatcher,
- MatchCallback *> >::const_iterator
- I = MatcherCallbackPairs->begin(),
- E = MatcherCallbackPairs->end();
+ for (std::vector<std::pair<const internal::DynTypedMatcher*,
+ MatchCallback*> >::const_iterator
+ I = MatcherCallbackPairs->begin(), E = MatcherCallbackPairs->end();
I != E; ++I) {
I->second->onStartOfTranslationUnit();
}
}
void onEndOfTranslationUnit() {
- for (std::vector<std::pair<internal::DynTypedMatcher,
- MatchCallback *> >::const_iterator
- I = MatcherCallbackPairs->begin(),
- E = MatcherCallbackPairs->end();
+ for (std::vector<std::pair<const internal::DynTypedMatcher*,
+ MatchCallback*> >::const_iterator
+ I = MatcherCallbackPairs->begin(), E = MatcherCallbackPairs->end();
I != E; ++I) {
I->second->onEndOfTranslationUnit();
}
@@ -451,13 +450,12 @@ 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<internal::DynTypedMatcher,
- MatchCallback *> >::const_iterator
- I = MatcherCallbackPairs->begin(),
- E = MatcherCallbackPairs->end();
+ for (std::vector<std::pair<const 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);
}
@@ -605,8 +603,8 @@ private:
return false;
}
- std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> > *const
- MatcherCallbackPairs;
+ std::vector<std::pair<const internal::DynTypedMatcher*,
+ MatchCallback*> > *const MatcherCallbackPairs;
ASTContext *ActiveASTContext;
// Maps a canonical type to its TypedefDecls.
@@ -745,10 +743,11 @@ bool MatchASTVisitor::TraverseNestedName
class MatchASTConsumer : public ASTConsumer {
public:
MatchASTConsumer(
- std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> > *
- MatcherCallbackPairs,
- MatchFinder::ParsingDoneTestCallback *ParsingDone)
- : Visitor(MatcherCallbackPairs), ParsingDone(ParsingDone) {}
+ std::vector<std::pair<const internal::DynTypedMatcher*,
+ MatchCallback*> > *MatcherCallbackPairs,
+ MatchFinder::ParsingDoneTestCallback *ParsingDone)
+ : Visitor(MatcherCallbackPairs),
+ ParsingDone(ParsingDone) {}
private:
virtual void HandleTranslationUnit(ASTContext &Context) {
@@ -779,36 +778,49 @@ MatchFinder::ParsingDoneTestCallback::~P
MatchFinder::MatchFinder() : ParsingDone(NULL) {}
-MatchFinder::~MatchFinder() {}
+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;
+ }
+}
void MatchFinder::addMatcher(const DeclarationMatcher &NodeMatch,
MatchCallback *Action) {
- MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
+ MatcherCallbackPairs.push_back(std::make_pair(
+ new internal::Matcher<Decl>(NodeMatch), Action));
}
void MatchFinder::addMatcher(const TypeMatcher &NodeMatch,
MatchCallback *Action) {
- MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
+ MatcherCallbackPairs.push_back(std::make_pair(
+ new internal::Matcher<QualType>(NodeMatch), Action));
}
void MatchFinder::addMatcher(const StatementMatcher &NodeMatch,
MatchCallback *Action) {
- MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
+ MatcherCallbackPairs.push_back(std::make_pair(
+ new internal::Matcher<Stmt>(NodeMatch), Action));
}
void MatchFinder::addMatcher(const NestedNameSpecifierMatcher &NodeMatch,
MatchCallback *Action) {
- MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
+ MatcherCallbackPairs.push_back(std::make_pair(
+ new NestedNameSpecifierMatcher(NodeMatch), Action));
}
void MatchFinder::addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch,
MatchCallback *Action) {
- MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
+ MatcherCallbackPairs.push_back(std::make_pair(
+ new NestedNameSpecifierLocMatcher(NodeMatch), Action));
}
void MatchFinder::addMatcher(const TypeLocMatcher &NodeMatch,
MatchCallback *Action) {
- MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
+ MatcherCallbackPairs.push_back(std::make_pair(
+ new TypeLocMatcher(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=193123&r1=193122&r2=193123&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp Mon Oct 21 17:26:36 2013
@@ -26,23 +26,25 @@ 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<DynTypedMatcher> InnerMatchers) {
+ ArrayRef<const 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;
@@ -51,12 +53,12 @@ bool AllOfVariadicOperator(const ast_typ
bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
- ArrayRef<DynTypedMatcher> InnerMatchers) {
+ ArrayRef<const 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);
}
@@ -68,10 +70,10 @@ bool EachOfVariadicOperator(const ast_ty
bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
- ArrayRef<DynTypedMatcher> InnerMatchers) {
+ ArrayRef<const 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=193123&r1=193122&r2=193123&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h Mon Oct 21 17:26:36 2013
@@ -167,13 +167,15 @@ private:
/// out of the polymorphic object.
template <class PolyMatcher>
static void mergePolyMatchers(const PolyMatcher &Poly,
- std::vector<DynTypedMatcher> &Out,
+ std::vector<const DynTypedMatcher *> &Out,
ast_matchers::internal::EmptyTypeList) {}
template <class PolyMatcher, class TypeList>
static void mergePolyMatchers(const PolyMatcher &Poly,
- std::vector<DynTypedMatcher> &Out, TypeList) {
- Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly));
+ std::vector<const DynTypedMatcher *> &Out,
+ TypeList) {
+ Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly)
+ .clone());
mergePolyMatchers(Poly, Out, typename TypeList::tail());
}
@@ -191,9 +193,10 @@ template <typename T>
static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher,
typename T::ReturnTypes * =
NULL) {
- std::vector<DynTypedMatcher> Matchers;
+ std::vector<const 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=193123&r1=193122&r2=193123&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp Mon Oct 21 17:26:36 2013
@@ -390,29 +390,29 @@ bool Parser::parseExpression(StringRef C
return true;
}
-llvm::Optional<DynTypedMatcher>
-Parser::parseMatcherExpression(StringRef Code, Diagnostics *Error) {
+DynTypedMatcher *Parser::parseMatcherExpression(StringRef Code,
+ Diagnostics *Error) {
RegistrySema S;
return parseMatcherExpression(Code, &S, Error);
}
-llvm::Optional<DynTypedMatcher>
-Parser::parseMatcherExpression(StringRef Code, Parser::Sema *S,
- Diagnostics *Error) {
+DynTypedMatcher *Parser::parseMatcherExpression(StringRef Code,
+ Parser::Sema *S,
+ Diagnostics *Error) {
VariantValue Value;
if (!parseExpression(Code, S, &Value, Error))
- return llvm::Optional<DynTypedMatcher>();
+ return NULL;
if (!Value.isMatcher()) {
Error->addError(SourceRange(), Error->ET_ParserNotAMatcher);
- return llvm::Optional<DynTypedMatcher>();
+ return NULL;
}
- llvm::Optional<DynTypedMatcher> Result =
- Value.getMatcher().getSingleMatcher();
- if (!Result.hasValue()) {
+ const DynTypedMatcher *Result;
+ if (!Value.getMatcher().getSingleMatcher(Result)) {
Error->addError(SourceRange(), Error->ET_ParserOverloadedType)
<< Value.getTypeAsString();
+ return NULL;
}
- return Result;
+ return Result->clone();
}
} // 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=193123&r1=193122&r2=193123&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp Mon Oct 21 17:26:36 2013
@@ -329,10 +329,10 @@ VariantMatcher Registry::constructBoundM
VariantMatcher Out = constructMatcher(MatcherName, NameRange, Args, Error);
if (Out.isNull()) return Out;
- llvm::Optional<DynTypedMatcher> Result = Out.getSingleMatcher();
- if (Result.hasValue()) {
- llvm::Optional<DynTypedMatcher> Bound = Result->tryBind(BindID);
- if (Bound.hasValue()) {
+ const DynTypedMatcher *Result;
+ if (Out.getSingleMatcher(Result)) {
+ OwningPtr<DynTypedMatcher> Bound(Result->tryBind(BindID));
+ if (Bound) {
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=193123&r1=193122&r2=193123&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp Mon Oct 21 17:26:36 2013
@@ -26,37 +26,44 @@ VariantMatcher::Payload::~Payload() {}
class VariantMatcher::SinglePayload : public VariantMatcher::Payload {
public:
- SinglePayload(const DynTypedMatcher &Matcher) : Matcher(Matcher) {}
+ SinglePayload(const DynTypedMatcher &Matcher) : Matcher(Matcher.clone()) {}
- virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
- return Matcher;
+ virtual bool getSingleMatcher(const DynTypedMatcher *&Out) const {
+ Out = Matcher.get();
+ return true;
}
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:
- const DynTypedMatcher Matcher;
+ OwningPtr<const DynTypedMatcher> Matcher;
};
class VariantMatcher::PolymorphicPayload : public VariantMatcher::Payload {
public:
- PolymorphicPayload(ArrayRef<DynTypedMatcher> MatchersIn)
- : Matchers(MatchersIn) {}
+ PolymorphicPayload(ArrayRef<const DynTypedMatcher *> MatchersIn) {
+ for (size_t i = 0, e = MatchersIn.size(); i != e; ++i) {
+ Matchers.push_back(MatchersIn[i]->clone());
+ }
+ }
- virtual ~PolymorphicPayload() {}
+ virtual ~PolymorphicPayload() {
+ llvm::DeleteContainerPointers(Matchers);
+ }
- virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
+ virtual bool getSingleMatcher(const DynTypedMatcher *&Out) const {
if (Matchers.size() != 1)
- return llvm::Optional<DynTypedMatcher>();
- return Matchers[0];
+ return false;
+ Out = Matchers[0];
+ return true;
}
virtual std::string getTypeAsString() const {
@@ -64,7 +71,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();
}
@@ -72,17 +79,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);
}
- const std::vector<DynTypedMatcher> Matchers;
+ std::vector<const DynTypedMatcher *> Matchers;
};
class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload {
@@ -91,8 +98,8 @@ public:
ArrayRef<VariantMatcher> Args)
: Func(Func), Args(Args) {}
- virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
- return llvm::Optional<DynTypedMatcher>();
+ virtual bool getSingleMatcher(const DynTypedMatcher *&Out) const {
+ return false;
}
virtual std::string getTypeAsString() const {
@@ -121,7 +128,7 @@ VariantMatcher VariantMatcher::SingleMat
}
VariantMatcher
-VariantMatcher::PolymorphicMatcher(ArrayRef<DynTypedMatcher> Matchers) {
+VariantMatcher::PolymorphicMatcher(ArrayRef<const DynTypedMatcher *> Matchers) {
return VariantMatcher(new PolymorphicPayload(Matchers));
}
@@ -131,8 +138,9 @@ VariantMatcher VariantMatcher::VariadicO
return VariantMatcher(new VariadicOpPayload(Func, Args));
}
-llvm::Optional<DynTypedMatcher> VariantMatcher::getSingleMatcher() const {
- return Value ? Value->getSingleMatcher() : llvm::Optional<DynTypedMatcher>();
+bool VariantMatcher::getSingleMatcher(const DynTypedMatcher *&Out) const {
+ if (Value) return Value->getSingleMatcher(Out);
+ return false;
}
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=193123&r1=193122&r2=193123&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp Mon Oct 21 17:26:36 2013
@@ -21,14 +21,51 @@ 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) {
- ast_matchers::internal::Matcher<Stmt> M = stmt();
- ExpectedMatchers.insert(std::make_pair(MatcherName, M));
- return M.getID();
+ uint64_t ID = ExpectedMatchers.size() + 1;
+ ExpectedMatchers[MatcherName] = ID;
+ return ID;
}
void parse(StringRef Code) {
@@ -46,8 +83,9 @@ public:
Diagnostics *Error) {
MatcherInfo ToStore = { MatcherName, NameRange, Args, BindID };
Matchers.push_back(ToStore);
- return VariantMatcher::SingleMatcher(
- ExpectedMatchers.find(MatcherName)->second);
+ DummyDynTypedMatcher Matcher(ExpectedMatchers[MatcherName]);
+ OwningPtr<DynTypedMatcher> Out(Matcher.tryBind(BindID));
+ return VariantMatcher::SingleMatcher(*Out);
}
struct MatcherInfo {
@@ -60,8 +98,7 @@ public:
std::vector<std::string> Errors;
std::vector<VariantValue> Values;
std::vector<MatcherInfo> Matchers;
- std::map<std::string, ast_matchers::internal::Matcher<Stmt> >
- ExpectedMatchers;
+ llvm::StringMap<uint64_t> ExpectedMatchers;
};
TEST(ParserTest, ParseUnsigned) {
@@ -100,11 +137,10 @@ bool matchesRange(const SourceRange &Ran
Range.Start.Column == StartColumn && Range.End.Column == EndColumn;
}
-llvm::Optional<DynTypedMatcher> getSingleMatcher(const VariantValue &Value) {
- llvm::Optional<DynTypedMatcher> Result =
- Value.getMatcher().getSingleMatcher();
- EXPECT_TRUE(Result.hasValue());
- return Result;
+const DynTypedMatcher *getSingleMatcher(const VariantValue &Value) {
+ const DynTypedMatcher *Out;
+ EXPECT_TRUE(Value.getMatcher().getSingleMatcher(Out));
+ return Out;
}
TEST(ParserTest, ParseMatcher) {
@@ -119,6 +155,8 @@ 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];
@@ -146,28 +184,27 @@ using ast_matchers::internal::Matcher;
TEST(ParserTest, FullParserTest) {
Diagnostics Error;
- llvm::Optional<DynTypedMatcher> VarDecl(Parser::parseMatcherExpression(
+ OwningPtr<DynTypedMatcher> VarDecl(Parser::parseMatcherExpression(
"varDecl(hasInitializer(binaryOperator(hasLHS(integerLiteral()),"
" hasOperatorName(\"+\"))))",
&Error));
EXPECT_EQ("", Error.toStringFull());
- Matcher<Decl> M = VarDecl->unconditionalConvertTo<Decl>();
+ Matcher<Decl> M = Matcher<Decl>::constructFrom(*VarDecl);
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));
- llvm::Optional<DynTypedMatcher> HasParameter(Parser::parseMatcherExpression(
+ OwningPtr<DynTypedMatcher> HasParameter(Parser::parseMatcherExpression(
"functionDecl(hasParameter(1, hasName(\"x\")))", &Error));
EXPECT_EQ("", Error.toStringFull());
- M = HasParameter->unconditionalConvertTo<Decl>();
+ M = Matcher<Decl>::constructFrom(*HasParameter);
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).hasValue());
+ EXPECT_TRUE(Parser::parseMatcherExpression(
+ "hasInitializer(\n binaryOperator(hasLHS(\"A\")))", &Error) == NULL);
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"
More information about the cfe-commits
mailing list