|
21 | 21 | #include "clang/AST/RecursiveASTVisitor.h"
|
22 | 22 | #include "llvm/ADT/DenseMap.h"
|
23 | 23 | #include "llvm/ADT/StringMap.h"
|
| 24 | +#include "llvm/Support/PrettyStackTrace.h" |
24 | 25 | #include "llvm/Support/Timer.h"
|
25 | 26 | #include <deque>
|
26 | 27 | #include <memory>
|
@@ -760,11 +761,67 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
|
760 | 761 | D);
|
761 | 762 | }
|
762 | 763 |
|
| 764 | + class TraceReporter : llvm::PrettyStackTraceEntry { |
| 765 | + public: |
| 766 | + TraceReporter(const MatchASTVisitor &MV) : MV(MV) {} |
| 767 | + void print(raw_ostream &OS) const override { |
| 768 | + if (!MV.CurMatched) { |
| 769 | + OS << "ASTMatcher: Not currently matching\n"; |
| 770 | + return; |
| 771 | + } |
| 772 | + assert(MV.ActiveASTContext && |
| 773 | + "ActiveASTContext should be set if there is a matched callback"); |
| 774 | + |
| 775 | + OS << "ASTMatcher: Processing '" << MV.CurMatched->getID() << "'\n"; |
| 776 | + const BoundNodes::IDToNodeMap &Map = MV.CurBoundNodes->getMap(); |
| 777 | + if (Map.empty()) { |
| 778 | + OS << "No bound nodes\n"; |
| 779 | + return; |
| 780 | + } |
| 781 | + OS << "--- Bound Nodes Begin ---\n"; |
| 782 | + for (const auto &Item : Map) { |
| 783 | + OS << " " << Item.first << " - { "; |
| 784 | + if (const auto *D = Item.second.get<Decl>()) { |
| 785 | + OS << D->getDeclKindName() << "Decl "; |
| 786 | + if (const auto *ND = dyn_cast<NamedDecl>(D)) { |
| 787 | + ND->printQualifiedName(OS); |
| 788 | + OS << " : "; |
| 789 | + } else |
| 790 | + OS << ": "; |
| 791 | + D->getSourceRange().print(OS, |
| 792 | + MV.ActiveASTContext->getSourceManager()); |
| 793 | + } else if (const auto *S = Item.second.get<Stmt>()) { |
| 794 | + OS << S->getStmtClassName() << " : "; |
| 795 | + S->getSourceRange().print(OS, |
| 796 | + MV.ActiveASTContext->getSourceManager()); |
| 797 | + } else if (const auto *T = Item.second.get<Type>()) { |
| 798 | + OS << T->getTypeClassName() << "Type : "; |
| 799 | + QualType(T, 0).print(OS, MV.ActiveASTContext->getPrintingPolicy()); |
| 800 | + } else if (const auto *QT = Item.second.get<QualType>()) { |
| 801 | + OS << "QualType : "; |
| 802 | + QT->print(OS, MV.ActiveASTContext->getPrintingPolicy()); |
| 803 | + } else { |
| 804 | + OS << Item.second.getNodeKind().asStringRef() << " : "; |
| 805 | + Item.second.getSourceRange().print( |
| 806 | + OS, MV.ActiveASTContext->getSourceManager()); |
| 807 | + } |
| 808 | + OS << " }\n"; |
| 809 | + } |
| 810 | + OS << "--- Bound Nodes End ---\n"; |
| 811 | + } |
| 812 | + |
| 813 | + private: |
| 814 | + const MatchASTVisitor &MV; |
| 815 | + }; |
| 816 | + |
763 | 817 | private:
|
764 | 818 | bool TraversingASTNodeNotSpelledInSource = false;
|
765 | 819 | bool TraversingASTNodeNotAsIs = false;
|
766 | 820 | bool TraversingASTChildrenNotSpelledInSource = false;
|
767 | 821 |
|
| 822 | + const MatchCallback *CurMatched = nullptr; |
| 823 | + const BoundNodes *CurBoundNodes = nullptr; |
| 824 | + |
768 | 825 | struct ASTNodeNotSpelledInSourceScope {
|
769 | 826 | ASTNodeNotSpelledInSourceScope(MatchASTVisitor *V, bool B)
|
770 | 827 | : MV(V), MB(V->TraversingASTNodeNotSpelledInSource) {
|
@@ -831,7 +888,7 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
|
831 | 888 | Timer.setBucket(&TimeByBucket[MP.second->getID()]);
|
832 | 889 | BoundNodesTreeBuilder Builder;
|
833 | 890 | if (MP.first.matches(Node, this, &Builder)) {
|
834 |
| - MatchVisitor Visitor(ActiveASTContext, MP.second); |
| 891 | + MatchVisitor Visitor(*this, ActiveASTContext, MP.second); |
835 | 892 | Builder.visitMatches(&Visitor);
|
836 | 893 | }
|
837 | 894 | }
|
@@ -863,7 +920,7 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
|
863 | 920 | }
|
864 | 921 |
|
865 | 922 | if (MP.first.matches(DynNode, this, &Builder)) {
|
866 |
| - MatchVisitor Visitor(ActiveASTContext, MP.second); |
| 923 | + MatchVisitor Visitor(*this, ActiveASTContext, MP.second); |
867 | 924 | Builder.visitMatches(&Visitor);
|
868 | 925 | }
|
869 | 926 | }
|
@@ -1049,18 +1106,36 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
|
1049 | 1106 | // Implements a BoundNodesTree::Visitor that calls a MatchCallback with
|
1050 | 1107 | // the aggregated bound nodes for each match.
|
1051 | 1108 | class MatchVisitor : public BoundNodesTreeBuilder::Visitor {
|
| 1109 | + struct CurBoundScope { |
| 1110 | + CurBoundScope(MatchASTVisitor &MV, const BoundNodes &BN) : MV(MV) { |
| 1111 | + assert(MV.CurMatched && !MV.CurBoundNodes); |
| 1112 | + MV.CurBoundNodes = &BN; |
| 1113 | + } |
| 1114 | + |
| 1115 | + ~CurBoundScope() { MV.CurBoundNodes = nullptr; } |
| 1116 | + |
| 1117 | + private: |
| 1118 | + MatchASTVisitor &MV; |
| 1119 | + }; |
| 1120 | + |
1052 | 1121 | public:
|
1053 |
| - MatchVisitor(ASTContext* Context, |
1054 |
| - MatchFinder::MatchCallback* Callback) |
1055 |
| - : Context(Context), |
1056 |
| - Callback(Callback) {} |
| 1122 | + MatchVisitor(MatchASTVisitor &MV, ASTContext *Context, |
| 1123 | + MatchFinder::MatchCallback *Callback) |
| 1124 | + : MV(MV), Context(Context), Callback(Callback) { |
| 1125 | + assert(!MV.CurMatched && !MV.CurBoundNodes); |
| 1126 | + MV.CurMatched = Callback; |
| 1127 | + } |
| 1128 | + |
| 1129 | + ~MatchVisitor() { MV.CurMatched = nullptr; } |
1057 | 1130 |
|
1058 | 1131 | void visitMatch(const BoundNodes& BoundNodesView) override {
|
1059 | 1132 | TraversalKindScope RAII(*Context, Callback->getCheckTraversalKind());
|
| 1133 | + CurBoundScope RAII2(MV, BoundNodesView); |
1060 | 1134 | Callback->run(MatchFinder::MatchResult(BoundNodesView, Context));
|
1061 | 1135 | }
|
1062 | 1136 |
|
1063 | 1137 | private:
|
| 1138 | + MatchASTVisitor &MV; |
1064 | 1139 | ASTContext* Context;
|
1065 | 1140 | MatchFinder::MatchCallback* Callback;
|
1066 | 1141 | };
|
@@ -1470,6 +1545,7 @@ void MatchFinder::match(const clang::DynTypedNode &Node, ASTContext &Context) {
|
1470 | 1545 |
|
1471 | 1546 | void MatchFinder::matchAST(ASTContext &Context) {
|
1472 | 1547 | internal::MatchASTVisitor Visitor(&Matchers, Options);
|
| 1548 | + internal::MatchASTVisitor::TraceReporter StackTrace(Visitor); |
1473 | 1549 | Visitor.set_active_ast_context(&Context);
|
1474 | 1550 | Visitor.onStartOfTranslationUnit();
|
1475 | 1551 | Visitor.TraverseAST(Context);
|
|
0 commit comments