From cd9931a60c2dce731a3dc5afcbd416d638152fe0 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sat, 26 Nov 2022 19:27:17 -0600 Subject: [PATCH] Record displacement from start of object in initializer records. The idea (not yet implemented) is to use this to support out-of-order initialization. For automatic variables, we can just initialize the subobjects in the order that initializers appear. For static variables, we will eventually need to reorder the initializers in order, but this can be done based on their recorded displacements. --- CCommon.pas | 1 + Parser.pas | 58 ++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/CCommon.pas b/CCommon.pas index 68638a8..fff416c 100644 --- a/CCommon.pas +++ b/CCommon.pas @@ -321,6 +321,7 @@ type initializerPtr = ^initializerRecord; {initializers} initializerRecord = record next: initializerPtr; {next record in the chain} + disp: longint; {disp within overall object being initialized} count: integer; {# of duplicate records} bitdisp: integer; {disp in byte (field lists only)} bitsize: integer; {width in bits; 0 for byte sizes} diff --git a/Parser.pas b/Parser.pas index ab4fc3e..16f861f 100644 --- a/Parser.pas +++ b/Parser.pas @@ -1856,6 +1856,7 @@ procedure Initializer (var variable: identPtr); var bitcount: integer; {# if bits initialized} bitvalue: longint; {bit field initializer value} + disp: longint; {disp within overall object being initialized} done: boolean; {for loop termination} errorFound: boolean; {used to remove bad initializations} iPtr,jPtr,kPtr: initializerPtr; {for reversing the list} @@ -1863,6 +1864,23 @@ var luseGlobalPool: boolean; {local copy of useGlobalPool} + procedure InsertInitializerRecord (iPtr: initializerPtr; size: longint); + + { Insert an initializer record in the initializer list } + { } + { parameters: } + { iPtr - the record to insert } + { size - number of bytes initialized by this record } + + begin {InsertInitializerRecord} + iPtr^.disp := disp; + iPtr^.next := variable^.iPtr; + variable^.iPtr := iPtr; +{ writeln('Inserted initializer record with size ', size:1, ' at disp ', disp:1); {debug} + disp := disp + size; + end; {InsertInitializerRecord} + + procedure InitializeBitField; { If bit fields have been initialized, fill them in } @@ -1879,8 +1897,6 @@ var { writeln('InitializeBitField; bitcount = ', bitcount:1); {debug} {create the initializer entry} iPtr := pointer(Malloc(sizeof(initializerRecord))); - iPtr^.next := variable^.iPtr; - variable^.iPtr := iPtr; iPtr^.isConstant := isConstant; iPtr^.count := 1; iPtr^.bitdisp := 0; @@ -1889,12 +1905,12 @@ var iPtr^.iVal := bitvalue; if bitcount <= 8 then iPtr^.basetype := cgUByte - else if bitcount <= 16 then + else if bitcount <= 24 then iPtr^.basetype := cgUWord - else if bitcount > 24 then - iPtr^.basetype := cgULong - else begin {3-byte bitfield: split into two parts} - iPtr^.basetype := cgUWord; + else + iPtr^.basetype := cgULong; + InsertInitializerRecord(iPtr, TypeSize(iPtr^.basetype)); + if bitcount in [17..24] then begin {3-byte bitfield: split into two parts} iPtr^.iVal := bitvalue & $0000FFFF; bitcount := bitcount - 16; bitvalue := bitvalue >> 16; @@ -2042,8 +2058,7 @@ var Expression(initializerExpression, [commach,rparench,rbracech]); if bitsize = 0 then begin iPtr := pointer(Malloc(sizeof(initializerRecord))); - iPtr^.next := variable^.iPtr; - variable^.iPtr := iPtr; + InsertInitializerRecord(iPtr, tp^.size); iPtr^.isConstant := isConstant; iPtr^.count := 1; iPtr^.bitdisp := 0; @@ -2320,8 +2335,7 @@ var {handle auto variables} if bitsize <> 0 then begin iPtr := pointer(Malloc(sizeof(initializerRecord))); - iPtr^.next := variable^.iPtr; - variable^.iPtr := iPtr; + InsertInitializerRecord(iPtr, 0); {TODO should size be 0?} iPtr^.isConstant := isConstant; iPtr^.count := 1; iPtr^.bitdisp := bitdisp; @@ -2367,6 +2381,7 @@ var ktp: typePtr; {array type with definedTypes removed} lSuppressMacroExpansions: boolean;{local copy of suppressMacroExpansions} 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} @@ -2423,8 +2438,6 @@ var {fill a single value} while count <> 0 do begin iPtr := pointer(Calloc(sizeof(initializerRecord))); - iPtr^.next := variable^.iPtr; - variable^.iPtr := iPtr; iPtr^.isConstant := variable^.storage in [external,global,private]; {iPtr^.bitdisp := 0;} {iPtr^.bitsize := 0;} @@ -2461,6 +2474,7 @@ var iPtr^.count := 16384; count := count-16384; end; {else} + InsertInitializerRecord(iPtr, tp^.size * iPtr^.count); end; {while} end; {Fill} @@ -2498,6 +2512,7 @@ var {TODO fill?} goto 1; end; {if} + startingDisp := disp; if kind = arrayType then begin ktp := tp^.atype; while ktp^.kind = definedType do @@ -2522,13 +2537,12 @@ var end; {else if} with ktp^ do begin iPtr := pointer(Malloc(sizeof(initializerRecord))); - iPtr^.next := variable^.iPtr; - variable^.iPtr := iPtr; iPtr^.count := 1; iPtr^.bitdisp := 0; iPtr^.bitsize := 0; iPtr^.isStructOrUnion := false; if (variable^.storage in [external,global,private]) then begin + InsertInitializerRecord(iPtr, token.sval^.length); iPtr^.isConstant := true; iPtr^.basetype := cgString; iPtr^.sval := token.sval; @@ -2543,6 +2557,8 @@ var end; {else if} end {if} else begin + InsertInitializerRecord(iPtr, + tp^.elements * stringElementType^.size); iPtr^.isConstant := false; new(ep); iPtr^.iTree := ep; @@ -2573,8 +2589,10 @@ var Error(183); count := 0; end {if} - else + else begin count := expressionValue; + disp := startingDisp + count * ktp^.size; + end; {else} Match(rbrackch, 24); {TODO if first designator (or expanding array size) and not nestedDesignator then fill in rest with zeros} if token.kind in [dotch,lbrackch] then begin @@ -2647,6 +2665,7 @@ var bitCount := (bitCount+7) div 8; count := count-bitCount; bitCount := 0; + disp := startingDisp + tp^.size - count; end; {if} InitializeTerm(ip^.itype, ip^.bitsize, ip^.bitdisp, false, false); if ip^.bitSize <> 0 then begin @@ -2679,6 +2698,7 @@ var bitCount := (bitCount+7) div 8; count := count-bitCount; bitCount := 0; + disp := startingDisp + tp^.size - count; end; {if} if count > 0 then if variable^.storage in [external,global,private] then @@ -2717,6 +2737,7 @@ var begin {Initializer} bitcount := 0; {set up for bit fields} bitvalue := 0; +disp := 0; {start at beginning of the object} errorFound := false; {no errors found so far} luseGlobalPool := useGlobalPool; {use global memory for global vars} useGlobalPool := (variable^.storage in [external,global,private]) @@ -4489,6 +4510,11 @@ var begin {Initialize} + if disp <> iptr^.disp then + if count = iptr^.count then begin + writeln('Mismatched disp from ',id^.name^,': ', iptr^.disp:1, ' vs ', disp:1); + Error(57); + end; {debug} while itype^.kind = definedType do itype := itype^.dType; case itype^.kind of