Iterate over struct's fields

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Iterate over struct's fields

Дилян Палаузов via cfe-dev

Hi,

I have following C code

    typedef struct
    {
       unsigned int    speed;
       int             len;
       snake_segment_t body[100];
    } snake_t;

    void f(snake_t snake) {}

And I want to iterate over function `f`'s arguments and in case if they are of struct type (like here), over fields of the struct too.

In Clang AST the structure looks like this:

    |-RecordDecl 0x5611f85ce6c0 <line:45:9, line:52:1> line:45:9 struct definition
    | |-FieldDecl 0x5611f85ce788 <line:47:4, col:20> col:20 referenced speed 'unsigned int'
    | |-FieldDecl 0x5611f85ce860 <line:50:4, col:20> col:20 referenced len 'int'
    | `-FieldDecl 0x5611f85ce9d8 <line:51:4, col:28> col:20 referenced body 'snake_segment_t [100]'

    |-TypedefDecl 0x5611f85cea70 <line:45:1, line:52:3> col:3 referenced snake_t 'struct snake_t':'snake_t'
    | `-ElaboratedType 0x5611f85cea20 'struct snake_t' sugar
    |   `-RecordType 0x5611f85ce750 'snake_t'
    |     `-Record 0x5611f85ce6c0 ''


 First I find FunctionDecl for f, then iterate over its' ParamDecls to find all arguments. But when I retrieve Decl from ParamDecl->getType() to iterate over struct fields, I get the TypedefDecl (in AST). How can I get the real RecordDecl, the one that also has FieldDecls for struct?

Best,
Anahit.


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Iterate over struct's fields

Дилян Палаузов via cfe-dev
Hi,

On Tue, Feb 05, 2019 at 08:38:36PM +0000, "Hayrapetyan, Anahit via cfe-dev" <[hidden email]> wrote:
>  How can I get the real RecordDecl, the one that also has FieldDecls for struct?

Did you try getUnderlyingType()? See
<http://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html>.

Regards,

Miklos

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

signature.asc (201 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Iterate over struct's fields

Дилян Палаузов via cfe-dev

Hi Miklos,

Yes, I tried getUnderlyingType(). Here is the code I have:

 
void iterateTypeFields(const clang::Type* type)
{
    clang::RecordDecl* recordDecl;
    if (auto* typedefType = llvm::dyn_cast<clang::TypedefType>(type)) {
        typedefType->getDecl()->getUnderlyingType()->dump();
        iterateTypeFields(&*typedefType->getDecl()->getUnderlyingType());
    } else if (auto* elaboratedType = llvm::dyn_cast<clang::ElaboratedType>(type)) {
        elaboratedType->getNamedType()->dump();
        iterateTypeFields(&*elaboratedType->getNamedType());
 
    } else if (auto* recordType = llvm::dyn_cast<clang::RecordType>(type)) {
        recordType->dump();
        recordDecl = recordType->getDecl()->getDefinition();
    } else if (type->isStructureType()) {
        recordDecl = type->getAsStructureType()->getDecl();
    } else {
        return;
    }
    int i  = 0;
    for (auto it = recordDecl->field_begin(); it != recordDecl->field_end(); ++it) {
          // Do stuff
 
    }
}

When this code is ran on the example I posted, first I get TypedefType, then its' underlying type is ElaboratedType which getNamedType is the RecordType. So this function is called with TypedefType, then ElaboratedType then RecordType. However when I try to call field_begin function on RecordDecl obtained from RecordType it crashes in clang sources. That's why I'm assuming that I'm doing something wrong here. 
 

Thanks!




From: Miklos Vajna <[hidden email]>
Sent: Wednesday, February 6, 2019 9:46 AM
To: Hayrapetyan, Anahit
Cc: [hidden email]
Subject: Re: [cfe-dev] Iterate over struct's fields
 
Hi,

On Tue, Feb 05, 2019 at 08:38:36PM +0000, "Hayrapetyan, Anahit via cfe-dev" <[hidden email]> wrote:
>  How can I get the real RecordDecl, the one that also has FieldDecls for struct?

Did you try getUnderlyingType()? See
<http://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html>.

Regards,

Miklos

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Iterate over struct's fields

Дилян Палаузов via cfe-dev
Hi,

On Wed, Feb 06, 2019 at 09:36:16AM +0000, "Hayrapetyan, Anahit" <[hidden email]> wrote:
> When this code is ran on the example I posted, first I get
> TypedefType, then its' underlying type is ElaboratedType which
> getNamedType is the RecordType. So this function is called with
> TypedefType, then ElaboratedType then RecordType. However when I try
> to call field_begin function on RecordDecl obtained from RecordType it
> crashes in clang sources.

Did you investigate the backtrace?

Is it possible you try to look up members of a struct which is
forward-declared only?

Regards,

Miklos

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

signature.asc (201 bytes) Download Attachment