[cfe-dev] clang_visitChildren to recurse into template instantiations

Gábor Márton via cfe-dev cfe-dev at lists.llvm.org
Sat Oct 3 14:28:40 PDT 2015


Hi,

Using libclang, I'd like to visit that part of the AST which is connected
to a class template instantiation.
I'm wondering if I could have the same behaviour with clang_visitChildern
as with RecursiveASTVisitor with shouldVisitTemplateInstantiations()
returning true.

Currently when I use clang_visitChildren, I can traverse only through the
StructDecl and a TypeRef node , but the child nodes are not reachable.
Do I have any feasible option with libclang to recurse into the
ClassTemplateSpecializationDecl part of the AST? Or must I use libtooling
(and RecursiveASTVisitor or the matchers) rather?

Many thanks,
Gábor

Detailed explanation via an example:

//main.cpp
struct A {
    void foo() {}
};
template <typename T>
struct X {
    void f() {
        T t;
        t.foo();
    }
};
template struct X<A>;

Visitation with clang_visitChildren:
StructDecl c A def main.cpp:1:8
  CXXMethod c foo() foo def main.cpp:2:10
    CompoundStmt o
ClassTemplate c X<T> X def main.cpp:5:8
  TemplateTypeParameter c T def main.cpp:4:20
  CXXMethod c f() f def main.cpp:6:10
    CompoundStmt o
      DeclStmt o
        VarDecl c t def main.cpp:7:11
          TypeRef r T main.cpp:7:9
      CallExpr r main.cpp:8:9
        MemberRefExpr r main.cpp:8:9
          DeclRefExpr r t main.cpp:8:9
StructDecl c X<A> X def main.cpp:11:17
  TypeRef r struct A main.cpp:11:19

Visitation with RecursiveASTVisitor:
|-CXXRecordDecl 0x1030316b0 <main.cpp:1:1, line:3:1> line:1:8 referenced
struct A definition
| |-CXXRecordDecl 0x1030317c0 <col:1, col:8> col:8 implicit struct A
| |-CXXMethodDecl 0x1030318a0 <line:2:5, col:17> col:10 used foo 'void
(void)'
| | `-CompoundStmt 0x103031978 <col:16, col:17>
| |-CXXConstructorDecl 0x103079250 <line:1:8> col:8 implicit used A 'void
(void) throw()' inline
| | `-CompoundStmt 0x103079560 <col:8>
| `-CXXConstructorDecl 0x103079380 <col:8> col:8 implicit A 'void (const
struct A &)' inline noexcept-unevaluated 0x103079380
|   `-ParmVarDecl 0x1030794c0 <col:8> col:8 'const struct A &'
|-ClassTemplateDecl 0x1030788d0 <line:4:1, line:10:1> line:5:8 X
| |-TemplateTypeParmDecl 0x103031990 <line:4:11, col:20> col:20 referenced
typename T
| |-CXXRecordDecl 0x103078840 <line:5:1, line:10:1> line:5:8 struct X
definition
| | |-CXXRecordDecl 0x103078b50 <col:1, col:8> col:8 implicit struct X
| | `-CXXMethodDecl 0x103078c00 <line:6:5, line:9:5> line:6:10 f 'void
(void)'
| |   `-CompoundStmt 0x103078e10 <col:14, line:9:5>
| |     |-DeclStmt 0x103078d50 <line:7:9, col:12>
| |     | `-VarDecl 0x103078cf0 <col:9, col:11> col:11 referenced t 'T'
| |     `-CallExpr 0x103078de8 <line:8:9, col:15> '<dependent type>'
| |       `-CXXDependentScopeMemberExpr 0x103078d90 <col:9, col:11>
'<dependent type>' lvalue
| |         `-DeclRefExpr 0x103078d68 <col:9> 'T' lvalue Var 0x103078cf0
't' 'T'
| `-ClassTemplateSpecialization 0x103078e50 'X'
`-ClassTemplateSpecializationDecl 0x103078e50 <line:11:1, col:20> col:17
struct X definition
  |-TemplateArgument type 'struct A'
  |-CXXRecordDecl 0x103079040 prev 0x103078e50 <line:5:1, col:8> col:8
implicit struct X
  `-CXXMethodDecl 0x1030790d0 <line:6:5, line:9:5> line:6:10 f 'void (void)'
    `-CompoundStmt 0x103079640 <col:14, line:9:5>
      |-DeclStmt 0x1030795a8 <line:7:9, col:12>
      | `-VarDecl 0x1030791d0 <col:9, col:11> col:11 used t 'struct
A':'struct A' callinit
      |   `-CXXConstructExpr 0x103079578 <col:11> 'struct A':'struct A'
'void (void) throw()'
      `-CXXMemberCallExpr 0x103079618 <line:8:9, col:15> 'void'
        `-MemberExpr 0x1030795e8 <col:9, col:11> '<bound member function
type>' .foo 0x1030318a0
          `-DeclRefExpr 0x1030795c0 <col:9> 'struct A':'struct A' lvalue
Var 0x1030791d0 't' 'struct A':'struct A'
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20151003/a5f65bc8/attachment.html>


More information about the cfe-dev mailing list