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