@@ -761,67 +761,173 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
761
761
D);
762
762
}
763
763
764
+ private:
765
+ bool TraversingASTNodeNotSpelledInSource = false ;
766
+ bool TraversingASTNodeNotAsIs = false ;
767
+ bool TraversingASTChildrenNotSpelledInSource = false ;
768
+
769
+ class CurMatchData {
770
+ public:
771
+ CurMatchData () = default ;
772
+
773
+ template <typename NodeType>
774
+ void SetCallbackAndRawNode (const MatchCallback *CB, const NodeType &N) {
775
+ assertEmpty ();
776
+ Callback = CB;
777
+ MatchingNode = &N;
778
+ }
779
+
780
+ const MatchCallback *getCallback () const { return Callback; }
781
+
782
+ void SetBoundNodes (const BoundNodes &BN) {
783
+ assertHoldsState ();
784
+ BNodes = &BN;
785
+ }
786
+
787
+ void clearBoundNodes () {
788
+ assertHoldsState ();
789
+ BNodes = nullptr ;
790
+ }
791
+
792
+ template <typename T> const T *getNode () const {
793
+ assertHoldsState ();
794
+ return MatchingNode.dyn_cast <const T *>();
795
+ }
796
+
797
+ const BoundNodes *getBoundNodes () const {
798
+ assertHoldsState ();
799
+ return BNodes;
800
+ }
801
+
802
+ void reset () {
803
+ assertHoldsState ();
804
+ Callback = nullptr ;
805
+ MatchingNode = nullptr ;
806
+ }
807
+
808
+ private:
809
+ void assertHoldsState () const {
810
+ assert (Callback != nullptr && !MatchingNode.isNull ());
811
+ }
812
+
813
+ void assertEmpty () const {
814
+ assert (Callback == nullptr && MatchingNode.isNull () && BNodes == nullptr );
815
+ }
816
+
817
+ const MatchCallback *Callback = nullptr ;
818
+ const BoundNodes *BNodes = nullptr ;
819
+
820
+ llvm::PointerUnion<
821
+ const QualType *, const TypeLoc *, const NestedNameSpecifier *,
822
+ const NestedNameSpecifierLoc *, const CXXCtorInitializer *,
823
+ const TemplateArgumentLoc *, const Attr *, const DynTypedNode *>
824
+ MatchingNode;
825
+ } CurMatchState;
826
+
827
+ struct CurMatchRAII {
828
+ template <typename NodeType>
829
+ CurMatchRAII (MatchASTVisitor &MV, const MatchCallback *CB,
830
+ const NodeType &NT)
831
+ : MV(MV) {
832
+ MV.CurMatchState .SetCallbackAndRawNode (CB, NT);
833
+ }
834
+
835
+ ~CurMatchRAII () { MV.CurMatchState .reset (); }
836
+
837
+ private:
838
+ MatchASTVisitor &MV;
839
+ };
840
+
841
+ public:
764
842
class TraceReporter : llvm::PrettyStackTraceEntry {
843
+ static void dumpNode (const ASTContext &Ctx, const DynTypedNode &Node,
844
+ raw_ostream &OS) {
845
+ if (const auto *D = Node.get <Decl>()) {
846
+ OS << D->getDeclKindName () << " Decl " ;
847
+ if (const auto *ND = dyn_cast<NamedDecl>(D)) {
848
+ ND->printQualifiedName (OS);
849
+ OS << " : " ;
850
+ } else
851
+ OS << " : " ;
852
+ D->getSourceRange ().print (OS, Ctx.getSourceManager ());
853
+ } else if (const auto *S = Node.get <Stmt>()) {
854
+ OS << S->getStmtClassName () << " : " ;
855
+ S->getSourceRange ().print (OS, Ctx.getSourceManager ());
856
+ } else if (const auto *T = Node.get <Type>()) {
857
+ OS << T->getTypeClassName () << " Type : " ;
858
+ QualType (T, 0 ).print (OS, Ctx.getPrintingPolicy ());
859
+ } else if (const auto *QT = Node.get <QualType>()) {
860
+ OS << " QualType : " ;
861
+ QT->print (OS, Ctx.getPrintingPolicy ());
862
+ } else {
863
+ OS << Node.getNodeKind ().asStringRef () << " : " ;
864
+ Node.getSourceRange ().print (OS, Ctx.getSourceManager ());
865
+ }
866
+ }
867
+
868
+ static void dumpNodeFromState (const ASTContext &Ctx,
869
+ const CurMatchData &State, raw_ostream &OS) {
870
+ if (const DynTypedNode *MatchNode = State.getNode <DynTypedNode>()) {
871
+ dumpNode (Ctx, *MatchNode, OS);
872
+ } else if (const auto *QT = State.getNode <QualType>()) {
873
+ dumpNode (Ctx, DynTypedNode::create (*QT), OS);
874
+ } else if (const auto *TL = State.getNode <TypeLoc>()) {
875
+ dumpNode (Ctx, DynTypedNode::create (*TL), OS);
876
+ } else if (const auto *NNS = State.getNode <NestedNameSpecifier>()) {
877
+ dumpNode (Ctx, DynTypedNode::create (*NNS), OS);
878
+ } else if (const auto *NNSL = State.getNode <NestedNameSpecifierLoc>()) {
879
+ dumpNode (Ctx, DynTypedNode::create (*NNSL), OS);
880
+ } else if (const auto *CtorInit = State.getNode <CXXCtorInitializer>()) {
881
+ dumpNode (Ctx, DynTypedNode::create (*CtorInit), OS);
882
+ } else if (const auto *TAL = State.getNode <TemplateArgumentLoc>()) {
883
+ dumpNode (Ctx, DynTypedNode::create (*TAL), OS);
884
+ } else if (const auto *At = State.getNode <Attr>()) {
885
+ dumpNode (Ctx, DynTypedNode::create (*At), OS);
886
+ }
887
+ }
888
+
765
889
public:
766
890
TraceReporter (const MatchASTVisitor &MV) : MV(MV) {}
767
891
void print (raw_ostream &OS) const override {
768
- if (!MV.CurMatched ) {
892
+ const CurMatchData &State = MV.CurMatchState ;
893
+ const MatchCallback *CB = State.getCallback ();
894
+ if (!CB) {
769
895
OS << " ASTMatcher: Not currently matching\n " ;
770
896
return ;
771
897
}
898
+
772
899
assert (MV.ActiveASTContext &&
773
900
" ActiveASTContext should be set if there is a matched callback" );
774
901
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 ());
902
+ ASTContext &Ctx = MV.getASTContext ();
903
+
904
+ if (const BoundNodes *Nodes = State.getBoundNodes ()) {
905
+ OS << " ASTMatcher: Processing '" << CB->getID () << " ' against:\n\t " ;
906
+ dumpNodeFromState (Ctx, State, OS);
907
+ const BoundNodes::IDToNodeMap &Map = Nodes->getMap ();
908
+ if (Map.empty ()) {
909
+ OS << " \n No bound nodes\n " ;
910
+ return ;
807
911
}
808
- OS << " }\n " ;
912
+ OS << " \n --- Bound Nodes Begin ---\n " ;
913
+ for (const auto &Item : Map) {
914
+ OS << " " << Item.first << " - { " ;
915
+ dumpNode (Ctx, Item.second , OS);
916
+ OS << " }\n " ;
917
+ }
918
+ OS << " --- Bound Nodes End ---\n " ;
919
+ } else {
920
+ OS << " ASTMatcher: Matching '" << CB->getID () << " ' against:\n\t " ;
921
+ dumpNodeFromState (Ctx, State, OS);
922
+ OS << ' \n ' ;
809
923
}
810
- OS << " --- Bound Nodes End ---\n " ;
811
924
}
812
925
813
926
private:
814
927
const MatchASTVisitor &MV;
815
928
};
816
929
817
930
private:
818
- bool TraversingASTNodeNotSpelledInSource = false ;
819
- bool TraversingASTNodeNotAsIs = false ;
820
- bool TraversingASTChildrenNotSpelledInSource = false ;
821
-
822
- const MatchCallback *CurMatched = nullptr ;
823
- const BoundNodes *CurBoundNodes = nullptr ;
824
-
825
931
struct ASTNodeNotSpelledInSourceScope {
826
932
ASTNodeNotSpelledInSourceScope (MatchASTVisitor *V, bool B)
827
933
: MV(V), MB(V->TraversingASTNodeNotSpelledInSource) {
@@ -887,6 +993,7 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
887
993
if (EnableCheckProfiling)
888
994
Timer.setBucket (&TimeByBucket[MP.second ->getID ()]);
889
995
BoundNodesTreeBuilder Builder;
996
+ CurMatchRAII RAII (*this , MP.second , Node);
890
997
if (MP.first .matches (Node, this , &Builder)) {
891
998
MatchVisitor Visitor (*this , ActiveASTContext, MP.second );
892
999
Builder.visitMatches (&Visitor);
@@ -919,6 +1026,7 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
919
1026
continue ;
920
1027
}
921
1028
1029
+ CurMatchRAII RAII (*this , MP.second , DynNode);
922
1030
if (MP.first .matches (DynNode, this , &Builder)) {
923
1031
MatchVisitor Visitor (*this , ActiveASTContext, MP.second );
924
1032
Builder.visitMatches (&Visitor);
@@ -1107,35 +1215,30 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
1107
1215
// the aggregated bound nodes for each match.
1108
1216
class MatchVisitor : public BoundNodesTreeBuilder ::Visitor {
1109
1217
struct CurBoundScope {
1110
- CurBoundScope (MatchASTVisitor &MV , const BoundNodes &BN) : MV(MV) {
1111
- assert (MV. CurMatched && !MV. CurBoundNodes );
1112
- MV. CurBoundNodes = &BN ;
1218
+ CurBoundScope (MatchASTVisitor::CurMatchData &State , const BoundNodes &BN)
1219
+ : State(State) {
1220
+ State. SetBoundNodes (BN) ;
1113
1221
}
1114
1222
1115
- ~CurBoundScope () { MV. CurBoundNodes = nullptr ; }
1223
+ ~CurBoundScope () { State. clearBoundNodes () ; }
1116
1224
1117
1225
private:
1118
- MatchASTVisitor &MV ;
1226
+ MatchASTVisitor::CurMatchData &State ;
1119
1227
};
1120
1228
1121
1229
public:
1122
1230
MatchVisitor (MatchASTVisitor &MV, ASTContext *Context,
1123
1231
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 ; }
1232
+ : State(MV.CurMatchState), Context(Context), Callback(Callback) {}
1130
1233
1131
1234
void visitMatch (const BoundNodes& BoundNodesView) override {
1132
1235
TraversalKindScope RAII (*Context, Callback->getCheckTraversalKind ());
1133
- CurBoundScope RAII2 (MV , BoundNodesView);
1236
+ CurBoundScope RAII2 (State , BoundNodesView);
1134
1237
Callback->run (MatchFinder::MatchResult (BoundNodesView, Context));
1135
1238
}
1136
1239
1137
1240
private:
1138
- MatchASTVisitor &MV ;
1241
+ MatchASTVisitor::CurMatchData &State ;
1139
1242
ASTContext* Context;
1140
1243
MatchFinder::MatchCallback* Callback;
1141
1244
};
0 commit comments