FR: allow nested fields for that offsetof-like trick that I almost sure already special-cased.
`PtrUint(@PRec(nil)^.field)` is the way to get the offset of the `field` in the `Rec` that is even used by the compiler codebase.
The most notable thing I found about it is that it becomes **true constant**. (So is it special-cased? Cool.)
However, it works worse for nested fields. The expression `PtrUint(@PType(nil)^.container.field)` can still be used in the procedure body, but does not become true constant, as can be observed in the example below on how it fails to compile explicit **const** declaration and on worse code generated for `MyObjFromB_SubOffsetOf`.
```pascal
type
PBContainer = ^BContainer;
BContainer = record
b: int32;
end;
PMyObj = ^MyObj;
MyObj = record
dummy: int32;
a: int32;
bCtr: BContainer;
end;
const
AOfs = PtrUint(@PMyObj(nil)^.a);
// BOfs = PtrUint(@PMyObj(nil)^.bCtr.b); // does not compile
BOfs = PtrUint(@PMyObj(nil)^.bCtr) + PtrUint(@PBContainer(nil)^.b); // ugly workaround
function MyObjFromA_SubOffsetOf(aPtr: PInt32): PMyObj;
begin
result := pointer(aPtr) - PtrUint(@PMyObj(nil)^.a);
end;
function MyObjFromA_SubConst(aPtr: PInt32): PMyObj;
begin
result := pointer(aPtr) - AOfs;
end;
function MyObjFromB_SubOffsetOf(bPtr: PInt32): PMyObj;
begin
result := pointer(bPtr) - PtrUint(@PMyObj(nil)^.bCtr.b);
end;
function MyObjFromB_SubConst(bPtr: PInt32): PMyObj;
begin
result := pointer(bPtr) - BOfs;
end;
var
mo: MyObj;
begin
writeln('''a'' offset in ''MyObj'': ', AOfs);
writeln('''b'' offset in ''MyObj'': ', BOfs);
writeln('@mo: ', HexStr(@mo));
writeln('@mo recovered from @mo.a by subtracting "offsetof": ', HexStr(MyObjFromA_SubOffsetOf(@mo.a)));
writeln('@mo recovered from @mo.a by subtracting constant: ', HexStr(MyObjFromA_SubConst(@mo.a)));
writeln('@mo recovered from @mo.b by subtracting "offsetof": ', HexStr(MyObjFromB_SubOffsetOf(@mo.bCtr.b)));
writeln('@mo recovered from @mo.b by subtracting constant: ', HexStr(MyObjFromB_SubConst(@mo.bCtr.b)));
end.
```
```
'a' offset in 'MyObj': 4
'b' offset in 'MyObj': 8
@mo: 0000000100012010
@mo recovered from @mo.a by subtracting "offsetof": 0000000100012010
@mo recovered from @mo.a by subtracting constant: 0000000100012010
@mo recovered from @mo.b by subtracting "offsetof": 0000000100012010
@mo recovered from @mo.b by subtracting constant: 0000000100012010
```
`MyObjFromA_SubOffsetOf`:
```nasm
lea rax,[rcx-$04]
ret
```
`MyObjFromA_SubConst`:
```nasm
lea rax,[rcx-$04]
ret
```
`MyObjFromB_SubOffsetOf`:
```nasm
mov rax,rcx
mov edx,$00000008
sub rax,rdx
ret
```
`MyObjFromB_SubConst`:
```nasm
lea rax,[rcx-$08]
ret
```
issue