clang_visitChildren to recurse into template instantiations

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
struct X {
void f() {
T t;
t.foo();
}
};
template struct X;

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 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
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> ‘’
-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> ‘’ .foo 0x1030318a0
`-DeclRefExpr 0x1030795c0 col:9 ‘struct A’:‘struct A’ lvalue Var 0x1030791d0 ‘t’ ‘struct A’:‘struct A’

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?

Currently, if you want tight control over what you visit, I think libtooling is your best bet; apart from that, changes to libclang are welcome, but be aware that we’ll want to keep it backwards compatible, so the bar for changes is much higher.