Allow declarations in first clause of for loop (C99).

This commit is contained in:
Stephen Heumann 2018-04-01 16:48:11 -05:00
parent 275e1f080b
commit caabb5addf
3 changed files with 24 additions and 10 deletions

2
CC.pas
View File

@ -115,7 +115,7 @@ while token.kind <> eofsy do begin {compile the program}
structsy,unionsy,typedef,voidsy,inlinesy,volatilesy, structsy,unionsy,typedef,voidsy,inlinesy,volatilesy,
constsy,ident,asmsy,pascalsy,asmsy,segmentsy]) constsy,ident,asmsy,pascalsy,asmsy,segmentsy])
then then
DoDeclaration(false) DoDeclaration(false, false)
else begin else begin
Error(26); Error(26);
NextToken; NextToken;

View File

@ -27,12 +27,13 @@ uses CCommon, Table, MM, CGI, Scanner, Header, Symbol, Expression, Asm;
{---------------------------------------------------------------} {---------------------------------------------------------------}
procedure DoDeclaration (doingPrototypes: boolean); procedure DoDeclaration (doingPrototypes, autoOrRegisterOnly: boolean);
{ process a variable or function declaration } { process a variable or function declaration }
{ } { }
{ parameters: } { parameters: }
{ doingPrototypes - are we processing a parameter list? } { doingPrototypes - are we processing a parameter list? }
{ autoOrRegisterOnly - limit storage classes allowed? }
procedure DoStatement; procedure DoStatement;
@ -601,11 +602,20 @@ var
if c99Scope then PushTable; if c99Scope then PushTable;
Match(lparench,13); {evaluate the start condition} Match(lparench,13); {evaluate the start condition}
if token.kind <> semicolonch then begin if allowMixedDeclarations
and (token.kind in [autosy,registersy,unsignedsy,signedsy,intsy,longsy,
charsy,shortsy,floatsy,doublesy,compsy,extendedsy,enumsy,
structsy,unionsy,typedef,voidsy,volatilesy,constsy,
externsy,staticsy,typedefsy]) then begin
DoDeclaration(false, true)
end {if}
else if token.kind <> semicolonch then begin
Expression(normalExpression, [semicolonch]); Expression(normalExpression, [semicolonch]);
Gen0t(pc_pop, UsualUnaryConversions); Gen0t(pc_pop, UsualUnaryConversions);
end; {if} Match(semicolonch,22);
Match(semicolonch,22); end {else if}
else
NextToken;
Gen1(dc_lab, forLoop); {this label points to the condition} Gen1(dc_lab, forLoop); {this label points to the condition}
if token.kind <> semicolonch then {handle the loop test} if token.kind <> semicolonch then {handle the loop test}
@ -1385,7 +1395,7 @@ var
typedef,voidsy,volatilesy,constsy]) typedef,voidsy,volatilesy,constsy])
then begin then begin
lLastParameter := lastParameter; lLastParameter := lastParameter;
DoDeclaration(true); DoDeclaration(true, false);
lastParameter := lLastParameter; lastParameter := lLastParameter;
if protoType <> nil then begin if protoType <> nil then begin
wp := pointer(Malloc(sizeof(parameterRecord))); wp := pointer(Malloc(sizeof(parameterRecord)));
@ -3002,7 +3012,7 @@ end; {TypeSpecifier}
{-- Externally available subroutines ---------------------------} {-- Externally available subroutines ---------------------------}
procedure DoDeclaration {doingPrototypes: boolean}; procedure DoDeclaration {doingPrototypes, autoOrRegisterOnly: boolean};
{ process a variable or function declaration } { process a variable or function declaration }
{ } { }
@ -3272,6 +3282,9 @@ if token.kind in [autosy,externsy,registersy,staticsy,typedefsy] then begin
end {if} end {if}
else if storageClass in [staticsy,typedefsy] then else if storageClass in [staticsy,typedefsy] then
useGlobalPool := true; useGlobalPool := true;
if autoOrRegisterOnly then
if not (storageClass in [autosy,registersy]) then
Error(127);
NextToken; NextToken;
end; {if} end; {if}
isAsm := false; isAsm := false;
@ -3458,7 +3471,7 @@ if isFunction then begin
floatsy,doublesy,compsy,extendedsy,enumsy, floatsy,doublesy,compsy,extendedsy,enumsy,
structsy,unionsy,typedef,voidsy,volatilesy, structsy,unionsy,typedef,voidsy,volatilesy,
constsy,ident]) then constsy,ident]) then
DoDeclaration(false) DoDeclaration(false, false)
else begin else begin
Error(27); Error(27);
NextToken; NextToken;
@ -3701,7 +3714,7 @@ case statementList^.kind of
then begin then begin
hasStatementNext := false; hasStatementNext := false;
if token.kind <> typedef then if token.kind <> typedef then
DoDeclaration(false) DoDeclaration(false, false)
else begin else begin
lToken := token; lToken := token;
lPrintMacroExpansions := printMacroExpansions; {inhibit token echo} lPrintMacroExpansions := printMacroExpansions; {inhibit token echo}
@ -3712,7 +3725,7 @@ case statementList^.kind of
PutBackToken(nToken, false); PutBackToken(nToken, false);
token := lToken; token := lToken;
if nToken.kind <> colonch then if nToken.kind <> colonch then
DoDeclaration(false) DoDeclaration(false, false)
else else
hasStatementNext := true; hasStatementNext := true;
end {else} end {else}

View File

@ -617,6 +617,7 @@ if list or (numErr <> 0) then begin
124: msg := @'invalid format string'; 124: msg := @'invalid format string';
125: msg := @'format string is not a string literal'; 125: msg := @'format string is not a string literal';
126: msg := @'scope rules may not be changed within a function'; 126: msg := @'scope rules may not be changed within a function';
127: msg := @'illegal storage class for declaration in for loop';
otherwise: Error(57); otherwise: Error(57);
end; {case} end; {case}
writeln(msg^); writeln(msg^);