blob: 602f8dff07feae6a5a1180ce22d3063adf798277 [file] [log] [blame]
Peter Szecsidedda6f2018-03-30 22:03:29 +00001//===- unittest/AST/DeclMatcher.h - AST unit test support ---------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_CLANG_UNITTESTS_AST_DECLMATCHER_H
11#define LLVM_CLANG_UNITTESTS_AST_DECLMATCHER_H
12
13#include "clang/ASTMatchers/ASTMatchFinder.h"
14
15namespace clang {
16namespace ast_matchers {
17
18enum class DeclMatcherKind { First, Last };
19
20// Matcher class to retrieve the first/last matched node under a given AST.
21template <typename NodeType, DeclMatcherKind MatcherKind>
22class DeclMatcher : public MatchFinder::MatchCallback {
23 NodeType *Node = nullptr;
24 void run(const MatchFinder::MatchResult &Result) override {
25 if ((MatcherKind == DeclMatcherKind::First && Node == nullptr) ||
26 MatcherKind == DeclMatcherKind::Last) {
27 Node = const_cast<NodeType *>(Result.Nodes.getNodeAs<NodeType>(""));
28 }
29 }
30public:
31 // Returns the first/last matched node under the tree rooted in `D`.
32 template <typename MatcherType>
33 NodeType *match(const Decl *D, const MatcherType &AMatcher) {
34 MatchFinder Finder;
35 Finder.addMatcher(AMatcher.bind(""), this);
36 Finder.matchAST(D->getASTContext());
37 assert(Node);
38 return Node;
39 }
40};
41template <typename NodeType>
42using LastDeclMatcher = DeclMatcher<NodeType, DeclMatcherKind::Last>;
43template <typename NodeType>
44using FirstDeclMatcher = DeclMatcher<NodeType, DeclMatcherKind::First>;
45
46template <typename NodeType>
Gabor Marton9581c332018-05-23 13:53:36 +000047class DeclCounterWithPredicate : public MatchFinder::MatchCallback {
48 using UnaryPredicate = std::function<bool(const NodeType *)>;
49 UnaryPredicate Predicate;
Peter Szecsidedda6f2018-03-30 22:03:29 +000050 unsigned Count = 0;
51 void run(const MatchFinder::MatchResult &Result) override {
Gabor Marton9581c332018-05-23 13:53:36 +000052 if (auto N = Result.Nodes.getNodeAs<NodeType>("")) {
53 if (Predicate(N))
Peter Szecsidedda6f2018-03-30 22:03:29 +000054 ++Count;
Gabor Marton9581c332018-05-23 13:53:36 +000055 }
Peter Szecsidedda6f2018-03-30 22:03:29 +000056 }
Gabor Marton9581c332018-05-23 13:53:36 +000057
Peter Szecsidedda6f2018-03-30 22:03:29 +000058public:
Gabor Marton9581c332018-05-23 13:53:36 +000059 DeclCounterWithPredicate()
60 : Predicate([](const NodeType *) { return true; }) {}
61 DeclCounterWithPredicate(UnaryPredicate P) : Predicate(P) {}
62 // Returns the number of matched nodes which satisfy the predicate under the
63 // tree rooted in `D`.
Peter Szecsidedda6f2018-03-30 22:03:29 +000064 template <typename MatcherType>
65 unsigned match(const Decl *D, const MatcherType &AMatcher) {
66 MatchFinder Finder;
67 Finder.addMatcher(AMatcher.bind(""), this);
68 Finder.matchAST(D->getASTContext());
69 return Count;
70 }
71};
72
Gabor Marton9581c332018-05-23 13:53:36 +000073template <typename NodeType>
74using DeclCounter = DeclCounterWithPredicate<NodeType>;
75
Peter Szecsidedda6f2018-03-30 22:03:29 +000076} // end namespace ast_matchers
77} // end namespace clang
78
79#endif