clang  3.9.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 
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 /// \brief 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  /// \brief 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 {
77 
78  /// \brief Contains the nodes bound on the current match.
79  ///
80  /// This allows user code to easily extract matched AST nodes.
82 
83  /// \brief Utilities for interpreting the matched AST structures.
84  /// @{
87  /// @}
88  };
89 
90  /// \brief Called when the Match registered for it was successfully found
91  /// in the AST.
92  class MatchCallback {
93  public:
94  virtual ~MatchCallback();
95 
96  /// \brief Called on every match by the \c MatchFinder.
97  virtual void run(const MatchResult &Result) = 0;
98 
99  /// \brief Called at the start of each translation unit.
100  ///
101  /// Optionally override to do per translation unit tasks.
102  virtual void onStartOfTranslationUnit() {}
103 
104  /// \brief Called at the end of each translation unit.
105  ///
106  /// Optionally override to do per translation unit tasks.
107  virtual void onEndOfTranslationUnit() {}
108 
109  /// \brief 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  /// \brief Called when parsing is finished. Intended for testing only.
118  public:
119  virtual ~ParsingDoneTestCallback();
120  virtual void run() = 0;
121  };
122 
124  struct Profiling {
125  Profiling(llvm::StringMap<llvm::TimeRecord> &Records)
126  : Records(Records) {}
127 
128  /// \brief Per bucket timing information.
129  llvm::StringMap<llvm::TimeRecord> &Records;
130  };
131 
132  /// \brief Enables per-check timers.
133  ///
134  /// It prints a report after match.
136  };
137 
139  ~MatchFinder();
140 
141  /// \brief 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,
151  void addMatcher(const TypeMatcher &NodeMatch,
153  void addMatcher(const StatementMatcher &NodeMatch,
155  void addMatcher(const NestedNameSpecifierMatcher &NodeMatch,
157  void addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch,
159  void addMatcher(const TypeLocMatcher &NodeMatch,
161  /// @}
162 
163  /// \brief Adds a matcher to execute when running over the AST.
164  ///
165  /// This is similar to \c addMatcher(), but it uses the dynamic interface. It
166  /// is more flexible, but the lost type information enables a caller to pass
167  /// a matcher that cannot match anything.
168  ///
169  /// \returns \c true if the matcher is a valid top-level matcher, \c false
170  /// otherwise.
171  bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch,
173 
174  /// \brief Creates a clang ASTConsumer that finds all matches.
175  std::unique_ptr<clang::ASTConsumer> newASTConsumer();
176 
177  /// \brief Calls the registered callbacks on all matches on the given \p Node.
178  ///
179  /// Note that there can be multiple matches on a single node, for
180  /// example when using decl(forEachDescendant(stmt())).
181  ///
182  /// @{
183  template <typename T> void match(const T &Node, ASTContext &Context) {
185  }
188  /// @}
189 
190  /// \brief Finds all matches in the given AST.
191  void matchAST(ASTContext &Context);
192 
193  /// \brief Registers a callback to notify the end of parsing.
194  ///
195  /// The provided closure is called after parsing is done, before the AST is
196  /// traversed. Useful for benchmarking.
197  /// Each call to FindAll(...) will call the closure once.
198  void registerTestCallbackAfterParsing(ParsingDoneTestCallback *ParsingDone);
199 
200  /// \brief For each \c Matcher<> a \c MatchCallback that will be called
201  /// when it matches.
202  struct MatchersByType {
203  std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *>>
205  std::vector<std::pair<TypeMatcher, MatchCallback *>> Type;
206  std::vector<std::pair<NestedNameSpecifierMatcher, MatchCallback *>>
208  std::vector<std::pair<NestedNameSpecifierLocMatcher, MatchCallback *>>
210  std::vector<std::pair<TypeLocMatcher, MatchCallback *>> TypeLoc;
211  /// \brief All the callbacks in one container to simplify iteration.
212  llvm::SmallPtrSet<MatchCallback *, 16> AllCallbacks;
213  };
214 
215 private:
216  MatchersByType Matchers;
217 
218  MatchFinderOptions Options;
219 
220  /// \brief Called when parsing is done.
221  ParsingDoneTestCallback *ParsingDone;
222 };
223 
224 /// \brief Returns the results of matching \p Matcher on \p Node.
225 ///
226 /// Collects the \c BoundNodes of all callback invocations when matching
227 /// \p Matcher on \p Node and returns the collected results.
228 ///
229 /// Multiple results occur when using matchers like \c forEachDescendant,
230 /// which generate a result for each sub-match.
231 ///
232 /// \see selectFirst
233 /// @{
234 template <typename MatcherT, typename NodeT>
236 match(MatcherT Matcher, const NodeT &Node, ASTContext &Context);
237 
238 template <typename MatcherT>
242 /// @}
243 
244 /// \brief Returns the results of matching \p Matcher on the translation unit of
245 /// \p Context and collects the \c BoundNodes of all callback invocations.
246 template <typename MatcherT>
248 
249 /// \brief Returns the first result of type \c NodeT bound to \p BoundTo.
250 ///
251 /// Returns \c NULL if there is no match, or if the matching node cannot be
252 /// casted to \c NodeT.
253 ///
254 /// This is useful in combanation with \c match():
255 /// \code
256 /// const Decl *D = selectFirst<Decl>("id", match(Matcher.bind("id"),
257 /// Node, Context));
258 /// \endcode
259 template <typename NodeT>
260 const NodeT *
261 selectFirst(StringRef BoundTo, const SmallVectorImpl<BoundNodes> &Results) {
262  for (const BoundNodes &N : Results) {
263  if (const NodeT *Node = N.getNodeAs<NodeT>(BoundTo))
264  return Node;
265  }
266  return nullptr;
267 }
268 
269 namespace internal {
271 public:
272  void run(const MatchFinder::MatchResult &Result) override {
273  Nodes.push_back(Result.Nodes);
274  }
276 };
277 }
278 
279 template <typename MatcherT>
282  ASTContext &Context) {
285  Finder.addMatcher(Matcher, &Callback);
286  Finder.match(Node, Context);
287  return std::move(Callback.Nodes);
288 }
289 
290 template <typename MatcherT, typename NodeT>
292 match(MatcherT Matcher, const NodeT &Node, ASTContext &Context) {
293  return match(Matcher, ast_type_traits::DynTypedNode::create(Node), Context);
294 }
295 
296 template <typename MatcherT>
301  Finder.addMatcher(Matcher, &Callback);
302  Finder.matchAST(Context);
303  return std::move(Callback.Nodes);
304 }
305 
306 } // end namespace ast_matchers
307 } // end namespace clang
308 
309 #endif
A class to allow finding matches over the Clang AST.
const NodeT * selectFirst(StringRef BoundTo, const SmallVectorImpl< BoundNodes > &Results)
Returns the first result of type NodeT bound to BoundTo.
llvm::StringMap< llvm::TimeRecord > & Records
Per bucket timing information.
internal::Matcher< Decl > DeclarationMatcher
Types of matchers for the top-level classes in the AST class hierarchy.
Definition: ASTMatchers.h:123
const DynTypedMatcher *const Matcher
llvm::SmallPtrSet< MatchCallback *, 16 > AllCallbacks
All the callbacks in one container to simplify iteration.
Called when parsing is finished. Intended for testing only.
MatchFinder(MatchFinderOptions Options=MatchFinderOptions())
void match(const T &Node, ASTContext &Context)
Calls the registered callbacks on all matches on the given Node.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:92
FrontendAction * Action
Definition: Tooling.cpp:201
void addMatcher(const DeclarationMatcher &NodeMatch, MatchCallback *Action)
Adds a matcher to execute when running over the AST.
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
internal::Matcher< Stmt > StatementMatcher
Definition: ASTMatchers.h:124
ASTContext * Context
internal::Matcher< NestedNameSpecifierLoc > NestedNameSpecifierLocMatcher
Definition: ASTMatchers.h:128
virtual StringRef getID() const
An id used to group the matchers.
MatchFinder::MatchCallback * Callback
Contains all information for a given match.
void registerTestCallbackAfterParsing(ParsingDoneTestCallback *ParsingDone)
Registers a callback to notify the end of parsing.
MatchResult(const BoundNodes &Nodes, clang::ASTContext *Context)
Profiling(llvm::StringMap< llvm::TimeRecord > &Records)
The result type of a method or function.
std::unique_ptr< clang::ASTConsumer > newASTConsumer()
Creates a clang ASTConsumer that finds all matches.
Maps string IDs to AST nodes matched by parts of a matcher.
Definition: ASTMatchers.h:68
ASTMatchFinder *const Finder
virtual void run(const MatchResult &Result)=0
Called on every match by the MatchFinder.
clang::ASTContext *const Context
Utilities for interpreting the matched AST structures.
internal::Matcher< TypeLoc > TypeLocMatcher
Definition: ASTMatchers.h:126
void matchAST(ASTContext &Context)
Finds all matches in the given AST.
std::vector< std::pair< NestedNameSpecifierLocMatcher, MatchCallback * > > NestedNameSpecifierLoc
std::vector< std::pair< internal::DynTypedMatcher, MatchCallback * > > DeclOrStmt
llvm::Optional< Profiling > CheckProfiling
Enables per-check timers.
static DynTypedNode create(const T &Node)
Creates a DynTypedNode from Node.
std::vector< std::pair< NestedNameSpecifierMatcher, MatchCallback * > > NestedNameSpecifier
std::vector< std::pair< TypeMatcher, MatchCallback * > > Type
virtual void onEndOfTranslationUnit()
Called at the end of each translation unit.
const BoundNodes Nodes
Contains the nodes bound on the current match.
ast_type_traits::DynTypedNode Node
For each Matcher<> a MatchCallback that will be called when it matches.
internal::Matcher< NestedNameSpecifier > NestedNameSpecifierMatcher
Definition: ASTMatchers.h:127
A dynamically typed AST node container.
std::vector< std::pair< TypeLocMatcher, MatchCallback * > > TypeLoc
internal::Matcher< QualType > TypeMatcher
Definition: ASTMatchers.h:125
void run(const MatchFinder::MatchResult &Result) override
Called on every match by the MatchFinder.
Called when the Match registered for it was successfully found in the AST.
clang::SourceManager *const SourceManager
virtual void onStartOfTranslationUnit()
Called at the start of each translation unit.
This class handles loading and caching of source files into memory.
bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, MatchCallback *Action)
Adds a matcher to execute when running over the AST.