Implement support for bitfields wider than 64 bits#306
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the C→D record translator to support C bitfield sequences whose total width exceeds 64 bits by splitting them into multiple std.bitmanip.bitfields mixins, avoiding D compilation errors when offsets would reach 64.
Changes:
- Split translated bitfield lists into multiple
bitfields!mixins when the cumulative width would exceed 64 bits. - Preserve existing codegen behavior for <=64-bit bitfield sequences while enabling wider overall sequences to compile.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Perhaps time to move to the built in syntax for bit fields. |
|
Okay so I completely rewrote this PR like 4 times till ended up at this version because I kept finding issues. |
|
In case someone ever wants to support 128-bitfields here are some edge case examples: struct Foo {
int a : 30;
long b : 34;
__int128 c : 62;
};
struct Foo {
__int128 a : 100;
int b : 20;
};
struct Foo {
int a : 30;
long b : 35;
__int128 c : 87;
int d : 21;
};
struct Foo {
__int128 a : 50;
__int128 b : 50;
};
struct Foo {
__int128 a : 100;
int b : 20;
short c : 4;
};
struct Foo {
__int128 a : 50;
int : 14;
int b : 10;
__int128 c : 62;
}; |
…tmanip.bitfields This is necessary so that D struct layouts match exactly with C layouts. If we would use std.bitmanip.bitfields then it's layout wouldn't match C. It is possible to implement std.bitmanip.bitfields in a way to match C layout but that's a lot of quite complex code.
C allows to have structs like this:
Currently it's converted like this:
But unfortunately D doesn't support bitfields wider than 64-bits:
This PR fixes this issue by splitting such cases. Producing D code: