clang API Documentation
00001 //===--- ASTMatchFinder.h - Structural query framework ----------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // Provides a way to construct an ASTConsumer that runs given matchers 00011 // over the AST and invokes a given callback on every match. 00012 // 00013 // The general idea is to construct a matcher expression that describes a 00014 // subtree match on the AST. Next, a callback that is executed every time the 00015 // expression matches is registered, and the matcher is run over the AST of 00016 // some code. Matched subexpressions can be bound to string IDs and easily 00017 // be accessed from the registered callback. The callback can than use the 00018 // AST nodes that the subexpressions matched on to output information about 00019 // the match or construct changes that can be applied to the code. 00020 // 00021 // Example: 00022 // class HandleMatch : public MatchFinder::MatchCallback { 00023 // public: 00024 // virtual void Run(const MatchFinder::MatchResult &Result) { 00025 // const CXXRecordDecl *Class = 00026 // Result.Nodes.GetDeclAs<CXXRecordDecl>("id"); 00027 // ... 00028 // } 00029 // }; 00030 // 00031 // int main(int argc, char **argv) { 00032 // ClangTool Tool(argc, argv); 00033 // MatchFinder finder; 00034 // finder.AddMatcher(Id("id", record(hasName("::a_namespace::AClass"))), 00035 // new HandleMatch); 00036 // return Tool.Run(newFrontendActionFactory(&finder)); 00037 // } 00038 // 00039 //===----------------------------------------------------------------------===// 00040 00041 #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHFINDER_H 00042 #define LLVM_CLANG_ASTMATCHERS_ASTMATCHFINDER_H 00043 00044 #include "clang/ASTMatchers/ASTMatchers.h" 00045 #include "llvm/ADT/StringMap.h" 00046 #include "llvm/Support/Timer.h" 00047 00048 namespace clang { 00049 00050 namespace ast_matchers { 00051 00052 /// \brief A class to allow finding matches over the Clang AST. 00053 /// 00054 /// After creation, you can add multiple matchers to the MatchFinder via 00055 /// calls to addMatcher(...). 00056 /// 00057 /// Once all matchers are added, newASTConsumer() returns an ASTConsumer 00058 /// that will trigger the callbacks specified via addMatcher(...) when a match 00059 /// is found. 00060 /// 00061 /// The order of matches is guaranteed to be equivalent to doing a pre-order 00062 /// traversal on the AST, and applying the matchers in the order in which they 00063 /// were added to the MatchFinder. 00064 /// 00065 /// See ASTMatchers.h for more information about how to create matchers. 00066 /// 00067 /// Not intended to be subclassed. 00068 class MatchFinder { 00069 public: 00070 /// \brief Contains all information for a given match. 00071 /// 00072 /// Every time a match is found, the MatchFinder will invoke the registered 00073 /// MatchCallback with a MatchResult containing information about the match. 00074 struct MatchResult { 00075 MatchResult(const BoundNodes &Nodes, clang::ASTContext *Context); 00076 00077 /// \brief Contains the nodes bound on the current match. 00078 /// 00079 /// This allows user code to easily extract matched AST nodes. 00080 const BoundNodes Nodes; 00081 00082 /// \brief Utilities for interpreting the matched AST structures. 00083 /// @{ 00084 clang::ASTContext * const Context; 00085 clang::SourceManager * const SourceManager; 00086 /// @} 00087 }; 00088 00089 /// \brief Called when the Match registered for it was successfully found 00090 /// in the AST. 00091 class MatchCallback { 00092 public: 00093 virtual ~MatchCallback(); 00094 00095 /// \brief Called on every match by the \c MatchFinder. 00096 virtual void run(const MatchResult &Result) = 0; 00097 00098 /// \brief Called at the start of each translation unit. 00099 /// 00100 /// Optionally override to do per translation unit tasks. 00101 virtual void onStartOfTranslationUnit() {} 00102 00103 /// \brief Called at the end of each translation unit. 00104 /// 00105 /// Optionally override to do per translation unit tasks. 00106 virtual void onEndOfTranslationUnit() {} 00107 00108 /// \brief An id used to group the matchers. 00109 /// 00110 /// This id is used, for example, for the profiling output. 00111 /// It defaults to "<unknown>". 00112 virtual StringRef getID() const; 00113 }; 00114 00115 /// \brief Called when parsing is finished. Intended for testing only. 00116 class ParsingDoneTestCallback { 00117 public: 00118 virtual ~ParsingDoneTestCallback(); 00119 virtual void run() = 0; 00120 }; 00121 00122 struct MatchFinderOptions { 00123 struct Profiling { 00124 Profiling(llvm::StringMap<llvm::TimeRecord> &Records) 00125 : Records(Records) {} 00126 00127 /// \brief Per bucket timing information. 00128 llvm::StringMap<llvm::TimeRecord> &Records; 00129 }; 00130 00131 /// \brief Enables per-check timers. 00132 /// 00133 /// It prints a report after match. 00134 llvm::Optional<Profiling> CheckProfiling; 00135 }; 00136 00137 MatchFinder(MatchFinderOptions Options = MatchFinderOptions()); 00138 ~MatchFinder(); 00139 00140 /// \brief Adds a matcher to execute when running over the AST. 00141 /// 00142 /// Calls 'Action' with the BoundNodes on every match. 00143 /// Adding more than one 'NodeMatch' allows finding different matches in a 00144 /// single pass over the AST. 00145 /// 00146 /// Does not take ownership of 'Action'. 00147 /// @{ 00148 void addMatcher(const DeclarationMatcher &NodeMatch, 00149 MatchCallback *Action); 00150 void addMatcher(const TypeMatcher &NodeMatch, 00151 MatchCallback *Action); 00152 void addMatcher(const StatementMatcher &NodeMatch, 00153 MatchCallback *Action); 00154 void addMatcher(const NestedNameSpecifierMatcher &NodeMatch, 00155 MatchCallback *Action); 00156 void addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch, 00157 MatchCallback *Action); 00158 void addMatcher(const TypeLocMatcher &NodeMatch, 00159 MatchCallback *Action); 00160 /// @} 00161 00162 /// \brief Adds a matcher to execute when running over the AST. 00163 /// 00164 /// This is similar to \c addMatcher(), but it uses the dynamic interface. It 00165 /// is more flexible, but the lost type information enables a caller to pass 00166 /// a matcher that cannot match anything. 00167 /// 00168 /// \returns \c true if the matcher is a valid top-level matcher, \c false 00169 /// otherwise. 00170 bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, 00171 MatchCallback *Action); 00172 00173 /// \brief Creates a clang ASTConsumer that finds all matches. 00174 std::unique_ptr<clang::ASTConsumer> newASTConsumer(); 00175 00176 /// \brief Calls the registered callbacks on all matches on the given \p Node. 00177 /// 00178 /// Note that there can be multiple matches on a single node, for 00179 /// example when using decl(forEachDescendant(stmt())). 00180 /// 00181 /// @{ 00182 template <typename T> void match(const T &Node, ASTContext &Context) { 00183 match(clang::ast_type_traits::DynTypedNode::create(Node), Context); 00184 } 00185 void match(const clang::ast_type_traits::DynTypedNode &Node, 00186 ASTContext &Context); 00187 /// @} 00188 00189 /// \brief Finds all matches in the given AST. 00190 void matchAST(ASTContext &Context); 00191 00192 /// \brief Registers a callback to notify the end of parsing. 00193 /// 00194 /// The provided closure is called after parsing is done, before the AST is 00195 /// traversed. Useful for benchmarking. 00196 /// Each call to FindAll(...) will call the closure once. 00197 void registerTestCallbackAfterParsing(ParsingDoneTestCallback *ParsingDone); 00198 00199 /// \brief For each \c Matcher<> a \c MatchCallback that will be called 00200 /// when it matches. 00201 struct MatchersByType { 00202 std::vector<std::pair<DeclarationMatcher, MatchCallback *>> Decl; 00203 std::vector<std::pair<TypeMatcher, MatchCallback *>> Type; 00204 std::vector<std::pair<StatementMatcher, MatchCallback *>> Stmt; 00205 std::vector<std::pair<NestedNameSpecifierMatcher, MatchCallback *>> 00206 NestedNameSpecifier; 00207 std::vector<std::pair<NestedNameSpecifierLocMatcher, MatchCallback *>> 00208 NestedNameSpecifierLoc; 00209 std::vector<std::pair<TypeLocMatcher, MatchCallback *>> TypeLoc; 00210 /// \brief All the callbacks in one container to simplify iteration. 00211 std::vector<MatchCallback *> AllCallbacks; 00212 }; 00213 00214 private: 00215 MatchersByType Matchers; 00216 00217 MatchFinderOptions Options; 00218 00219 /// \brief Called when parsing is done. 00220 ParsingDoneTestCallback *ParsingDone; 00221 }; 00222 00223 /// \brief Returns the results of matching \p Matcher on \p Node. 00224 /// 00225 /// Collects the \c BoundNodes of all callback invocations when matching 00226 /// \p Matcher on \p Node and returns the collected results. 00227 /// 00228 /// Multiple results occur when using matchers like \c forEachDescendant, 00229 /// which generate a result for each sub-match. 00230 /// 00231 /// \see selectFirst 00232 /// @{ 00233 template <typename MatcherT, typename NodeT> 00234 SmallVector<BoundNodes, 1> 00235 match(MatcherT Matcher, const NodeT &Node, ASTContext &Context); 00236 00237 template <typename MatcherT> 00238 SmallVector<BoundNodes, 1> 00239 match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node, 00240 ASTContext &Context); 00241 /// @} 00242 00243 /// \brief Returns the first result of type \c NodeT bound to \p BoundTo. 00244 /// 00245 /// Returns \c NULL if there is no match, or if the matching node cannot be 00246 /// casted to \c NodeT. 00247 /// 00248 /// This is useful in combanation with \c match(): 00249 /// \code 00250 /// const Decl *D = selectFirst<Decl>("id", match(Matcher.bind("id"), 00251 /// Node, Context)); 00252 /// \endcode 00253 template <typename NodeT> 00254 const NodeT * 00255 selectFirst(StringRef BoundTo, const SmallVectorImpl<BoundNodes> &Results) { 00256 for (const BoundNodes &N : Results) { 00257 if (const NodeT *Node = N.getNodeAs<NodeT>(BoundTo)) 00258 return Node; 00259 } 00260 return nullptr; 00261 } 00262 00263 namespace internal { 00264 class CollectMatchesCallback : public MatchFinder::MatchCallback { 00265 public: 00266 void run(const MatchFinder::MatchResult &Result) override { 00267 Nodes.push_back(Result.Nodes); 00268 } 00269 SmallVector<BoundNodes, 1> Nodes; 00270 }; 00271 } 00272 00273 template <typename MatcherT> 00274 SmallVector<BoundNodes, 1> 00275 match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node, 00276 ASTContext &Context) { 00277 internal::CollectMatchesCallback Callback; 00278 MatchFinder Finder; 00279 Finder.addMatcher(Matcher, &Callback); 00280 Finder.match(Node, Context); 00281 return std::move(Callback.Nodes); 00282 } 00283 00284 template <typename MatcherT, typename NodeT> 00285 SmallVector<BoundNodes, 1> 00286 match(MatcherT Matcher, const NodeT &Node, ASTContext &Context) { 00287 return match(Matcher, ast_type_traits::DynTypedNode::create(Node), Context); 00288 } 00289 00290 } // end namespace ast_matchers 00291 } // end namespace clang 00292 00293 #endif