[cfe-dev] clang-c: determining struct layout

Corey Richardson corey at octayn.net
Sun Jul 13 01:34:50 PDT 2014


The C bindings generator for Rust uses clang-c, and we're hitting an
issue with anonymous unions
(https://github.com/crabtw/rust-bindgen/issues/94). In particular,
given a simple program that will walk the AST and print the
names/kinds of every cursor
(https://gist.github.com/cmr/9adfcc2e65488699f453), the following
code:

struct bar {
    union {
        int a;
        int b;
    };
    union {
        int x;
        int y;
    } z;
};

prints the AST:

__int128_t <TypedefDecl>
__uint128_t <TypedefDecl>
__builtin_va_list <TypedefDecl>
    __va_list_tag <TypeRef>
bar <StructDecl>
    !anonymous <UnionDecl>
        a <FieldDecl>
        b <FieldDecl>
    !anonymous <UnionDecl>
        x <FieldDecl>
        y <FieldDecl>
    z <FieldDecl>
        !anonymous <UnionDecl>
            x <FieldDecl>
            y <FieldDecl>

However, I see no way to determine the layout that `bar` should have.
Moreover, the AST seems to be incomplete. clang -cc1 -ast-dump makes:

TranslationUnitDecl 0x2856dd0 <<invalid sloc>>
|-TypedefDecl 0x28572d0 <<invalid sloc>> __int128_t '__int128'
|-TypedefDecl 0x2857330 <<invalid sloc>> __uint128_t 'unsigned __int128'
|-TypedefDecl 0x2857680 <<invalid sloc>> __builtin_va_list '__va_list_tag [1]'
`-RecordDecl 0x28576d0 <foo.c:1:1, line:10:1> struct bar definition
  |-RecordDecl 0x2857770 <line:2:5, line:5:5> union definition
  | |-FieldDecl 0x2857820 <line:3:9, col:13> a 'int'
  | `-FieldDecl 0x2857880 <line:4:9, col:13> b 'int'
  |-FieldDecl 0x2857920 <line:2:5> 'union bar::<anonymous at foo.c:2:5>'
  |-IndirectFieldDecl 0x2857980 <line:3:13> a 'int'
  | |-Field 0x2857920 '' 'union bar::<anonymous at foo.c:2:5>'
  | `-Field 0x2857820 'a' 'int'
  |-IndirectFieldDecl 0x28579d0 <line:4:13> b 'int'
  | |-Field 0x2857920 '' 'union bar::<anonymous at foo.c:2:5>'
  | `-Field 0x2857880 'b' 'int'
  |-RecordDecl 0x2857a10 <line:6:5, line:9:5> union definition
  | |-FieldDecl 0x289ec20 <line:7:9, col:13> x 'int'
  | `-FieldDecl 0x289ec80 <line:8:9, col:13> y 'int'
  `-FieldDecl 0x289ed20 <line:6:5, line:9:7> z 'union <anonymous union
at foo.c:6:5>':'union bar::<anonymous at foo.c:6:5>'


which has extra IndirectFieldDecl's and one extra FieldDecl. Is it
just a matter of fixing clang-c to expose more of the AST? Is there
something better we should be using for our bindings generator?

Thanks,

-- 
Corey Richardson
http://octayn.net/



More information about the cfe-dev mailing list