[cfe-dev] RecursiveASTVisitor: Actually walking the AST

Manuel Klimek klimek at google.com
Mon Sep 29 01:20:01 PDT 2014


On Sun Sep 28 2014 at 1:47:19 AM Steven Lu <stevenlu443 at gmail.com> wrote:

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

I wasn't there when this was implemented, but I'd say it's the way it is
because of engineering trade-offs. Putting a single common interface just
for traversal in only helps in a small subset of cases. On the other hand,
the RAV is of course a pretty complex beast :)

We have tried to build something for tool writers that makes it easier to
find stuff in the AST, which is called the AST matchers:
http://clang.llvm.org/docs/LibASTMatchers.html

To your specific problem: if I understand you correctly, you want the
ClassTemplateDecl, which nicely points to the CXXRecordDecl that describes
the template.

Cheers,
/Manuel


>
> Thanks.
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140929/393b121f/attachment.html>


More information about the cfe-dev mailing list