On Fri, Jul 27, 2018 at 10:39 AM Gabor Marton via Phabricator < revi...@reviews.llvm.org> wrote:
> martong added a comment. > > > MatchFinder::match allows you to match a node. Wrapping your matcher > code with: > > auto m = <my cool matcher>; > > ast_matchers::match(anyOf(m, hashDescendant(m)), node, context); > > Okay, I understand and accept that. > However, I consider that a different level of abstraction. > `ast_matchers::match` uses `internal::CollectMatchesCallback` in its > implementation. If I already have my own custom MatchCallback implemented > then there is no way to achieve the desired behavior. > > For example, in `ASTImporter` tests we use the following customized > callback class: > > enum class DeclMatcherKind { First, Last }; > > // Matcher class to retrieve the first/last matched node under a given > AST. > template <typename NodeType, DeclMatcherKind MatcherKind> > class DeclMatcher : public MatchFinder::MatchCallback { > NodeType *Node = nullptr; > void run(const MatchFinder::MatchResult &Result) override { > if ((MatcherKind == DeclMatcherKind::First && Node == nullptr) || > MatcherKind == DeclMatcherKind::Last) { > Node = const_cast<NodeType > *>(Result.Nodes.getNodeAs<NodeType>("")); > } > } > public: > // Returns the first/last matched node under the tree rooted in `D`. > template <typename MatcherType> > NodeType *match(const Decl *D, const MatcherType &AMatcher) { > MatchFinder Finder; > Finder.addMatcher(AMatcher.bind(""), this); > Finder.matchAST(D->getASTContext()); > assert(Node); > return Node; > } > }; > template <typename NodeType> > using LastDeclMatcher = DeclMatcher<NodeType, DeclMatcherKind::Last>; > template <typename NodeType> > using FirstDeclMatcher = DeclMatcher<NodeType, DeclMatcherKind::First>; > > And this is how we use it in the tests: > > Decl *FromTU = getTuDecl("void f(); void f(); void f();", Lang_CXX); > auto Pattern = functionDecl(hasName("f")); > auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); > auto *D2 = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern); > > At this point we would like to extend this `DeclMatcher` to be able to > match a subtree, and be able to start the traverse from a specific `Decl`, > something like this : > > auto *DV = FirsDeclMatcher<VarDecl>().match(D2, SomeOtherPattern); > > Currently, I don't see how we could do this extension without the proposed > `matchSubtree`. > (Perhaps, we could refactor our `DeclMatcher` to not use a customized > MatchCallback, rather use `ast_matchers::match`, but that sounds like a bad > workaround to me.) > > Hope this makes the the goal of this patch cleaner. > Finder.match also has an overload that takes the node. Can you wrap "Pattern" above in the anyOf(hasDescendant(...), ...) and match on the node instead of the full AST? > > > Repository: > rC Clang > > https://reviews.llvm.org/D49840 > > > >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits