From 5500833180888e1de50ddada4af67cc94b8bc574 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Fri, 25 Nov 2022 22:32:59 -0600 Subject: [PATCH] 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. --- CCommon.pas | 6 +++++- Header.pas | 9 ++++----- Parser.pas | 20 +++++++++++++------- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/CCommon.pas b/CCommon.pas index 6e707e3..8e20e63 100644 --- a/CCommon.pas +++ b/CCommon.pas @@ -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} diff --git a/Header.pas b/Header.pas index 69bf312..a0ba0c2 100644 --- a/Header.pas +++ b/Header.pas @@ -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; diff --git a/Parser.pas b/Parser.pas index 818d2c2..32d601d 100644 --- a/Parser.pas +++ b/Parser.pas @@ -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}