Record which anon struct/union an anonymous member field came from.

This is preparatory to supporting designated initializers.

Any struct/union type with an anonymous member now forces .sym file generation to end, since we do not have a scheme for serializing this information in a .sym file. It would be possible to do so, but for now we just avoid this situation for simplicity.
This commit is contained in:
Stephen Heumann 2022-11-25 22:32:59 -06:00
parent 3f450bdb80
commit 5500833180
3 changed files with 22 additions and 13 deletions

View File

@ -376,7 +376,11 @@ type
pnext: identPtr); {next parameter}
external: (inlineDefinition: boolean); {(potential) inline definition of function?}
global,private: ();
none: (anonMemberField: boolean); {field from an anonymous struct/union member?}
none: (
case anonMemberField: boolean of {field from an anonymous struct/union member?}
true : (anonMember: identPtr); {containing anonymous struct/union}
false: ();
);
end;
{mini-assembler}

View File

@ -18,7 +18,7 @@ uses CCommon, MM, Scanner, Symbol, CGI;
{$segment 'HEADER'}
const
symFileVersion = 33; {version number of .sym file format}
symFileVersion = 34; {version number of .sym file format}
var
inhibitHeader: boolean; {should .sym includes be blocked?}
@ -1105,10 +1105,9 @@ procedure EndInclude {chPtr: ptr};
WriteByte(ord(ip^.isForwardDeclared));
WriteByte(ord(ip^.class));
WriteByte(ord(ip^.storage));
if ip^.storage = none then
WriteByte(ord(ip^.anonMemberField))
else if ip^.storage = external then
if ip^.storage = external then
WriteByte(ord(ip^.inlineDefinition));
{if ip^.storage = none then ip^.anonMemberField must be false}
end; {WriteIdent}
@ -1810,7 +1809,7 @@ var
sp^.class := tokenEnum(ReadByte);
sp^.storage := storageType(ReadByte);
if sp^.storage = none then
sp^.anonMemberField := boolean(ReadByte)
sp^.anonMemberField := false
else if sp^.storage = external then
sp^.inlineDefinition := boolean(ReadByte);
ReadIdent := sp;

View File

@ -2811,15 +2811,15 @@ var
tPtr: typePtr; {for building types}
anonMember: boolean; {processing an anonymous struct/union?}
procedure AddField(variable: identPtr; anonMemberField: boolean);
procedure AddField(variable: identPtr; anonMember: identPtr);
{ add a field to the field list }
{ }
{ parameters }
{ variable - field to add }
{ checkDups - check for duplicate-named fields }
{ anonMemberField - is this a field from an anonymous }
{ struct/union member? }
{ anonMember - anonymous struct/union that this field }
{ came from, if any (nil if not an anonymous }
{ member field) }
label 1;
@ -2838,7 +2838,12 @@ var
end; {while}
end; {if}
1: variable^.next := fl;
variable^.anonMemberField := anonMemberField;
if anonMember <> nil then begin
variable^.anonMemberField := true;
variable^.anonMember := anonMember;
end {if}
else
variable^.anonMemberField := false;
fl := variable;
end; {AddField}
@ -2876,12 +2881,13 @@ var
variable := NewSymbol(@'~anonymous', tPtr, ident,
fieldListSpace, defined, false);
anonMember := true;
TermHeader; {cannot record anon member in .sym file}
end; {if}
end {if}
else
Declarator(fieldDeclSpecifiers, variable, fieldListSpace, false);
if variable <> nil then {enter the var in the field list}
AddField(variable, false);
AddField(variable, nil);
end; {if}
if kind = unionType then begin
disp := 0;
@ -2938,7 +2944,7 @@ var
while tfl <> nil do begin
ufl := pointer(Malloc(sizeof(identRecord)));
ufl^ := tfl^;
AddField(ufl, true);
AddField(ufl, variable);
ufl^.disp := ufl^.disp + disp;
tfl := tfl^.next;
end; {while}