Reported helper bug for subrange types is still there, but I have found a work around for my use case. Initial goal was to have
bitpacked PGN record inside of another record to achieve dotted field access like this:
J1939CanID.PGN.Value := 100;
J1939CanID.PGN.PS.Value := 255;
J1939CanID.PGN.PF := 122;
J1939CanID.PGN.DP := true;
Unfortunately PGN is 18 bits in length so when put inside of another record it expanded it self to 24 bits, which was bad since I needed 3 Priority bits right after PGN record structure (with side effect that whole record was now 1 byte bigger then original C structure). At first I was able to do it only after I gave up on PGN record (to avoid byte alignment of bitpacked sub-record structure) which looked really ugly:
J1939CanID.PGN := 100;
J1939CanID.PGN_PS.Value := 255;
J1939CanID.PGN_PF := 122;
J1939CanID.PGN_DP := true;
Finally, I have now managed to solve it by multiple overlays and dummy bit inserts, Maybe it will be of use to someone else, so here it is:
program testforum;
{$mode delphi} {$H+}
uses
baseunix;
type
T1939SimplePGN = 0..(1 shl 18)-1;
TJ1939PS = record case byte of
1: (Value: cuint8);
2: (DA: cuint8);
3: (GE: cuint8);
end;
TNewJ1939PGN = bitpacked record case byte of // J1939 PGN (Parameter Group Number), as used in J1939 29 bit CAN ID
1: (Value: T1939SimplePGN; ); // full access helper
2: (PS: TJ1939PS; // 8 bit: PS in PDU2 , else 0 (PDU specific)
PF: cuint8; // 8 bit: PF (PDU format). PDU1 (0..239) indicates a destination address in PS, PDU2 (250-255) indicates extension to PDU Format (PF).
DP: boolean; // 1 bit: DP (Data Page), page selector for PDU (Protocol Data Unit) Format (PF) field. Currently at 0, pointing to Page 0. Page 1 is for future purposes)
R: boolean); // 1 bit: R (Reserved), should always be set to 0 when transmitting messages
end;
TNewJ1939CanID = bitpacked record case byte of
1: ( SA: byte;
case byte of
1: ( PGN: TNewJ1939PGN; ); // PGN's 18 bits expand to 24 bits when used in record
2: ( __DummyPGN: T1939SimplePGN; // so we need __DummyPGN just to skip 18 bits
Priority: 0..7; ); ); // and then put these Priority 3 bits immediately after PGN's 18 bits
2: (Bit: bitpacked array[0..31] of boolean); // bit access helper
3: (Full: cuint32); // full access helper
end;
var
NewJ1939CanID: TNewJ1939CanID;
begin
NewJ1939CanID.PGN.Value := 100;
NewJ1939CanID.PGN.PS.Value := 255;
//NewJ1939CanID.PGN.Value := (1 shl 18)-1;
//NewJ1939CanID.PGN.DP := true;
//NewJ1939CanID.Priority := 7;
WriteLn('BitSizeOf(NewJ1939CanID) = ', BitSizeOf(NewJ1939CanID));
WriteLn('BitSizeOf(NewJ1939CanID.SA) = ', BitSizeOf(NewJ1939CanID.SA));
WriteLn('BitSizeOf(NewJ1939CanID.PGN) = ', BitSizeOf(NewJ1939CanID.PGN));
WriteLn('BitSizeOf(NewJ1939CanID.Priority) = ', BitSizeOf(NewJ1939CanID.Priority));
WriteLn('NewJ1939CanID.PGN.Value = ', NewJ1939CanID.PGN.Value);
WriteLn('NewJ1939CanID.PGN.PS.Value = ', NewJ1939CanID.PGN.PS.Value);
WriteLn('BinStr(NewJ1939CanID.Full, 32) = ', BinStr(NewJ1939CanID.Full, 32));
end.
You can explore comments for more explanation.