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