[cfe-dev] ast matchers for nested function calls

John Leidel via cfe-dev cfe-dev at lists.llvm.org
Thu Sep 30 09:24:25 PDT 2021


CFE-Dev, we're working on building a series of AST matchers that
differentiates between similar function calls in a nested fashion.
Consider the following:

void MyFunction(){
  nspace::method(...){ // top-level
    nspace::method(...){ // second-level
      nspace::method(...){ // third-level
      }
    }
    nspace::method(...){ // second-level
    }
  }
}

We would like to develop matchers that do the following:
- Match the top-level function call and ONLY the top-level function call
- Match the nested function call and ONLY the nested function call
(regardless of the nesting level)

We currently have matchers that look like the following:

StatementMatcher Top =
callExpr( callee( functionDecl( matchesName("nspace::method"),
       unless( hasAncestor( callExpr ( callee ( functionDecl(
matchesName( "nspace::method"))))))))).bind("top-level");

StatementMatcher Nested =
callExpr( callee( functionDecl( matchesName("nspace::method"),
      forEachDescendent(
          callExpr( callee( functionDecl( matchesName("nspace::method"))))),
      unless( hasAncestor( callExpr( callee( functionDecl(
matchesName( "nspace::method")))))))).bind("nested");

We get odd behavior where the top-level function calls are matched by
both the `Top` matcher and the `Nested` matcher.  Further, the nested
function calls are matched by the `Top` matcher and not the `Nested`
matcher.  Any thoughts on what I'm missing?

Second, I've seen others reference the use of RecursiveASTVisitors to
handle complexity similar to this.  We have a litany of other matchers
that we need to handle various function arguments.  If using
RecursiveASTVisitors is the right path, can we safely mix these with
standard AST Matchers?  Does anyone have a decent example of doing so?

best
john


More information about the cfe-dev mailing list