[cfe-dev] clang_visitChildren to recurse into template instantiations

Manuel Klimek via cfe-dev cfe-dev at lists.llvm.org
Mon Oct 5 01:59:34 PDT 2015


On Sat, Oct 3, 2015 at 11:28 PM Gábor Márton <cfe-dev at lists.llvm.org> wrote:

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


>
> 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'
>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20151005/0c4b2ace/attachment.html>


More information about the cfe-dev mailing list