123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===--- ASTMatchersMacros.h - Structural query framework -------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // Defines macros that enable us to define new matchers in a single place.
- // Since a matcher is a function which returns a Matcher<T> object, where
- // T is the type of the actual implementation of the matcher, the macros allow
- // us to write matchers like functions and take care of the definition of the
- // class boilerplate.
- //
- // Note that when you define a matcher with an AST_MATCHER* macro, only the
- // function which creates the matcher goes into the current namespace - the
- // class that implements the actual matcher, which gets returned by the
- // generator function, is put into the 'internal' namespace. This allows us
- // to only have the functions (which is all the user cares about) in the
- // 'ast_matchers' namespace and hide the boilerplate.
- //
- // To define a matcher in user code, put it into your own namespace. This would
- // help to prevent ODR violations in case a matcher with the same name is
- // defined in multiple translation units:
- //
- // namespace my_matchers {
- // AST_MATCHER_P(clang::MemberExpr, Member,
- // clang::ast_matchers::internal::Matcher<clang::ValueDecl>,
- // InnerMatcher) {
- // return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
- // }
- // } // namespace my_matchers
- //
- // Alternatively, an unnamed namespace may be used:
- //
- // namespace clang {
- // namespace ast_matchers {
- // namespace {
- // AST_MATCHER_P(MemberExpr, Member,
- // internal::Matcher<ValueDecl>, InnerMatcher) {
- // return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
- // }
- // } // namespace
- // } // namespace ast_matchers
- // } // namespace clang
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
- #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
- /// AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) { ... }
- /// defines a zero parameter function named DefineMatcher() that returns a
- /// ReturnType object.
- #define AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) \
- inline ReturnType DefineMatcher##_getInstance(); \
- inline ReturnType DefineMatcher() { \
- return ::clang::ast_matchers::internal::MemoizedMatcher< \
- ReturnType, DefineMatcher##_getInstance>::getInstance(); \
- } \
- inline ReturnType DefineMatcher##_getInstance()
- /// AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
- /// ... }
- /// defines a single-parameter function named DefineMatcher() that returns a
- /// ReturnType object.
- ///
- /// The code between the curly braces has access to the following variables:
- ///
- /// Param: the parameter passed to the function; its type
- /// is ParamType.
- ///
- /// The code should return an instance of ReturnType.
- #define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) \
- AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \
- 0)
- #define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, \
- Param, OverloadId) \
- inline ReturnType DefineMatcher(ParamType const &Param); \
- typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &); \
- inline ReturnType DefineMatcher(ParamType const &Param)
- /// AST_MATCHER(Type, DefineMatcher) { ... }
- /// defines a zero parameter function named DefineMatcher() that returns a
- /// Matcher<Type> object.
- ///
- /// The code between the curly braces has access to the following variables:
- ///
- /// Node: the AST node being matched; its type is Type.
- /// Finder: an ASTMatchFinder*.
- /// Builder: a BoundNodesTreeBuilder*.
- ///
- /// The code should return true if 'Node' matches.
- #define AST_MATCHER(Type, DefineMatcher) \
- namespace internal { \
- class matcher_##DefineMatcher##Matcher \
- : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \
- public: \
- explicit matcher_##DefineMatcher##Matcher() = default; \
- bool matches(const Type &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
- *Builder) const override; \
- }; \
- } \
- inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher() { \
- return ::clang::ast_matchers::internal::makeMatcher( \
- new internal::matcher_##DefineMatcher##Matcher()); \
- } \
- inline bool internal::matcher_##DefineMatcher##Matcher::matches( \
- const Type &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
- /// AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
- /// defines a single-parameter function named DefineMatcher() that returns a
- /// Matcher<Type> object.
- ///
- /// The code between the curly braces has access to the following variables:
- ///
- /// Node: the AST node being matched; its type is Type.
- /// Param: the parameter passed to the function; its type
- /// is ParamType.
- /// Finder: an ASTMatchFinder*.
- /// Builder: a BoundNodesTreeBuilder*.
- ///
- /// The code should return true if 'Node' matches.
- #define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) \
- AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0)
- #define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, \
- OverloadId) \
- namespace internal { \
- class matcher_##DefineMatcher##OverloadId##Matcher \
- : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \
- public: \
- explicit matcher_##DefineMatcher##OverloadId##Matcher( \
- ParamType const &A##Param) \
- : Param(A##Param) {} \
- bool matches(const Type &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
- *Builder) const override; \
- \
- private: \
- ParamType Param; \
- }; \
- } \
- inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \
- ParamType const &Param) { \
- return ::clang::ast_matchers::internal::makeMatcher( \
- new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \
- } \
- typedef ::clang::ast_matchers::internal::Matcher<Type> ( \
- &DefineMatcher##_Type##OverloadId)(ParamType const &Param); \
- inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
- const Type &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
- /// AST_MATCHER_P2(
- /// Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
- /// defines a two-parameter function named DefineMatcher() that returns a
- /// Matcher<Type> object.
- ///
- /// The code between the curly braces has access to the following variables:
- ///
- /// Node: the AST node being matched; its type is Type.
- /// Param1, Param2: the parameters passed to the function; their types
- /// are ParamType1 and ParamType2.
- /// Finder: an ASTMatchFinder*.
- /// Builder: a BoundNodesTreeBuilder*.
- ///
- /// The code should return true if 'Node' matches.
- #define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
- Param2) \
- AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
- Param2, 0)
- #define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, \
- ParamType2, Param2, OverloadId) \
- namespace internal { \
- class matcher_##DefineMatcher##OverloadId##Matcher \
- : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \
- public: \
- matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \
- ParamType2 const &A##Param2) \
- : Param1(A##Param1), Param2(A##Param2) {} \
- bool matches(const Type &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
- *Builder) const override; \
- \
- private: \
- ParamType1 Param1; \
- ParamType2 Param2; \
- }; \
- } \
- inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \
- ParamType1 const &Param1, ParamType2 const &Param2) { \
- return ::clang::ast_matchers::internal::makeMatcher( \
- new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \
- Param2)); \
- } \
- typedef ::clang::ast_matchers::internal::Matcher<Type> ( \
- &DefineMatcher##_Type##OverloadId)(ParamType1 const &Param1, \
- ParamType2 const &Param2); \
- inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
- const Type &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
- /// Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER*
- /// macros.
- ///
- /// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it
- /// will look at that as two arguments. However, you can pass
- /// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis.
- /// The \c PolymorphicMatcherWithParam* classes will unpack the function type to
- /// extract the TypeList object.
- #define AST_POLYMORPHIC_SUPPORTED_TYPES(...) \
- void(::clang::ast_matchers::internal::TypeList<__VA_ARGS__>)
- /// AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
- /// defines a single-parameter function named DefineMatcher() that is
- /// polymorphic in the return type.
- ///
- /// The variables are the same as for AST_MATCHER, but NodeType will be deduced
- /// from the calling context.
- #define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF) \
- namespace internal { \
- template <typename NodeType> \
- class matcher_##DefineMatcher##Matcher \
- : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \
- public: \
- bool matches(const NodeType &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
- *Builder) const override; \
- }; \
- } \
- inline ::clang::ast_matchers::internal::PolymorphicMatcher< \
- internal::matcher_##DefineMatcher##Matcher, ReturnTypesF> \
- DefineMatcher() { \
- return ::clang::ast_matchers::internal::PolymorphicMatcher< \
- internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>(); \
- } \
- template <typename NodeType> \
- bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches( \
- const NodeType &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
- /// AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
- /// defines a single-parameter function named DefineMatcher() that is
- /// polymorphic in the return type.
- ///
- /// The variables are the same as for
- /// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
- /// of the matcher Matcher<NodeType> returned by the function matcher().
- ///
- /// FIXME: Pull out common code with above macro?
- #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType, \
- Param) \
- AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType, \
- Param, 0)
- #define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, \
- ParamType, Param, OverloadId) \
- namespace internal { \
- template <typename NodeType, typename ParamT> \
- class matcher_##DefineMatcher##OverloadId##Matcher \
- : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \
- public: \
- explicit matcher_##DefineMatcher##OverloadId##Matcher( \
- ParamType const &A##Param) \
- : Param(A##Param) {} \
- bool matches(const NodeType &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
- *Builder) const override; \
- \
- private: \
- ParamType Param; \
- }; \
- } \
- inline ::clang::ast_matchers::internal::PolymorphicMatcher< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
- ParamType> \
- DefineMatcher(ParamType const &Param) { \
- return ::clang::ast_matchers::internal::PolymorphicMatcher< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
- ParamType>(Param); \
- } \
- typedef ::clang::ast_matchers::internal::PolymorphicMatcher< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
- ParamType> (&DefineMatcher##_Type##OverloadId)(ParamType const &Param); \
- template <typename NodeType, typename ParamT> \
- bool internal:: \
- matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \
- const NodeType &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \
- const
- /// AST_POLYMORPHIC_MATCHER_P2(
- /// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
- /// defines a two-parameter function named matcher() that is polymorphic in
- /// the return type.
- ///
- /// The variables are the same as for AST_MATCHER_P2, with the
- /// addition of NodeType, which specifies the node type of the matcher
- /// Matcher<NodeType> returned by the function DefineMatcher().
- #define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1, \
- Param1, ParamType2, Param2) \
- AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \
- Param1, ParamType2, Param2, 0)
- #define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, \
- ParamType1, Param1, ParamType2, \
- Param2, OverloadId) \
- namespace internal { \
- template <typename NodeType, typename ParamT1, typename ParamT2> \
- class matcher_##DefineMatcher##OverloadId##Matcher \
- : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \
- public: \
- matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \
- ParamType2 const &A##Param2) \
- : Param1(A##Param1), Param2(A##Param2) {} \
- bool matches(const NodeType &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
- *Builder) const override; \
- \
- private: \
- ParamType1 Param1; \
- ParamType2 Param2; \
- }; \
- } \
- inline ::clang::ast_matchers::internal::PolymorphicMatcher< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
- ParamType1, ParamType2> \
- DefineMatcher(ParamType1 const &Param1, ParamType2 const &Param2) { \
- return ::clang::ast_matchers::internal::PolymorphicMatcher< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
- ParamType1, ParamType2>(Param1, Param2); \
- } \
- typedef ::clang::ast_matchers::internal::PolymorphicMatcher< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
- ParamType1, ParamType2> (&DefineMatcher##_Type##OverloadId)( \
- ParamType1 const &Param1, ParamType2 const &Param2); \
- template <typename NodeType, typename ParamT1, typename ParamT2> \
- bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \
- NodeType, ParamT1, ParamT2>:: \
- matches(const NodeType &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \
- const
- // FIXME: add a matcher for TypeLoc derived classes using its custom casting
- // API (no longer dyn_cast) if/when we need such matching
- #define AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName, \
- ReturnTypesF) \
- namespace internal { \
- template <typename T> struct TypeMatcher##MatcherName##Getter { \
- static QualType (T::*value())() const { return &T::FunctionName; } \
- }; \
- } \
- extern const ::clang::ast_matchers::internal:: \
- TypeTraversePolymorphicMatcher< \
- QualType, \
- ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \
- ::clang::ast_matchers::internal::TypeTraverseMatcher, \
- ReturnTypesF>::Func MatcherName
- #define AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) \
- const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \
- QualType, \
- ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \
- ::clang::ast_matchers::internal::TypeTraverseMatcher, \
- ReturnTypesF>::Func MatcherName
- /// AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
- /// the matcher \c MatcherName that can be used to traverse from one \c Type
- /// to another.
- ///
- /// For a specific \c SpecificType, the traversal is done using
- /// \c SpecificType::FunctionName. The existence of such a function determines
- /// whether a corresponding matcher can be used on \c SpecificType.
- #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \
- namespace internal { \
- template <typename T> struct TypeMatcher##MatcherName##Getter { \
- static QualType (T::*value())() const { return &T::FunctionName; } \
- }; \
- } \
- const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \
- QualType, \
- ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \
- ::clang::ast_matchers::internal::TypeTraverseMatcher, \
- ReturnTypesF>::Func MatcherName
- #define AST_TYPELOC_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName, \
- ReturnTypesF) \
- namespace internal { \
- template <typename T> struct TypeLocMatcher##MatcherName##Getter { \
- static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \
- }; \
- } \
- extern const ::clang::ast_matchers::internal:: \
- TypeTraversePolymorphicMatcher< \
- TypeLoc, \
- ::clang::ast_matchers::internal:: \
- TypeLocMatcher##MatcherName##Getter, \
- ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \
- ReturnTypesF>::Func MatcherName##Loc; \
- AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName##Type, ReturnTypesF)
- #define AST_TYPELOC_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) \
- const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \
- TypeLoc, \
- ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter, \
- ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \
- ReturnTypesF>::Func MatcherName##Loc; \
- AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF)
- /// AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
- /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
- #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \
- namespace internal { \
- template <typename T> struct TypeLocMatcher##MatcherName##Getter { \
- static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \
- }; \
- } \
- const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \
- TypeLoc, \
- ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter, \
- ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \
- ReturnTypesF>::Func MatcherName##Loc; \
- AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
- /// AST_MATCHER_REGEX(Type, DefineMatcher, Param) { ... }
- /// defines a function named DefineMatcher() that takes a regular expression
- /// string paramater and an optional RegexFlags parameter and returns a
- /// Matcher<Type> object.
- ///
- /// The code between the curly braces has access to the following variables:
- ///
- /// Node: the AST node being matched; its type is Type.
- /// Param: a pointer to an \ref llvm::Regex object
- /// Finder: an ASTMatchFinder*.
- /// Builder: a BoundNodesTreeBuilder*.
- ///
- /// The code should return true if 'Node' matches.
- #define AST_MATCHER_REGEX(Type, DefineMatcher, Param) \
- AST_MATCHER_REGEX_OVERLOAD(Type, DefineMatcher, Param, 0)
- #define AST_MATCHER_REGEX_OVERLOAD(Type, DefineMatcher, Param, OverloadId) \
- namespace internal { \
- class matcher_##DefineMatcher##OverloadId##Matcher \
- : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \
- public: \
- explicit matcher_##DefineMatcher##OverloadId##Matcher( \
- std::shared_ptr<llvm::Regex> RE) \
- : Param(std::move(RE)) {} \
- bool matches(const Type &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
- *Builder) const override; \
- \
- private: \
- std::shared_ptr<llvm::Regex> Param; \
- }; \
- } \
- inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \
- llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags) { \
- return ::clang::ast_matchers::internal::makeMatcher( \
- new internal::matcher_##DefineMatcher##OverloadId##Matcher( \
- ::clang::ast_matchers::internal::createAndVerifyRegex( \
- Param, RegexFlags, #DefineMatcher))); \
- } \
- inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \
- llvm::StringRef Param) { \
- return DefineMatcher(Param, llvm::Regex::NoFlags); \
- } \
- \
- typedef ::clang::ast_matchers::internal::Matcher<Type> ( \
- &DefineMatcher##_Type##OverloadId##Flags)(llvm::StringRef, \
- llvm::Regex::RegexFlags); \
- typedef ::clang::ast_matchers::internal::Matcher<Type> ( \
- &DefineMatcher##_Type##OverloadId)(llvm::StringRef); \
- inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
- const Type &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
- /// AST_POLYMORPHIC_MATCHER_REGEX(DefineMatcher, ReturnTypesF, Param) { ... }
- /// defines a function named DefineMatcher() that takes a regular expression
- /// string paramater and an optional RegexFlags parameter that is polymorphic in
- /// the return type.
- ///
- /// The variables are the same as for
- /// AST_MATCHER_REGEX, with the addition of NodeType, which specifies the node
- /// type of the matcher Matcher<NodeType> returned by the function matcher().
- #define AST_POLYMORPHIC_MATCHER_REGEX(DefineMatcher, ReturnTypesF, Param) \
- AST_POLYMORPHIC_MATCHER_REGEX_OVERLOAD(DefineMatcher, ReturnTypesF, Param, 0)
- #define AST_POLYMORPHIC_MATCHER_REGEX_OVERLOAD(DefineMatcher, ReturnTypesF, \
- Param, OverloadId) \
- namespace internal { \
- template <typename NodeType, typename ParamT> \
- class matcher_##DefineMatcher##OverloadId##Matcher \
- : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \
- public: \
- explicit matcher_##DefineMatcher##OverloadId##Matcher( \
- std::shared_ptr<llvm::Regex> RE) \
- : Param(std::move(RE)) {} \
- bool matches(const NodeType &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
- *Builder) const override; \
- \
- private: \
- std::shared_ptr<llvm::Regex> Param; \
- }; \
- } \
- inline ::clang::ast_matchers::internal::PolymorphicMatcher< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
- std::shared_ptr<llvm::Regex>> \
- DefineMatcher(llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags) { \
- return ::clang::ast_matchers::internal::PolymorphicMatcher< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
- std::shared_ptr<llvm::Regex>>( \
- ::clang::ast_matchers::internal::createAndVerifyRegex( \
- Param, RegexFlags, #DefineMatcher)); \
- } \
- inline ::clang::ast_matchers::internal::PolymorphicMatcher< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
- std::shared_ptr<llvm::Regex>> \
- DefineMatcher(llvm::StringRef Param) { \
- return DefineMatcher(Param, llvm::Regex::NoFlags); \
- } \
- typedef ::clang::ast_matchers::internal::PolymorphicMatcher< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
- std::shared_ptr<llvm::Regex>> ( \
- &DefineMatcher##_Type##OverloadId##Flags)( \
- llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags); \
- typedef ::clang::ast_matchers::internal::PolymorphicMatcher< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
- std::shared_ptr<llvm::Regex>> (&DefineMatcher##_Type##OverloadId)( \
- llvm::StringRef Param); \
- template <typename NodeType, typename ParamT> \
- bool internal:: \
- matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \
- const NodeType &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \
- const
- #endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|