RFR: 7903609: Jextract can not handle some anonymous nested structs [v2]

Jorn Vernee jvernee at openjdk.org
Wed Dec 13 16:38:45 UTC 2023


> Improve the handling of nested anonymous records (structs and unions).
> 
> The current way in which we find the offset of a nested anonymous record is by getting the offset of the first field relative to the first named (or unnamed outermost) parent. However, if the first field doesn't have a name, we bail out, as getting the offset of an unnamed field is not supported by libclang.
> 
> But, we can reliably compute the offset of a nested anonymous record that has at least one named field nested somewhere inside of it, by: 1.) getting the offset of the named field to the first named parent record. 2.) getting the offset of the first named field to the anonymous record for which we want to know the offset (also nested inside the same named parent). 3.) computing the offset of the anonymous record by subtracting the offset found in 2. by the offset found in 1.
> 
> This is also sufficient to address cases like these:
> 
>      struct Foo {
>          char c; // offset = 0
>          struct <anon1> { // offset = 96 - 64 = 32
>              int: 32;
>              struct <anon2> { // offset = 96 - 32 = 64
>                  int: 32;
>                  int x; // offset(Foo) = 96, offset(anon2) = 32, offset(anon1) = 64
>              };
>          };
>      };
> 
> This offset is attached through the `AnonymousStruct` attribute during parsing (which is where we have the Cursors needed to compute these offsets).
> 
> Furthermore, this PR contains some additional improvements:
> - We were manually skipping `BITFIELDS` scoped declaration in the record layout generating code. I've changed this to use a `Skip` that is added to the BITFIELDS declaration, rather than to the individual bitfields inside of it. We can then just look for the `Skip` when generating the layout, and that also handles skipped nested anonymous records correctly (which don't have any named fields).
> - I also noticed that we don't print out the name of a skipped bitfield correctly, because we use the name of the immediate parent to generated the name of the field, which for a bitfield is always empty, since the immediate parent is a scoped BITFIELDS decl. This resulted in warnings about e.g. `.a` being skipped. I'm now propagating the first named parent instead of the immediate parent, which can then be used to generate a valid field name.

Jorn Vernee has updated the pull request incrementally with one additional commit since the last revision:

  propagated varTree as named parent

-------------

Changes:
  - all: https://git.openjdk.org/jextract/pull/159/files
  - new: https://git.openjdk.org/jextract/pull/159/files/a9ddc1bd..c4449593

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jextract&pr=159&range=01
 - incr: https://webrevs.openjdk.org/?repo=jextract&pr=159&range=00-01

  Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod
  Patch: https://git.openjdk.org/jextract/pull/159.diff
  Fetch: git fetch https://git.openjdk.org/jextract.git pull/159/head:pull/159

PR: https://git.openjdk.org/jextract/pull/159


More information about the jextract-dev mailing list