|
28 | 28 | #include <deque> |
29 | 29 | #include <memory> |
30 | 30 | #include <set> |
| 31 | +#include <vector> |
31 | 32 |
|
32 | 33 | namespace clang { |
33 | 34 | namespace ast_matchers { |
@@ -422,7 +423,7 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>, |
422 | 423 | public ASTMatchFinder { |
423 | 424 | public: |
424 | 425 | MatchASTVisitor(const MatchFinder::MatchersByType *Matchers, |
425 | | - const MatchFinder::MatchFinderOptions &Options) |
| 426 | + const MatchFinderOptions &Options) |
426 | 427 | : Matchers(Matchers), Options(Options), ActiveASTContext(nullptr) {} |
427 | 428 |
|
428 | 429 | ~MatchASTVisitor() override { |
@@ -1350,7 +1351,7 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>, |
1350 | 1351 | /// We precalculate a list of matchers that pass the toplevel restrict check. |
1351 | 1352 | llvm::DenseMap<ASTNodeKind, std::vector<unsigned short>> MatcherFiltersMap; |
1352 | 1353 |
|
1353 | | - const MatchFinder::MatchFinderOptions &Options; |
| 1354 | + const MatchFinderOptions &Options; |
1354 | 1355 | ASTContext *ActiveASTContext; |
1355 | 1356 |
|
1356 | 1357 | // Maps a canonical type to its TypedefDecls. |
@@ -1573,19 +1574,41 @@ bool MatchASTVisitor::TraverseAttr(Attr *AttrNode) { |
1573 | 1574 | class MatchASTConsumer : public ASTConsumer { |
1574 | 1575 | public: |
1575 | 1576 | MatchASTConsumer(MatchFinder *Finder, |
1576 | | - MatchFinder::ParsingDoneTestCallback *ParsingDone) |
1577 | | - : Finder(Finder), ParsingDone(ParsingDone) {} |
| 1577 | + MatchFinder::ParsingDoneTestCallback *ParsingDone, |
| 1578 | + const MatchFinderOptions &Options) |
| 1579 | + : Finder(Finder), ParsingDone(ParsingDone), Options(Options) {} |
1578 | 1580 |
|
1579 | 1581 | private: |
| 1582 | + bool HandleTopLevelDecl(DeclGroupRef DG) override { |
| 1583 | + if (Options.SkipSystemHeaders) { |
| 1584 | + for (Decl *D : DG) { |
| 1585 | + if (!isInSystemHeader(D)) |
| 1586 | + TraversalScope.push_back(D); |
| 1587 | + } |
| 1588 | + } |
| 1589 | + return true; |
| 1590 | + } |
| 1591 | + |
1580 | 1592 | void HandleTranslationUnit(ASTContext &Context) override { |
| 1593 | + if (!TraversalScope.empty()) |
| 1594 | + Context.setTraversalScope(TraversalScope); |
| 1595 | + |
1581 | 1596 | if (ParsingDone != nullptr) { |
1582 | 1597 | ParsingDone->run(); |
1583 | 1598 | } |
1584 | 1599 | Finder->matchAST(Context); |
1585 | 1600 | } |
1586 | 1601 |
|
| 1602 | + bool isInSystemHeader(Decl *D) { |
| 1603 | + const SourceManager &SM = D->getASTContext().getSourceManager(); |
| 1604 | + const SourceLocation Loc = SM.getExpansionLoc(D->getBeginLoc()); |
| 1605 | + return SM.isInSystemHeader(Loc); |
| 1606 | + } |
| 1607 | + |
1587 | 1608 | MatchFinder *Finder; |
1588 | 1609 | MatchFinder::ParsingDoneTestCallback *ParsingDone; |
| 1610 | + const MatchFinderOptions &Options; |
| 1611 | + std::vector<Decl *> TraversalScope; |
1589 | 1612 | }; |
1590 | 1613 |
|
1591 | 1614 | } // end namespace |
@@ -1704,7 +1727,8 @@ bool MatchFinder::addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, |
1704 | 1727 | } |
1705 | 1728 |
|
1706 | 1729 | std::unique_ptr<ASTConsumer> MatchFinder::newASTConsumer() { |
1707 | | - return std::make_unique<internal::MatchASTConsumer>(this, ParsingDone); |
| 1730 | + return std::make_unique<internal::MatchASTConsumer>(this, ParsingDone, |
| 1731 | + Options); |
1708 | 1732 | } |
1709 | 1733 |
|
1710 | 1734 | void MatchFinder::match(const clang::DynTypedNode &Node, ASTContext &Context) { |
|
0 commit comments