[cfe-dev] Matching FunctionTemplateDecl body in AST matcher

Mitchell, Liam via cfe-dev cfe-dev at lists.llvm.org
Thu Feb 22 16:07:03 PST 2018


Hi cfe-dev,

My adventures with clang-refactor and AST matchers continue, with some good results! Now I'm looking at some more complicated refactorings, and I've run into something I can't figure out.

When I look at the AST that gets emitted in http://bastian.rieck.ru/blog/posts/2015/baby_steps_libclang_ast/ , the FunctionTemplateDecl node has a grandchild CompoundStmt representing the body of the function. However, when I match a FunctionTemplateDecl using an AST matcher, the body is always null. Is this supposed to work? I'd like to replace the body of the template function in my refactoring, which works perfectly fine for non-template functions (using just functionDecl() instead of functionTemplateDecl()).

For reference, the sample code in that blog post looks like:

    template <class T> bool f( T x )
    {
      return x % 2;
    }

And the dumped AST looks like (some lines clipped for clarity):

    `-FunctionTemplateDecl 0x2fefdc0 <foo.cc:1:1, line:4:1> line:1:25 f
      |-TemplateTypeParmDecl 0x2fefb60 <col:11, col:17> col:17 referenced class T
      `-FunctionDecl 0x2fefd20 <col:20, line:4:1> line:1:25 f '_Bool (T)'
        |-ParmVarDecl 0x2fefc20 <col:28, col:30> col:30 referenced x 'T'
        `-CompoundStmt 0x2fefea0 <line:2:1, line:4:1>

However, when I match the AST with the matcher:

    functionTemplateDecl(hasName("f")).bind("root");

I can't see the body of the template function decl - the following code just leaves 'Body' null.

    if (const FunctionTemplateDecl* Template = Result.Nodes.getNodeAs<FunctionTemplateDecl>("root"))
      const Stmt* Body = Template->getTemplatedDecl()->getBody();

I've also tried a few other ways to get the body, such as using getAsFunction()->getBody(), getCanonicalDecl()->getBody() and just raw getBody() - nothing worked. I assume this has to do with the fact that the body isn't actually instantiated yet - but I can't find anything in the docs that explains how to get the source range for the body of a template function. Is there any way to make this work? 

Thanks!
Liam



More information about the cfe-dev mailing list