1 1.1 joerg //===--- ASTMatchFinder.cpp - Structural query framework ------------------===// 2 1.1 joerg // 3 1.1 joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 1.1 joerg // See https://llvm.org/LICENSE.txt for license information. 5 1.1 joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 1.1 joerg // 7 1.1 joerg //===----------------------------------------------------------------------===// 8 1.1 joerg // 9 1.1 joerg // Implements an algorithm to efficiently search for matches on AST nodes. 10 1.1 joerg // Uses memoization to support recursive matches like HasDescendant. 11 1.1 joerg // 12 1.1 joerg // The general idea is to visit all AST nodes with a RecursiveASTVisitor, 13 1.1 joerg // calling the Matches(...) method of each matcher we are running on each 14 1.1 joerg // AST node. The matcher can recurse via the ASTMatchFinder interface. 15 1.1 joerg // 16 1.1 joerg //===----------------------------------------------------------------------===// 17 1.1 joerg 18 1.1 joerg #include "clang/ASTMatchers/ASTMatchFinder.h" 19 1.1 joerg #include "clang/AST/ASTConsumer.h" 20 1.1 joerg #include "clang/AST/ASTContext.h" 21 1.1 joerg #include "clang/AST/RecursiveASTVisitor.h" 22 1.1 joerg #include "llvm/ADT/DenseMap.h" 23 1.1 joerg #include "llvm/ADT/StringMap.h" 24 1.1 joerg #include "llvm/Support/Timer.h" 25 1.1 joerg #include <deque> 26 1.1 joerg #include <memory> 27 1.1 joerg #include <set> 28 1.1 joerg 29 1.1 joerg namespace clang { 30 1.1 joerg namespace ast_matchers { 31 1.1 joerg namespace internal { 32 1.1 joerg namespace { 33 1.1 joerg 34 1.1 joerg typedef MatchFinder::MatchCallback MatchCallback; 35 1.1 joerg 36 1.1 joerg // The maximum number of memoization entries to store. 37 1.1 joerg // 10k has been experimentally found to give a good trade-off 38 1.1 joerg // of performance vs. memory consumption by running matcher 39 1.1 joerg // that match on every statement over a very large codebase. 40 1.1 joerg // 41 1.1 joerg // FIXME: Do some performance optimization in general and 42 1.1 joerg // revisit this number; also, put up micro-benchmarks that we can 43 1.1 joerg // optimize this on. 44 1.1 joerg static const unsigned MaxMemoizationEntries = 10000; 45 1.1 joerg 46 1.1.1.2 joerg enum class MatchType { 47 1.1.1.2 joerg Ancestors, 48 1.1.1.2 joerg 49 1.1.1.2 joerg Descendants, 50 1.1.1.2 joerg Child, 51 1.1.1.2 joerg }; 52 1.1.1.2 joerg 53 1.1 joerg // We use memoization to avoid running the same matcher on the same 54 1.1 joerg // AST node twice. This struct is the key for looking up match 55 1.1 joerg // result. It consists of an ID of the MatcherInterface (for 56 1.1 joerg // identifying the matcher), a pointer to the AST node and the 57 1.1 joerg // bound nodes before the matcher was executed. 58 1.1 joerg // 59 1.1 joerg // We currently only memoize on nodes whose pointers identify the 60 1.1 joerg // nodes (\c Stmt and \c Decl, but not \c QualType or \c TypeLoc). 61 1.1 joerg // For \c QualType and \c TypeLoc it is possible to implement 62 1.1 joerg // generation of keys for each type. 63 1.1 joerg // FIXME: Benchmark whether memoization of non-pointer typed nodes 64 1.1 joerg // provides enough benefit for the additional amount of code. 65 1.1 joerg struct MatchKey { 66 1.1 joerg DynTypedMatcher::MatcherIDType MatcherID; 67 1.1.1.2 joerg DynTypedNode Node; 68 1.1 joerg BoundNodesTreeBuilder BoundNodes; 69 1.1.1.2 joerg TraversalKind Traversal = TK_AsIs; 70 1.1.1.2 joerg MatchType Type; 71 1.1 joerg 72 1.1 joerg bool operator<(const MatchKey &Other) const { 73 1.1.1.2 joerg return std::tie(Traversal, Type, MatcherID, Node, BoundNodes) < 74 1.1.1.2 joerg std::tie(Other.Traversal, Other.Type, Other.MatcherID, Other.Node, 75 1.1.1.2 joerg Other.BoundNodes); 76 1.1 joerg } 77 1.1 joerg }; 78 1.1 joerg 79 1.1 joerg // Used to store the result of a match and possibly bound nodes. 80 1.1 joerg struct MemoizedMatchResult { 81 1.1 joerg bool ResultOfMatch; 82 1.1 joerg BoundNodesTreeBuilder Nodes; 83 1.1 joerg }; 84 1.1 joerg 85 1.1 joerg // A RecursiveASTVisitor that traverses all children or all descendants of 86 1.1 joerg // a node. 87 1.1 joerg class MatchChildASTVisitor 88 1.1 joerg : public RecursiveASTVisitor<MatchChildASTVisitor> { 89 1.1 joerg public: 90 1.1 joerg typedef RecursiveASTVisitor<MatchChildASTVisitor> VisitorBase; 91 1.1 joerg 92 1.1 joerg // Creates an AST visitor that matches 'matcher' on all children or 93 1.1 joerg // descendants of a traversed node. max_depth is the maximum depth 94 1.1 joerg // to traverse: use 1 for matching the children and INT_MAX for 95 1.1 joerg // matching the descendants. 96 1.1 joerg MatchChildASTVisitor(const DynTypedMatcher *Matcher, ASTMatchFinder *Finder, 97 1.1 joerg BoundNodesTreeBuilder *Builder, int MaxDepth, 98 1.1.1.2 joerg bool IgnoreImplicitChildren, 99 1.1 joerg ASTMatchFinder::BindKind Bind) 100 1.1 joerg : Matcher(Matcher), Finder(Finder), Builder(Builder), CurrentDepth(0), 101 1.1.1.2 joerg MaxDepth(MaxDepth), IgnoreImplicitChildren(IgnoreImplicitChildren), 102 1.1.1.2 joerg Bind(Bind), Matches(false) {} 103 1.1 joerg 104 1.1 joerg // Returns true if a match is found in the subtree rooted at the 105 1.1 joerg // given AST node. This is done via a set of mutually recursive 106 1.1 joerg // functions. Here's how the recursion is done (the *wildcard can 107 1.1 joerg // actually be Decl, Stmt, or Type): 108 1.1 joerg // 109 1.1 joerg // - Traverse(node) calls BaseTraverse(node) when it needs 110 1.1 joerg // to visit the descendants of node. 111 1.1 joerg // - BaseTraverse(node) then calls (via VisitorBase::Traverse*(node)) 112 1.1 joerg // Traverse*(c) for each child c of 'node'. 113 1.1 joerg // - Traverse*(c) in turn calls Traverse(c), completing the 114 1.1 joerg // recursion. 115 1.1.1.2 joerg bool findMatch(const DynTypedNode &DynNode) { 116 1.1 joerg reset(); 117 1.1 joerg if (const Decl *D = DynNode.get<Decl>()) 118 1.1 joerg traverse(*D); 119 1.1 joerg else if (const Stmt *S = DynNode.get<Stmt>()) 120 1.1 joerg traverse(*S); 121 1.1 joerg else if (const NestedNameSpecifier *NNS = 122 1.1 joerg DynNode.get<NestedNameSpecifier>()) 123 1.1 joerg traverse(*NNS); 124 1.1 joerg else if (const NestedNameSpecifierLoc *NNSLoc = 125 1.1 joerg DynNode.get<NestedNameSpecifierLoc>()) 126 1.1 joerg traverse(*NNSLoc); 127 1.1 joerg else if (const QualType *Q = DynNode.get<QualType>()) 128 1.1 joerg traverse(*Q); 129 1.1 joerg else if (const TypeLoc *T = DynNode.get<TypeLoc>()) 130 1.1 joerg traverse(*T); 131 1.1 joerg else if (const auto *C = DynNode.get<CXXCtorInitializer>()) 132 1.1 joerg traverse(*C); 133 1.1.1.2 joerg else if (const TemplateArgumentLoc *TALoc = 134 1.1.1.2 joerg DynNode.get<TemplateArgumentLoc>()) 135 1.1.1.2 joerg traverse(*TALoc); 136 1.1 joerg // FIXME: Add other base types after adding tests. 137 1.1 joerg 138 1.1 joerg // It's OK to always overwrite the bound nodes, as if there was 139 1.1 joerg // no match in this recursive branch, the result set is empty 140 1.1 joerg // anyway. 141 1.1 joerg *Builder = ResultBindings; 142 1.1 joerg 143 1.1 joerg return Matches; 144 1.1 joerg } 145 1.1 joerg 146 1.1 joerg // The following are overriding methods from the base visitor class. 147 1.1 joerg // They are public only to allow CRTP to work. They are *not *part 148 1.1 joerg // of the public API of this class. 149 1.1 joerg bool TraverseDecl(Decl *DeclNode) { 150 1.1.1.2 joerg 151 1.1.1.2 joerg if (DeclNode && DeclNode->isImplicit() && 152 1.1.1.2 joerg Finder->isTraversalIgnoringImplicitNodes()) 153 1.1.1.2 joerg return baseTraverse(*DeclNode); 154 1.1.1.2 joerg 155 1.1 joerg ScopedIncrement ScopedDepth(&CurrentDepth); 156 1.1 joerg return (DeclNode == nullptr) || traverse(*DeclNode); 157 1.1 joerg } 158 1.1.1.2 joerg 159 1.1.1.2 joerg Stmt *getStmtToTraverse(Stmt *StmtNode) { 160 1.1.1.2 joerg Stmt *StmtToTraverse = StmtNode; 161 1.1.1.2 joerg if (auto *ExprNode = dyn_cast_or_null<Expr>(StmtNode)) { 162 1.1.1.2 joerg auto *LambdaNode = dyn_cast_or_null<LambdaExpr>(StmtNode); 163 1.1.1.2 joerg if (LambdaNode && Finder->isTraversalIgnoringImplicitNodes()) 164 1.1.1.2 joerg StmtToTraverse = LambdaNode; 165 1.1.1.2 joerg else 166 1.1.1.2 joerg StmtToTraverse = 167 1.1.1.2 joerg Finder->getASTContext().getParentMapContext().traverseIgnored( 168 1.1.1.2 joerg ExprNode); 169 1.1.1.2 joerg } 170 1.1.1.2 joerg return StmtToTraverse; 171 1.1.1.2 joerg } 172 1.1.1.2 joerg 173 1.1 joerg bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr) { 174 1.1 joerg // If we need to keep track of the depth, we can't perform data recursion. 175 1.1 joerg if (CurrentDepth == 0 || (CurrentDepth <= MaxDepth && MaxDepth < INT_MAX)) 176 1.1 joerg Queue = nullptr; 177 1.1 joerg 178 1.1 joerg ScopedIncrement ScopedDepth(&CurrentDepth); 179 1.1.1.2 joerg Stmt *StmtToTraverse = getStmtToTraverse(StmtNode); 180 1.1 joerg if (!StmtToTraverse) 181 1.1 joerg return true; 182 1.1.1.2 joerg 183 1.1.1.2 joerg if (IgnoreImplicitChildren && isa<CXXDefaultArgExpr>(StmtNode)) 184 1.1.1.2 joerg return true; 185 1.1.1.2 joerg 186 1.1 joerg if (!match(*StmtToTraverse)) 187 1.1 joerg return false; 188 1.1 joerg return VisitorBase::TraverseStmt(StmtToTraverse, Queue); 189 1.1 joerg } 190 1.1 joerg // We assume that the QualType and the contained type are on the same 191 1.1 joerg // hierarchy level. Thus, we try to match either of them. 192 1.1 joerg bool TraverseType(QualType TypeNode) { 193 1.1 joerg if (TypeNode.isNull()) 194 1.1 joerg return true; 195 1.1 joerg ScopedIncrement ScopedDepth(&CurrentDepth); 196 1.1 joerg // Match the Type. 197 1.1 joerg if (!match(*TypeNode)) 198 1.1 joerg return false; 199 1.1 joerg // The QualType is matched inside traverse. 200 1.1 joerg return traverse(TypeNode); 201 1.1 joerg } 202 1.1 joerg // We assume that the TypeLoc, contained QualType and contained Type all are 203 1.1 joerg // on the same hierarchy level. Thus, we try to match all of them. 204 1.1 joerg bool TraverseTypeLoc(TypeLoc TypeLocNode) { 205 1.1 joerg if (TypeLocNode.isNull()) 206 1.1 joerg return true; 207 1.1 joerg ScopedIncrement ScopedDepth(&CurrentDepth); 208 1.1 joerg // Match the Type. 209 1.1 joerg if (!match(*TypeLocNode.getType())) 210 1.1 joerg return false; 211 1.1 joerg // Match the QualType. 212 1.1 joerg if (!match(TypeLocNode.getType())) 213 1.1 joerg return false; 214 1.1 joerg // The TypeLoc is matched inside traverse. 215 1.1 joerg return traverse(TypeLocNode); 216 1.1 joerg } 217 1.1 joerg bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) { 218 1.1 joerg ScopedIncrement ScopedDepth(&CurrentDepth); 219 1.1 joerg return (NNS == nullptr) || traverse(*NNS); 220 1.1 joerg } 221 1.1 joerg bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { 222 1.1 joerg if (!NNS) 223 1.1 joerg return true; 224 1.1 joerg ScopedIncrement ScopedDepth(&CurrentDepth); 225 1.1 joerg if (!match(*NNS.getNestedNameSpecifier())) 226 1.1 joerg return false; 227 1.1 joerg return traverse(NNS); 228 1.1 joerg } 229 1.1 joerg bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit) { 230 1.1 joerg if (!CtorInit) 231 1.1 joerg return true; 232 1.1 joerg ScopedIncrement ScopedDepth(&CurrentDepth); 233 1.1 joerg return traverse(*CtorInit); 234 1.1 joerg } 235 1.1.1.2 joerg bool TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL) { 236 1.1.1.2 joerg ScopedIncrement ScopedDepth(&CurrentDepth); 237 1.1.1.2 joerg return traverse(TAL); 238 1.1.1.2 joerg } 239 1.1.1.2 joerg bool TraverseCXXForRangeStmt(CXXForRangeStmt *Node) { 240 1.1.1.2 joerg if (!Finder->isTraversalIgnoringImplicitNodes()) 241 1.1.1.2 joerg return VisitorBase::TraverseCXXForRangeStmt(Node); 242 1.1.1.2 joerg if (!Node) 243 1.1.1.2 joerg return true; 244 1.1.1.2 joerg ScopedIncrement ScopedDepth(&CurrentDepth); 245 1.1.1.2 joerg if (auto *Init = Node->getInit()) 246 1.1.1.2 joerg if (!traverse(*Init)) 247 1.1.1.2 joerg return false; 248 1.1.1.2 joerg if (!match(*Node->getLoopVariable())) 249 1.1.1.2 joerg return false; 250 1.1.1.2 joerg if (match(*Node->getRangeInit())) 251 1.1.1.2 joerg if (!VisitorBase::TraverseStmt(Node->getRangeInit())) 252 1.1.1.2 joerg return false; 253 1.1.1.2 joerg if (!match(*Node->getBody())) 254 1.1.1.2 joerg return false; 255 1.1.1.2 joerg return VisitorBase::TraverseStmt(Node->getBody()); 256 1.1.1.2 joerg } 257 1.1.1.2 joerg bool TraverseCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *Node) { 258 1.1.1.2 joerg if (!Finder->isTraversalIgnoringImplicitNodes()) 259 1.1.1.2 joerg return VisitorBase::TraverseCXXRewrittenBinaryOperator(Node); 260 1.1.1.2 joerg if (!Node) 261 1.1.1.2 joerg return true; 262 1.1.1.2 joerg ScopedIncrement ScopedDepth(&CurrentDepth); 263 1.1.1.2 joerg 264 1.1.1.2 joerg return match(*Node->getLHS()) && match(*Node->getRHS()); 265 1.1.1.2 joerg } 266 1.1.1.2 joerg bool TraverseLambdaExpr(LambdaExpr *Node) { 267 1.1.1.2 joerg if (!Finder->isTraversalIgnoringImplicitNodes()) 268 1.1.1.2 joerg return VisitorBase::TraverseLambdaExpr(Node); 269 1.1.1.2 joerg if (!Node) 270 1.1.1.2 joerg return true; 271 1.1.1.2 joerg ScopedIncrement ScopedDepth(&CurrentDepth); 272 1.1.1.2 joerg 273 1.1.1.2 joerg for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) { 274 1.1.1.2 joerg const auto *C = Node->capture_begin() + I; 275 1.1.1.2 joerg if (!C->isExplicit()) 276 1.1.1.2 joerg continue; 277 1.1.1.2 joerg if (Node->isInitCapture(C) && !match(*C->getCapturedVar())) 278 1.1.1.2 joerg return false; 279 1.1.1.2 joerg if (!match(*Node->capture_init_begin()[I])) 280 1.1.1.2 joerg return false; 281 1.1.1.2 joerg } 282 1.1.1.2 joerg 283 1.1.1.2 joerg if (const auto *TPL = Node->getTemplateParameterList()) { 284 1.1.1.2 joerg for (const auto *TP : *TPL) { 285 1.1.1.2 joerg if (!match(*TP)) 286 1.1.1.2 joerg return false; 287 1.1.1.2 joerg } 288 1.1.1.2 joerg } 289 1.1.1.2 joerg 290 1.1.1.2 joerg for (const auto *P : Node->getCallOperator()->parameters()) { 291 1.1.1.2 joerg if (!match(*P)) 292 1.1.1.2 joerg return false; 293 1.1.1.2 joerg } 294 1.1.1.2 joerg 295 1.1.1.2 joerg if (!match(*Node->getBody())) 296 1.1.1.2 joerg return false; 297 1.1.1.2 joerg 298 1.1.1.2 joerg return VisitorBase::TraverseStmt(Node->getBody()); 299 1.1.1.2 joerg } 300 1.1 joerg 301 1.1 joerg bool shouldVisitTemplateInstantiations() const { return true; } 302 1.1.1.2 joerg bool shouldVisitImplicitCode() const { return !IgnoreImplicitChildren; } 303 1.1 joerg 304 1.1 joerg private: 305 1.1 joerg // Used for updating the depth during traversal. 306 1.1 joerg struct ScopedIncrement { 307 1.1 joerg explicit ScopedIncrement(int *Depth) : Depth(Depth) { ++(*Depth); } 308 1.1 joerg ~ScopedIncrement() { --(*Depth); } 309 1.1 joerg 310 1.1 joerg private: 311 1.1 joerg int *Depth; 312 1.1 joerg }; 313 1.1 joerg 314 1.1 joerg // Resets the state of this object. 315 1.1 joerg void reset() { 316 1.1 joerg Matches = false; 317 1.1 joerg CurrentDepth = 0; 318 1.1 joerg } 319 1.1 joerg 320 1.1 joerg // Forwards the call to the corresponding Traverse*() method in the 321 1.1 joerg // base visitor class. 322 1.1 joerg bool baseTraverse(const Decl &DeclNode) { 323 1.1 joerg return VisitorBase::TraverseDecl(const_cast<Decl*>(&DeclNode)); 324 1.1 joerg } 325 1.1 joerg bool baseTraverse(const Stmt &StmtNode) { 326 1.1 joerg return VisitorBase::TraverseStmt(const_cast<Stmt*>(&StmtNode)); 327 1.1 joerg } 328 1.1 joerg bool baseTraverse(QualType TypeNode) { 329 1.1 joerg return VisitorBase::TraverseType(TypeNode); 330 1.1 joerg } 331 1.1 joerg bool baseTraverse(TypeLoc TypeLocNode) { 332 1.1 joerg return VisitorBase::TraverseTypeLoc(TypeLocNode); 333 1.1 joerg } 334 1.1 joerg bool baseTraverse(const NestedNameSpecifier &NNS) { 335 1.1 joerg return VisitorBase::TraverseNestedNameSpecifier( 336 1.1 joerg const_cast<NestedNameSpecifier*>(&NNS)); 337 1.1 joerg } 338 1.1 joerg bool baseTraverse(NestedNameSpecifierLoc NNS) { 339 1.1 joerg return VisitorBase::TraverseNestedNameSpecifierLoc(NNS); 340 1.1 joerg } 341 1.1 joerg bool baseTraverse(const CXXCtorInitializer &CtorInit) { 342 1.1 joerg return VisitorBase::TraverseConstructorInitializer( 343 1.1 joerg const_cast<CXXCtorInitializer *>(&CtorInit)); 344 1.1 joerg } 345 1.1.1.2 joerg bool baseTraverse(TemplateArgumentLoc TAL) { 346 1.1.1.2 joerg return VisitorBase::TraverseTemplateArgumentLoc(TAL); 347 1.1.1.2 joerg } 348 1.1 joerg 349 1.1 joerg // Sets 'Matched' to true if 'Matcher' matches 'Node' and: 350 1.1 joerg // 0 < CurrentDepth <= MaxDepth. 351 1.1 joerg // 352 1.1 joerg // Returns 'true' if traversal should continue after this function 353 1.1 joerg // returns, i.e. if no match is found or 'Bind' is 'BK_All'. 354 1.1 joerg template <typename T> 355 1.1 joerg bool match(const T &Node) { 356 1.1 joerg if (CurrentDepth == 0 || CurrentDepth > MaxDepth) { 357 1.1 joerg return true; 358 1.1 joerg } 359 1.1 joerg if (Bind != ASTMatchFinder::BK_All) { 360 1.1 joerg BoundNodesTreeBuilder RecursiveBuilder(*Builder); 361 1.1.1.2 joerg if (Matcher->matches(DynTypedNode::create(Node), Finder, 362 1.1 joerg &RecursiveBuilder)) { 363 1.1 joerg Matches = true; 364 1.1 joerg ResultBindings.addMatch(RecursiveBuilder); 365 1.1 joerg return false; // Abort as soon as a match is found. 366 1.1 joerg } 367 1.1 joerg } else { 368 1.1 joerg BoundNodesTreeBuilder RecursiveBuilder(*Builder); 369 1.1.1.2 joerg if (Matcher->matches(DynTypedNode::create(Node), Finder, 370 1.1 joerg &RecursiveBuilder)) { 371 1.1 joerg // After the first match the matcher succeeds. 372 1.1 joerg Matches = true; 373 1.1 joerg ResultBindings.addMatch(RecursiveBuilder); 374 1.1 joerg } 375 1.1 joerg } 376 1.1 joerg return true; 377 1.1 joerg } 378 1.1 joerg 379 1.1 joerg // Traverses the subtree rooted at 'Node'; returns true if the 380 1.1 joerg // traversal should continue after this function returns. 381 1.1 joerg template <typename T> 382 1.1 joerg bool traverse(const T &Node) { 383 1.1 joerg static_assert(IsBaseType<T>::value, 384 1.1 joerg "traverse can only be instantiated with base type"); 385 1.1 joerg if (!match(Node)) 386 1.1 joerg return false; 387 1.1 joerg return baseTraverse(Node); 388 1.1 joerg } 389 1.1 joerg 390 1.1 joerg const DynTypedMatcher *const Matcher; 391 1.1 joerg ASTMatchFinder *const Finder; 392 1.1 joerg BoundNodesTreeBuilder *const Builder; 393 1.1 joerg BoundNodesTreeBuilder ResultBindings; 394 1.1 joerg int CurrentDepth; 395 1.1 joerg const int MaxDepth; 396 1.1.1.2 joerg const bool IgnoreImplicitChildren; 397 1.1 joerg const ASTMatchFinder::BindKind Bind; 398 1.1 joerg bool Matches; 399 1.1 joerg }; 400 1.1 joerg 401 1.1 joerg // Controls the outermost traversal of the AST and allows to match multiple 402 1.1 joerg // matchers. 403 1.1 joerg class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>, 404 1.1 joerg public ASTMatchFinder { 405 1.1 joerg public: 406 1.1 joerg MatchASTVisitor(const MatchFinder::MatchersByType *Matchers, 407 1.1 joerg const MatchFinder::MatchFinderOptions &Options) 408 1.1 joerg : Matchers(Matchers), Options(Options), ActiveASTContext(nullptr) {} 409 1.1 joerg 410 1.1 joerg ~MatchASTVisitor() override { 411 1.1 joerg if (Options.CheckProfiling) { 412 1.1 joerg Options.CheckProfiling->Records = std::move(TimeByBucket); 413 1.1 joerg } 414 1.1 joerg } 415 1.1 joerg 416 1.1 joerg void onStartOfTranslationUnit() { 417 1.1 joerg const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 418 1.1 joerg TimeBucketRegion Timer; 419 1.1 joerg for (MatchCallback *MC : Matchers->AllCallbacks) { 420 1.1 joerg if (EnableCheckProfiling) 421 1.1 joerg Timer.setBucket(&TimeByBucket[MC->getID()]); 422 1.1 joerg MC->onStartOfTranslationUnit(); 423 1.1 joerg } 424 1.1 joerg } 425 1.1 joerg 426 1.1 joerg void onEndOfTranslationUnit() { 427 1.1 joerg const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 428 1.1 joerg TimeBucketRegion Timer; 429 1.1 joerg for (MatchCallback *MC : Matchers->AllCallbacks) { 430 1.1 joerg if (EnableCheckProfiling) 431 1.1 joerg Timer.setBucket(&TimeByBucket[MC->getID()]); 432 1.1 joerg MC->onEndOfTranslationUnit(); 433 1.1 joerg } 434 1.1 joerg } 435 1.1 joerg 436 1.1 joerg void set_active_ast_context(ASTContext *NewActiveASTContext) { 437 1.1 joerg ActiveASTContext = NewActiveASTContext; 438 1.1 joerg } 439 1.1 joerg 440 1.1 joerg // The following Visit*() and Traverse*() functions "override" 441 1.1 joerg // methods in RecursiveASTVisitor. 442 1.1 joerg 443 1.1 joerg bool VisitTypedefNameDecl(TypedefNameDecl *DeclNode) { 444 1.1 joerg // When we see 'typedef A B', we add name 'B' to the set of names 445 1.1 joerg // A's canonical type maps to. This is necessary for implementing 446 1.1 joerg // isDerivedFrom(x) properly, where x can be the name of the base 447 1.1 joerg // class or any of its aliases. 448 1.1 joerg // 449 1.1 joerg // In general, the is-alias-of (as defined by typedefs) relation 450 1.1 joerg // is tree-shaped, as you can typedef a type more than once. For 451 1.1 joerg // example, 452 1.1 joerg // 453 1.1 joerg // typedef A B; 454 1.1 joerg // typedef A C; 455 1.1 joerg // typedef C D; 456 1.1 joerg // typedef C E; 457 1.1 joerg // 458 1.1 joerg // gives you 459 1.1 joerg // 460 1.1 joerg // A 461 1.1 joerg // |- B 462 1.1 joerg // `- C 463 1.1 joerg // |- D 464 1.1 joerg // `- E 465 1.1 joerg // 466 1.1 joerg // It is wrong to assume that the relation is a chain. A correct 467 1.1 joerg // implementation of isDerivedFrom() needs to recognize that B and 468 1.1 joerg // E are aliases, even though neither is a typedef of the other. 469 1.1 joerg // Therefore, we cannot simply walk through one typedef chain to 470 1.1 joerg // find out whether the type name matches. 471 1.1 joerg const Type *TypeNode = DeclNode->getUnderlyingType().getTypePtr(); 472 1.1 joerg const Type *CanonicalType = // root of the typedef tree 473 1.1 joerg ActiveASTContext->getCanonicalType(TypeNode); 474 1.1 joerg TypeAliases[CanonicalType].insert(DeclNode); 475 1.1 joerg return true; 476 1.1 joerg } 477 1.1 joerg 478 1.1 joerg bool VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) { 479 1.1 joerg const ObjCInterfaceDecl *InterfaceDecl = CAD->getClassInterface(); 480 1.1 joerg CompatibleAliases[InterfaceDecl].insert(CAD); 481 1.1 joerg return true; 482 1.1 joerg } 483 1.1 joerg 484 1.1 joerg bool TraverseDecl(Decl *DeclNode); 485 1.1 joerg bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr); 486 1.1 joerg bool TraverseType(QualType TypeNode); 487 1.1 joerg bool TraverseTypeLoc(TypeLoc TypeNode); 488 1.1 joerg bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS); 489 1.1 joerg bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); 490 1.1 joerg bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit); 491 1.1.1.2 joerg bool TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL); 492 1.1.1.2 joerg 493 1.1.1.2 joerg bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue) { 494 1.1.1.2 joerg if (auto *RF = dyn_cast<CXXForRangeStmt>(S)) { 495 1.1.1.2 joerg { 496 1.1.1.2 joerg ASTNodeNotAsIsSourceScope RAII(this, true); 497 1.1.1.2 joerg TraverseStmt(RF->getInit()); 498 1.1.1.2 joerg // Don't traverse under the loop variable 499 1.1.1.2 joerg match(*RF->getLoopVariable()); 500 1.1.1.2 joerg TraverseStmt(RF->getRangeInit()); 501 1.1.1.2 joerg } 502 1.1.1.2 joerg { 503 1.1.1.2 joerg ASTNodeNotSpelledInSourceScope RAII(this, true); 504 1.1.1.2 joerg for (auto *SubStmt : RF->children()) { 505 1.1.1.2 joerg if (SubStmt != RF->getBody()) 506 1.1.1.2 joerg TraverseStmt(SubStmt); 507 1.1.1.2 joerg } 508 1.1.1.2 joerg } 509 1.1.1.2 joerg TraverseStmt(RF->getBody()); 510 1.1.1.2 joerg return true; 511 1.1.1.2 joerg } else if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) { 512 1.1.1.2 joerg { 513 1.1.1.2 joerg ASTNodeNotAsIsSourceScope RAII(this, true); 514 1.1.1.2 joerg TraverseStmt(const_cast<Expr *>(RBO->getLHS())); 515 1.1.1.2 joerg TraverseStmt(const_cast<Expr *>(RBO->getRHS())); 516 1.1.1.2 joerg } 517 1.1.1.2 joerg { 518 1.1.1.2 joerg ASTNodeNotSpelledInSourceScope RAII(this, true); 519 1.1.1.2 joerg for (auto *SubStmt : RBO->children()) { 520 1.1.1.2 joerg TraverseStmt(SubStmt); 521 1.1.1.2 joerg } 522 1.1.1.2 joerg } 523 1.1.1.2 joerg return true; 524 1.1.1.2 joerg } else if (auto *LE = dyn_cast<LambdaExpr>(S)) { 525 1.1.1.2 joerg for (auto I : llvm::zip(LE->captures(), LE->capture_inits())) { 526 1.1.1.2 joerg auto C = std::get<0>(I); 527 1.1.1.2 joerg ASTNodeNotSpelledInSourceScope RAII( 528 1.1.1.2 joerg this, TraversingASTNodeNotSpelledInSource || !C.isExplicit()); 529 1.1.1.2 joerg TraverseLambdaCapture(LE, &C, std::get<1>(I)); 530 1.1.1.2 joerg } 531 1.1.1.2 joerg 532 1.1.1.2 joerg { 533 1.1.1.2 joerg ASTNodeNotSpelledInSourceScope RAII(this, true); 534 1.1.1.2 joerg TraverseDecl(LE->getLambdaClass()); 535 1.1.1.2 joerg } 536 1.1.1.2 joerg { 537 1.1.1.2 joerg ASTNodeNotAsIsSourceScope RAII(this, true); 538 1.1.1.2 joerg 539 1.1.1.2 joerg // We need to poke around to find the bits that might be explicitly 540 1.1.1.2 joerg // written. 541 1.1.1.2 joerg TypeLoc TL = LE->getCallOperator()->getTypeSourceInfo()->getTypeLoc(); 542 1.1.1.2 joerg FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>(); 543 1.1.1.2 joerg 544 1.1.1.2 joerg if (auto *TPL = LE->getTemplateParameterList()) { 545 1.1.1.2 joerg for (NamedDecl *D : *TPL) { 546 1.1.1.2 joerg TraverseDecl(D); 547 1.1.1.2 joerg } 548 1.1.1.2 joerg if (Expr *RequiresClause = TPL->getRequiresClause()) { 549 1.1.1.2 joerg TraverseStmt(RequiresClause); 550 1.1.1.2 joerg } 551 1.1.1.2 joerg } 552 1.1.1.2 joerg 553 1.1.1.2 joerg if (LE->hasExplicitParameters()) { 554 1.1.1.2 joerg // Visit parameters. 555 1.1.1.2 joerg for (ParmVarDecl *Param : Proto.getParams()) 556 1.1.1.2 joerg TraverseDecl(Param); 557 1.1.1.2 joerg } 558 1.1.1.2 joerg 559 1.1.1.2 joerg const auto *T = Proto.getTypePtr(); 560 1.1.1.2 joerg for (const auto &E : T->exceptions()) 561 1.1.1.2 joerg TraverseType(E); 562 1.1.1.2 joerg 563 1.1.1.2 joerg if (Expr *NE = T->getNoexceptExpr()) 564 1.1.1.2 joerg TraverseStmt(NE, Queue); 565 1.1.1.2 joerg 566 1.1.1.2 joerg if (LE->hasExplicitResultType()) 567 1.1.1.2 joerg TraverseTypeLoc(Proto.getReturnLoc()); 568 1.1.1.2 joerg TraverseStmt(LE->getTrailingRequiresClause()); 569 1.1.1.2 joerg } 570 1.1.1.2 joerg 571 1.1.1.2 joerg TraverseStmt(LE->getBody()); 572 1.1.1.2 joerg return true; 573 1.1.1.2 joerg } 574 1.1.1.2 joerg return RecursiveASTVisitor<MatchASTVisitor>::dataTraverseNode(S, Queue); 575 1.1.1.2 joerg } 576 1.1 joerg 577 1.1 joerg // Matches children or descendants of 'Node' with 'BaseMatcher'. 578 1.1.1.2 joerg bool memoizedMatchesRecursively(const DynTypedNode &Node, ASTContext &Ctx, 579 1.1 joerg const DynTypedMatcher &Matcher, 580 1.1 joerg BoundNodesTreeBuilder *Builder, int MaxDepth, 581 1.1 joerg BindKind Bind) { 582 1.1 joerg // For AST-nodes that don't have an identity, we can't memoize. 583 1.1 joerg if (!Node.getMemoizationData() || !Builder->isComparable()) 584 1.1.1.2 joerg return matchesRecursively(Node, Matcher, Builder, MaxDepth, Bind); 585 1.1 joerg 586 1.1 joerg MatchKey Key; 587 1.1 joerg Key.MatcherID = Matcher.getID(); 588 1.1 joerg Key.Node = Node; 589 1.1 joerg // Note that we key on the bindings *before* the match. 590 1.1 joerg Key.BoundNodes = *Builder; 591 1.1.1.2 joerg Key.Traversal = Ctx.getParentMapContext().getTraversalKind(); 592 1.1.1.2 joerg // Memoize result even doing a single-level match, it might be expensive. 593 1.1.1.2 joerg Key.Type = MaxDepth == 1 ? MatchType::Child : MatchType::Descendants; 594 1.1 joerg MemoizationMap::iterator I = ResultCache.find(Key); 595 1.1 joerg if (I != ResultCache.end()) { 596 1.1 joerg *Builder = I->second.Nodes; 597 1.1 joerg return I->second.ResultOfMatch; 598 1.1 joerg } 599 1.1 joerg 600 1.1 joerg MemoizedMatchResult Result; 601 1.1 joerg Result.Nodes = *Builder; 602 1.1.1.2 joerg Result.ResultOfMatch = 603 1.1.1.2 joerg matchesRecursively(Node, Matcher, &Result.Nodes, MaxDepth, Bind); 604 1.1 joerg 605 1.1 joerg MemoizedMatchResult &CachedResult = ResultCache[Key]; 606 1.1 joerg CachedResult = std::move(Result); 607 1.1 joerg 608 1.1 joerg *Builder = CachedResult.Nodes; 609 1.1 joerg return CachedResult.ResultOfMatch; 610 1.1 joerg } 611 1.1 joerg 612 1.1 joerg // Matches children or descendants of 'Node' with 'BaseMatcher'. 613 1.1.1.2 joerg bool matchesRecursively(const DynTypedNode &Node, 614 1.1 joerg const DynTypedMatcher &Matcher, 615 1.1 joerg BoundNodesTreeBuilder *Builder, int MaxDepth, 616 1.1 joerg BindKind Bind) { 617 1.1.1.2 joerg bool ScopedTraversal = TraversingASTNodeNotSpelledInSource || 618 1.1.1.2 joerg TraversingASTChildrenNotSpelledInSource; 619 1.1.1.2 joerg 620 1.1.1.2 joerg bool IgnoreImplicitChildren = false; 621 1.1.1.2 joerg 622 1.1.1.2 joerg if (isTraversalIgnoringImplicitNodes()) { 623 1.1.1.2 joerg IgnoreImplicitChildren = true; 624 1.1.1.2 joerg } 625 1.1.1.2 joerg 626 1.1.1.2 joerg ASTNodeNotSpelledInSourceScope RAII(this, ScopedTraversal); 627 1.1.1.2 joerg 628 1.1.1.2 joerg MatchChildASTVisitor Visitor(&Matcher, this, Builder, MaxDepth, 629 1.1.1.2 joerg IgnoreImplicitChildren, Bind); 630 1.1 joerg return Visitor.findMatch(Node); 631 1.1 joerg } 632 1.1 joerg 633 1.1 joerg bool classIsDerivedFrom(const CXXRecordDecl *Declaration, 634 1.1 joerg const Matcher<NamedDecl> &Base, 635 1.1 joerg BoundNodesTreeBuilder *Builder, 636 1.1 joerg bool Directly) override; 637 1.1 joerg 638 1.1 joerg bool objcClassIsDerivedFrom(const ObjCInterfaceDecl *Declaration, 639 1.1 joerg const Matcher<NamedDecl> &Base, 640 1.1 joerg BoundNodesTreeBuilder *Builder, 641 1.1 joerg bool Directly) override; 642 1.1 joerg 643 1.1 joerg // Implements ASTMatchFinder::matchesChildOf. 644 1.1.1.2 joerg bool matchesChildOf(const DynTypedNode &Node, ASTContext &Ctx, 645 1.1 joerg const DynTypedMatcher &Matcher, 646 1.1.1.2 joerg BoundNodesTreeBuilder *Builder, BindKind Bind) override { 647 1.1 joerg if (ResultCache.size() > MaxMemoizationEntries) 648 1.1 joerg ResultCache.clear(); 649 1.1.1.2 joerg return memoizedMatchesRecursively(Node, Ctx, Matcher, Builder, 1, Bind); 650 1.1 joerg } 651 1.1 joerg // Implements ASTMatchFinder::matchesDescendantOf. 652 1.1.1.2 joerg bool matchesDescendantOf(const DynTypedNode &Node, ASTContext &Ctx, 653 1.1 joerg const DynTypedMatcher &Matcher, 654 1.1 joerg BoundNodesTreeBuilder *Builder, 655 1.1 joerg BindKind Bind) override { 656 1.1 joerg if (ResultCache.size() > MaxMemoizationEntries) 657 1.1 joerg ResultCache.clear(); 658 1.1.1.2 joerg return memoizedMatchesRecursively(Node, Ctx, Matcher, Builder, INT_MAX, 659 1.1 joerg Bind); 660 1.1 joerg } 661 1.1 joerg // Implements ASTMatchFinder::matchesAncestorOf. 662 1.1.1.2 joerg bool matchesAncestorOf(const DynTypedNode &Node, ASTContext &Ctx, 663 1.1 joerg const DynTypedMatcher &Matcher, 664 1.1 joerg BoundNodesTreeBuilder *Builder, 665 1.1 joerg AncestorMatchMode MatchMode) override { 666 1.1 joerg // Reset the cache outside of the recursive call to make sure we 667 1.1 joerg // don't invalidate any iterators. 668 1.1 joerg if (ResultCache.size() > MaxMemoizationEntries) 669 1.1 joerg ResultCache.clear(); 670 1.1.1.2 joerg if (MatchMode == AncestorMatchMode::AMM_ParentOnly) 671 1.1.1.2 joerg return matchesParentOf(Node, Matcher, Builder); 672 1.1.1.2 joerg return matchesAnyAncestorOf(Node, Ctx, Matcher, Builder); 673 1.1 joerg } 674 1.1 joerg 675 1.1 joerg // Matches all registered matchers on the given node and calls the 676 1.1 joerg // result callback for every node that matches. 677 1.1.1.2 joerg void match(const DynTypedNode &Node) { 678 1.1 joerg // FIXME: Improve this with a switch or a visitor pattern. 679 1.1 joerg if (auto *N = Node.get<Decl>()) { 680 1.1 joerg match(*N); 681 1.1 joerg } else if (auto *N = Node.get<Stmt>()) { 682 1.1 joerg match(*N); 683 1.1 joerg } else if (auto *N = Node.get<Type>()) { 684 1.1 joerg match(*N); 685 1.1 joerg } else if (auto *N = Node.get<QualType>()) { 686 1.1 joerg match(*N); 687 1.1 joerg } else if (auto *N = Node.get<NestedNameSpecifier>()) { 688 1.1 joerg match(*N); 689 1.1 joerg } else if (auto *N = Node.get<NestedNameSpecifierLoc>()) { 690 1.1 joerg match(*N); 691 1.1 joerg } else if (auto *N = Node.get<TypeLoc>()) { 692 1.1 joerg match(*N); 693 1.1 joerg } else if (auto *N = Node.get<CXXCtorInitializer>()) { 694 1.1 joerg match(*N); 695 1.1.1.2 joerg } else if (auto *N = Node.get<TemplateArgumentLoc>()) { 696 1.1.1.2 joerg match(*N); 697 1.1 joerg } 698 1.1 joerg } 699 1.1 joerg 700 1.1 joerg template <typename T> void match(const T &Node) { 701 1.1 joerg matchDispatch(&Node); 702 1.1 joerg } 703 1.1 joerg 704 1.1 joerg // Implements ASTMatchFinder::getASTContext. 705 1.1 joerg ASTContext &getASTContext() const override { return *ActiveASTContext; } 706 1.1 joerg 707 1.1 joerg bool shouldVisitTemplateInstantiations() const { return true; } 708 1.1 joerg bool shouldVisitImplicitCode() const { return true; } 709 1.1 joerg 710 1.1.1.2 joerg // We visit the lambda body explicitly, so instruct the RAV 711 1.1.1.2 joerg // to not visit it on our behalf too. 712 1.1.1.2 joerg bool shouldVisitLambdaBody() const { return false; } 713 1.1.1.2 joerg 714 1.1.1.2 joerg bool IsMatchingInASTNodeNotSpelledInSource() const override { 715 1.1.1.2 joerg return TraversingASTNodeNotSpelledInSource; 716 1.1.1.2 joerg } 717 1.1.1.2 joerg bool isMatchingChildrenNotSpelledInSource() const override { 718 1.1.1.2 joerg return TraversingASTChildrenNotSpelledInSource; 719 1.1.1.2 joerg } 720 1.1.1.2 joerg void setMatchingChildrenNotSpelledInSource(bool Set) override { 721 1.1.1.2 joerg TraversingASTChildrenNotSpelledInSource = Set; 722 1.1.1.2 joerg } 723 1.1.1.2 joerg 724 1.1.1.2 joerg bool IsMatchingInASTNodeNotAsIs() const override { 725 1.1.1.2 joerg return TraversingASTNodeNotAsIs; 726 1.1.1.2 joerg } 727 1.1.1.2 joerg 728 1.1.1.2 joerg bool TraverseTemplateInstantiations(ClassTemplateDecl *D) { 729 1.1.1.2 joerg ASTNodeNotSpelledInSourceScope RAII(this, true); 730 1.1.1.2 joerg return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations( 731 1.1.1.2 joerg D); 732 1.1.1.2 joerg } 733 1.1.1.2 joerg 734 1.1.1.2 joerg bool TraverseTemplateInstantiations(VarTemplateDecl *D) { 735 1.1.1.2 joerg ASTNodeNotSpelledInSourceScope RAII(this, true); 736 1.1.1.2 joerg return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations( 737 1.1.1.2 joerg D); 738 1.1.1.2 joerg } 739 1.1.1.2 joerg 740 1.1.1.2 joerg bool TraverseTemplateInstantiations(FunctionTemplateDecl *D) { 741 1.1.1.2 joerg ASTNodeNotSpelledInSourceScope RAII(this, true); 742 1.1.1.2 joerg return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations( 743 1.1.1.2 joerg D); 744 1.1.1.2 joerg } 745 1.1.1.2 joerg 746 1.1 joerg private: 747 1.1.1.2 joerg bool TraversingASTNodeNotSpelledInSource = false; 748 1.1.1.2 joerg bool TraversingASTNodeNotAsIs = false; 749 1.1.1.2 joerg bool TraversingASTChildrenNotSpelledInSource = false; 750 1.1.1.2 joerg 751 1.1.1.2 joerg struct ASTNodeNotSpelledInSourceScope { 752 1.1.1.2 joerg ASTNodeNotSpelledInSourceScope(MatchASTVisitor *V, bool B) 753 1.1.1.2 joerg : MV(V), MB(V->TraversingASTNodeNotSpelledInSource) { 754 1.1.1.2 joerg V->TraversingASTNodeNotSpelledInSource = B; 755 1.1.1.2 joerg } 756 1.1.1.2 joerg ~ASTNodeNotSpelledInSourceScope() { 757 1.1.1.2 joerg MV->TraversingASTNodeNotSpelledInSource = MB; 758 1.1.1.2 joerg } 759 1.1.1.2 joerg 760 1.1.1.2 joerg private: 761 1.1.1.2 joerg MatchASTVisitor *MV; 762 1.1.1.2 joerg bool MB; 763 1.1.1.2 joerg }; 764 1.1.1.2 joerg 765 1.1.1.2 joerg struct ASTNodeNotAsIsSourceScope { 766 1.1.1.2 joerg ASTNodeNotAsIsSourceScope(MatchASTVisitor *V, bool B) 767 1.1.1.2 joerg : MV(V), MB(V->TraversingASTNodeNotAsIs) { 768 1.1.1.2 joerg V->TraversingASTNodeNotAsIs = B; 769 1.1.1.2 joerg } 770 1.1.1.2 joerg ~ASTNodeNotAsIsSourceScope() { MV->TraversingASTNodeNotAsIs = MB; } 771 1.1.1.2 joerg 772 1.1.1.2 joerg private: 773 1.1.1.2 joerg MatchASTVisitor *MV; 774 1.1.1.2 joerg bool MB; 775 1.1.1.2 joerg }; 776 1.1.1.2 joerg 777 1.1 joerg class TimeBucketRegion { 778 1.1 joerg public: 779 1.1 joerg TimeBucketRegion() : Bucket(nullptr) {} 780 1.1 joerg ~TimeBucketRegion() { setBucket(nullptr); } 781 1.1 joerg 782 1.1 joerg /// Start timing for \p NewBucket. 783 1.1 joerg /// 784 1.1 joerg /// If there was a bucket already set, it will finish the timing for that 785 1.1 joerg /// other bucket. 786 1.1 joerg /// \p NewBucket will be timed until the next call to \c setBucket() or 787 1.1 joerg /// until the \c TimeBucketRegion is destroyed. 788 1.1 joerg /// If \p NewBucket is the same as the currently timed bucket, this call 789 1.1 joerg /// does nothing. 790 1.1 joerg void setBucket(llvm::TimeRecord *NewBucket) { 791 1.1 joerg if (Bucket != NewBucket) { 792 1.1 joerg auto Now = llvm::TimeRecord::getCurrentTime(true); 793 1.1 joerg if (Bucket) 794 1.1 joerg *Bucket += Now; 795 1.1 joerg if (NewBucket) 796 1.1 joerg *NewBucket -= Now; 797 1.1 joerg Bucket = NewBucket; 798 1.1 joerg } 799 1.1 joerg } 800 1.1 joerg 801 1.1 joerg private: 802 1.1 joerg llvm::TimeRecord *Bucket; 803 1.1 joerg }; 804 1.1 joerg 805 1.1 joerg /// Runs all the \p Matchers on \p Node. 806 1.1 joerg /// 807 1.1 joerg /// Used by \c matchDispatch() below. 808 1.1 joerg template <typename T, typename MC> 809 1.1 joerg void matchWithoutFilter(const T &Node, const MC &Matchers) { 810 1.1 joerg const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 811 1.1 joerg TimeBucketRegion Timer; 812 1.1 joerg for (const auto &MP : Matchers) { 813 1.1 joerg if (EnableCheckProfiling) 814 1.1 joerg Timer.setBucket(&TimeByBucket[MP.second->getID()]); 815 1.1 joerg BoundNodesTreeBuilder Builder; 816 1.1 joerg if (MP.first.matches(Node, this, &Builder)) { 817 1.1 joerg MatchVisitor Visitor(ActiveASTContext, MP.second); 818 1.1 joerg Builder.visitMatches(&Visitor); 819 1.1 joerg } 820 1.1 joerg } 821 1.1 joerg } 822 1.1 joerg 823 1.1.1.2 joerg void matchWithFilter(const DynTypedNode &DynNode) { 824 1.1 joerg auto Kind = DynNode.getNodeKind(); 825 1.1 joerg auto it = MatcherFiltersMap.find(Kind); 826 1.1 joerg const auto &Filter = 827 1.1 joerg it != MatcherFiltersMap.end() ? it->second : getFilterForKind(Kind); 828 1.1 joerg 829 1.1 joerg if (Filter.empty()) 830 1.1 joerg return; 831 1.1 joerg 832 1.1 joerg const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 833 1.1 joerg TimeBucketRegion Timer; 834 1.1 joerg auto &Matchers = this->Matchers->DeclOrStmt; 835 1.1 joerg for (unsigned short I : Filter) { 836 1.1 joerg auto &MP = Matchers[I]; 837 1.1 joerg if (EnableCheckProfiling) 838 1.1 joerg Timer.setBucket(&TimeByBucket[MP.second->getID()]); 839 1.1 joerg BoundNodesTreeBuilder Builder; 840 1.1.1.2 joerg 841 1.1.1.2 joerg { 842 1.1.1.2 joerg TraversalKindScope RAII(getASTContext(), MP.first.getTraversalKind()); 843 1.1.1.2 joerg if (getASTContext().getParentMapContext().traverseIgnored(DynNode) != 844 1.1.1.2 joerg DynNode) 845 1.1.1.2 joerg continue; 846 1.1.1.2 joerg } 847 1.1.1.2 joerg 848 1.1.1.2 joerg if (MP.first.matches(DynNode, this, &Builder)) { 849 1.1 joerg MatchVisitor Visitor(ActiveASTContext, MP.second); 850 1.1 joerg Builder.visitMatches(&Visitor); 851 1.1 joerg } 852 1.1 joerg } 853 1.1 joerg } 854 1.1 joerg 855 1.1.1.2 joerg const std::vector<unsigned short> &getFilterForKind(ASTNodeKind Kind) { 856 1.1 joerg auto &Filter = MatcherFiltersMap[Kind]; 857 1.1 joerg auto &Matchers = this->Matchers->DeclOrStmt; 858 1.1 joerg assert((Matchers.size() < USHRT_MAX) && "Too many matchers."); 859 1.1 joerg for (unsigned I = 0, E = Matchers.size(); I != E; ++I) { 860 1.1 joerg if (Matchers[I].first.canMatchNodesOfKind(Kind)) { 861 1.1 joerg Filter.push_back(I); 862 1.1 joerg } 863 1.1 joerg } 864 1.1 joerg return Filter; 865 1.1 joerg } 866 1.1 joerg 867 1.1 joerg /// @{ 868 1.1 joerg /// Overloads to pair the different node types to their matchers. 869 1.1 joerg void matchDispatch(const Decl *Node) { 870 1.1.1.2 joerg return matchWithFilter(DynTypedNode::create(*Node)); 871 1.1 joerg } 872 1.1 joerg void matchDispatch(const Stmt *Node) { 873 1.1.1.2 joerg return matchWithFilter(DynTypedNode::create(*Node)); 874 1.1 joerg } 875 1.1 joerg 876 1.1 joerg void matchDispatch(const Type *Node) { 877 1.1 joerg matchWithoutFilter(QualType(Node, 0), Matchers->Type); 878 1.1 joerg } 879 1.1 joerg void matchDispatch(const TypeLoc *Node) { 880 1.1 joerg matchWithoutFilter(*Node, Matchers->TypeLoc); 881 1.1 joerg } 882 1.1 joerg void matchDispatch(const QualType *Node) { 883 1.1 joerg matchWithoutFilter(*Node, Matchers->Type); 884 1.1 joerg } 885 1.1 joerg void matchDispatch(const NestedNameSpecifier *Node) { 886 1.1 joerg matchWithoutFilter(*Node, Matchers->NestedNameSpecifier); 887 1.1 joerg } 888 1.1 joerg void matchDispatch(const NestedNameSpecifierLoc *Node) { 889 1.1 joerg matchWithoutFilter(*Node, Matchers->NestedNameSpecifierLoc); 890 1.1 joerg } 891 1.1 joerg void matchDispatch(const CXXCtorInitializer *Node) { 892 1.1 joerg matchWithoutFilter(*Node, Matchers->CtorInit); 893 1.1 joerg } 894 1.1.1.2 joerg void matchDispatch(const TemplateArgumentLoc *Node) { 895 1.1.1.2 joerg matchWithoutFilter(*Node, Matchers->TemplateArgumentLoc); 896 1.1.1.2 joerg } 897 1.1 joerg void matchDispatch(const void *) { /* Do nothing. */ } 898 1.1 joerg /// @} 899 1.1 joerg 900 1.1.1.2 joerg // Returns whether a direct parent of \p Node matches \p Matcher. 901 1.1.1.2 joerg // Unlike matchesAnyAncestorOf there's no memoization: it doesn't save much. 902 1.1.1.2 joerg bool matchesParentOf(const DynTypedNode &Node, const DynTypedMatcher &Matcher, 903 1.1.1.2 joerg BoundNodesTreeBuilder *Builder) { 904 1.1.1.2 joerg for (const auto &Parent : ActiveASTContext->getParents(Node)) { 905 1.1.1.2 joerg BoundNodesTreeBuilder BuilderCopy = *Builder; 906 1.1.1.2 joerg if (Matcher.matches(Parent, this, &BuilderCopy)) { 907 1.1.1.2 joerg *Builder = std::move(BuilderCopy); 908 1.1.1.2 joerg return true; 909 1.1.1.2 joerg } 910 1.1.1.2 joerg } 911 1.1.1.2 joerg return false; 912 1.1.1.2 joerg } 913 1.1.1.2 joerg 914 1.1 joerg // Returns whether an ancestor of \p Node matches \p Matcher. 915 1.1 joerg // 916 1.1.1.2 joerg // The order of matching (which can lead to different nodes being bound in 917 1.1 joerg // case there are multiple matches) is breadth first search. 918 1.1 joerg // 919 1.1 joerg // To allow memoization in the very common case of having deeply nested 920 1.1 joerg // expressions inside a template function, we first walk up the AST, memoizing 921 1.1 joerg // the result of the match along the way, as long as there is only a single 922 1.1 joerg // parent. 923 1.1 joerg // 924 1.1 joerg // Once there are multiple parents, the breadth first search order does not 925 1.1 joerg // allow simple memoization on the ancestors. Thus, we only memoize as long 926 1.1 joerg // as there is a single parent. 927 1.1.1.2 joerg // 928 1.1.1.2 joerg // We avoid a recursive implementation to prevent excessive stack use on 929 1.1.1.2 joerg // very deep ASTs (similarly to RecursiveASTVisitor's data recursion). 930 1.1.1.2 joerg bool matchesAnyAncestorOf(DynTypedNode Node, ASTContext &Ctx, 931 1.1.1.2 joerg const DynTypedMatcher &Matcher, 932 1.1.1.2 joerg BoundNodesTreeBuilder *Builder) { 933 1.1 joerg 934 1.1.1.2 joerg // Memoization keys that can be updated with the result. 935 1.1.1.2 joerg // These are the memoizable nodes in the chain of unique parents, which 936 1.1.1.2 joerg // terminates when a node has multiple parents, or matches, or is the root. 937 1.1.1.2 joerg std::vector<MatchKey> Keys; 938 1.1.1.2 joerg // When returning, update the memoization cache. 939 1.1.1.2 joerg auto Finish = [&](bool Matched) { 940 1.1.1.2 joerg for (const auto &Key : Keys) { 941 1.1.1.2 joerg MemoizedMatchResult &CachedResult = ResultCache[Key]; 942 1.1.1.2 joerg CachedResult.ResultOfMatch = Matched; 943 1.1.1.2 joerg CachedResult.Nodes = *Builder; 944 1.1.1.2 joerg } 945 1.1.1.2 joerg return Matched; 946 1.1.1.2 joerg }; 947 1.1 joerg 948 1.1.1.2 joerg // Loop while there's a single parent and we want to attempt memoization. 949 1.1.1.2 joerg DynTypedNodeList Parents{ArrayRef<DynTypedNode>()}; // after loop: size != 1 950 1.1.1.2 joerg for (;;) { 951 1.1.1.2 joerg // A cache key only makes sense if memoization is possible. 952 1.1.1.2 joerg if (Builder->isComparable()) { 953 1.1.1.2 joerg Keys.emplace_back(); 954 1.1.1.2 joerg Keys.back().MatcherID = Matcher.getID(); 955 1.1.1.2 joerg Keys.back().Node = Node; 956 1.1.1.2 joerg Keys.back().BoundNodes = *Builder; 957 1.1.1.2 joerg Keys.back().Traversal = Ctx.getParentMapContext().getTraversalKind(); 958 1.1.1.2 joerg Keys.back().Type = MatchType::Ancestors; 959 1.1.1.2 joerg 960 1.1.1.2 joerg // Check the cache. 961 1.1.1.2 joerg MemoizationMap::iterator I = ResultCache.find(Keys.back()); 962 1.1.1.2 joerg if (I != ResultCache.end()) { 963 1.1.1.2 joerg Keys.pop_back(); // Don't populate the cache for the matching node! 964 1.1.1.2 joerg *Builder = I->second.Nodes; 965 1.1.1.2 joerg return Finish(I->second.ResultOfMatch); 966 1.1.1.2 joerg } 967 1.1.1.2 joerg } 968 1.1 joerg 969 1.1.1.2 joerg Parents = ActiveASTContext->getParents(Node); 970 1.1.1.2 joerg // Either no parents or multiple parents: leave chain+memoize mode and 971 1.1.1.2 joerg // enter bfs+forgetful mode. 972 1.1.1.2 joerg if (Parents.size() != 1) 973 1.1.1.2 joerg break; 974 1.1 joerg 975 1.1.1.2 joerg // Check the next parent. 976 1.1.1.2 joerg Node = *Parents.begin(); 977 1.1.1.2 joerg BoundNodesTreeBuilder BuilderCopy = *Builder; 978 1.1.1.2 joerg if (Matcher.matches(Node, this, &BuilderCopy)) { 979 1.1.1.2 joerg *Builder = std::move(BuilderCopy); 980 1.1.1.2 joerg return Finish(true); 981 1.1.1.2 joerg } 982 1.1.1.2 joerg } 983 1.1.1.2 joerg // We reached the end of the chain. 984 1.1 joerg 985 1.1 joerg if (Parents.empty()) { 986 1.1 joerg // Nodes may have no parents if: 987 1.1 joerg // a) the node is the TranslationUnitDecl 988 1.1 joerg // b) we have a limited traversal scope that excludes the parent edges 989 1.1 joerg // c) there is a bug in the AST, and the node is not reachable 990 1.1 joerg // Usually the traversal scope is the whole AST, which precludes b. 991 1.1 joerg // Bugs are common enough that it's worthwhile asserting when we can. 992 1.1 joerg #ifndef NDEBUG 993 1.1 joerg if (!Node.get<TranslationUnitDecl>() && 994 1.1 joerg /* Traversal scope is full AST if any of the bounds are the TU */ 995 1.1 joerg llvm::any_of(ActiveASTContext->getTraversalScope(), [](Decl *D) { 996 1.1 joerg return D->getKind() == Decl::TranslationUnit; 997 1.1 joerg })) { 998 1.1 joerg llvm::errs() << "Tried to match orphan node:\n"; 999 1.1.1.2 joerg Node.dump(llvm::errs(), *ActiveASTContext); 1000 1.1 joerg llvm_unreachable("Parent map should be complete!"); 1001 1.1 joerg } 1002 1.1 joerg #endif 1003 1.1 joerg } else { 1004 1.1.1.2 joerg assert(Parents.size() > 1); 1005 1.1.1.2 joerg // BFS starting from the parents not yet considered. 1006 1.1.1.2 joerg // Memoization of newly visited nodes is not possible (but we still update 1007 1.1.1.2 joerg // results for the elements in the chain we found above). 1008 1.1.1.2 joerg std::deque<DynTypedNode> Queue(Parents.begin(), Parents.end()); 1009 1.1 joerg llvm::DenseSet<const void *> Visited; 1010 1.1 joerg while (!Queue.empty()) { 1011 1.1 joerg BoundNodesTreeBuilder BuilderCopy = *Builder; 1012 1.1 joerg if (Matcher.matches(Queue.front(), this, &BuilderCopy)) { 1013 1.1 joerg *Builder = std::move(BuilderCopy); 1014 1.1.1.2 joerg return Finish(true); 1015 1.1 joerg } 1016 1.1.1.2 joerg for (const auto &Parent : ActiveASTContext->getParents(Queue.front())) { 1017 1.1.1.2 joerg // Make sure we do not visit the same node twice. 1018 1.1.1.2 joerg // Otherwise, we'll visit the common ancestors as often as there 1019 1.1.1.2 joerg // are splits on the way down. 1020 1.1.1.2 joerg if (Visited.insert(Parent.getMemoizationData()).second) 1021 1.1.1.2 joerg Queue.push_back(Parent); 1022 1.1 joerg } 1023 1.1 joerg Queue.pop_front(); 1024 1.1 joerg } 1025 1.1 joerg } 1026 1.1.1.2 joerg return Finish(false); 1027 1.1 joerg } 1028 1.1 joerg 1029 1.1 joerg // Implements a BoundNodesTree::Visitor that calls a MatchCallback with 1030 1.1 joerg // the aggregated bound nodes for each match. 1031 1.1 joerg class MatchVisitor : public BoundNodesTreeBuilder::Visitor { 1032 1.1 joerg public: 1033 1.1 joerg MatchVisitor(ASTContext* Context, 1034 1.1 joerg MatchFinder::MatchCallback* Callback) 1035 1.1 joerg : Context(Context), 1036 1.1 joerg Callback(Callback) {} 1037 1.1 joerg 1038 1.1 joerg void visitMatch(const BoundNodes& BoundNodesView) override { 1039 1.1.1.2 joerg TraversalKindScope RAII(*Context, Callback->getCheckTraversalKind()); 1040 1.1 joerg Callback->run(MatchFinder::MatchResult(BoundNodesView, Context)); 1041 1.1 joerg } 1042 1.1 joerg 1043 1.1 joerg private: 1044 1.1 joerg ASTContext* Context; 1045 1.1 joerg MatchFinder::MatchCallback* Callback; 1046 1.1 joerg }; 1047 1.1 joerg 1048 1.1 joerg // Returns true if 'TypeNode' has an alias that matches the given matcher. 1049 1.1 joerg bool typeHasMatchingAlias(const Type *TypeNode, 1050 1.1 joerg const Matcher<NamedDecl> &Matcher, 1051 1.1 joerg BoundNodesTreeBuilder *Builder) { 1052 1.1 joerg const Type *const CanonicalType = 1053 1.1 joerg ActiveASTContext->getCanonicalType(TypeNode); 1054 1.1 joerg auto Aliases = TypeAliases.find(CanonicalType); 1055 1.1 joerg if (Aliases == TypeAliases.end()) 1056 1.1 joerg return false; 1057 1.1 joerg for (const TypedefNameDecl *Alias : Aliases->second) { 1058 1.1 joerg BoundNodesTreeBuilder Result(*Builder); 1059 1.1 joerg if (Matcher.matches(*Alias, this, &Result)) { 1060 1.1 joerg *Builder = std::move(Result); 1061 1.1 joerg return true; 1062 1.1 joerg } 1063 1.1 joerg } 1064 1.1 joerg return false; 1065 1.1 joerg } 1066 1.1 joerg 1067 1.1 joerg bool 1068 1.1 joerg objcClassHasMatchingCompatibilityAlias(const ObjCInterfaceDecl *InterfaceDecl, 1069 1.1 joerg const Matcher<NamedDecl> &Matcher, 1070 1.1 joerg BoundNodesTreeBuilder *Builder) { 1071 1.1 joerg auto Aliases = CompatibleAliases.find(InterfaceDecl); 1072 1.1 joerg if (Aliases == CompatibleAliases.end()) 1073 1.1 joerg return false; 1074 1.1 joerg for (const ObjCCompatibleAliasDecl *Alias : Aliases->second) { 1075 1.1 joerg BoundNodesTreeBuilder Result(*Builder); 1076 1.1 joerg if (Matcher.matches(*Alias, this, &Result)) { 1077 1.1 joerg *Builder = std::move(Result); 1078 1.1 joerg return true; 1079 1.1 joerg } 1080 1.1 joerg } 1081 1.1 joerg return false; 1082 1.1 joerg } 1083 1.1 joerg 1084 1.1 joerg /// Bucket to record map. 1085 1.1 joerg /// 1086 1.1 joerg /// Used to get the appropriate bucket for each matcher. 1087 1.1 joerg llvm::StringMap<llvm::TimeRecord> TimeByBucket; 1088 1.1 joerg 1089 1.1 joerg const MatchFinder::MatchersByType *Matchers; 1090 1.1 joerg 1091 1.1 joerg /// Filtered list of matcher indices for each matcher kind. 1092 1.1 joerg /// 1093 1.1 joerg /// \c Decl and \c Stmt toplevel matchers usually apply to a specific node 1094 1.1 joerg /// kind (and derived kinds) so it is a waste to try every matcher on every 1095 1.1 joerg /// node. 1096 1.1 joerg /// We precalculate a list of matchers that pass the toplevel restrict check. 1097 1.1.1.2 joerg llvm::DenseMap<ASTNodeKind, std::vector<unsigned short>> MatcherFiltersMap; 1098 1.1 joerg 1099 1.1 joerg const MatchFinder::MatchFinderOptions &Options; 1100 1.1 joerg ASTContext *ActiveASTContext; 1101 1.1 joerg 1102 1.1 joerg // Maps a canonical type to its TypedefDecls. 1103 1.1 joerg llvm::DenseMap<const Type*, std::set<const TypedefNameDecl*> > TypeAliases; 1104 1.1 joerg 1105 1.1 joerg // Maps an Objective-C interface to its ObjCCompatibleAliasDecls. 1106 1.1 joerg llvm::DenseMap<const ObjCInterfaceDecl *, 1107 1.1 joerg llvm::SmallPtrSet<const ObjCCompatibleAliasDecl *, 2>> 1108 1.1 joerg CompatibleAliases; 1109 1.1 joerg 1110 1.1 joerg // Maps (matcher, node) -> the match result for memoization. 1111 1.1 joerg typedef std::map<MatchKey, MemoizedMatchResult> MemoizationMap; 1112 1.1 joerg MemoizationMap ResultCache; 1113 1.1 joerg }; 1114 1.1 joerg 1115 1.1 joerg static CXXRecordDecl * 1116 1.1 joerg getAsCXXRecordDeclOrPrimaryTemplate(const Type *TypeNode) { 1117 1.1 joerg if (auto *RD = TypeNode->getAsCXXRecordDecl()) 1118 1.1 joerg return RD; 1119 1.1 joerg 1120 1.1 joerg // Find the innermost TemplateSpecializationType that isn't an alias template. 1121 1.1 joerg auto *TemplateType = TypeNode->getAs<TemplateSpecializationType>(); 1122 1.1 joerg while (TemplateType && TemplateType->isTypeAlias()) 1123 1.1 joerg TemplateType = 1124 1.1 joerg TemplateType->getAliasedType()->getAs<TemplateSpecializationType>(); 1125 1.1 joerg 1126 1.1 joerg // If this is the name of a (dependent) template specialization, use the 1127 1.1 joerg // definition of the template, even though it might be specialized later. 1128 1.1 joerg if (TemplateType) 1129 1.1 joerg if (auto *ClassTemplate = dyn_cast_or_null<ClassTemplateDecl>( 1130 1.1 joerg TemplateType->getTemplateName().getAsTemplateDecl())) 1131 1.1 joerg return ClassTemplate->getTemplatedDecl(); 1132 1.1 joerg 1133 1.1 joerg return nullptr; 1134 1.1 joerg } 1135 1.1 joerg 1136 1.1 joerg // Returns true if the given C++ class is directly or indirectly derived 1137 1.1 joerg // from a base type with the given name. A class is not considered to be 1138 1.1 joerg // derived from itself. 1139 1.1 joerg bool MatchASTVisitor::classIsDerivedFrom(const CXXRecordDecl *Declaration, 1140 1.1 joerg const Matcher<NamedDecl> &Base, 1141 1.1 joerg BoundNodesTreeBuilder *Builder, 1142 1.1 joerg bool Directly) { 1143 1.1 joerg if (!Declaration->hasDefinition()) 1144 1.1 joerg return false; 1145 1.1 joerg for (const auto &It : Declaration->bases()) { 1146 1.1 joerg const Type *TypeNode = It.getType().getTypePtr(); 1147 1.1 joerg 1148 1.1 joerg if (typeHasMatchingAlias(TypeNode, Base, Builder)) 1149 1.1 joerg return true; 1150 1.1 joerg 1151 1.1 joerg // FIXME: Going to the primary template here isn't really correct, but 1152 1.1 joerg // unfortunately we accept a Decl matcher for the base class not a Type 1153 1.1 joerg // matcher, so it's the best thing we can do with our current interface. 1154 1.1 joerg CXXRecordDecl *ClassDecl = getAsCXXRecordDeclOrPrimaryTemplate(TypeNode); 1155 1.1 joerg if (!ClassDecl) 1156 1.1 joerg continue; 1157 1.1 joerg if (ClassDecl == Declaration) { 1158 1.1.1.2 joerg // This can happen for recursive template definitions. 1159 1.1.1.2 joerg continue; 1160 1.1 joerg } 1161 1.1 joerg BoundNodesTreeBuilder Result(*Builder); 1162 1.1 joerg if (Base.matches(*ClassDecl, this, &Result)) { 1163 1.1 joerg *Builder = std::move(Result); 1164 1.1 joerg return true; 1165 1.1 joerg } 1166 1.1 joerg if (!Directly && classIsDerivedFrom(ClassDecl, Base, Builder, Directly)) 1167 1.1 joerg return true; 1168 1.1 joerg } 1169 1.1 joerg return false; 1170 1.1 joerg } 1171 1.1 joerg 1172 1.1 joerg // Returns true if the given Objective-C class is directly or indirectly 1173 1.1 joerg // derived from a matching base class. A class is not considered to be derived 1174 1.1 joerg // from itself. 1175 1.1 joerg bool MatchASTVisitor::objcClassIsDerivedFrom( 1176 1.1 joerg const ObjCInterfaceDecl *Declaration, const Matcher<NamedDecl> &Base, 1177 1.1 joerg BoundNodesTreeBuilder *Builder, bool Directly) { 1178 1.1 joerg // Check if any of the superclasses of the class match. 1179 1.1 joerg for (const ObjCInterfaceDecl *ClassDecl = Declaration->getSuperClass(); 1180 1.1 joerg ClassDecl != nullptr; ClassDecl = ClassDecl->getSuperClass()) { 1181 1.1 joerg // Check if there are any matching compatibility aliases. 1182 1.1 joerg if (objcClassHasMatchingCompatibilityAlias(ClassDecl, Base, Builder)) 1183 1.1 joerg return true; 1184 1.1 joerg 1185 1.1 joerg // Check if there are any matching type aliases. 1186 1.1 joerg const Type *TypeNode = ClassDecl->getTypeForDecl(); 1187 1.1 joerg if (typeHasMatchingAlias(TypeNode, Base, Builder)) 1188 1.1 joerg return true; 1189 1.1 joerg 1190 1.1 joerg if (Base.matches(*ClassDecl, this, Builder)) 1191 1.1 joerg return true; 1192 1.1 joerg 1193 1.1.1.2 joerg // Not `return false` as a temporary workaround for PR43879. 1194 1.1 joerg if (Directly) 1195 1.1.1.2 joerg break; 1196 1.1 joerg } 1197 1.1 joerg 1198 1.1 joerg return false; 1199 1.1 joerg } 1200 1.1 joerg 1201 1.1 joerg bool MatchASTVisitor::TraverseDecl(Decl *DeclNode) { 1202 1.1 joerg if (!DeclNode) { 1203 1.1 joerg return true; 1204 1.1 joerg } 1205 1.1.1.2 joerg 1206 1.1.1.2 joerg bool ScopedTraversal = 1207 1.1.1.2 joerg TraversingASTNodeNotSpelledInSource || DeclNode->isImplicit(); 1208 1.1.1.2 joerg bool ScopedChildren = TraversingASTChildrenNotSpelledInSource; 1209 1.1.1.2 joerg 1210 1.1.1.2 joerg if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(DeclNode)) { 1211 1.1.1.2 joerg auto SK = CTSD->getSpecializationKind(); 1212 1.1.1.2 joerg if (SK == TSK_ExplicitInstantiationDeclaration || 1213 1.1.1.2 joerg SK == TSK_ExplicitInstantiationDefinition) 1214 1.1.1.2 joerg ScopedChildren = true; 1215 1.1.1.2 joerg } else if (const auto *FD = dyn_cast<FunctionDecl>(DeclNode)) { 1216 1.1.1.2 joerg if (FD->isDefaulted()) 1217 1.1.1.2 joerg ScopedChildren = true; 1218 1.1.1.2 joerg if (FD->isTemplateInstantiation()) 1219 1.1.1.2 joerg ScopedTraversal = true; 1220 1.1.1.2 joerg } else if (isa<BindingDecl>(DeclNode)) { 1221 1.1.1.2 joerg ScopedChildren = true; 1222 1.1.1.2 joerg } 1223 1.1.1.2 joerg 1224 1.1.1.2 joerg ASTNodeNotSpelledInSourceScope RAII1(this, ScopedTraversal); 1225 1.1.1.2 joerg ASTChildrenNotSpelledInSourceScope RAII2(this, ScopedChildren); 1226 1.1.1.2 joerg 1227 1.1 joerg match(*DeclNode); 1228 1.1 joerg return RecursiveASTVisitor<MatchASTVisitor>::TraverseDecl(DeclNode); 1229 1.1 joerg } 1230 1.1 joerg 1231 1.1 joerg bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue) { 1232 1.1 joerg if (!StmtNode) { 1233 1.1 joerg return true; 1234 1.1 joerg } 1235 1.1.1.2 joerg bool ScopedTraversal = TraversingASTNodeNotSpelledInSource || 1236 1.1.1.2 joerg TraversingASTChildrenNotSpelledInSource; 1237 1.1.1.2 joerg 1238 1.1.1.2 joerg ASTNodeNotSpelledInSourceScope RAII(this, ScopedTraversal); 1239 1.1 joerg match(*StmtNode); 1240 1.1 joerg return RecursiveASTVisitor<MatchASTVisitor>::TraverseStmt(StmtNode, Queue); 1241 1.1 joerg } 1242 1.1 joerg 1243 1.1 joerg bool MatchASTVisitor::TraverseType(QualType TypeNode) { 1244 1.1 joerg match(TypeNode); 1245 1.1 joerg return RecursiveASTVisitor<MatchASTVisitor>::TraverseType(TypeNode); 1246 1.1 joerg } 1247 1.1 joerg 1248 1.1 joerg bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLocNode) { 1249 1.1 joerg // The RecursiveASTVisitor only visits types if they're not within TypeLocs. 1250 1.1 joerg // We still want to find those types via matchers, so we match them here. Note 1251 1.1 joerg // that the TypeLocs are structurally a shadow-hierarchy to the expressed 1252 1.1 joerg // type, so we visit all involved parts of a compound type when matching on 1253 1.1 joerg // each TypeLoc. 1254 1.1 joerg match(TypeLocNode); 1255 1.1 joerg match(TypeLocNode.getType()); 1256 1.1 joerg return RecursiveASTVisitor<MatchASTVisitor>::TraverseTypeLoc(TypeLocNode); 1257 1.1 joerg } 1258 1.1 joerg 1259 1.1 joerg bool MatchASTVisitor::TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) { 1260 1.1 joerg match(*NNS); 1261 1.1 joerg return RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifier(NNS); 1262 1.1 joerg } 1263 1.1 joerg 1264 1.1 joerg bool MatchASTVisitor::TraverseNestedNameSpecifierLoc( 1265 1.1 joerg NestedNameSpecifierLoc NNS) { 1266 1.1 joerg if (!NNS) 1267 1.1 joerg return true; 1268 1.1 joerg 1269 1.1 joerg match(NNS); 1270 1.1 joerg 1271 1.1 joerg // We only match the nested name specifier here (as opposed to traversing it) 1272 1.1 joerg // because the traversal is already done in the parallel "Loc"-hierarchy. 1273 1.1 joerg if (NNS.hasQualifier()) 1274 1.1 joerg match(*NNS.getNestedNameSpecifier()); 1275 1.1 joerg return 1276 1.1 joerg RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifierLoc(NNS); 1277 1.1 joerg } 1278 1.1 joerg 1279 1.1 joerg bool MatchASTVisitor::TraverseConstructorInitializer( 1280 1.1 joerg CXXCtorInitializer *CtorInit) { 1281 1.1 joerg if (!CtorInit) 1282 1.1 joerg return true; 1283 1.1 joerg 1284 1.1.1.2 joerg bool ScopedTraversal = TraversingASTNodeNotSpelledInSource || 1285 1.1.1.2 joerg TraversingASTChildrenNotSpelledInSource; 1286 1.1.1.2 joerg 1287 1.1.1.2 joerg if (!CtorInit->isWritten()) 1288 1.1.1.2 joerg ScopedTraversal = true; 1289 1.1.1.2 joerg 1290 1.1.1.2 joerg ASTNodeNotSpelledInSourceScope RAII1(this, ScopedTraversal); 1291 1.1.1.2 joerg 1292 1.1 joerg match(*CtorInit); 1293 1.1 joerg 1294 1.1 joerg return RecursiveASTVisitor<MatchASTVisitor>::TraverseConstructorInitializer( 1295 1.1 joerg CtorInit); 1296 1.1 joerg } 1297 1.1 joerg 1298 1.1.1.2 joerg bool MatchASTVisitor::TraverseTemplateArgumentLoc(TemplateArgumentLoc Loc) { 1299 1.1.1.2 joerg match(Loc); 1300 1.1.1.2 joerg return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateArgumentLoc(Loc); 1301 1.1.1.2 joerg } 1302 1.1.1.2 joerg 1303 1.1 joerg class MatchASTConsumer : public ASTConsumer { 1304 1.1 joerg public: 1305 1.1 joerg MatchASTConsumer(MatchFinder *Finder, 1306 1.1 joerg MatchFinder::ParsingDoneTestCallback *ParsingDone) 1307 1.1 joerg : Finder(Finder), ParsingDone(ParsingDone) {} 1308 1.1 joerg 1309 1.1 joerg private: 1310 1.1 joerg void HandleTranslationUnit(ASTContext &Context) override { 1311 1.1 joerg if (ParsingDone != nullptr) { 1312 1.1 joerg ParsingDone->run(); 1313 1.1 joerg } 1314 1.1 joerg Finder->matchAST(Context); 1315 1.1 joerg } 1316 1.1 joerg 1317 1.1 joerg MatchFinder *Finder; 1318 1.1 joerg MatchFinder::ParsingDoneTestCallback *ParsingDone; 1319 1.1 joerg }; 1320 1.1 joerg 1321 1.1 joerg } // end namespace 1322 1.1 joerg } // end namespace internal 1323 1.1 joerg 1324 1.1 joerg MatchFinder::MatchResult::MatchResult(const BoundNodes &Nodes, 1325 1.1 joerg ASTContext *Context) 1326 1.1 joerg : Nodes(Nodes), Context(Context), 1327 1.1 joerg SourceManager(&Context->getSourceManager()) {} 1328 1.1 joerg 1329 1.1 joerg MatchFinder::MatchCallback::~MatchCallback() {} 1330 1.1 joerg MatchFinder::ParsingDoneTestCallback::~ParsingDoneTestCallback() {} 1331 1.1 joerg 1332 1.1 joerg MatchFinder::MatchFinder(MatchFinderOptions Options) 1333 1.1 joerg : Options(std::move(Options)), ParsingDone(nullptr) {} 1334 1.1 joerg 1335 1.1 joerg MatchFinder::~MatchFinder() {} 1336 1.1 joerg 1337 1.1 joerg void MatchFinder::addMatcher(const DeclarationMatcher &NodeMatch, 1338 1.1 joerg MatchCallback *Action) { 1339 1.1.1.2 joerg llvm::Optional<TraversalKind> TK; 1340 1.1.1.2 joerg if (Action) 1341 1.1.1.2 joerg TK = Action->getCheckTraversalKind(); 1342 1.1.1.2 joerg if (TK) 1343 1.1.1.2 joerg Matchers.DeclOrStmt.emplace_back(traverse(*TK, NodeMatch), Action); 1344 1.1.1.2 joerg else 1345 1.1.1.2 joerg Matchers.DeclOrStmt.emplace_back(NodeMatch, Action); 1346 1.1 joerg Matchers.AllCallbacks.insert(Action); 1347 1.1 joerg } 1348 1.1 joerg 1349 1.1 joerg void MatchFinder::addMatcher(const TypeMatcher &NodeMatch, 1350 1.1 joerg MatchCallback *Action) { 1351 1.1 joerg Matchers.Type.emplace_back(NodeMatch, Action); 1352 1.1 joerg Matchers.AllCallbacks.insert(Action); 1353 1.1 joerg } 1354 1.1 joerg 1355 1.1 joerg void MatchFinder::addMatcher(const StatementMatcher &NodeMatch, 1356 1.1 joerg MatchCallback *Action) { 1357 1.1.1.2 joerg llvm::Optional<TraversalKind> TK; 1358 1.1.1.2 joerg if (Action) 1359 1.1.1.2 joerg TK = Action->getCheckTraversalKind(); 1360 1.1.1.2 joerg if (TK) 1361 1.1.1.2 joerg Matchers.DeclOrStmt.emplace_back(traverse(*TK, NodeMatch), Action); 1362 1.1.1.2 joerg else 1363 1.1.1.2 joerg Matchers.DeclOrStmt.emplace_back(NodeMatch, Action); 1364 1.1 joerg Matchers.AllCallbacks.insert(Action); 1365 1.1 joerg } 1366 1.1 joerg 1367 1.1 joerg void MatchFinder::addMatcher(const NestedNameSpecifierMatcher &NodeMatch, 1368 1.1 joerg MatchCallback *Action) { 1369 1.1 joerg Matchers.NestedNameSpecifier.emplace_back(NodeMatch, Action); 1370 1.1 joerg Matchers.AllCallbacks.insert(Action); 1371 1.1 joerg } 1372 1.1 joerg 1373 1.1 joerg void MatchFinder::addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch, 1374 1.1 joerg MatchCallback *Action) { 1375 1.1 joerg Matchers.NestedNameSpecifierLoc.emplace_back(NodeMatch, Action); 1376 1.1 joerg Matchers.AllCallbacks.insert(Action); 1377 1.1 joerg } 1378 1.1 joerg 1379 1.1 joerg void MatchFinder::addMatcher(const TypeLocMatcher &NodeMatch, 1380 1.1 joerg MatchCallback *Action) { 1381 1.1 joerg Matchers.TypeLoc.emplace_back(NodeMatch, Action); 1382 1.1 joerg Matchers.AllCallbacks.insert(Action); 1383 1.1 joerg } 1384 1.1 joerg 1385 1.1 joerg void MatchFinder::addMatcher(const CXXCtorInitializerMatcher &NodeMatch, 1386 1.1 joerg MatchCallback *Action) { 1387 1.1 joerg Matchers.CtorInit.emplace_back(NodeMatch, Action); 1388 1.1 joerg Matchers.AllCallbacks.insert(Action); 1389 1.1 joerg } 1390 1.1 joerg 1391 1.1.1.2 joerg void MatchFinder::addMatcher(const TemplateArgumentLocMatcher &NodeMatch, 1392 1.1.1.2 joerg MatchCallback *Action) { 1393 1.1.1.2 joerg Matchers.TemplateArgumentLoc.emplace_back(NodeMatch, Action); 1394 1.1.1.2 joerg Matchers.AllCallbacks.insert(Action); 1395 1.1.1.2 joerg } 1396 1.1.1.2 joerg 1397 1.1 joerg bool MatchFinder::addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, 1398 1.1 joerg MatchCallback *Action) { 1399 1.1 joerg if (NodeMatch.canConvertTo<Decl>()) { 1400 1.1 joerg addMatcher(NodeMatch.convertTo<Decl>(), Action); 1401 1.1 joerg return true; 1402 1.1 joerg } else if (NodeMatch.canConvertTo<QualType>()) { 1403 1.1 joerg addMatcher(NodeMatch.convertTo<QualType>(), Action); 1404 1.1 joerg return true; 1405 1.1 joerg } else if (NodeMatch.canConvertTo<Stmt>()) { 1406 1.1 joerg addMatcher(NodeMatch.convertTo<Stmt>(), Action); 1407 1.1 joerg return true; 1408 1.1 joerg } else if (NodeMatch.canConvertTo<NestedNameSpecifier>()) { 1409 1.1 joerg addMatcher(NodeMatch.convertTo<NestedNameSpecifier>(), Action); 1410 1.1 joerg return true; 1411 1.1 joerg } else if (NodeMatch.canConvertTo<NestedNameSpecifierLoc>()) { 1412 1.1 joerg addMatcher(NodeMatch.convertTo<NestedNameSpecifierLoc>(), Action); 1413 1.1 joerg return true; 1414 1.1 joerg } else if (NodeMatch.canConvertTo<TypeLoc>()) { 1415 1.1 joerg addMatcher(NodeMatch.convertTo<TypeLoc>(), Action); 1416 1.1 joerg return true; 1417 1.1 joerg } else if (NodeMatch.canConvertTo<CXXCtorInitializer>()) { 1418 1.1 joerg addMatcher(NodeMatch.convertTo<CXXCtorInitializer>(), Action); 1419 1.1 joerg return true; 1420 1.1.1.2 joerg } else if (NodeMatch.canConvertTo<TemplateArgumentLoc>()) { 1421 1.1.1.2 joerg addMatcher(NodeMatch.convertTo<TemplateArgumentLoc>(), Action); 1422 1.1.1.2 joerg return true; 1423 1.1 joerg } 1424 1.1 joerg return false; 1425 1.1 joerg } 1426 1.1 joerg 1427 1.1 joerg std::unique_ptr<ASTConsumer> MatchFinder::newASTConsumer() { 1428 1.1 joerg return std::make_unique<internal::MatchASTConsumer>(this, ParsingDone); 1429 1.1 joerg } 1430 1.1 joerg 1431 1.1.1.2 joerg void MatchFinder::match(const clang::DynTypedNode &Node, ASTContext &Context) { 1432 1.1 joerg internal::MatchASTVisitor Visitor(&Matchers, Options); 1433 1.1 joerg Visitor.set_active_ast_context(&Context); 1434 1.1 joerg Visitor.match(Node); 1435 1.1 joerg } 1436 1.1 joerg 1437 1.1 joerg void MatchFinder::matchAST(ASTContext &Context) { 1438 1.1 joerg internal::MatchASTVisitor Visitor(&Matchers, Options); 1439 1.1 joerg Visitor.set_active_ast_context(&Context); 1440 1.1 joerg Visitor.onStartOfTranslationUnit(); 1441 1.1 joerg Visitor.TraverseAST(Context); 1442 1.1 joerg Visitor.onEndOfTranslationUnit(); 1443 1.1 joerg } 1444 1.1 joerg 1445 1.1 joerg void MatchFinder::registerTestCallbackAfterParsing( 1446 1.1 joerg MatchFinder::ParsingDoneTestCallback *NewParsingDone) { 1447 1.1 joerg ParsingDone = NewParsingDone; 1448 1.1 joerg } 1449 1.1 joerg 1450 1.1 joerg StringRef MatchFinder::MatchCallback::getID() const { return "<unknown>"; } 1451 1.1 joerg 1452 1.1.1.2 joerg llvm::Optional<TraversalKind> 1453 1.1.1.2 joerg MatchFinder::MatchCallback::getCheckTraversalKind() const { 1454 1.1.1.2 joerg return llvm::None; 1455 1.1.1.2 joerg } 1456 1.1.1.2 joerg 1457 1.1 joerg } // end namespace ast_matchers 1458 1.1 joerg } // end namespace clang 1459