|  | //===- unittest/AST/DeclMatcher.h - AST unit test support ---------------===// | 
|  | // | 
|  | // 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 | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #ifndef LLVM_CLANG_UNITTESTS_AST_DECLMATCHER_H | 
|  | #define LLVM_CLANG_UNITTESTS_AST_DECLMATCHER_H | 
|  |  | 
|  | #include "clang/ASTMatchers/ASTMatchFinder.h" | 
|  |  | 
|  | namespace clang { | 
|  | namespace ast_matchers { | 
|  |  | 
|  | enum class DeclMatcherKind { First, Last }; | 
|  |  | 
|  | // Matcher class to retrieve the first/last matched node under a given AST. | 
|  | template <typename NodeType, DeclMatcherKind MatcherKind> | 
|  | class DeclMatcher : public MatchFinder::MatchCallback { | 
|  | NodeType *Node = nullptr; | 
|  | void run(const MatchFinder::MatchResult &Result) override { | 
|  | if ((MatcherKind == DeclMatcherKind::First && Node == nullptr) || | 
|  | MatcherKind == DeclMatcherKind::Last) { | 
|  | Node = const_cast<NodeType *>(Result.Nodes.getNodeAs<NodeType>("")); | 
|  | } | 
|  | } | 
|  | public: | 
|  | // Returns the first/last matched node under the tree rooted in `D`. | 
|  | template <typename MatcherType> | 
|  | NodeType *match(const Decl *D, const MatcherType &AMatcher) { | 
|  | MatchFinder Finder; | 
|  | Finder.addMatcher(AMatcher.bind(""), this); | 
|  | Finder.matchAST(D->getASTContext()); | 
|  | assert(Node); | 
|  | return Node; | 
|  | } | 
|  | }; | 
|  | template <typename NodeType> | 
|  | using LastDeclMatcher = DeclMatcher<NodeType, DeclMatcherKind::Last>; | 
|  | template <typename NodeType> | 
|  | using FirstDeclMatcher = DeclMatcher<NodeType, DeclMatcherKind::First>; | 
|  |  | 
|  | template <typename NodeType> | 
|  | class DeclCounterWithPredicate : public MatchFinder::MatchCallback { | 
|  | using UnaryPredicate = std::function<bool(const NodeType *)>; | 
|  | UnaryPredicate Predicate; | 
|  | unsigned Count = 0; | 
|  | void run(const MatchFinder::MatchResult &Result) override { | 
|  | if (auto N = Result.Nodes.getNodeAs<NodeType>("")) { | 
|  | if (Predicate(N)) | 
|  | ++Count; | 
|  | } | 
|  | } | 
|  |  | 
|  | public: | 
|  | DeclCounterWithPredicate() | 
|  | : Predicate([](const NodeType *) { return true; }) {} | 
|  | DeclCounterWithPredicate(UnaryPredicate P) : Predicate(P) {} | 
|  | // Returns the number of matched nodes which satisfy the predicate under the | 
|  | // tree rooted in `D`. | 
|  | template <typename MatcherType> | 
|  | unsigned match(const Decl *D, const MatcherType &AMatcher) { | 
|  | MatchFinder Finder; | 
|  | Finder.addMatcher(AMatcher.bind(""), this); | 
|  | Finder.matchAST(D->getASTContext()); | 
|  | return Count; | 
|  | } | 
|  | }; | 
|  |  | 
|  | template <typename NodeType> | 
|  | using DeclCounter = DeclCounterWithPredicate<NodeType>; | 
|  |  | 
|  | } // end namespace ast_matchers | 
|  | } // end namespace clang | 
|  |  | 
|  | #endif |