|
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