[cfe-dev] Tracing Typedef Chain

Richard Smith via cfe-dev cfe-dev at lists.llvm.org
Mon Nov 30 14:15:28 PST 2015


On Mon, Nov 30, 2015 at 12:48 PM, Daniel Dilts <diltsman at gmail.com> wrote:

> On Mon, Nov 30, 2015 at 11:12 AM, Richard Smith <richard at metafoo.co.uk>
> wrote:
>
>> On Mon, Nov 30, 2015 at 10:51 AM, Daniel Dilts via cfe-dev <
>> cfe-dev at lists.llvm.org> wrote:
>>
>>> I tried this with:
>>> auto t = type.getTypePtr();
>>> auto tt = dyn_cast<TypedefType>(t);
>>> while(tt) {
>>>   tt->getDecl()->dumpColor();
>>>   auto x = tt->getDecl()->getNameAsString();
>>>   tt = dyn_cast<TypedefType>(tt->desugar().getTypePtr());
>>> }
>>>
>>> It appeared to work fine when the typedef was at global scope, but when
>>> I put the typedef in a namespace the first dyn_cast returned nullptr.
>>>
>>
>> Right, in that case you will have an ElaboratedType representing the
>> nested name specifier written in the source, which desugars to the
>> TypedefType. Clang has a very rich modeling of type sugar, and you should
>> expect to see things other than TypedefTypes in your walk.
>>
>> Depending on what you're trying to do, you might want to consider
>> visiting the type with a RecursiveASTVisitor or repeatedly calling
>> getSingleStepDesugaredType to walk the desugarings of the type, or changing
>> your dyn_cast<TypedefType>(x) calls into x.getAs<TypedefType>() (which will
>> find the minimally-desugared typedef type in the single-step desugaring
>> sequence for x).
>>
>
> I tried using getSingleStepDesugaredType with this code:
> namespace Test
> {
>    typedef int X;
>    typedef X Y;
>    typedef Y Z;
> }
> Test::Z i;
>
>
> std::vector<std::string> names;
> names.push_back(type.getAsString());
> while(true)
>  {
>   type = type.getSingleStepDesugaredType(*result.Context);
>   names.push_back(type.getAsString());
> }
>
> getAsString() on the QualType returned this chain:
> Test::Z
> Z
> Y
> X
> int
>
> Ideally I would get this:
> Test::Z
> Test::Y
> Test::X
> int
>

You could check if each type is a TypedefType, grab its TypedefNameDecl,
and get the corresponding fully-qualified name. Clang's type sugar nodes
track how the type was written, and that's what you're seeing above.


> How would I use a RecursiveASTVisitor to walk just the type?  I can figure
> it out for an entire AST.
>

The same way, but start the recursion by calling TraverseType instead of
TraverseDecl. Note that this will recursively visit all of the AST "owned"
by that type, which may be more than you want.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20151130/240c3699/attachment.html>


More information about the cfe-dev mailing list