jcking1034 created this revision. jcking1034 added reviewers: ymandel, tdl-g, aaron.ballman. jcking1034 requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Adds a `withTag` matcher which outputs contextual information for better debugging. This relies on changes made in https://reviews.llvm.org/D113917 to access the names of matchers. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D113943 Files: clang/include/clang/ASTMatchers/ASTMatchers.h clang/include/clang/ASTMatchers/ASTMatchersInternal.h Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -43,6 +43,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/PrettyPrinter.h" #include "clang/AST/Stmt.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" @@ -1042,6 +1043,44 @@ std::vector<std::string> Names; }; +template <typename T> class WithTagMatcher : public MatcherInterface<T> { +public: + explicit WithTagMatcher(std::string _BeforeTag, std::string _AfterTag, + internal::Matcher<T> _InnerMatcher) + : BeforeTag(std::move(_BeforeTag)), AfterTag(std::move(_AfterTag)), + InnerMatcher(_InnerMatcher) {} + explicit WithTagMatcher(internal::Matcher<T> _InnerMatcher) + : BeforeTag("⭐ Attempting new match"), + AfterTag("✔️ Concluding attempt"), InnerMatcher(_InnerMatcher) {} + bool matches(const T &Node, ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const override { + DynTypedNode DTN = DynTypedNode::create(Node); + + llvm::errs() << BeforeTag << "\n"; + + llvm::errs() << "Matcher Name: " << InnerMatcher.getMatcherName() << "\n"; + + llvm::errs() << "Node Kind: " << DTN.getNodeKind().asStringRef() << "\n" + << "Node Value:\n```\n"; + DTN.print(llvm::errs(), PrintingPolicy(LangOptions())); + llvm::errs() << "\n```\n" + << "Node AST:\n"; + DTN.dump(llvm::errs(), Finder->getASTContext()); + + bool result = InnerMatcher.matches(Node, Finder, Builder); + llvm::errs() << "Result: " << (result ? "Successful\n" : "Unsuccessful\n"); + + llvm::errs() << AfterTag << "\n\n"; + + return result; + } + +private: + std::string BeforeTag; + std::string AfterTag; + internal::Matcher<T> InnerMatcher; +}; + /// Matches named declarations with a specific name. /// /// See \c hasName() and \c hasAnyName() in ASTMatchers.h for details. Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -2993,6 +2993,37 @@ new internal::HasNameMatcher({std::string(Name)})); } +template <typename T> +inline internal::Matcher<T> withTag(std::string BeforeTag, std::string AfterTag, + const internal::Matcher<T> &InnerMatcher) { + return internal::Matcher<T>( + new internal::WithTagMatcher<T>(BeforeTag, AfterTag, InnerMatcher)); +} + +template <typename T, template <typename, typename... Params> class MatcherT, + typename ReturnTypesF, typename... ParamTypes> +inline MatcherT<T> +withTag(std::string BeforeTag, std::string AfterTag, + const internal::PolymorphicMatcher<MatcherT, ReturnTypesF, + ParamTypes...> &InnerMatcher) { + return internal::Matcher<T>(new internal::WithTagMatcher<T>( + BeforeTag, AfterTag, internal::Matcher<T>(InnerMatcher))); +} + +template <typename T> +inline internal::Matcher<T> withTag(const internal::Matcher<T> &InnerMatcher) { + return internal::Matcher<T>(new internal::WithTagMatcher<T>(InnerMatcher)); +} + +template <typename T, template <typename, typename... Params> class MatcherT, + typename ReturnTypesF, typename... ParamTypes> +inline MatcherT<T> +withTag(const internal::PolymorphicMatcher<MatcherT, ReturnTypesF, + ParamTypes...> &InnerMatcher) { + return internal::Matcher<T>( + new internal::WithTagMatcher<T>(internal::Matcher<T>(InnerMatcher))); +} + /// Matches NamedDecl nodes that have any of the specified names. /// /// This matcher is only provided as a performance optimization of hasName.
Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -43,6 +43,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/PrettyPrinter.h" #include "clang/AST/Stmt.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" @@ -1042,6 +1043,44 @@ std::vector<std::string> Names; }; +template <typename T> class WithTagMatcher : public MatcherInterface<T> { +public: + explicit WithTagMatcher(std::string _BeforeTag, std::string _AfterTag, + internal::Matcher<T> _InnerMatcher) + : BeforeTag(std::move(_BeforeTag)), AfterTag(std::move(_AfterTag)), + InnerMatcher(_InnerMatcher) {} + explicit WithTagMatcher(internal::Matcher<T> _InnerMatcher) + : BeforeTag("â Attempting new match"), + AfterTag("âï¸ Concluding attempt"), InnerMatcher(_InnerMatcher) {} + bool matches(const T &Node, ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const override { + DynTypedNode DTN = DynTypedNode::create(Node); + + llvm::errs() << BeforeTag << "\n"; + + llvm::errs() << "Matcher Name: " << InnerMatcher.getMatcherName() << "\n"; + + llvm::errs() << "Node Kind: " << DTN.getNodeKind().asStringRef() << "\n" + << "Node Value:\n```\n"; + DTN.print(llvm::errs(), PrintingPolicy(LangOptions())); + llvm::errs() << "\n```\n" + << "Node AST:\n"; + DTN.dump(llvm::errs(), Finder->getASTContext()); + + bool result = InnerMatcher.matches(Node, Finder, Builder); + llvm::errs() << "Result: " << (result ? "Successful\n" : "Unsuccessful\n"); + + llvm::errs() << AfterTag << "\n\n"; + + return result; + } + +private: + std::string BeforeTag; + std::string AfterTag; + internal::Matcher<T> InnerMatcher; +}; + /// Matches named declarations with a specific name. /// /// See \c hasName() and \c hasAnyName() in ASTMatchers.h for details. Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -2993,6 +2993,37 @@ new internal::HasNameMatcher({std::string(Name)})); } +template <typename T> +inline internal::Matcher<T> withTag(std::string BeforeTag, std::string AfterTag, + const internal::Matcher<T> &InnerMatcher) { + return internal::Matcher<T>( + new internal::WithTagMatcher<T>(BeforeTag, AfterTag, InnerMatcher)); +} + +template <typename T, template <typename, typename... Params> class MatcherT, + typename ReturnTypesF, typename... ParamTypes> +inline MatcherT<T> +withTag(std::string BeforeTag, std::string AfterTag, + const internal::PolymorphicMatcher<MatcherT, ReturnTypesF, + ParamTypes...> &InnerMatcher) { + return internal::Matcher<T>(new internal::WithTagMatcher<T>( + BeforeTag, AfterTag, internal::Matcher<T>(InnerMatcher))); +} + +template <typename T> +inline internal::Matcher<T> withTag(const internal::Matcher<T> &InnerMatcher) { + return internal::Matcher<T>(new internal::WithTagMatcher<T>(InnerMatcher)); +} + +template <typename T, template <typename, typename... Params> class MatcherT, + typename ReturnTypesF, typename... ParamTypes> +inline MatcherT<T> +withTag(const internal::PolymorphicMatcher<MatcherT, ReturnTypesF, + ParamTypes...> &InnerMatcher) { + return internal::Matcher<T>( + new internal::WithTagMatcher<T>(internal::Matcher<T>(InnerMatcher))); +} + /// Matches NamedDecl nodes that have any of the specified names. /// /// This matcher is only provided as a performance optimization of hasName.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits