79 lines · c
1//===- unittest/AST/DeclMatcher.h - AST unit test support ---------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_UNITTESTS_AST_DECLMATCHER_H10#define LLVM_CLANG_UNITTESTS_AST_DECLMATCHER_H11 12#include "clang/ASTMatchers/ASTMatchFinder.h"13 14namespace clang {15namespace ast_matchers {16 17enum class DeclMatcherKind { First, Last };18 19// Matcher class to retrieve the first/last matched node under a given AST.20template <typename NodeType, DeclMatcherKind MatcherKind>21class DeclMatcher : public MatchFinder::MatchCallback {22 NodeType *Node = nullptr;23 void run(const MatchFinder::MatchResult &Result) override {24 if ((MatcherKind == DeclMatcherKind::First && Node == nullptr) ||25 MatcherKind == DeclMatcherKind::Last) {26 Node = const_cast<NodeType *>(Result.Nodes.getNodeAs<NodeType>(""));27 }28 }29public:30 // Returns the first/last matched node under the tree rooted in `D`.31 template <typename MatcherType>32 NodeType *match(const Decl *D, const MatcherType &AMatcher) {33 MatchFinder Finder;34 Finder.addMatcher(AMatcher.bind(""), this);35 Finder.matchAST(D->getASTContext());36 assert(Node);37 return Node;38 }39};40template <typename NodeType>41using LastDeclMatcher = DeclMatcher<NodeType, DeclMatcherKind::Last>;42template <typename NodeType>43using FirstDeclMatcher = DeclMatcher<NodeType, DeclMatcherKind::First>;44 45template <typename NodeType>46class DeclCounterWithPredicate : public MatchFinder::MatchCallback {47 using UnaryPredicate = std::function<bool(const NodeType *)>;48 UnaryPredicate Predicate;49 unsigned Count = 0;50 void run(const MatchFinder::MatchResult &Result) override {51 if (auto N = Result.Nodes.getNodeAs<NodeType>("")) {52 if (Predicate(N))53 ++Count;54 }55 }56 57public:58 DeclCounterWithPredicate()59 : Predicate([](const NodeType *) { return true; }) {}60 DeclCounterWithPredicate(UnaryPredicate P) : Predicate(P) {}61 // Returns the number of matched nodes which satisfy the predicate under the62 // tree rooted in `D`.63 template <typename MatcherType>64 unsigned match(const Decl *D, const MatcherType &AMatcher) {65 MatchFinder Finder;66 Finder.addMatcher(AMatcher.bind(""), this);67 Finder.matchAST(D->getASTContext());68 return Count;69 }70};71 72template <typename NodeType>73using DeclCounter = DeclCounterWithPredicate<NodeType>;74 75} // end namespace ast_matchers76} // end namespace clang77 78#endif79