1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
| //===- 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
|