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

Jorn Vernee jvernee at openjdk.org
Wed Dec 13 18:14:38 UTC 2023


On Wed, 13 Dec 2023 18:04:41 GMT, Jorn Vernee <jvernee at openjdk.org> wrote:

>> 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:
> 
>   add short-circuiting version of Cursor::forEach

I've turned on verbose output for failed jtreg tests: https://github.com/openjdk/jextract/pull/159/commits/363f04a1c9e4dc11c5398a46b980177de5fbd653

So, that I can see why the new test is failing in GHA.

I think this mode is probably good to use in general? (the same as in the JDK).

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

PR Comment: https://git.openjdk.org/jextract/pull/159#issuecomment-1854474071


More information about the jextract-dev mailing list