clang 8.0.0

ASTMatchFinder.h
Go to the documentation of this file.
1 //===--- ASTMatchFinder.h - Structural query framework ----------*- C++ -*-===//
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 // Provides a way to construct an ASTConsumer that runs given matchers
11 // over the AST and invokes a given callback on every match.
12 //
13 // The general idea is to construct a matcher expression that describes a
14 // subtree match on the AST. Next, a callback that is executed every time the
15 // expression matches is registered, and the matcher is run over the AST of
16 // some code. Matched subexpressions can be bound to string IDs and easily
17 // be accessed from the registered callback. The callback can than use the
18 // AST nodes that the subexpressions matched on to output information about
19 // the match or construct changes that can be applied to the code.
20 //
21 // Example:
22 // class HandleMatch : public MatchFinder::MatchCallback {
23 // public:
24 // virtual void Run(const MatchFinder::MatchResult &Result) {
25 // const CXXRecordDecl *Class =
26 // Result.Nodes.GetDeclAs<CXXRecordDecl>("id");
27 // ...
28 // }
29 // };
30 //
31 // int main(int argc, char **argv) {
32 // ClangTool Tool(argc, argv);
33 // MatchFinder finder;
34 // finder.AddMatcher(Id("id", record(hasName("::a_namespace::AClass"))),
35 // new HandleMatch);
36 // return Tool.Run(newFrontendActionFactory(&finder));
37 // }
38 //
39 //===----------------------------------------------------------------------===//
40
41 #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHFINDER_H
42 #define LLVM_CLANG_ASTMATCHERS_ASTMATCHFINDER_H
43
44 #include "clang/ASTMatchers/ASTMatchers.h"
45 #include "llvm/ADT/SmallPtrSet.h"
46 #include "llvm/ADT/StringMap.h"
47 #include "llvm/Support/Timer.h"
48
49 namespace clang {
50
51 namespace ast_matchers {
52
53 /// A class to allow finding matches over the Clang AST.
54 ///
55 /// After creation, you can add multiple matchers to the MatchFinder via
56 /// calls to addMatcher(...).
57 ///
58 /// Once all matchers are added, newASTConsumer() returns an ASTConsumer
59 /// that will trigger the callbacks specified via addMatcher(...) when a match
60 /// is found.
61 ///
62 /// The order of matches is guaranteed to be equivalent to doing a pre-order
63 /// traversal on the AST, and applying the matchers in the order in which they
64 /// were added to the MatchFinder.
65 ///
66 /// See ASTMatchers.h for more information about how to create matchers.
67 ///
68 /// Not intended to be subclassed.
69 class MatchFinder {
70 public:
71 /// Contains all information for a given match.
72 ///
73 /// Every time a match is found, the MatchFinder will invoke the registered
74 /// MatchCallback with a MatchResult containing information about the match.
75 struct MatchResult {
76 MatchResult(const BoundNodes &Nodes, clang::ASTContext *Context);
77
78 /// Contains the nodes bound on the current match.
79 ///
80 /// This allows user code to easily extract matched AST nodes.
81 const BoundNodes Nodes;
82
83 /// Utilities for interpreting the matched AST structures.
84 /// @{
85 clang::ASTContext * const Context;
86 clang::SourceManager * const SourceManager;
87 /// @}
88 };
89
90 /// Called when the Match registered for it was successfully found
91 /// in the AST.
92 class MatchCallback {
93 public:
94 virtual ~MatchCallback();
95
96 /// Called on every match by the \c MatchFinder.
97 virtual void run(const MatchResult &Result) = 0;
98
99 /// Called at the start of each translation unit.
100 ///
101 /// Optionally override to do per translation unit tasks.
102 virtual void onStartOfTranslationUnit() {}
103
104 /// Called at the end of each translation unit.
105 ///
106 /// Optionally override to do per translation unit tasks.
107 virtual void onEndOfTranslationUnit() {}
108
109 /// An id used to group the matchers.
110 ///
111 /// This id is used, for example, for the profiling output.
112 /// It defaults to "<unknown>".
113 virtual StringRef getID() const;
114 };
115
116 /// Called when parsing is finished. Intended for testing only.
117 class ParsingDoneTestCallback {
118 public:
119 virtual ~ParsingDoneTestCallback();
120 virtual void run() = 0;
121 };
122
123 struct MatchFinderOptions {
124 struct Profiling {
125 Profiling(llvm::StringMap<llvm::TimeRecord> &Records)
126 : Records(Records) {}
127
128 /// Per bucket timing information.
129 llvm::StringMap<llvm::TimeRecord> &Records;
130 };
131
132 /// Enables per-check timers.
133 ///
134 /// It prints a report after match.
135 llvm::Optional<Profiling> CheckProfiling;
136 };
137
138 MatchFinder(MatchFinderOptions Options = MatchFinderOptions());
139 ~MatchFinder();
140
141 /// Adds a matcher to execute when running over the AST.
142 ///
143 /// Calls 'Action' with the BoundNodes on every match.
144 /// Adding more than one 'NodeMatch' allows finding different matches in a
145 /// single pass over the AST.
146 ///
147 /// Does not take ownership of 'Action'.
148 /// @{
149 void addMatcher(const DeclarationMatcher &NodeMatch,
150 MatchCallback *Action);
151 void addMatcher(const TypeMatcher &NodeMatch,
152 MatchCallback *Action);
153 void addMatcher(const StatementMatcher &NodeMatch,
154 MatchCallback *Action);
155 void addMatcher(const NestedNameSpecifierMatcher &NodeMatch,
156 MatchCallback *Action);
157 void addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch,
158 MatchCallback *Action);
159 void addMatcher(const TypeLocMatcher &NodeMatch,
160 MatchCallback *Action);
161 void addMatcher(const CXXCtorInitializerMatcher &NodeMatch,
162 MatchCallback *Action);
163 /// @}
164
165 /// Adds a matcher to execute when running over the AST.
166 ///
167 /// This is similar to \c addMatcher(), but it uses the dynamic interface. It
168 /// is more flexible, but the lost type information enables a caller to pass
169 /// a matcher that cannot match anything.
170 ///
171 /// \returns \c true if the matcher is a valid top-level matcher, \c false
172 /// otherwise.
173 bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch,
174 MatchCallback *Action);
175
176 /// Creates a clang ASTConsumer that finds all matches.
177 std::unique_ptr<clang::ASTConsumer> newASTConsumer();
178
179 /// Calls the registered callbacks on all matches on the given \p Node.
180 ///
181 /// Note that there can be multiple matches on a single node, for
182 /// example when using decl(forEachDescendant(stmt())).
183 ///
184 /// @{
185 template <typename T> void match(const T &Node, ASTContext &Context) {
186 match(clang::ast_type_traits::DynTypedNode::create(Node), Context);
187 }
188 void match(const clang::ast_type_traits::DynTypedNode &Node,
189 ASTContext &Context);
190 /// @}
191
192 /// Finds all matches in the given AST.
193 void matchAST(ASTContext &Context);
194
195 /// Registers a callback to notify the end of parsing.
196 ///
197 /// The provided closure is called after parsing is done, before the AST is
198 /// traversed. Useful for benchmarking.
199 /// Each call to FindAll(...) will call the closure once.
200 void registerTestCallbackAfterParsing(ParsingDoneTestCallback *ParsingDone);
201
202 /// For each \c Matcher<> a \c MatchCallback that will be called
203 /// when it matches.
204 struct MatchersByType {
205 std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *>>
206 DeclOrStmt;
207 std::vector<std::pair<TypeMatcher, MatchCallback *>> Type;
208 std::vector<std::pair<NestedNameSpecifierMatcher, MatchCallback *>>
209 NestedNameSpecifier;
210 std::vector<std::pair<NestedNameSpecifierLocMatcher, MatchCallback *>>
211 NestedNameSpecifierLoc;
212 std::vector<std::pair<TypeLocMatcher, MatchCallback *>> TypeLoc;
213 std::vector<std::pair<CXXCtorInitializerMatcher, MatchCallback *>> CtorInit;
214 /// All the callbacks in one container to simplify iteration.
215 llvm::SmallPtrSet<MatchCallback *, 16> AllCallbacks;
216 };
217
218 private:
219 MatchersByType Matchers;
220
221 MatchFinderOptions Options;
222
223 /// Called when parsing is done.
224 ParsingDoneTestCallback *ParsingDone;
225 };
226
227 /// Returns the results of matching \p Matcher on \p Node.
228 ///
229 /// Collects the \c BoundNodes of all callback invocations when matching
230 /// \p Matcher on \p Node and returns the collected results.
231 ///
232 /// Multiple results occur when using matchers like \c forEachDescendant,
233 /// which generate a result for each sub-match.
234 ///
235 /// If you want to find all matches on the sub-tree rooted at \c Node (rather
236 /// than only the matches on \c Node itself), surround the \c Matcher with a
237 /// \c findAll().
238 ///
239 /// \see selectFirst
240 /// @{
241 template <typename MatcherT, typename NodeT>
242 SmallVector<BoundNodes, 1>
243 match(MatcherT Matcher, const NodeT &Node, ASTContext &Context);
244
245 template <typename MatcherT>
246 SmallVector<BoundNodes, 1>
247 match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
248 ASTContext &Context);
249 /// @}
250
251 /// Returns the results of matching \p Matcher on the translation unit of
252 /// \p Context and collects the \c BoundNodes of all callback invocations.
253 template <typename MatcherT>
254 SmallVector<BoundNodes, 1> match(MatcherT Matcher, ASTContext &Context);
255
256 /// Returns the first result of type \c NodeT bound to \p BoundTo.
257 ///
258 /// Returns \c NULL if there is no match, or if the matching node cannot be
259 /// casted to \c NodeT.
260 ///
261 /// This is useful in combanation with \c match():
262 /// \code
263 /// const Decl *D = selectFirst<Decl>("id", match(Matcher.bind("id"),
264 /// Node, Context));
265 /// \endcode
266 template <typename NodeT>
267 const NodeT *
268 selectFirst(StringRef BoundTo, const SmallVectorImpl<BoundNodes> &Results) {
269 for (const BoundNodes &N : Results) {
270 if (const NodeT *Node = N.getNodeAs<NodeT>(BoundTo))
271 return Node;
272 }
273 return nullptr;
274 }
275
276 namespace internal {
277 class CollectMatchesCallback : public MatchFinder::MatchCallback {
278 public:
279 void run(const MatchFinder::MatchResult &Result) override {
280 Nodes.push_back(Result.Nodes);
281 }
282 SmallVector<BoundNodes, 1> Nodes;
283 };
284 }
285
286 template <typename MatcherT>
287 SmallVector<BoundNodes, 1>
288 match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
289 ASTContext &Context) {
290 internal::CollectMatchesCallback Callback;
291 MatchFinder Finder;
292 Finder.addMatcher(Matcher, &Callback);
293 Finder.match(Node, Context);
294 return std::move(Callback.Nodes);
295 }
296
297 template <typename MatcherT, typename NodeT>
298 SmallVector<BoundNodes, 1>
299 match(MatcherT Matcher, const NodeT &Node, ASTContext &Context) {
300 return match(Matcher, ast_type_traits::DynTypedNode::create(Node), Context);
301 }
302
303 template <typename MatcherT>
304 SmallVector<BoundNodes, 1>
305 match(MatcherT Matcher, ASTContext &Context) {
306 internal::CollectMatchesCallback Callback;
307 MatchFinder Finder;
308 Finder.addMatcher(Matcher, &Callback);
309 Finder.matchAST(Context);
310 return std::move(Callback.Nodes);
311 }
312
313 } // end namespace ast_matchers
314 } // end namespace clang
315
316 #endif
clang::ast_matchers::MatchFinder
A class to allow finding matches over the Clang AST.
Definition: ASTMatchFinder.h:69
clang::ast_matchers::NestedNameSpecifierMatcher
internal::Matcher< NestedNameSpecifier > NestedNameSpecifierMatcher
Definition: ASTMatchers.h:149
clang::ast_matchers::selectFirst
const NodeT * selectFirst(StringRef BoundTo, const SmallVectorImpl< BoundNodes > &Results)
Returns the first result of type NodeT bound to BoundTo.
Definition: ASTMatchFinder.h:268
clang::ast_matchers::internal::CollectMatchesCallback
Definition: ASTMatchFinder.h:277
clang::ast_matchers::StatementMatcher
internal::Matcher< Stmt > StatementMatcher
Definition: ASTMatchers.h:146
clang::ast_matchers::MatchFinder::MatchFinderOptions::Profiling::Records
llvm::StringMap< llvm::TimeRecord > & Records
Per bucket timing information.
Definition: ASTMatchFinder.h:129
clang::ast_matchers::MatchFinder::MatchersByType::AllCallbacks
llvm::SmallPtrSet< MatchCallback *, 16 > AllCallbacks
All the callbacks in one container to simplify iteration.
Definition: ASTMatchFinder.h:215
clang::ast_matchers::MatchFinder::ParsingDoneTestCallback
Called when parsing is finished. Intended for testing only.
Definition: ASTMatchFinder.h:117
clang::ast_matchers::MatchFinder::MatchFinder
MatchFinder(MatchFinderOptions Options=MatchFinderOptions())
Definition: ASTMatchFinder.cpp:948
clang::ast_matchers::TypeMatcher
internal::Matcher< QualType > TypeMatcher
Definition: ASTMatchers.h:147
clang::ast_matchers::MatchFinder::match
void match(const T &Node, ASTContext &Context)
Calls the registered callbacks on all matches on the given Node.
Definition: ASTMatchFinder.h:185
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:155
llvm::Optional
Definition: LLVM.h:38
llvm::SmallVectorImpl
Definition: LLVM.h:37
clang::ast_matchers::MatchFinder::addMatcher
void addMatcher(const DeclarationMatcher &NodeMatch, MatchCallback *Action)
Adds a matcher to execute when running over the AST.
Definition: ASTMatchFinder.cpp:953
ASTMatchers.h
clang::ast_matchers::MatchFinder::MatchersByType::CtorInit
std::vector< std::pair< CXXCtorInitializerMatcher, MatchCallback * > > CtorInit
Definition: ASTMatchFinder.h:213
clang::ast_matchers::MatchFinder::MatchResult
Contains all information for a given match.
Definition: ASTMatchFinder.h:75
clang::ast_matchers::MatchFinder::registerTestCallbackAfterParsing
void registerTestCallbackAfterParsing(ParsingDoneTestCallback *ParsingDone)
Registers a callback to notify the end of parsing.
Definition: ASTMatchFinder.cpp:1041
clang::ast_matchers::internal::CollectMatchesCallback::Nodes
SmallVector< BoundNodes, 1 > Nodes
Definition: ASTMatchFinder.h:282
clang::ast_matchers::MatchFinder::MatchResult::MatchResult
MatchResult(const BoundNodes &Nodes, clang::ASTContext *Context)
Definition: ASTMatchFinder.cpp:940
clang::ast_matchers::MatchFinder::MatchFinderOptions::Profiling::Profiling
Profiling(llvm::StringMap< llvm::TimeRecord > &Records)
Definition: ASTMatchFinder.h:125
clang::ast_matchers::MatchFinder::~MatchFinder
~MatchFinder()
Definition: ASTMatchFinder.cpp:951
clang::ast_matchers::MatchFinder::newASTConsumer
std::unique_ptr< clang::ASTConsumer > newASTConsumer()
Creates a clang ASTConsumer that finds all matches.
Definition: ASTMatchFinder.cpp:1022
clang::ast_matchers::BoundNodes
Maps string IDs to AST nodes matched by parts of a matcher.
Definition: ASTMatchers.h:102
clang::ast_matchers::MatchFinder::MatchFinderOptions
Definition: ASTMatchFinder.h:123
llvm::getID
llvm::DOTGraphTraits< ExplodedGraph * > DefaultDOTGraphTraits const ExplodedNode const ExplodedNode *Out<< "\l\|";Out<< "StateID: ST"<< State-> getID()<< "
clang::ast_matchers::MatchFinder::MatchResult::Context
clang::ASTContext *const Context
Utilities for interpreting the matched AST structures.
Definition: ASTMatchFinder.h:85
clang::ast_matchers::MatchFinder::matchAST
void matchAST(ASTContext &Context)
Finds all matches in the given AST.
Definition: ASTMatchFinder.cpp:1033
clang::ast_matchers::MatchFinder::MatchersByType::NestedNameSpecifierLoc
std::vector< std::pair< NestedNameSpecifierLocMatcher, MatchCallback * > > NestedNameSpecifierLoc
Definition: ASTMatchFinder.h:211
llvm::SmallVector
Definition: LLVM.h:36
clang::ast_matchers::MatchFinder::MatchersByType::DeclOrStmt
std::vector< std::pair< internal::DynTypedMatcher, MatchCallback * > > DeclOrStmt
Definition: ASTMatchFinder.h:206
clang::ast_matchers::MatchFinder::MatchFinderOptions::CheckProfiling
llvm::Optional< Profiling > CheckProfiling
Enables per-check timers.
Definition: ASTMatchFinder.h:135
clang::ast_type_traits::DynTypedNode::create
static DynTypedNode create(const T &Node)
Creates a DynTypedNode from Node.
Definition: ASTTypeTraits.h:216
clang::ast_matchers::MatchFinder::MatchersByType::NestedNameSpecifier
std::vector< std::pair< NestedNameSpecifierMatcher, MatchCallback * > > NestedNameSpecifier
Definition: ASTMatchFinder.h:209
clang::ast_matchers::MatchFinder::MatchersByType::Type
std::vector< std::pair< TypeMatcher, MatchCallback * > > Type
Definition: ASTMatchFinder.h:207
clang::ast_matchers::MatchFinder::MatchCallback::onEndOfTranslationUnit
virtual void onEndOfTranslationUnit()
Called at the end of each translation unit.
Definition: ASTMatchFinder.h:107
clang::ast_matchers::MatchFinder::MatchResult::Nodes
const BoundNodes Nodes
Contains the nodes bound on the current match.
Definition: ASTMatchFinder.h:81
Node
ast_type_traits::DynTypedNode Node
Definition: ASTMatchFinder.cpp:61
clang::ast_matchers::MatchFinder::MatchersByType
For each Matcher<> a MatchCallback that will be called when it matches.
Definition: ASTMatchFinder.h:204
clang
Dataflow Directional Tag Classes.
Definition: CFGReachabilityAnalysis.h:22
ast_matchers
clang::ast_matchers::CXXCtorInitializerMatcher
internal::Matcher< CXXCtorInitializer > CXXCtorInitializerMatcher
Definition: ASTMatchers.h:151
clang::ast_type_traits::DynTypedNode
A dynamically typed AST node container.
Definition: ASTTypeTraits.h:212
clang::ast_matchers::MatchFinder::MatchersByType::TypeLoc
std::vector< std::pair< TypeLocMatcher, MatchCallback * > > TypeLoc
Definition: ASTMatchFinder.h:212
clang::ast_matchers::MatchFinder::MatchFinderOptions::Profiling
Definition: ASTMatchFinder.h:124
clang::ast_matchers::NestedNameSpecifierLocMatcher
internal::Matcher< NestedNameSpecifierLoc > NestedNameSpecifierLocMatcher
Definition: ASTMatchers.h:150
clang::ast_matchers::TypeLocMatcher
internal::Matcher< TypeLoc > TypeLocMatcher
Definition: ASTMatchers.h:148
clang::ast_matchers::internal::CollectMatchesCallback::run
void run(const MatchFinder::MatchResult &Result) override
Called on every match by the MatchFinder.
Definition: ASTMatchFinder.h:279
clang::ast_matchers::MatchFinder::MatchCallback
Called when the Match registered for it was successfully found in the AST.
Definition: ASTMatchFinder.h:92
clang::ast_matchers::MatchFinder::MatchResult::SourceManager
clang::SourceManager *const SourceManager
Definition: ASTMatchFinder.h:86
clang::ast_matchers::MatchFinder::MatchCallback::onStartOfTranslationUnit
virtual void onStartOfTranslationUnit()
Called at the start of each translation unit.
Definition: ASTMatchFinder.h:102
clang::SourceManager
This class handles loading and caching of source files into memory.
Definition: SourceManager.h:582
clang::ast_matchers::DeclarationMatcher
internal::Matcher< Decl > DeclarationMatcher
Types of matchers for the top-level classes in the AST class hierarchy.
Definition: ASTMatchers.h:145
clang::ast_matchers::MatchFinder::addDynamicMatcher
bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, MatchCallback *Action)
Adds a matcher to execute when running over the AST.
Definition: ASTMatchFinder.cpp:995