clang: include/clang/Analysis/FlowSensitive/MatchSwitch.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_MATCHSWITCH_H_
23#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_MATCHSWITCH_H_
24
30#include "llvm/ADT/StringRef.h"
31#include
32#include
33#include <type_traits>
34#include
35#include
36
38namespace dataflow {
39
40
44
45
48};
49
50
51
52
53
54
58
59
62};
63
64template
66
67template <typename T, typename State, typename Result = void>
70
71template <typename BaseT, typename State, typename Result = void>
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95template <typename BaseT, typename State, typename Result = void>
97public:
98
99
100
101
102
103
104 template
107 static_assert(std::is_base_of<BaseT, NodeT>::value,
108 "NodeT must be derived from BaseT.");
109 Matchers.push_back(std::move(M));
110 Actions.push_back(
111 [A = std::move(A)](const BaseT *Node,
113 State &S) { return A(cast(Node), R, S); });
114 return std::move(*this);
115 }
116
118 return [Matcher = BuildMatcher(), Actions = std::move(Actions)](
121 if (Results.empty()) {
123 }
124
125
126 for (const auto &Element : Results[0].getMap()) {
127 llvm::StringRef ID(Element.first);
128 size_t Index = 0;
129 if (ID.consume_front("Tag") && .getAsInteger(10, Index) &&
130 Index < Actions.size()) {
131 return Actions[Index](
134 }
135 }
137 };
138 }
139
140private:
141 ast_matchers::internal::DynTypedMatcher BuildMatcher() {
145 using ast_matchers::internal::DynTypedMatcher;
146 if (Matchers.empty())
148 for (int I = 0, N = Matchers.size(); I < N; ++I) {
149 std::string Tag = ("Tag" + llvm::Twine(I)).str();
150
151 Matchers[I].setAllowBind(true);
152 auto M = *Matchers[I].tryBind(Tag);
153
154
155
156
157
158 Matchers[I] =
159 !M.getTraversalKind() ? M.withTraversalKind(TK_AsIs) : std::move(M);
160 }
161
162
163 return DynTypedMatcher::constructVariadic(
164 DynTypedMatcher::VO_AnyOf, ASTNodeKind::getFromNodeKind(),
165 std::move(Matchers));
166 }
167
168 std::vector<ast_matchers::internal::DynTypedMatcher> Matchers;
169 std::vector<MatchSwitchAction<BaseT, State, Result>> Actions;
170};
171
172}
173}
174#endif
Defines the clang::ASTContext interface.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Collects cases of a "match switch": a collection of matchers paired with callbacks,...
ASTMatchSwitchBuilder && CaseOf(MatchSwitchMatcher< BaseT > M, MatchSwitchAction< NodeT, State, Result > A) &&
Registers an action that will be triggered by the match of a pattern against the input statement.
ASTMatchSwitch< BaseT, State, Result > Build() &&
Holds the state of the program (store and heap) at a given program point.
const internal::VariadicOperatorMatcherFunc< 1, 1 > unless
Matches if the provided matcher does not match.
internal::TrueMatcher anything()
Matches any node.
SmallVector< BoundNodes, 1 > matchDynamic(internal::DynTypedMatcher Matcher, const DynTypedNode &Node, ASTContext &Context)
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
std::function< Result(const T *, const ast_matchers::MatchFinder::MatchResult &, State &)> MatchSwitchAction
std::function< Result(const BaseT &, ASTContext &, State &)> ASTMatchSwitch
ast_matchers::internal::Matcher< T > MatchSwitchMatcher
The JSON file list parser is used to communicate input to InstallAPI.
@ TK_AsIs
Will traverse all child nodes.
@ Result
The result type of a method or function.
const FunctionProtoType * T
Contains all information for a given match.
A read-only version of TransferState.
const LatticeT & Lattice
Current lattice element.
TransferStateForDiagnostics(const LatticeT &Lattice, const Environment &Env)
A common form of state shared between the cases of a transfer function.
TransferState(LatticeT &Lattice, Environment &Env)
LatticeT & Lattice
Current lattice element.