[cfe-dev] RecursiveASTVisitor: Actually walking the AST

Steven Lu stevenlu443 at gmail.com
Sat Sep 27 16:39:13 PDT 2014


Hi,

I have a rather basic conceptual question for the clang experts out there.
I am starting out and the examples and tutorials that exist have been very
helpful to let me get to the point where I can find all the details about
all class/struct/union declarations (with VisitCXXRecordDecl()), and also I
am able to enumerate all the fields inside of such items by using
VisitFieldDecl().

My question is related to the apparent difficulty of directly navigating
the AST as opposed to using callbacks on the RecursiveASTVisitor. I reckon
that this difficulty might be the motivation behind the design of
RecursiveASTVisitor itself, but nevertheless it is restrictive.

For example: When looking at the output of ast-dump for some code, I can
see that there are CXXRecordDecls shown as children of TemplateDecls.
Supposing I want to enumerate just the TemplateDecls, it is straightforward
to implement RecursiveASTVisitor::VisitTemplateDecl(), but I have been
having a very difficult time retrieving any pointer to TemplateDecl from
within VisitCXXRecordDecl. Indeed CXXRecordDecl::getParent() yields a
DeclContext*, yet TemplateDecl's aren't even DeclContexts, AFAICT. The deep
AST class hierarchy is making this difficult.

So the next best attempt I can make is to use the SourceManager's tools to
help me narrow down if these separate TemplateDecls and CXXRecordDecls that
I find are referring to the same source code locations. This is done
manually by comparing actual source location values: If a TemplateDecl and
CXXRecordDecl share a location, then I can join together the information
that I find (e.g. whether the class/struct is empty and the text list of
the template parameters).

This is moderately straightforward, but much less so than directly using
AST traversal to achieve such a correlation.

So hopefully someone can shed some light for me on why this is how it is,
and what might perhaps be a better way to establish information about the
decl's that are found in the code. In particular, why is it that I can
easily and reliably query the CXXRecordDecl to see if it is a template
specialization, and similarly easy to query any given FieldDecl for its
(CXX)RecordDecl context, but not at all easy to see if a particular
CXXRecordDecl happens to be a template declaration.

Thanks.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140927/2fb189ce/attachment.html>


More information about the cfe-dev mailing list