diff --git a/CCommon.pas b/CCommon.pas index 7666d35..07aed11 100644 --- a/CCommon.pas +++ b/CCommon.pas @@ -310,6 +310,7 @@ type unionType : (fieldList: identPtr; {field list} sName: stringPtr; {struct name; for forward refs} constMember: boolean; {does it have a const member?} + flexibleArrayMember: boolean; {does it have a FAM?} ); end; diff --git a/Header.pas b/Header.pas index d93d0b4..38637c7 100644 --- a/Header.pas +++ b/Header.pas @@ -18,7 +18,7 @@ uses CCommon, MM, Scanner, Symbol, CGI; {$segment 'SCANNER'} const - symFileVersion = 17; {version number of .sym file format} + symFileVersion = 18; {version number of .sym file format} var inhibitHeader: boolean; {should .sym includes be blocked?} @@ -1063,6 +1063,7 @@ procedure EndInclude {chPtr: ptr}; end; {while} WriteByte(0); WriteByte(ord(tp^.constMember)); + WriteByte(ord(tp^.flexibleArrayMember)); end; otherwise: ; @@ -1700,6 +1701,7 @@ var ep := ip; end; {while} tp^.constMember := boolean(ReadByte); + tp^.flexibleArrayMember := boolean(ReadByte); end; enumType: ; diff --git a/Parser.pas b/Parser.pas index dc40054..0377ed3 100644 --- a/Parser.pas +++ b/Parser.pas @@ -2847,8 +2847,10 @@ var maxDisp := disp; if variable^.itype^.size = 0 then if (variable^.itype^.kind = arrayType) - and (disp > 0) then {handle flexible array member} - didFlexibleArray := true + and (disp > 0) then begin {handle flexible array member} + didFlexibleArray := true; + tp^.flexibleArrayMember := true; + end {if} else Error(117); end {if} @@ -2868,10 +2870,16 @@ var tPtr := tPtr^.aType; end; {while} if tqConst in tPtr^.qualifiers then - tp^.constMember := true - else if tPtr^.kind in [structType,unionType] then + tp^.constMember := true; + if tPtr^.kind in [structType,unionType] then begin if tPtr^.constMember then tp^.constMember := true; + if tPtr^.flexibleArrayMember then + if kind = structType then + Error(169) + else {if kind = unionType then} + tp^.flexibleArrayMember := true; + end; {if} if token.kind = commach then {allow repeated declarations} begin @@ -3220,6 +3228,7 @@ while token.kind in allowedTokens do begin {structTypePtr^.fieldList := nil;} {structTypePtr^.sName := nil;} {structTypePtr^.constMember := false;} + {structTypePtr^.flexibleArrayMember := false;} structPtr := NewSymbol(ttoken.name, structTypePtr, ident, tagSpace, defined); structTypePtr^.sName := structPtr^.name; @@ -3253,6 +3262,7 @@ while token.kind in allowedTokens do begin {structTypePtr^.fieldList := nil;} {structTypePtr^.sName := nil;} {structTypePtr^.constMember := false;} + {structTypePtr^.flexibleArrayMember := false;} end; {if} if structPtr <> nil then structPtr^.itype := structTypePtr; @@ -3389,6 +3399,9 @@ var Error(123); goto 1; end; {if} + if tp^.aType^.kind in [structType,unionType] then + if tp^.aType^.flexibleArrayMember then + Error(169); end; {if} firstVariable := false; {unspecified sizes are only allowed in } { the first subscript } diff --git a/Scanner.pas b/Scanner.pas index 8a0573a..d59c02a 100644 --- a/Scanner.pas +++ b/Scanner.pas @@ -740,6 +740,7 @@ if list or (numErr <> 0) then begin 166: msg := @'string literals with these prefixes may not be merged'; 167: msg := @'''L''-prefixed character or string constants are not supported by ORCA/C'; 168: msg := @'malformed hexadecimal floating constant'; + 169: msg := @'struct or array may not contain a struct with a flexible array member'; otherwise: Error(57); end; {case} writeln(msg^); diff --git a/Symbol.pas b/Symbol.pas index 228905b..7578a64 100644 --- a/Symbol.pas +++ b/Symbol.pas @@ -1612,6 +1612,8 @@ with defaultStruct^ do begin {(for structures with errors)} qualifiers := []; kind := structType; sName := nil; + constMember := false; + flexibleArrayMember := false; new(fieldList); with fieldlist^ do begin next := nil;