martong added a comment.

> 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?

Ok, I changed and wrapped the pattern:

  template <typename MatcherType>
  NodeType *match(const Decl *D, const MatcherType &AMatcher) {
    MatchFinder Finder;
    auto WrappedMatcher = anyOf(AMatcher.bind(""), 
hasDescendant(AMatcher.bind("")));
    Finder.addMatcher(WrappedMatcher, this);
    // ...
  }

But this results in an ambigous call of `addMatcher` because the compiler 
cannot choose the appropriate overload:

  ../../git/llvm/tools/clang/unittests/AST/DeclMatcher.h:36:12: error: call to 
member function 'addMatcher' is ambiguous
      Finder.addMatcher(WrappedMatcher, this);
      ~~~~~~~^~~~~~~~~~
  ...
  ../../git/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h:149:8: 
note: candidate function
    void addMatcher(const DeclarationMatcher &NodeMatch,
         ^
  ../../git/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h:151:8: 
note: candidate function
    void addMatcher(const TypeMatcher &NodeMatch,
         ^
  ../../git/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h:153:8: 
note: candidate function
    void addMatcher(const StatementMatcher &NodeMatch,
         ^
  ../../git/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h:155:8: 
note: candidate function
    void addMatcher(const NestedNameSpecifierMatcher &NodeMatch,
         ^
  ../../git/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h:157:8: 
note: candidate function
    void addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch,
         ^
  ../../git/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h:159:8: 
note: candidate function
    void addMatcher(const TypeLocMatcher &NodeMatch,
         ^
  ../../git/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h:161:8: 
note: candidate function
    void addMatcher(const CXXCtorInitializerMatcher &NodeMatch,
         ^

This seems quite logical to me, since `anyOf` wraps many matchers, which could 
refer to Nodes with different type.
So, I went on and specified which overload to call (note, from this point this 
is getting hacky and would not consider such an API easy to use):

  And then I gave up.
    template <typename MatcherType>
    NodeType *match(const Decl *D, const MatcherType &AMatcher) {
      MatchFinder Finder;
      auto WrappedMatcher = anyOf(AMatcher.bind(""), 
hasDescendant(AMatcher.bind("")));
      auto PtrToMemFun = static_cast<void (MatchFinder::*)(
          const DeclarationMatcher&, MatchCallback*)>(&MatchFinder::addMatcher);
      (Finder.*PtrToMemFun)(WrappedMatcher, this);

This time it turned out that we can't just add a matcker like this because 
`getMatchers` in `anyOf` would call the private ctor of `Matcher`:

  
../../git/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h:1339:13:
 error: calling a private constructor of class 
'clang::ast_matchers::internal::Matcher<clang::Decl>'
      return {Matcher<T>(std::get<Is>(Params))...};
              ^
  
../../git/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h:1331:16:
 note: in instantiation of function template specialization 
'clang::ast_matchers::internal::VariadicOperatorMatcher<clang::ast_matchers::internal::Matcher<clang::Stmt>,
 
clang::ast_matchers::internal::ArgumentAdaptingMatcherFunc<internal::HasDescendantMatcher,
 clang::ast_matchers::internal::TypeList<clang::Decl, clang::Stmt, 
clang::NestedNameSpecifier, clang::NestedNameSpecifierLoc, clang::QualType, 
clang::Type, clang::TypeLoc, clang::CXXCtorInitializer>, 
clang::ast_matchers::internal::TypeList<clang::Decl, clang::Stmt, 
clang::NestedNameSpecifier, clang::NestedNameSpecifierLoc, clang::TypeLoc, 
clang::QualType> >::Adaptor<clang::Stmt> >::getMatchers<clang::Decl, 0, 1>' 
requested here
                 getMatchers<T>(llvm::index_sequence_for<Ps...>()))
                 ^

As an alternative, I tried to call addDynamicMatcher, which resulted in a 
conversion error:

  template <typename MatcherType>
  NodeType *match(const Decl *D, const MatcherType &AMatcher) {
    MatchFinder Finder;
    auto WrappedMatcher = anyOf(AMatcher.bind(""), 
hasDescendant(AMatcher.bind("")));
    Finder.addDynamicMatcher(WrappedMatcher, this);

  ../../git/llvm/tools/clang/unittests/AST/DeclMatcher.h:40:30: error: no 
viable conversion from 
'clang::ast_matchers::internal::VariadicOperatorMatcher<clang::ast_matchers::internal::Matcher<clang::Decl>,
 
clang::ast_matchers::internal::ArgumentAdaptingMatcherFunc<internal::HasDescendantMatcher,
 clang::ast_matchers::internal::TypeList<clang::Decl, clang::Stmt, 
clang::NestedNameSpecifier, clang::NestedNameSpecifierLoc, clang::QualType, 
clang::Type, clang::TypeLoc, clang::CXXCtorInitializer>, 
clang::ast_matchers::internal::TypeList<clang::Decl, clang::Stmt, 
clang::NestedNameSpecifier, clang::NestedNameSpecifierLoc, clang::TypeLoc, 
clang::QualType> >::Adaptor<clang::Decl> >' to 'const internal::DynTypedMatcher'
      Finder.addDynamicMatcher(WrappedMatcher, this);
                               ^~~~~~~~~~~~~~

Perhaps I am doing something wrong because I really could not find a way to add 
the wrapped matcher.
These results motivated me to double check your original idea of using 
`ast_matchers::match`:

  Decl *FromTU = getTuDecl("void f();", Lang_CXX);
  auto Pattern = functionDecl(hasName("f"));
  match(anyOf(Pattern, hasDescendant(Pattern)), FromTU, 
FromTU->getASTContext());

This resulted an ambigous call again, but this time the compiler could not 
resolve the call inside `ast_matchers::match`:

  ../../git/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h:301:10: 
error: call to member function 'addMatcher' is ambiguous
    Finder.addMatcher(Matcher, &Callback);
    ~~~~~~~^~~~~~~~~~


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

Reply via email to