[clang] ce24bb0 - [ASTMatchers] NFC Rearrange declarations to allow more arg adapting
Stephen Kelly via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 19 13:32:57 PST 2021
Author: Stephen Kelly
Date: 2021-01-19T21:32:42Z
New Revision: ce24bb0eddab12460a01e4d91faa435f2fc84bb6
URL: https://github.com/llvm/llvm-project/commit/ce24bb0eddab12460a01e4d91faa435f2fc84bb6
DIFF: https://github.com/llvm/llvm-project/commit/ce24bb0eddab12460a01e4d91faa435f2fc84bb6.diff
LOG: [ASTMatchers] NFC Rearrange declarations to allow more arg adapting
Added:
Modified:
clang/include/clang/ASTMatchers/ASTMatchersInternal.h
Removed:
################################################################################
diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
index f56cda318f4e..aa78a893dcf6 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1171,6 +1171,232 @@ using HasDeclarationSupportedTypes =
TemplateSpecializationType, TemplateTypeParmType, TypedefType,
UnresolvedUsingType, ObjCIvarRefExpr>;
+/// 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:
+ explicit BindableMatcher(const Matcher<T> &M) : Matcher<T>(M) {}
+ explicit BindableMatcher(MatcherInterface<T> *Implementation)
+ : Matcher<T>(Implementation) {}
+
+ /// 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 {
+ return DynTypedMatcher(*this)
+ .tryBind(ID)
+ ->template unconditionalConvertTo<T>();
+ }
+
+ /// Same as Matcher<T>'s conversion operator, but enables binding on
+ /// the returned matcher.
+ operator DynTypedMatcher() const {
+ DynTypedMatcher Result = static_cast<const Matcher<T> &>(*this);
+ Result.setAllowBind(true);
+ return Result;
+ }
+};
+
+/// Matches any instance of the given NodeType.
+///
+/// This is useful when a matcher syntactically requires a child matcher,
+/// but the context doesn't care. See for example: anything().
+class TrueMatcher {
+public:
+ using ReturnTypes = AllNodeBaseTypes;
+
+ template <typename T> operator Matcher<T>() const {
+ return DynTypedMatcher::trueMatcher(ASTNodeKind::getFromNodeKind<T>())
+ .template unconditionalConvertTo<T>();
+ }
+};
+
+/// Creates a Matcher<T> that matches if all inner matchers match.
+template <typename T>
+BindableMatcher<T>
+makeAllOfComposite(ArrayRef<const Matcher<T> *> InnerMatchers) {
+ // For the size() == 0 case, we return a "true" matcher.
+ if (InnerMatchers.empty()) {
+ return BindableMatcher<T>(TrueMatcher());
+ }
+ // For the size() == 1 case, we simply return that one matcher.
+ // No need to wrap it in a variadic operation.
+ if (InnerMatchers.size() == 1) {
+ return BindableMatcher<T>(*InnerMatchers[0]);
+ }
+
+ using PI = llvm::pointee_iterator<const Matcher<T> *const *>;
+
+ std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()),
+ PI(InnerMatchers.end()));
+ return BindableMatcher<T>(
+ DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf,
+ ASTNodeKind::getFromNodeKind<T>(),
+ std::move(DynMatchers))
+ .template unconditionalConvertTo<T>());
+}
+
+/// 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>
+BindableMatcher<T>
+makeDynCastAllOfComposite(ArrayRef<const Matcher<InnerT> *> InnerMatchers) {
+ return BindableMatcher<T>(
+ makeAllOfComposite(InnerMatchers).template dynCastTo<T>());
+}
+
+/// A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a
+/// variadic functor that takes a number of Matcher<TargetT> and returns a
+/// Matcher<SourceT> that matches TargetT nodes that are matched by all of the
+/// given matchers, if SourceT can be dynamically casted into TargetT.
+///
+/// For example:
+/// const VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> record;
+/// Creates a functor record(...) that creates a Matcher<Decl> given
+/// a variable number of arguments of type Matcher<CXXRecordDecl>.
+/// The returned matcher matches if the given Decl can by dynamically
+/// casted to CXXRecordDecl and all given matchers match.
+template <typename SourceT, typename TargetT>
+class VariadicDynCastAllOfMatcher
+ : public VariadicFunction<BindableMatcher<SourceT>, Matcher<TargetT>,
+ makeDynCastAllOfComposite<SourceT, TargetT>> {
+public:
+ VariadicDynCastAllOfMatcher() {}
+};
+
+/// A \c VariadicAllOfMatcher<T> object is a variadic functor that takes
+/// a number of \c Matcher<T> and returns a \c Matcher<T> that matches \c T
+/// nodes that are matched by all of the given matchers.
+///
+/// For example:
+/// const VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
+/// Creates a functor nestedNameSpecifier(...) that creates a
+/// \c Matcher<NestedNameSpecifier> given a variable number of arguments of type
+/// \c Matcher<NestedNameSpecifier>.
+/// The returned matcher matches if all given matchers match.
+template <typename T>
+class VariadicAllOfMatcher
+ : public VariadicFunction<BindableMatcher<T>, Matcher<T>,
+ makeAllOfComposite<T>> {
+public:
+ VariadicAllOfMatcher() {}
+};
+
+/// VariadicOperatorMatcher related types.
+/// @{
+
+/// Polymorphic matcher object that uses a \c
+/// DynTypedMatcher::VariadicOperator operator.
+///
+/// Input matchers can have any type (including other polymorphic matcher
+/// types), and the actual Matcher<T> is generated on demand with an implicit
+/// conversion operator.
+template <typename... Ps> class VariadicOperatorMatcher {
+public:
+ VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params)
+ : Op(Op), Params(std::forward<Ps>(Params)...) {}
+
+ template <typename T> operator Matcher<T>() const {
+ return DynTypedMatcher::constructVariadic(
+ Op, ASTNodeKind::getFromNodeKind<T>(),
+ getMatchers<T>(std::index_sequence_for<Ps...>()))
+ .template unconditionalConvertTo<T>();
+ }
+
+private:
+ // Helper method to unpack the tuple into a vector.
+ template <typename T, std::size_t... Is>
+ std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) const {
+ return {Matcher<T>(std::get<Is>(Params))...};
+ }
+
+ const DynTypedMatcher::VariadicOperator Op;
+ std::tuple<Ps...> Params;
+};
+
+/// Overloaded function object to generate VariadicOperatorMatcher
+/// objects from arbitrary matchers.
+template <unsigned MinCount, unsigned MaxCount>
+struct VariadicOperatorMatcherFunc {
+ DynTypedMatcher::VariadicOperator Op;
+
+ template <typename... Ms>
+ VariadicOperatorMatcher<Ms...> operator()(Ms &&... Ps) const {
+ static_assert(MinCount <= sizeof...(Ms) && sizeof...(Ms) <= MaxCount,
+ "invalid number of parameters for variadic matcher");
+ return VariadicOperatorMatcher<Ms...>(Op, std::forward<Ms>(Ps)...);
+ }
+};
+
+template <typename F, typename Tuple, std::size_t... I>
+constexpr auto applyMatcherImpl(F &&f, Tuple &&args,
+ std::index_sequence<I...>) {
+ return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(args))...);
+}
+
+template <typename F, typename Tuple>
+constexpr auto applyMatcher(F &&f, Tuple &&args) {
+ return applyMatcherImpl(
+ std::forward<F>(f), std::forward<Tuple>(args),
+ std::make_index_sequence<
+ std::tuple_size<typename std::decay<Tuple>::type>::value>());
+}
+
+template <typename T, bool IsBaseOf, typename Head, typename Tail>
+struct GetCladeImpl {
+ using Type = Head;
+};
+template <typename T, typename Head, typename Tail>
+struct GetCladeImpl<T, false, Head, Tail>
+ : GetCladeImpl<T, std::is_base_of<typename Tail::head, T>::value,
+ typename Tail::head, typename Tail::tail> {};
+
+template <typename T, typename... U>
+struct GetClade : GetCladeImpl<T, false, T, AllNodeBaseTypes> {};
+
+template <typename CladeType, typename... MatcherTypes>
+struct MapAnyOfMatcherImpl {
+
+ template <typename... InnerMatchers>
+ BindableMatcher<CladeType>
+ operator()(InnerMatchers &&... InnerMatcher) const {
+ // TODO: Use std::apply from c++17
+ return VariadicAllOfMatcher<CladeType>()(applyMatcher(
+ internal::VariadicOperatorMatcherFunc<
+ 0, std::numeric_limits<unsigned>::max()>{
+ internal::DynTypedMatcher::VO_AnyOf},
+ applyMatcher(
+ [&](auto... Matcher) {
+ return std::make_tuple(Matcher(
+ std::forward<decltype(InnerMatcher)>(InnerMatcher)...)...);
+ },
+ std::tuple<
+ VariadicDynCastAllOfMatcher<CladeType, MatcherTypes>...>())));
+ }
+};
+
+template <typename... MatcherTypes>
+using MapAnyOfMatcher =
+ MapAnyOfMatcherImpl<typename GetClade<MatcherTypes...>::Type,
+ MatcherTypes...>;
+
+template <typename... MatcherTypes> struct MapAnyOfHelper {
+ using CladeType = typename GetClade<MatcherTypes...>::Type;
+
+ MapAnyOfMatcher<MatcherTypes...> with;
+
+ operator BindableMatcher<CladeType>() const { return with(); }
+
+ Matcher<CladeType> bind(StringRef ID) const { return with().bind(ID); }
+};
+
template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
typename T, typename ToTypes>
class ArgumentAdaptingMatcherFuncAdaptor {
@@ -1327,51 +1553,6 @@ class PolymorphicMatcherWithParam2 {
const P2 Param2;
};
-/// Matches any instance of the given NodeType.
-///
-/// This is useful when a matcher syntactically requires a child matcher,
-/// but the context doesn't care. See for example: anything().
-class TrueMatcher {
-public:
- using ReturnTypes = AllNodeBaseTypes;
-
- template <typename T>
- operator Matcher<T>() const {
- return DynTypedMatcher::trueMatcher(ASTNodeKind::getFromNodeKind<T>())
- .template unconditionalConvertTo<T>();
- }
-};
-
-/// 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:
- explicit BindableMatcher(const Matcher<T> &M) : Matcher<T>(M) {}
- explicit BindableMatcher(MatcherInterface<T> *Implementation)
- : Matcher<T>(Implementation) {}
-
- /// 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 {
- return DynTypedMatcher(*this)
- .tryBind(ID)
- ->template unconditionalConvertTo<T>();
- }
-
- /// Same as Matcher<T>'s conversion operator, but enables binding on
- /// the returned matcher.
- operator DynTypedMatcher() const {
- DynTypedMatcher Result = static_cast<const Matcher<T>&>(*this);
- Result.setAllowBind(true);
- return Result;
- }
-};
-
/// Matches nodes of type T that have child nodes of type ChildT for
/// which a specified child matcher matches.
///
@@ -1415,52 +1596,6 @@ class ForEachMatcher : public MatcherInterface<T> {
}
};
-/// VariadicOperatorMatcher related types.
-/// @{
-
-/// Polymorphic matcher object that uses a \c
-/// DynTypedMatcher::VariadicOperator operator.
-///
-/// Input matchers can have any type (including other polymorphic matcher
-/// types), and the actual Matcher<T> is generated on demand with an implicit
-/// conversion operator.
-template <typename... Ps> class VariadicOperatorMatcher {
-public:
- VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params)
- : Op(Op), Params(std::forward<Ps>(Params)...) {}
-
- template <typename T> operator Matcher<T>() const {
- return DynTypedMatcher::constructVariadic(
- Op, ASTNodeKind::getFromNodeKind<T>(),
- getMatchers<T>(std::index_sequence_for<Ps...>()))
- .template unconditionalConvertTo<T>();
- }
-
-private:
- // Helper method to unpack the tuple into a vector.
- template <typename T, std::size_t... Is>
- std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) const {
- return {Matcher<T>(std::get<Is>(Params))...};
- }
-
- const DynTypedMatcher::VariadicOperator Op;
- std::tuple<Ps...> Params;
-};
-
-/// Overloaded function object to generate VariadicOperatorMatcher
-/// objects from arbitrary matchers.
-template <unsigned MinCount, unsigned MaxCount>
-struct VariadicOperatorMatcherFunc {
- DynTypedMatcher::VariadicOperator Op;
-
- template <typename... Ms>
- VariadicOperatorMatcher<Ms...> operator()(Ms &&... Ps) const {
- static_assert(MinCount <= sizeof...(Ms) && sizeof...(Ms) <= MaxCount,
- "invalid number of parameters for variadic matcher");
- return VariadicOperatorMatcher<Ms...>(Op, std::forward<Ms>(Ps)...);
- }
-};
-
/// @}
template <typename T>
@@ -1468,44 +1603,6 @@ inline Matcher<T> DynTypedMatcher::unconditionalConvertTo() const {
return Matcher<T>(*this);
}
-/// Creates a Matcher<T> that matches if all inner matchers match.
-template<typename T>
-BindableMatcher<T> makeAllOfComposite(
- ArrayRef<const Matcher<T> *> InnerMatchers) {
- // For the size() == 0 case, we return a "true" matcher.
- if (InnerMatchers.empty()) {
- return BindableMatcher<T>(TrueMatcher());
- }
- // For the size() == 1 case, we simply return that one matcher.
- // No need to wrap it in a variadic operation.
- if (InnerMatchers.size() == 1) {
- return BindableMatcher<T>(*InnerMatchers[0]);
- }
-
- using PI = llvm::pointee_iterator<const Matcher<T> *const *>;
-
- std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()),
- PI(InnerMatchers.end()));
- return BindableMatcher<T>(
- DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf,
- ASTNodeKind::getFromNodeKind<T>(),
- std::move(DynMatchers))
- .template unconditionalConvertTo<T>());
-}
-
-/// 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>
-BindableMatcher<T> makeDynCastAllOfComposite(
- ArrayRef<const Matcher<InnerT> *> InnerMatchers) {
- return BindableMatcher<T>(
- makeAllOfComposite(InnerMatchers).template dynCastTo<T>());
-}
-
/// Matches nodes of type T that have at least one descendant node of
/// type DescendantT for which the given inner matcher matches.
///
@@ -1645,43 +1742,6 @@ inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode(
return ExpectedValue.compare(Node.getValue()) == llvm::APFloat::cmpEqual;
}
-/// A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a
-/// variadic functor that takes a number of Matcher<TargetT> and returns a
-/// Matcher<SourceT> that matches TargetT nodes that are matched by all of the
-/// given matchers, if SourceT can be dynamically casted into TargetT.
-///
-/// For example:
-/// const VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> record;
-/// Creates a functor record(...) that creates a Matcher<Decl> given
-/// a variable number of arguments of type Matcher<CXXRecordDecl>.
-/// The returned matcher matches if the given Decl can by dynamically
-/// casted to CXXRecordDecl and all given matchers match.
-template <typename SourceT, typename TargetT>
-class VariadicDynCastAllOfMatcher
- : public VariadicFunction<BindableMatcher<SourceT>, Matcher<TargetT>,
- makeDynCastAllOfComposite<SourceT, TargetT>> {
-public:
- VariadicDynCastAllOfMatcher() {}
-};
-
-/// A \c VariadicAllOfMatcher<T> object is a variadic functor that takes
-/// a number of \c Matcher<T> and returns a \c Matcher<T> that matches \c T
-/// nodes that are matched by all of the given matchers.
-///
-/// For example:
-/// const VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
-/// Creates a functor nestedNameSpecifier(...) that creates a
-/// \c Matcher<NestedNameSpecifier> given a variable number of arguments of type
-/// \c Matcher<NestedNameSpecifier>.
-/// The returned matcher matches if all given matchers match.
-template <typename T>
-class VariadicAllOfMatcher
- : public VariadicFunction<BindableMatcher<T>, Matcher<T>,
- makeAllOfComposite<T>> {
-public:
- VariadicAllOfMatcher() {}
-};
-
/// Matches nodes of type \c TLoc for which the inner
/// \c Matcher<T> matches.
template <typename TLoc, typename T>
@@ -2180,68 +2240,6 @@ std::shared_ptr<llvm::Regex> createAndVerifyRegex(StringRef Regex,
llvm::Regex::RegexFlags Flags,
StringRef MatcherID);
-template <typename F, typename Tuple, std::size_t... I>
-constexpr auto applyMatcherImpl(F &&f, Tuple &&args,
- std::index_sequence<I...>) {
- return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(args))...);
-}
-
-template <typename F, typename Tuple>
-constexpr auto applyMatcher(F &&f, Tuple &&args) {
- return applyMatcherImpl(
- std::forward<F>(f), std::forward<Tuple>(args),
- std::make_index_sequence<
- std::tuple_size<typename std::decay<Tuple>::type>::value>());
-}
-
-template <typename T, bool IsBaseOf, typename Head, typename Tail>
-struct GetCladeImpl {
- using Type = Head;
-};
-template <typename T, typename Head, typename Tail>
-struct GetCladeImpl<T, false, Head, Tail>
- : GetCladeImpl<T, std::is_base_of<typename Tail::head, T>::value,
- typename Tail::head, typename Tail::tail> {};
-
-template <typename T, typename... U>
-struct GetClade : GetCladeImpl<T, false, T, AllNodeBaseTypes> {};
-
-template <typename CladeType, typename... MatcherTypes>
-struct MapAnyOfMatcherImpl {
-
- template <typename... InnerMatchers>
- BindableMatcher<CladeType>
- operator()(InnerMatchers &&... InnerMatcher) const {
- // TODO: Use std::apply from c++17
- return VariadicAllOfMatcher<CladeType>()(applyMatcher(
- internal::VariadicOperatorMatcherFunc<
- 0, std::numeric_limits<unsigned>::max()>{
- internal::DynTypedMatcher::VO_AnyOf},
- applyMatcher(
- [&](auto... Matcher) {
- return std::make_tuple(Matcher(
- std::forward<decltype(InnerMatcher)>(InnerMatcher)...)...);
- },
- std::tuple<
- VariadicDynCastAllOfMatcher<CladeType, MatcherTypes>...>())));
- }
-};
-
-template <typename... MatcherTypes>
-using MapAnyOfMatcher =
- MapAnyOfMatcherImpl<typename GetClade<MatcherTypes...>::Type,
- MatcherTypes...>;
-
-template <typename... MatcherTypes> struct MapAnyOfHelper {
- using CladeType = typename GetClade<MatcherTypes...>::Type;
-
- MapAnyOfMatcher<MatcherTypes...> with;
-
- operator BindableMatcher<CladeType>() const { return with(); }
-
- Matcher<CladeType> bind(StringRef ID) const { return with().bind(ID); }
-};
-
} // namespace internal
} // namespace ast_matchers
More information about the cfe-commits
mailing list