Basic code to handle struct/union designators.

This does not deal with filling yet.
This commit is contained in:
Stephen Heumann 2022-11-27 23:20:52 -06:00
parent def9e56e8e
commit 250a6361c1
1 changed files with 57 additions and 28 deletions

View File

@ -2366,7 +2366,7 @@ var
{ designator in a designator list? }
{ noFill - if set, do not fill empty space with zeros }
label 1;
label 1,2;
var
bitCount: integer; {# of bits in a union}
@ -2374,6 +2374,7 @@ var
count,maxCount: longint; {for tracking the size of an initializer}
ep: tokenPtr; {for forming string expression}
fillSize: longint; {size to fill with zeros}
hasNestedDesignator: boolean; {nested designator in current designation?}
iPtr: initializerPtr; {for creating an initializer entry}
ip: identPtr; {for tracing field lists}
kind: typeKind; {base type of an initializer}
@ -2382,7 +2383,6 @@ var
maxDisp: longint; {maximum disp value so far}
newDisp: longint; {new disp set by a designator}
setNoFill: boolean; {set noFill on recursive calls?}
skipToNext: boolean; {skip to next array/struct element?}
startingDisp: longint; {disp at start of this term}
stringElementType: typePtr; {element type of string literal}
stringLength: integer; {elements in a string literal}
@ -2586,7 +2586,7 @@ var
maxDisp := disp;
if token.kind <> rbracech then
repeat
skipToNext := false;
hasNestedDesignator := false;
if token.kind = lbrackch then begin
if not (braces or (nestedDesignator and (disp=startingDisp)))
then begin
@ -2618,15 +2618,13 @@ var
end; {if}
setNoFill := true;
disp := newDisp;
if token.kind in [dotch,lbrackch] then begin
InitializeTerm(ktp, 0, 0, false, true, true);
skipToNext := true;
end {if}
if token.kind in [dotch,lbrackch] then
hasNestedDesignator := true
else
Match(eqch, 182);
end; {if}
if not skipToNext then
InitializeTerm(ktp, 0, 0, false, false, setNoFill);
InitializeTerm(ktp, 0, 0, false, hasNestedDesignator,
setNoFill or hasNestedDesignator);
if disp > maxDisp then
maxDisp := disp;
count := count+1;
@ -2675,21 +2673,47 @@ var
count := tp^.size;
ip := tp^.fieldList;
bitCount := 0;
maxDisp := disp;
lSuppressMacroExpansions := suppressMacroExpansions;
while (ip <> nil) and (ip^.itype^.size > 0) do begin
if ip^.isForwardDeclared then
while true do begin
if (ip <> nil) and ip^.isForwardDeclared then
ResolveForwardReference(ip);
if token.kind = rbracech then begin {initialize this field to 0}
suppressMacroExpansions := true; {inhibit token echo}
PutBackToken(token, false);
PutBackToken(token, false);
token.kind := intconst;
token.class := intConstant;
token.ival := 0;
PutBackToken(token, false);
token.kind := lbracech;
token.class := reservedSymbol;
if token.kind = rbracech then {fill remainder with zeros}
goto 2;
hasNestedDesignator := false;
if token.kind = dotch then begin
if not (braces or (nestedDesignator and (disp=startingDisp)))
then begin
skipComma := true;
goto 1;
end; {if}
NextToken;
if token.kind = ident then begin
ip := tp^.fieldList;
done := false;
while (ip <> nil) and not done do
if ip^.name^ = token.name^ then
done := true
else
ip := ip^.next;
if ip = nil then
Error(81);
NextToken;
{TODO if ip is an anonymous member field ...}
{TODO fill}
if token.kind in [dotch,lbrackch] then begin
hasNestedDesignator := true;
end {if}
else
Match(eqch, 182);
end {if}
else begin
Error(9);
ip := nil;
end; {else}
end; {if}
if (ip = nil) or (ip^.itype^.size = 0) then
goto 2;
if ip^.bitSize = 0 then
if bitCount > 0 then begin
InitializeBitField;
@ -2698,8 +2722,9 @@ var
bitCount := 0;
disp := startingDisp + tp^.size - count;
end; {if}
InitializeTerm(ip^.itype, ip^.bitsize, ip^.bitdisp, false, false,
setNoFill);
disp := startingDisp + ip^.disp;
InitializeTerm(ip^.itype, ip^.bitsize, ip^.bitdisp, false,
hasNestedDesignator, setNoFill or hasNestedDesignator);
if ip^.bitSize <> 0 then begin
bitCount := bitCount + ip^.bitSize;
if bitCount > maxBitField then begin
@ -2710,6 +2735,8 @@ var
else begin
count := count-ip^.itype^.size;
end; {else}
if disp > maxDisp then
maxDisp := disp;
{ writeln('Initializer: ', ip^.bitsize:10, ip^.bitdisp:10, bitCount:10); {debug}
if kind = unionType then
ip := nil
@ -2718,20 +2745,22 @@ var
while (ip <> nil) and ip^.anonMemberField do
ip := ip^.next;
end; {else}
if token.kind = commach then begin
if ip <> nil then
NextToken;
end {if}
if ((ip = nil) or (ip^.itype^.size = 0)) and not braces then
goto 2;
{TODO need other code to disallow dual commas before right brace?}
if token.kind = commach then
NextToken
else if token.kind <> rbracech then
ip := nil;
end; {while}
if bitCount > 0 then begin
2: if bitCount > 0 then begin
InitializeBitField;
bitCount := (bitCount+7) div 8;
count := count-bitCount;
bitCount := 0;
disp := startingDisp + tp^.size - count;
end; {if}
{TODO fill as appropriate in auto case too}
if count > 0 then
if variable^.storage in [external,global,private] then
Fill(count, sCharPtr);