ASTMatchFinder.cpp 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000
  1. //===--- ASTMatchFinder.cpp - Structural query framework ------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // Implements an algorithm to efficiently search for matches on AST nodes.
  11. // Uses memoization to support recursive matches like HasDescendant.
  12. //
  13. // The general idea is to visit all AST nodes with a RecursiveASTVisitor,
  14. // calling the Matches(...) method of each matcher we are running on each
  15. // AST node. The matcher can recurse via the ASTMatchFinder interface.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #include "clang/ASTMatchers/ASTMatchFinder.h"
  19. #include "clang/AST/ASTConsumer.h"
  20. #include "clang/AST/ASTContext.h"
  21. #include "clang/AST/RecursiveASTVisitor.h"
  22. #include "llvm/ADT/DenseMap.h"
  23. #include "llvm/ADT/StringMap.h"
  24. #include "llvm/Support/Timer.h"
  25. #include <deque>
  26. #include <memory>
  27. #include <set>
  28. namespace clang {
  29. namespace ast_matchers {
  30. namespace internal {
  31. namespace {
  32. typedef MatchFinder::MatchCallback MatchCallback;
  33. // The maximum number of memoization entries to store.
  34. // 10k has been experimentally found to give a good trade-off
  35. // of performance vs. memory consumption by running matcher
  36. // that match on every statement over a very large codebase.
  37. //
  38. // FIXME: Do some performance optimization in general and
  39. // revisit this number; also, put up micro-benchmarks that we can
  40. // optimize this on.
  41. static const unsigned MaxMemoizationEntries = 10000;
  42. // We use memoization to avoid running the same matcher on the same
  43. // AST node twice. This struct is the key for looking up match
  44. // result. It consists of an ID of the MatcherInterface (for
  45. // identifying the matcher), a pointer to the AST node and the
  46. // bound nodes before the matcher was executed.
  47. //
  48. // We currently only memoize on nodes whose pointers identify the
  49. // nodes (\c Stmt and \c Decl, but not \c QualType or \c TypeLoc).
  50. // For \c QualType and \c TypeLoc it is possible to implement
  51. // generation of keys for each type.
  52. // FIXME: Benchmark whether memoization of non-pointer typed nodes
  53. // provides enough benefit for the additional amount of code.
  54. struct MatchKey {
  55. DynTypedMatcher::MatcherIDType MatcherID;
  56. ast_type_traits::DynTypedNode Node;
  57. BoundNodesTreeBuilder BoundNodes;
  58. bool operator<(const MatchKey &Other) const {
  59. return std::tie(MatcherID, Node, BoundNodes) <
  60. std::tie(Other.MatcherID, Other.Node, Other.BoundNodes);
  61. }
  62. };
  63. // Used to store the result of a match and possibly bound nodes.
  64. struct MemoizedMatchResult {
  65. bool ResultOfMatch;
  66. BoundNodesTreeBuilder Nodes;
  67. };
  68. // A RecursiveASTVisitor that traverses all children or all descendants of
  69. // a node.
  70. class MatchChildASTVisitor
  71. : public RecursiveASTVisitor<MatchChildASTVisitor> {
  72. public:
  73. typedef RecursiveASTVisitor<MatchChildASTVisitor> VisitorBase;
  74. // Creates an AST visitor that matches 'matcher' on all children or
  75. // descendants of a traversed node. max_depth is the maximum depth
  76. // to traverse: use 1 for matching the children and INT_MAX for
  77. // matching the descendants.
  78. MatchChildASTVisitor(const DynTypedMatcher *Matcher,
  79. ASTMatchFinder *Finder,
  80. BoundNodesTreeBuilder *Builder,
  81. int MaxDepth,
  82. ASTMatchFinder::TraversalKind Traversal,
  83. ASTMatchFinder::BindKind Bind)
  84. : Matcher(Matcher),
  85. Finder(Finder),
  86. Builder(Builder),
  87. CurrentDepth(0),
  88. MaxDepth(MaxDepth),
  89. Traversal(Traversal),
  90. Bind(Bind),
  91. Matches(false) {}
  92. // Returns true if a match is found in the subtree rooted at the
  93. // given AST node. This is done via a set of mutually recursive
  94. // functions. Here's how the recursion is done (the *wildcard can
  95. // actually be Decl, Stmt, or Type):
  96. //
  97. // - Traverse(node) calls BaseTraverse(node) when it needs
  98. // to visit the descendants of node.
  99. // - BaseTraverse(node) then calls (via VisitorBase::Traverse*(node))
  100. // Traverse*(c) for each child c of 'node'.
  101. // - Traverse*(c) in turn calls Traverse(c), completing the
  102. // recursion.
  103. bool findMatch(const ast_type_traits::DynTypedNode &DynNode) {
  104. reset();
  105. if (const Decl *D = DynNode.get<Decl>())
  106. traverse(*D);
  107. else if (const Stmt *S = DynNode.get<Stmt>())
  108. traverse(*S);
  109. else if (const NestedNameSpecifier *NNS =
  110. DynNode.get<NestedNameSpecifier>())
  111. traverse(*NNS);
  112. else if (const NestedNameSpecifierLoc *NNSLoc =
  113. DynNode.get<NestedNameSpecifierLoc>())
  114. traverse(*NNSLoc);
  115. else if (const QualType *Q = DynNode.get<QualType>())
  116. traverse(*Q);
  117. else if (const TypeLoc *T = DynNode.get<TypeLoc>())
  118. traverse(*T);
  119. // FIXME: Add other base types after adding tests.
  120. // It's OK to always overwrite the bound nodes, as if there was
  121. // no match in this recursive branch, the result set is empty
  122. // anyway.
  123. *Builder = ResultBindings;
  124. return Matches;
  125. }
  126. // The following are overriding methods from the base visitor class.
  127. // They are public only to allow CRTP to work. They are *not *part
  128. // of the public API of this class.
  129. bool TraverseDecl(Decl *DeclNode) {
  130. ScopedIncrement ScopedDepth(&CurrentDepth);
  131. return (DeclNode == nullptr) || traverse(*DeclNode);
  132. }
  133. bool TraverseStmt(Stmt *StmtNode) {
  134. ScopedIncrement ScopedDepth(&CurrentDepth);
  135. const Stmt *StmtToTraverse = StmtNode;
  136. if (Traversal ==
  137. ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses) {
  138. const Expr *ExprNode = dyn_cast_or_null<Expr>(StmtNode);
  139. if (ExprNode) {
  140. StmtToTraverse = ExprNode->IgnoreParenImpCasts();
  141. }
  142. }
  143. return (StmtToTraverse == nullptr) || traverse(*StmtToTraverse);
  144. }
  145. // We assume that the QualType and the contained type are on the same
  146. // hierarchy level. Thus, we try to match either of them.
  147. bool TraverseType(QualType TypeNode) {
  148. if (TypeNode.isNull())
  149. return true;
  150. ScopedIncrement ScopedDepth(&CurrentDepth);
  151. // Match the Type.
  152. if (!match(*TypeNode))
  153. return false;
  154. // The QualType is matched inside traverse.
  155. return traverse(TypeNode);
  156. }
  157. // We assume that the TypeLoc, contained QualType and contained Type all are
  158. // on the same hierarchy level. Thus, we try to match all of them.
  159. bool TraverseTypeLoc(TypeLoc TypeLocNode) {
  160. if (TypeLocNode.isNull())
  161. return true;
  162. ScopedIncrement ScopedDepth(&CurrentDepth);
  163. // Match the Type.
  164. if (!match(*TypeLocNode.getType()))
  165. return false;
  166. // Match the QualType.
  167. if (!match(TypeLocNode.getType()))
  168. return false;
  169. // The TypeLoc is matched inside traverse.
  170. return traverse(TypeLocNode);
  171. }
  172. bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) {
  173. ScopedIncrement ScopedDepth(&CurrentDepth);
  174. return (NNS == nullptr) || traverse(*NNS);
  175. }
  176. bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
  177. if (!NNS)
  178. return true;
  179. ScopedIncrement ScopedDepth(&CurrentDepth);
  180. if (!match(*NNS.getNestedNameSpecifier()))
  181. return false;
  182. return traverse(NNS);
  183. }
  184. bool shouldVisitTemplateInstantiations() const { return true; }
  185. bool shouldVisitImplicitCode() const { return true; }
  186. // Disables data recursion. We intercept Traverse* methods in the RAV, which
  187. // are not triggered during data recursion.
  188. bool shouldUseDataRecursionFor(clang::Stmt *S) const { return false; }
  189. private:
  190. // Used for updating the depth during traversal.
  191. struct ScopedIncrement {
  192. explicit ScopedIncrement(int *Depth) : Depth(Depth) { ++(*Depth); }
  193. ~ScopedIncrement() { --(*Depth); }
  194. private:
  195. int *Depth;
  196. };
  197. // Resets the state of this object.
  198. void reset() {
  199. Matches = false;
  200. CurrentDepth = 0;
  201. }
  202. // Forwards the call to the corresponding Traverse*() method in the
  203. // base visitor class.
  204. bool baseTraverse(const Decl &DeclNode) {
  205. return VisitorBase::TraverseDecl(const_cast<Decl*>(&DeclNode));
  206. }
  207. bool baseTraverse(const Stmt &StmtNode) {
  208. return VisitorBase::TraverseStmt(const_cast<Stmt*>(&StmtNode));
  209. }
  210. bool baseTraverse(QualType TypeNode) {
  211. return VisitorBase::TraverseType(TypeNode);
  212. }
  213. bool baseTraverse(TypeLoc TypeLocNode) {
  214. return VisitorBase::TraverseTypeLoc(TypeLocNode);
  215. }
  216. bool baseTraverse(const NestedNameSpecifier &NNS) {
  217. return VisitorBase::TraverseNestedNameSpecifier(
  218. const_cast<NestedNameSpecifier*>(&NNS));
  219. }
  220. bool baseTraverse(NestedNameSpecifierLoc NNS) {
  221. return VisitorBase::TraverseNestedNameSpecifierLoc(NNS);
  222. }
  223. // Sets 'Matched' to true if 'Matcher' matches 'Node' and:
  224. // 0 < CurrentDepth <= MaxDepth.
  225. //
  226. // Returns 'true' if traversal should continue after this function
  227. // returns, i.e. if no match is found or 'Bind' is 'BK_All'.
  228. template <typename T>
  229. bool match(const T &Node) {
  230. if (CurrentDepth == 0 || CurrentDepth > MaxDepth) {
  231. return true;
  232. }
  233. if (Bind != ASTMatchFinder::BK_All) {
  234. BoundNodesTreeBuilder RecursiveBuilder(*Builder);
  235. if (Matcher->matches(ast_type_traits::DynTypedNode::create(Node), Finder,
  236. &RecursiveBuilder)) {
  237. Matches = true;
  238. ResultBindings.addMatch(RecursiveBuilder);
  239. return false; // Abort as soon as a match is found.
  240. }
  241. } else {
  242. BoundNodesTreeBuilder RecursiveBuilder(*Builder);
  243. if (Matcher->matches(ast_type_traits::DynTypedNode::create(Node), Finder,
  244. &RecursiveBuilder)) {
  245. // After the first match the matcher succeeds.
  246. Matches = true;
  247. ResultBindings.addMatch(RecursiveBuilder);
  248. }
  249. }
  250. return true;
  251. }
  252. // Traverses the subtree rooted at 'Node'; returns true if the
  253. // traversal should continue after this function returns.
  254. template <typename T>
  255. bool traverse(const T &Node) {
  256. static_assert(IsBaseType<T>::value,
  257. "traverse can only be instantiated with base type");
  258. if (!match(Node))
  259. return false;
  260. return baseTraverse(Node);
  261. }
  262. const DynTypedMatcher *const Matcher;
  263. ASTMatchFinder *const Finder;
  264. BoundNodesTreeBuilder *const Builder;
  265. BoundNodesTreeBuilder ResultBindings;
  266. int CurrentDepth;
  267. const int MaxDepth;
  268. const ASTMatchFinder::TraversalKind Traversal;
  269. const ASTMatchFinder::BindKind Bind;
  270. bool Matches;
  271. };
  272. // Controls the outermost traversal of the AST and allows to match multiple
  273. // matchers.
  274. class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
  275. public ASTMatchFinder {
  276. public:
  277. MatchASTVisitor(const MatchFinder::MatchersByType *Matchers,
  278. const MatchFinder::MatchFinderOptions &Options)
  279. : Matchers(Matchers), Options(Options), ActiveASTContext(nullptr) {}
  280. ~MatchASTVisitor() override {
  281. if (Options.CheckProfiling) {
  282. Options.CheckProfiling->Records = std::move(TimeByBucket);
  283. }
  284. }
  285. void onStartOfTranslationUnit() {
  286. const bool EnableCheckProfiling = Options.CheckProfiling.hasValue();
  287. TimeBucketRegion Timer;
  288. for (MatchCallback *MC : Matchers->AllCallbacks) {
  289. if (EnableCheckProfiling)
  290. Timer.setBucket(&TimeByBucket[MC->getID()]);
  291. MC->onStartOfTranslationUnit();
  292. }
  293. }
  294. void onEndOfTranslationUnit() {
  295. const bool EnableCheckProfiling = Options.CheckProfiling.hasValue();
  296. TimeBucketRegion Timer;
  297. for (MatchCallback *MC : Matchers->AllCallbacks) {
  298. if (EnableCheckProfiling)
  299. Timer.setBucket(&TimeByBucket[MC->getID()]);
  300. MC->onEndOfTranslationUnit();
  301. }
  302. }
  303. void set_active_ast_context(ASTContext *NewActiveASTContext) {
  304. ActiveASTContext = NewActiveASTContext;
  305. }
  306. // The following Visit*() and Traverse*() functions "override"
  307. // methods in RecursiveASTVisitor.
  308. bool VisitTypedefNameDecl(TypedefNameDecl *DeclNode) {
  309. // When we see 'typedef A B', we add name 'B' to the set of names
  310. // A's canonical type maps to. This is necessary for implementing
  311. // isDerivedFrom(x) properly, where x can be the name of the base
  312. // class or any of its aliases.
  313. //
  314. // In general, the is-alias-of (as defined by typedefs) relation
  315. // is tree-shaped, as you can typedef a type more than once. For
  316. // example,
  317. //
  318. // typedef A B;
  319. // typedef A C;
  320. // typedef C D;
  321. // typedef C E;
  322. //
  323. // gives you
  324. //
  325. // A
  326. // |- B
  327. // `- C
  328. // |- D
  329. // `- E
  330. //
  331. // It is wrong to assume that the relation is a chain. A correct
  332. // implementation of isDerivedFrom() needs to recognize that B and
  333. // E are aliases, even though neither is a typedef of the other.
  334. // Therefore, we cannot simply walk through one typedef chain to
  335. // find out whether the type name matches.
  336. const Type *TypeNode = DeclNode->getUnderlyingType().getTypePtr();
  337. const Type *CanonicalType = // root of the typedef tree
  338. ActiveASTContext->getCanonicalType(TypeNode);
  339. TypeAliases[CanonicalType].insert(DeclNode);
  340. return true;
  341. }
  342. bool TraverseDecl(Decl *DeclNode);
  343. bool TraverseStmt(Stmt *StmtNode);
  344. bool TraverseType(QualType TypeNode);
  345. bool TraverseTypeLoc(TypeLoc TypeNode);
  346. bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
  347. bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
  348. // Matches children or descendants of 'Node' with 'BaseMatcher'.
  349. bool memoizedMatchesRecursively(const ast_type_traits::DynTypedNode &Node,
  350. const DynTypedMatcher &Matcher,
  351. BoundNodesTreeBuilder *Builder, int MaxDepth,
  352. TraversalKind Traversal, BindKind Bind) {
  353. // For AST-nodes that don't have an identity, we can't memoize.
  354. if (!Node.getMemoizationData() || !Builder->isComparable())
  355. return matchesRecursively(Node, Matcher, Builder, MaxDepth, Traversal,
  356. Bind);
  357. MatchKey Key;
  358. Key.MatcherID = Matcher.getID();
  359. Key.Node = Node;
  360. // Note that we key on the bindings *before* the match.
  361. Key.BoundNodes = *Builder;
  362. MemoizationMap::iterator I = ResultCache.find(Key);
  363. if (I != ResultCache.end()) {
  364. *Builder = I->second.Nodes;
  365. return I->second.ResultOfMatch;
  366. }
  367. MemoizedMatchResult Result;
  368. Result.Nodes = *Builder;
  369. Result.ResultOfMatch = matchesRecursively(Node, Matcher, &Result.Nodes,
  370. MaxDepth, Traversal, Bind);
  371. MemoizedMatchResult &CachedResult = ResultCache[Key];
  372. CachedResult = std::move(Result);
  373. *Builder = CachedResult.Nodes;
  374. return CachedResult.ResultOfMatch;
  375. }
  376. // Matches children or descendants of 'Node' with 'BaseMatcher'.
  377. bool matchesRecursively(const ast_type_traits::DynTypedNode &Node,
  378. const DynTypedMatcher &Matcher,
  379. BoundNodesTreeBuilder *Builder, int MaxDepth,
  380. TraversalKind Traversal, BindKind Bind) {
  381. MatchChildASTVisitor Visitor(
  382. &Matcher, this, Builder, MaxDepth, Traversal, Bind);
  383. return Visitor.findMatch(Node);
  384. }
  385. bool classIsDerivedFrom(const CXXRecordDecl *Declaration,
  386. const Matcher<NamedDecl> &Base,
  387. BoundNodesTreeBuilder *Builder) override;
  388. // Implements ASTMatchFinder::matchesChildOf.
  389. bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
  390. const DynTypedMatcher &Matcher,
  391. BoundNodesTreeBuilder *Builder,
  392. TraversalKind Traversal,
  393. BindKind Bind) override {
  394. if (ResultCache.size() > MaxMemoizationEntries)
  395. ResultCache.clear();
  396. return memoizedMatchesRecursively(Node, Matcher, Builder, 1, Traversal,
  397. Bind);
  398. }
  399. // Implements ASTMatchFinder::matchesDescendantOf.
  400. bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node,
  401. const DynTypedMatcher &Matcher,
  402. BoundNodesTreeBuilder *Builder,
  403. BindKind Bind) override {
  404. if (ResultCache.size() > MaxMemoizationEntries)
  405. ResultCache.clear();
  406. return memoizedMatchesRecursively(Node, Matcher, Builder, INT_MAX,
  407. TK_AsIs, Bind);
  408. }
  409. // Implements ASTMatchFinder::matchesAncestorOf.
  410. bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node,
  411. const DynTypedMatcher &Matcher,
  412. BoundNodesTreeBuilder *Builder,
  413. AncestorMatchMode MatchMode) override {
  414. // Reset the cache outside of the recursive call to make sure we
  415. // don't invalidate any iterators.
  416. if (ResultCache.size() > MaxMemoizationEntries)
  417. ResultCache.clear();
  418. return memoizedMatchesAncestorOfRecursively(Node, Matcher, Builder,
  419. MatchMode);
  420. }
  421. // Matches all registered matchers on the given node and calls the
  422. // result callback for every node that matches.
  423. void match(const ast_type_traits::DynTypedNode &Node) {
  424. // FIXME: Improve this with a switch or a visitor pattern.
  425. if (auto *N = Node.get<Decl>()) {
  426. match(*N);
  427. } else if (auto *N = Node.get<Stmt>()) {
  428. match(*N);
  429. } else if (auto *N = Node.get<Type>()) {
  430. match(*N);
  431. } else if (auto *N = Node.get<QualType>()) {
  432. match(*N);
  433. } else if (auto *N = Node.get<NestedNameSpecifier>()) {
  434. match(*N);
  435. } else if (auto *N = Node.get<NestedNameSpecifierLoc>()) {
  436. match(*N);
  437. } else if (auto *N = Node.get<TypeLoc>()) {
  438. match(*N);
  439. }
  440. }
  441. template <typename T> void match(const T &Node) {
  442. matchDispatch(&Node);
  443. }
  444. // Implements ASTMatchFinder::getASTContext.
  445. ASTContext &getASTContext() const override { return *ActiveASTContext; }
  446. bool shouldVisitTemplateInstantiations() const { return true; }
  447. bool shouldVisitImplicitCode() const { return true; }
  448. // Disables data recursion. We intercept Traverse* methods in the RAV, which
  449. // are not triggered during data recursion.
  450. bool shouldUseDataRecursionFor(clang::Stmt *S) const { return false; }
  451. private:
  452. class TimeBucketRegion {
  453. public:
  454. TimeBucketRegion() : Bucket(nullptr) {}
  455. ~TimeBucketRegion() { setBucket(nullptr); }
  456. /// \brief Start timing for \p NewBucket.
  457. ///
  458. /// If there was a bucket already set, it will finish the timing for that
  459. /// other bucket.
  460. /// \p NewBucket will be timed until the next call to \c setBucket() or
  461. /// until the \c TimeBucketRegion is destroyed.
  462. /// If \p NewBucket is the same as the currently timed bucket, this call
  463. /// does nothing.
  464. void setBucket(llvm::TimeRecord *NewBucket) {
  465. if (Bucket != NewBucket) {
  466. auto Now = llvm::TimeRecord::getCurrentTime(true);
  467. if (Bucket)
  468. *Bucket += Now;
  469. if (NewBucket)
  470. *NewBucket -= Now;
  471. Bucket = NewBucket;
  472. }
  473. }
  474. private:
  475. llvm::TimeRecord *Bucket;
  476. };
  477. /// \brief Runs all the \p Matchers on \p Node.
  478. ///
  479. /// Used by \c matchDispatch() below.
  480. template <typename T, typename MC>
  481. void matchWithoutFilter(const T &Node, const MC &Matchers) {
  482. const bool EnableCheckProfiling = Options.CheckProfiling.hasValue();
  483. TimeBucketRegion Timer;
  484. for (const auto &MP : Matchers) {
  485. if (EnableCheckProfiling)
  486. Timer.setBucket(&TimeByBucket[MP.second->getID()]);
  487. BoundNodesTreeBuilder Builder;
  488. if (MP.first.matches(Node, this, &Builder)) {
  489. MatchVisitor Visitor(ActiveASTContext, MP.second);
  490. Builder.visitMatches(&Visitor);
  491. }
  492. }
  493. }
  494. void matchWithFilter(const ast_type_traits::DynTypedNode &DynNode) {
  495. auto Kind = DynNode.getNodeKind();
  496. auto it = MatcherFiltersMap.find(Kind);
  497. const auto &Filter =
  498. it != MatcherFiltersMap.end() ? it->second : getFilterForKind(Kind);
  499. if (Filter.empty())
  500. return;
  501. const bool EnableCheckProfiling = Options.CheckProfiling.hasValue();
  502. TimeBucketRegion Timer;
  503. auto &Matchers = this->Matchers->DeclOrStmt;
  504. for (unsigned short I : Filter) {
  505. auto &MP = Matchers[I];
  506. if (EnableCheckProfiling)
  507. Timer.setBucket(&TimeByBucket[MP.second->getID()]);
  508. BoundNodesTreeBuilder Builder;
  509. if (MP.first.matchesNoKindCheck(DynNode, this, &Builder)) {
  510. MatchVisitor Visitor(ActiveASTContext, MP.second);
  511. Builder.visitMatches(&Visitor);
  512. }
  513. }
  514. }
  515. const std::vector<unsigned short> &
  516. getFilterForKind(ast_type_traits::ASTNodeKind Kind) {
  517. auto &Filter = MatcherFiltersMap[Kind];
  518. auto &Matchers = this->Matchers->DeclOrStmt;
  519. assert((Matchers.size() < USHRT_MAX) && "Too many matchers.");
  520. for (unsigned I = 0, E = Matchers.size(); I != E; ++I) {
  521. if (Matchers[I].first.canMatchNodesOfKind(Kind)) {
  522. Filter.push_back(I);
  523. }
  524. }
  525. return Filter;
  526. }
  527. /// @{
  528. /// \brief Overloads to pair the different node types to their matchers.
  529. void matchDispatch(const Decl *Node) {
  530. return matchWithFilter(ast_type_traits::DynTypedNode::create(*Node));
  531. }
  532. void matchDispatch(const Stmt *Node) {
  533. return matchWithFilter(ast_type_traits::DynTypedNode::create(*Node));
  534. }
  535. void matchDispatch(const Type *Node) {
  536. matchWithoutFilter(QualType(Node, 0), Matchers->Type);
  537. }
  538. void matchDispatch(const TypeLoc *Node) {
  539. matchWithoutFilter(*Node, Matchers->TypeLoc);
  540. }
  541. void matchDispatch(const QualType *Node) {
  542. matchWithoutFilter(*Node, Matchers->Type);
  543. }
  544. void matchDispatch(const NestedNameSpecifier *Node) {
  545. matchWithoutFilter(*Node, Matchers->NestedNameSpecifier);
  546. }
  547. void matchDispatch(const NestedNameSpecifierLoc *Node) {
  548. matchWithoutFilter(*Node, Matchers->NestedNameSpecifierLoc);
  549. }
  550. void matchDispatch(const void *) { /* Do nothing. */ }
  551. /// @}
  552. // Returns whether an ancestor of \p Node matches \p Matcher.
  553. //
  554. // The order of matching ((which can lead to different nodes being bound in
  555. // case there are multiple matches) is breadth first search.
  556. //
  557. // To allow memoization in the very common case of having deeply nested
  558. // expressions inside a template function, we first walk up the AST, memoizing
  559. // the result of the match along the way, as long as there is only a single
  560. // parent.
  561. //
  562. // Once there are multiple parents, the breadth first search order does not
  563. // allow simple memoization on the ancestors. Thus, we only memoize as long
  564. // as there is a single parent.
  565. bool memoizedMatchesAncestorOfRecursively(
  566. const ast_type_traits::DynTypedNode &Node, const DynTypedMatcher &Matcher,
  567. BoundNodesTreeBuilder *Builder, AncestorMatchMode MatchMode) {
  568. if (Node.get<TranslationUnitDecl>() ==
  569. ActiveASTContext->getTranslationUnitDecl())
  570. return false;
  571. assert(Node.getMemoizationData() &&
  572. "Invariant broken: only nodes that support memoization may be "
  573. "used in the parent map.");
  574. MatchKey Key;
  575. Key.MatcherID = Matcher.getID();
  576. Key.Node = Node;
  577. Key.BoundNodes = *Builder;
  578. // Note that we cannot use insert and reuse the iterator, as recursive
  579. // calls to match might invalidate the result cache iterators.
  580. MemoizationMap::iterator I = ResultCache.find(Key);
  581. if (I != ResultCache.end()) {
  582. *Builder = I->second.Nodes;
  583. return I->second.ResultOfMatch;
  584. }
  585. MemoizedMatchResult Result;
  586. Result.ResultOfMatch = false;
  587. Result.Nodes = *Builder;
  588. const auto &Parents = ActiveASTContext->getParents(Node);
  589. assert(!Parents.empty() && "Found node that is not in the parent map.");
  590. if (Parents.size() == 1) {
  591. // Only one parent - do recursive memoization.
  592. const ast_type_traits::DynTypedNode Parent = Parents[0];
  593. if (Matcher.matches(Parent, this, &Result.Nodes)) {
  594. Result.ResultOfMatch = true;
  595. } else if (MatchMode != ASTMatchFinder::AMM_ParentOnly) {
  596. // Reset the results to not include the bound nodes from the failed
  597. // match above.
  598. Result.Nodes = *Builder;
  599. Result.ResultOfMatch = memoizedMatchesAncestorOfRecursively(
  600. Parent, Matcher, &Result.Nodes, MatchMode);
  601. // Once we get back from the recursive call, the result will be the
  602. // same as the parent's result.
  603. }
  604. } else {
  605. // Multiple parents - BFS over the rest of the nodes.
  606. llvm::DenseSet<const void *> Visited;
  607. std::deque<ast_type_traits::DynTypedNode> Queue(Parents.begin(),
  608. Parents.end());
  609. while (!Queue.empty()) {
  610. Result.Nodes = *Builder;
  611. if (Matcher.matches(Queue.front(), this, &Result.Nodes)) {
  612. Result.ResultOfMatch = true;
  613. break;
  614. }
  615. if (MatchMode != ASTMatchFinder::AMM_ParentOnly) {
  616. for (const auto &Parent :
  617. ActiveASTContext->getParents(Queue.front())) {
  618. // Make sure we do not visit the same node twice.
  619. // Otherwise, we'll visit the common ancestors as often as there
  620. // are splits on the way down.
  621. if (Visited.insert(Parent.getMemoizationData()).second)
  622. Queue.push_back(Parent);
  623. }
  624. }
  625. Queue.pop_front();
  626. }
  627. }
  628. MemoizedMatchResult &CachedResult = ResultCache[Key];
  629. CachedResult = std::move(Result);
  630. *Builder = CachedResult.Nodes;
  631. return CachedResult.ResultOfMatch;
  632. }
  633. // Implements a BoundNodesTree::Visitor that calls a MatchCallback with
  634. // the aggregated bound nodes for each match.
  635. class MatchVisitor : public BoundNodesTreeBuilder::Visitor {
  636. public:
  637. MatchVisitor(ASTContext* Context,
  638. MatchFinder::MatchCallback* Callback)
  639. : Context(Context),
  640. Callback(Callback) {}
  641. void visitMatch(const BoundNodes& BoundNodesView) override {
  642. Callback->run(MatchFinder::MatchResult(BoundNodesView, Context));
  643. }
  644. private:
  645. ASTContext* Context;
  646. MatchFinder::MatchCallback* Callback;
  647. };
  648. // Returns true if 'TypeNode' has an alias that matches the given matcher.
  649. bool typeHasMatchingAlias(const Type *TypeNode,
  650. const Matcher<NamedDecl> Matcher,
  651. BoundNodesTreeBuilder *Builder) {
  652. const Type *const CanonicalType =
  653. ActiveASTContext->getCanonicalType(TypeNode);
  654. for (const TypedefNameDecl *Alias : TypeAliases.lookup(CanonicalType)) {
  655. BoundNodesTreeBuilder Result(*Builder);
  656. if (Matcher.matches(*Alias, this, &Result)) {
  657. *Builder = std::move(Result);
  658. return true;
  659. }
  660. }
  661. return false;
  662. }
  663. /// \brief Bucket to record map.
  664. ///
  665. /// Used to get the appropriate bucket for each matcher.
  666. llvm::StringMap<llvm::TimeRecord> TimeByBucket;
  667. const MatchFinder::MatchersByType *Matchers;
  668. /// \brief Filtered list of matcher indices for each matcher kind.
  669. ///
  670. /// \c Decl and \c Stmt toplevel matchers usually apply to a specific node
  671. /// kind (and derived kinds) so it is a waste to try every matcher on every
  672. /// node.
  673. /// We precalculate a list of matchers that pass the toplevel restrict check.
  674. /// This also allows us to skip the restrict check at matching time. See
  675. /// use \c matchesNoKindCheck() above.
  676. llvm::DenseMap<ast_type_traits::ASTNodeKind, std::vector<unsigned short>>
  677. MatcherFiltersMap;
  678. const MatchFinder::MatchFinderOptions &Options;
  679. ASTContext *ActiveASTContext;
  680. // Maps a canonical type to its TypedefDecls.
  681. llvm::DenseMap<const Type*, std::set<const TypedefNameDecl*> > TypeAliases;
  682. // Maps (matcher, node) -> the match result for memoization.
  683. typedef std::map<MatchKey, MemoizedMatchResult> MemoizationMap;
  684. MemoizationMap ResultCache;
  685. };
  686. static CXXRecordDecl *getAsCXXRecordDecl(const Type *TypeNode) {
  687. // Type::getAs<...>() drills through typedefs.
  688. if (TypeNode->getAs<DependentNameType>() != nullptr ||
  689. TypeNode->getAs<DependentTemplateSpecializationType>() != nullptr ||
  690. TypeNode->getAs<TemplateTypeParmType>() != nullptr)
  691. // Dependent names and template TypeNode parameters will be matched when
  692. // the template is instantiated.
  693. return nullptr;
  694. TemplateSpecializationType const *TemplateType =
  695. TypeNode->getAs<TemplateSpecializationType>();
  696. if (!TemplateType) {
  697. return TypeNode->getAsCXXRecordDecl();
  698. }
  699. if (TemplateType->getTemplateName().isDependent())
  700. // Dependent template specializations will be matched when the
  701. // template is instantiated.
  702. return nullptr;
  703. // For template specialization types which are specializing a template
  704. // declaration which is an explicit or partial specialization of another
  705. // template declaration, getAsCXXRecordDecl() returns the corresponding
  706. // ClassTemplateSpecializationDecl.
  707. //
  708. // For template specialization types which are specializing a template
  709. // declaration which is neither an explicit nor partial specialization of
  710. // another template declaration, getAsCXXRecordDecl() returns NULL and
  711. // we get the CXXRecordDecl of the templated declaration.
  712. CXXRecordDecl *SpecializationDecl = TemplateType->getAsCXXRecordDecl();
  713. if (SpecializationDecl) {
  714. return SpecializationDecl;
  715. }
  716. NamedDecl *Templated =
  717. TemplateType->getTemplateName().getAsTemplateDecl()->getTemplatedDecl();
  718. if (CXXRecordDecl *TemplatedRecord = dyn_cast<CXXRecordDecl>(Templated)) {
  719. return TemplatedRecord;
  720. }
  721. // Now it can still be that we have an alias template.
  722. TypeAliasDecl *AliasDecl = dyn_cast<TypeAliasDecl>(Templated);
  723. assert(AliasDecl);
  724. return getAsCXXRecordDecl(AliasDecl->getUnderlyingType().getTypePtr());
  725. }
  726. // Returns true if the given class is directly or indirectly derived
  727. // from a base type with the given name. A class is not considered to be
  728. // derived from itself.
  729. bool MatchASTVisitor::classIsDerivedFrom(const CXXRecordDecl *Declaration,
  730. const Matcher<NamedDecl> &Base,
  731. BoundNodesTreeBuilder *Builder) {
  732. if (!Declaration->hasDefinition())
  733. return false;
  734. for (const auto &It : Declaration->bases()) {
  735. const Type *TypeNode = It.getType().getTypePtr();
  736. if (typeHasMatchingAlias(TypeNode, Base, Builder))
  737. return true;
  738. CXXRecordDecl *ClassDecl = getAsCXXRecordDecl(TypeNode);
  739. if (!ClassDecl)
  740. continue;
  741. if (ClassDecl == Declaration) {
  742. // This can happen for recursive template definitions; if the
  743. // current declaration did not match, we can safely return false.
  744. return false;
  745. }
  746. BoundNodesTreeBuilder Result(*Builder);
  747. if (Base.matches(*ClassDecl, this, &Result)) {
  748. *Builder = std::move(Result);
  749. return true;
  750. }
  751. if (classIsDerivedFrom(ClassDecl, Base, Builder))
  752. return true;
  753. }
  754. return false;
  755. }
  756. bool MatchASTVisitor::TraverseDecl(Decl *DeclNode) {
  757. if (!DeclNode) {
  758. return true;
  759. }
  760. match(*DeclNode);
  761. return RecursiveASTVisitor<MatchASTVisitor>::TraverseDecl(DeclNode);
  762. }
  763. bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode) {
  764. if (!StmtNode) {
  765. return true;
  766. }
  767. match(*StmtNode);
  768. return RecursiveASTVisitor<MatchASTVisitor>::TraverseStmt(StmtNode);
  769. }
  770. bool MatchASTVisitor::TraverseType(QualType TypeNode) {
  771. match(TypeNode);
  772. return RecursiveASTVisitor<MatchASTVisitor>::TraverseType(TypeNode);
  773. }
  774. bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLocNode) {
  775. // The RecursiveASTVisitor only visits types if they're not within TypeLocs.
  776. // We still want to find those types via matchers, so we match them here. Note
  777. // that the TypeLocs are structurally a shadow-hierarchy to the expressed
  778. // type, so we visit all involved parts of a compound type when matching on
  779. // each TypeLoc.
  780. match(TypeLocNode);
  781. match(TypeLocNode.getType());
  782. return RecursiveASTVisitor<MatchASTVisitor>::TraverseTypeLoc(TypeLocNode);
  783. }
  784. bool MatchASTVisitor::TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) {
  785. match(*NNS);
  786. return RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifier(NNS);
  787. }
  788. bool MatchASTVisitor::TraverseNestedNameSpecifierLoc(
  789. NestedNameSpecifierLoc NNS) {
  790. match(NNS);
  791. // We only match the nested name specifier here (as opposed to traversing it)
  792. // because the traversal is already done in the parallel "Loc"-hierarchy.
  793. if (NNS.hasQualifier())
  794. match(*NNS.getNestedNameSpecifier());
  795. return
  796. RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifierLoc(NNS);
  797. }
  798. class MatchASTConsumer : public ASTConsumer {
  799. public:
  800. MatchASTConsumer(MatchFinder *Finder,
  801. MatchFinder::ParsingDoneTestCallback *ParsingDone)
  802. : Finder(Finder), ParsingDone(ParsingDone) {}
  803. private:
  804. void HandleTranslationUnit(ASTContext &Context) override {
  805. if (ParsingDone != nullptr) {
  806. ParsingDone->run();
  807. }
  808. Finder->matchAST(Context);
  809. }
  810. MatchFinder *Finder;
  811. MatchFinder::ParsingDoneTestCallback *ParsingDone;
  812. };
  813. } // end namespace
  814. } // end namespace internal
  815. MatchFinder::MatchResult::MatchResult(const BoundNodes &Nodes,
  816. ASTContext *Context)
  817. : Nodes(Nodes), Context(Context),
  818. SourceManager(&Context->getSourceManager()) {}
  819. MatchFinder::MatchCallback::~MatchCallback() {}
  820. MatchFinder::ParsingDoneTestCallback::~ParsingDoneTestCallback() {}
  821. MatchFinder::MatchFinder(MatchFinderOptions Options)
  822. : Options(std::move(Options)), ParsingDone(nullptr) {}
  823. MatchFinder::~MatchFinder() {}
  824. void MatchFinder::addMatcher(const DeclarationMatcher &NodeMatch,
  825. MatchCallback *Action) {
  826. Matchers.DeclOrStmt.emplace_back(NodeMatch, Action);
  827. Matchers.AllCallbacks.push_back(Action);
  828. }
  829. void MatchFinder::addMatcher(const TypeMatcher &NodeMatch,
  830. MatchCallback *Action) {
  831. Matchers.Type.emplace_back(NodeMatch, Action);
  832. Matchers.AllCallbacks.push_back(Action);
  833. }
  834. void MatchFinder::addMatcher(const StatementMatcher &NodeMatch,
  835. MatchCallback *Action) {
  836. Matchers.DeclOrStmt.emplace_back(NodeMatch, Action);
  837. Matchers.AllCallbacks.push_back(Action);
  838. }
  839. void MatchFinder::addMatcher(const NestedNameSpecifierMatcher &NodeMatch,
  840. MatchCallback *Action) {
  841. Matchers.NestedNameSpecifier.emplace_back(NodeMatch, Action);
  842. Matchers.AllCallbacks.push_back(Action);
  843. }
  844. void MatchFinder::addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch,
  845. MatchCallback *Action) {
  846. Matchers.NestedNameSpecifierLoc.emplace_back(NodeMatch, Action);
  847. Matchers.AllCallbacks.push_back(Action);
  848. }
  849. void MatchFinder::addMatcher(const TypeLocMatcher &NodeMatch,
  850. MatchCallback *Action) {
  851. Matchers.TypeLoc.emplace_back(NodeMatch, Action);
  852. Matchers.AllCallbacks.push_back(Action);
  853. }
  854. bool MatchFinder::addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch,
  855. MatchCallback *Action) {
  856. if (NodeMatch.canConvertTo<Decl>()) {
  857. addMatcher(NodeMatch.convertTo<Decl>(), Action);
  858. return true;
  859. } else if (NodeMatch.canConvertTo<QualType>()) {
  860. addMatcher(NodeMatch.convertTo<QualType>(), Action);
  861. return true;
  862. } else if (NodeMatch.canConvertTo<Stmt>()) {
  863. addMatcher(NodeMatch.convertTo<Stmt>(), Action);
  864. return true;
  865. } else if (NodeMatch.canConvertTo<NestedNameSpecifier>()) {
  866. addMatcher(NodeMatch.convertTo<NestedNameSpecifier>(), Action);
  867. return true;
  868. } else if (NodeMatch.canConvertTo<NestedNameSpecifierLoc>()) {
  869. addMatcher(NodeMatch.convertTo<NestedNameSpecifierLoc>(), Action);
  870. return true;
  871. } else if (NodeMatch.canConvertTo<TypeLoc>()) {
  872. addMatcher(NodeMatch.convertTo<TypeLoc>(), Action);
  873. return true;
  874. }
  875. return false;
  876. }
  877. std::unique_ptr<ASTConsumer> MatchFinder::newASTConsumer() {
  878. return llvm::make_unique<internal::MatchASTConsumer>(this, ParsingDone);
  879. }
  880. void MatchFinder::match(const clang::ast_type_traits::DynTypedNode &Node,
  881. ASTContext &Context) {
  882. internal::MatchASTVisitor Visitor(&Matchers, Options);
  883. Visitor.set_active_ast_context(&Context);
  884. Visitor.match(Node);
  885. }
  886. void MatchFinder::matchAST(ASTContext &Context) {
  887. internal::MatchASTVisitor Visitor(&Matchers, Options);
  888. Visitor.set_active_ast_context(&Context);
  889. Visitor.onStartOfTranslationUnit();
  890. Visitor.TraverseDecl(Context.getTranslationUnitDecl());
  891. Visitor.onEndOfTranslationUnit();
  892. }
  893. void MatchFinder::registerTestCallbackAfterParsing(
  894. MatchFinder::ParsingDoneTestCallback *NewParsingDone) {
  895. ParsingDone = NewParsingDone;
  896. }
  897. StringRef MatchFinder::MatchCallback::getID() const { return "<unknown>"; }
  898. } // end namespace ast_matchers
  899. } // end namespace clang