aboutsummaryrefslogtreecommitdiff
path: root/include/clang/ASTMatchers/ASTMatchersInternal.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/ASTMatchers/ASTMatchersInternal.h')
-rw-r--r--include/clang/ASTMatchers/ASTMatchersInternal.h68
1 files changed, 40 insertions, 28 deletions
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index 4d044018a9..3f5568521c 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -440,20 +440,19 @@ public:
BindKind Bind) = 0;
};
-/// \brief Converts a Matcher<T> to a matcher of desired type To by "adapting"
-/// a To into a T.
+/// \brief Converts a \c Matcher<T> to a matcher of desired type \c To by
+/// "adapting" a \c To into a \c T.
///
-/// The ArgumentAdapterT argument specifies how the adaptation is done.
+/// The \c ArgumentAdapterT argument specifies how the adaptation is done.
///
/// For example:
-/// ArgumentAdaptingMatcher<DynCastMatcher, T>(InnerMatcher);
-/// returns a matcher that can be used where a Matcher<To> is required, if
-/// To and T are in the same type hierarchy, and thus dyn_cast can be
-/// called to convert a To to a T.
+/// \c ArgumentAdaptingMatcher<HasMatcher, T>(InnerMatcher);
+/// Given that \c InnerMatcher is of type \c Matcher<T>, this returns a matcher
+/// that is convertible into any matcher of type \c To by constructing
+/// \c HasMatcher<To, T>(InnerMatcher).
///
-/// FIXME: Make sure all our applications of this class actually require
-/// knowledge about the inner type. DynCastMatcher obviously does, but the
-/// Has *matchers require the inner type solely for COMPILE_ASSERT purposes.
+/// If a matcher does not need knowledge about the inner type, prefer to use
+/// PolymorphicMatcherWithParam1.
template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
typename T>
class ArgumentAdaptingMatcher {
@@ -567,19 +566,6 @@ private:
const Matcher<To> InnerMatcher;
};
-/// \brief Enables the user to pass a Matcher<CXXMemberCallExpr> to
-/// Call().
-///
-/// FIXME: Alternatives are using more specific methods than Call, like
-/// MemberCall, or not using VariadicFunction for Call and overloading it.
-template <>
-template <>
-inline Matcher<CXXMemberCallExpr>::
-operator Matcher<CallExpr>() const {
- return makeMatcher(
- new DynCastMatcher<CallExpr, CXXMemberCallExpr>(*this));
-}
-
/// \brief Matcher<T> that wraps an inner Matcher<T> and binds the matched node
/// to an ID if the inner matcher matches on the node.
template <typename T>
@@ -605,6 +591,28 @@ private:
const Matcher<T> InnerMatcher;
};
+/// \brief A Matcher that allows binding the node it matches to an id.
+///
+/// BindableMatcher provides a \a bind() method that allows binding the
+/// matched node to an id if the match was successful.
+template <typename T>
+class BindableMatcher : public Matcher<T> {
+public:
+ BindableMatcher(MatcherInterface<T> *Implementation)
+ : Matcher<T>(Implementation) {}
+
+ /// \brief Returns a matcher that will bind the matched node on a match.
+ ///
+ /// The returned matcher is equivalent to this matcher, but will
+ /// bind the matched node on a match.
+ Matcher<T> bind(StringRef ID) const {
+ TOOLING_COMPILE_ASSERT((llvm::is_base_of<Stmt, T>::value ||
+ llvm::is_base_of<Decl, T>::value),
+ trying_to_bind_unsupported_node_type__only_decl_and_stmt_supported);
+ return Matcher<T>(new IdMatcher<T>(ID, *this));
+ }
+};
+
/// \brief Matches nodes of type T that have child nodes of type ChildT for
/// which a specified child matcher matches.
///
@@ -727,12 +735,16 @@ private:
/// \brief Creates a Matcher<T> that matches if
/// T is dyn_cast'able into InnerT and all inner matchers match.
+///
+/// Returns BindableMatcher, as matchers that use dyn_cast have
+/// the same object both to match on and to run submatchers on,
+/// so there is no ambiguity with what gets bound.
template<typename T, typename InnerT>
-Matcher<T> makeDynCastAllOfComposite(
+BindableMatcher<T> makeDynCastAllOfComposite(
ArrayRef<const Matcher<InnerT> *> InnerMatchers) {
if (InnerMatchers.empty()) {
- return ArgumentAdaptingMatcher<DynCastMatcher, InnerT>(
- makeMatcher(new TrueMatcher<InnerT>));
+ Matcher<InnerT> InnerMatcher = makeMatcher(new TrueMatcher<InnerT>);
+ return BindableMatcher<T>(new DynCastMatcher<T, InnerT>(InnerMatcher));
}
Matcher<InnerT> InnerMatcher = *InnerMatchers.back();
for (int i = InnerMatchers.size() - 2; i >= 0; --i) {
@@ -740,7 +752,7 @@ Matcher<T> makeDynCastAllOfComposite(
new AllOfMatcher<InnerT, Matcher<InnerT>, Matcher<InnerT> >(
*InnerMatchers[i], InnerMatcher));
}
- return ArgumentAdaptingMatcher<DynCastMatcher, InnerT>(InnerMatcher);
+ return BindableMatcher<T>(new DynCastMatcher<T, InnerT>(InnerMatcher));
}
/// \brief Matches nodes of type T that have at least one descendant node of
@@ -876,7 +888,7 @@ class IsConstQualifiedMatcher
template <typename SourceT, typename TargetT>
class VariadicDynCastAllOfMatcher
: public llvm::VariadicFunction<
- Matcher<SourceT>, Matcher<TargetT>,
+ BindableMatcher<SourceT>, Matcher<TargetT>,
makeDynCastAllOfComposite<SourceT, TargetT> > {
public:
VariadicDynCastAllOfMatcher() {}