[cfe-dev] Getting multiple AST matches as a list

Gábor Kozár kozargabor at gmail.com
Mon Sep 2 05:50:34 PDT 2013


Hi,

The AST dump above clearly shows how the AST is structured, and that should
be all the information you need.

Basically, you can see that the children of the InitListExpr are the nodes
you're interested in. So you bind the whole InitListExpr that you're
interested, and you iterate through its children. According to the AST
dump, the actual StringLiteral nodes are wrapped by ImplicitCastExpr-s - a
phenomenon that's very common in Clang's AST - so you need to throw these
away: Expr-s have a lot of methods to do this, IgnoreImpCasts() and so on -
see the documentation for the exact naming and descriptions.
After this, all you need to do is llvm::dyn_cast the Expr to StringLiteral,
and the StringLiteral class has methods to get the actual string value.

AST matchers are usually used to give you a rough approximation of the
information you need - you'll find that usually you will need to perform
some additional logic to get to the data you actually want. AST matchers
give you a substitute to the complex state machines you'd have to implement
in RecursiveASTVisitor, but they're not meant to be a complete way of
getting all the information from the AST.
Nonetheless, if you find that you still want to do this using AST matchers,
feel free to implement them yourself using the macros and classes defined
in ASTMatchersMacros.h. For examples, the best place to look at is
ASTMatchers.h. However, you may find this confusing, and the compiler error
messages are not that helpful, due to the fact that AST matchers rely
heavily on C++ templates (and some macros).

Hope this helps!

Gabor


2013/8/30 Jesper Eskilson <jesper.eskilson at iar.com>

> On 08/30/2013 04:17 PM, Vane, Edwin wrote:
>
>> Wouldn't binding the result of the initListExpr() give you access to the
>> InitListExpr that you could get the items from? Or did you want something
>> that was a little nicer?
>>
>
> How do I get out the value used in the initializer? I've tried finding a
> way to "evaluate" an "Expr *" and get out a value (if possible), but I
> cannot figure out what API to use to do that. I realize that it may not
> always be possible to find a value, but it's ok to bail out if the
> expression does not consist of (string) literals.
>
> Ideally I'd like to be able to something like this:
>
>    // Evaluate the initializer list
>
>    std::vector<std::string> listOfInitializers =
> initListExpr->Evaluate(...);
>
>
>
>  Another option would be to bind to every child of the initListExpr() but
>> then you don't get the matches all at once to your match callback. Rather
>> the callback gets called once per child.
>>
>> If you wanted every child at once, you'd need to bind a different name to
>> each child. There's no way to do that currently. Or we'd need some
>> mechanism to collect a bunch of matches under a single name.
>>
> I can't do that because I don't know how many children there are.
>
> /Jesper
>
>
>  -----Original Message-----
>>> From: cfe-dev-bounces at cs.uiuc.edu [mailto:cfe-dev-bounces at cs.**uiuc.edu<cfe-dev-bounces at cs.uiuc.edu>]
>>> On
>>> Behalf Of Jesper Eskilson
>>> Sent: Friday, August 30, 2013 7:23 AM
>>> To: cfe-dev at cs.uiuc.edu
>>> Subject: [cfe-dev] Getting multiple AST matches as a list
>>>
>>>
>>> Hello,
>>>
>>> I'm learning about how to use AST matchers, but one usecase is giving me
>>> headaches. I have a declaration like this:
>>>
>>> const char *list = { "a", "b" };
>>>
>>> and I would like to retrieve the array initializer as a list of strings
>>> in my matcher
>>> callback.  I've managed to get a pointer to the InitListExpr which looks
>>> like this:
>>>
>>>  InitListExpr 0x46be670 'const char *[2]'
>>>> |-ImplicitCastExpr 0x46be6c0 'const char *' <ArrayToPointerDecay>
>>>> |`-StringLiteral 0x46be5b8 'const char [12]' lvalue "semihosting"
>>>> `-ImplicitCastExpr 0x46be6d8 'const char *' <ArrayToPointerDecay>
>>>>    `-StringLiteral 0x46be5f0 'const char [4]' lvalue "swo"
>>>>
>>> I've looked through the traversal matchers, but it seems like I can only
>>> get
>>> matchers which will generate a match for each element in the list.
>>> Is there any way to generate a single match with all elements wrapped up
>>> in a
>>> list?
>>>
>>> /Jesper
>>> --
>>> *Jesper Eskilson* /Development Engineer/ IAR Systems AB Box 23051,
>>> Strandbodgatan 1
>>> SE-750 23 Uppsala, SWEDEN
>>> E-mail: jesper.eskilson at iar.com <mailto:jesper.eskilson at iar.**com<jesper.eskilson at iar.com>
>>> >
>>> Website: www.iar.com
>>> <http://www.iar.com> Twitter: www.twitter.com/iarsystems
>>> <http://www.twitter.com/**iarsystems <http://www.twitter.com/iarsystems>
>>> >
>>> ______________________________**_________________
>>> cfe-dev mailing list
>>> cfe-dev at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/**mailman/listinfo/cfe-dev<http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev>
>>>
>>
>
> --
> *Jesper Eskilson* /Development Engineer/
> IAR Systems AB
> Box 23051, Strandbodgatan 1
> SE-750 23 Uppsala, SWEDEN
> E-mail: jesper.eskilson at iar.com <mailto:jesper.eskilson at iar.**com<jesper.eskilson at iar.com>>
> Website: www.iar.com
> <http://www.iar.com> Twitter: www.twitter.com/iarsystems <
> http://www.twitter.com/**iarsystems <http://www.twitter.com/iarsystems>>
> ______________________________**_________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/**mailman/listinfo/cfe-dev<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/20130902/a4dace29/attachment.html>


More information about the cfe-dev mailing list