mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2025-01-04 02:30:40 +00:00
Simplify some code in DoDeclaration and improve error detection.
This detects errors in the following cases that were previously missed: * A function declaration and definition being part of the same overall declaration, e.g.: void f(void), g(void) {} * A function declaration (not definition) with no declaration specifiers, e.g.: f(void); (Function definitions with no declaration specifiers continue to be accepted by default, consistent with C90 rules.)
This commit is contained in:
parent
7d6b732d23
commit
986a283540
64
Parser.pas
64
Parser.pas
@ -3482,6 +3482,8 @@ procedure DoDeclaration {doingPrototypes: boolean};
|
|||||||
label 1,2,3,4;
|
label 1,2,3,4;
|
||||||
|
|
||||||
var
|
var
|
||||||
|
declarationSpecifierFound: boolean; {has some decl specifier been found?}
|
||||||
|
first: boolean; {handling first declarator in decl?}
|
||||||
fName: stringPtr; {for forming uppercase names}
|
fName: stringPtr; {for forming uppercase names}
|
||||||
i: integer; {loop variable}
|
i: integer; {loop variable}
|
||||||
isAsm: boolean; {has the asm modifier been used?}
|
isAsm: boolean; {has the asm modifier been used?}
|
||||||
@ -3493,14 +3495,12 @@ var
|
|||||||
lp,tlp,tlp2: identPtr; {for tracing parameter list}
|
lp,tlp,tlp2: identPtr; {for tracing parameter list}
|
||||||
lUseGlobalPool: boolean; {local copy of useGlobalPool}
|
lUseGlobalPool: boolean; {local copy of useGlobalPool}
|
||||||
nextPdisp: integer; {for calculating parameter disps}
|
nextPdisp: integer; {for calculating parameter disps}
|
||||||
noFDefinitions: boolean; {are function definitions inhibited?}
|
|
||||||
p1,p2,p3: parameterPtr; {for reversing prototyped parameters}
|
p1,p2,p3: parameterPtr; {for reversing prototyped parameters}
|
||||||
variable: identPtr; {pointer to the variable being declared}
|
variable: identPtr; {pointer to the variable being declared}
|
||||||
fnType: typePtr; {function type}
|
fnType: typePtr; {function type}
|
||||||
segType: integer; {segment type}
|
segType: integer; {segment type}
|
||||||
tp: typePtr; {for tracing type lists}
|
tp: typePtr; {for tracing type lists}
|
||||||
tk: tokenType; {work token}
|
tk: tokenType; {work token}
|
||||||
typeFound: boolean; {has some type specifier been found?}
|
|
||||||
startLine: longint; {line where this declaration starts}
|
startLine: longint; {line where this declaration starts}
|
||||||
declSpecifiers: declSpecifiersRecord; {type & specifiers for the declaration}
|
declSpecifiers: declSpecifiersRecord; {type & specifiers for the declaration}
|
||||||
|
|
||||||
@ -3700,12 +3700,11 @@ if token.kind = _Static_assertsy then begin
|
|||||||
goto 4;
|
goto 4;
|
||||||
end; {if}
|
end; {if}
|
||||||
lDoingParameters := doingParameters; {record the status}
|
lDoingParameters := doingParameters; {record the status}
|
||||||
noFDefinitions := false; {are function definitions inhibited?}
|
first := true; {preparing to handle first declarator}
|
||||||
if doingPrototypes then {prototypes implies a parm list}
|
if doingPrototypes then {prototypes implies a parm list}
|
||||||
doingParameters := true
|
doingParameters := true
|
||||||
else
|
else
|
||||||
lastParameter := nil; {init parm list if we're not doing prototypes}
|
lastParameter := nil; {init parm list if we're not doing prototypes}
|
||||||
isFunction := false; {assume it's not a function}
|
|
||||||
startLine := lineNumber;
|
startLine := lineNumber;
|
||||||
if not doingFunction then {handle any segment statements}
|
if not doingFunction then {handle any segment statements}
|
||||||
while token.kind = segmentsy do
|
while token.kind = segmentsy do
|
||||||
@ -3713,7 +3712,7 @@ if not doingFunction then {handle any segment statements}
|
|||||||
inhibitHeader := true; {block imbedded includes in headers}
|
inhibitHeader := true; {block imbedded includes in headers}
|
||||||
lUseGlobalPool := useGlobalPool;
|
lUseGlobalPool := useGlobalPool;
|
||||||
{handle a TypeSpecifier/declarator}
|
{handle a TypeSpecifier/declarator}
|
||||||
typeFound := token.kind in declarationSpecifiersElement;
|
declarationSpecifierFound := token.kind in declarationSpecifiersElement;
|
||||||
declaredTagOrEnumConst := false;
|
declaredTagOrEnumConst := false;
|
||||||
DeclarationSpecifiers(declSpecifiers, declarationSpecifiersElement, 176);
|
DeclarationSpecifiers(declSpecifiers, declarationSpecifiersElement, 176);
|
||||||
isPascal := pascalsy in declSpecifiers.declarationModifiers;
|
isPascal := pascalsy in declSpecifiers.declarationModifiers;
|
||||||
@ -3725,6 +3724,9 @@ if token.kind = semicolonch then
|
|||||||
if not doingPrototypes then
|
if not doingPrototypes then
|
||||||
if not declaredTagOrEnumConst then
|
if not declaredTagOrEnumConst then
|
||||||
Error(176);
|
Error(176);
|
||||||
|
|
||||||
|
3:
|
||||||
|
isFunction := false; {assume it's not a function}
|
||||||
variable := nil;
|
variable := nil;
|
||||||
Declarator(declSpecifiers, variable, variableSpace, doingPrototypes);
|
Declarator(declSpecifiers, variable, variableSpace, doingPrototypes);
|
||||||
if variable = nil then begin
|
if variable = nil then begin
|
||||||
@ -3738,21 +3740,17 @@ if variable = nil then begin
|
|||||||
goto 1;
|
goto 1;
|
||||||
end; {if}
|
end; {if}
|
||||||
|
|
||||||
{make sure variables have some type info}
|
|
||||||
if isFunction then begin
|
|
||||||
if not typeFound then
|
|
||||||
if (lint & lintNoFnType) <> 0 then
|
|
||||||
if (lint & lintC99Syntax) = 0 then
|
|
||||||
Error(104);
|
|
||||||
end {if}
|
|
||||||
else
|
|
||||||
if not typeFound then
|
|
||||||
Error(26);
|
|
||||||
|
|
||||||
3:
|
|
||||||
{handle a function declaration}
|
{handle a function declaration}
|
||||||
if isFunction then begin
|
if isFunction then begin
|
||||||
|
|
||||||
|
if not declarationSpecifierFound then
|
||||||
|
if first then
|
||||||
|
if doingPrototypes or (token.kind in [commach,semicolonch]) then
|
||||||
|
Error(26)
|
||||||
|
else
|
||||||
|
if (lint & lintNoFnType) <> 0 then
|
||||||
|
if (lint & lintC99Syntax) = 0 then
|
||||||
|
Error(104);
|
||||||
if doingParameters then {a function cannot be a parameter}
|
if doingParameters then {a function cannot be a parameter}
|
||||||
Error(28);
|
Error(28);
|
||||||
fnType := variable^.itype; {get the type of the function}
|
fnType := variable^.itype; {get the type of the function}
|
||||||
@ -3834,19 +3832,7 @@ if isFunction then begin
|
|||||||
else if (token.kind = commach) and (not doingPrototypes) then begin
|
else if (token.kind = commach) and (not doingPrototypes) then begin
|
||||||
PopTable; {pop the symbol table}
|
PopTable; {pop the symbol table}
|
||||||
NextToken; {allow further declarations}
|
NextToken; {allow further declarations}
|
||||||
variable := nil;
|
first := false;
|
||||||
isFunction := false;
|
|
||||||
Declarator(declSpecifiers, variable, variableSpace, doingPrototypes);
|
|
||||||
if variable = nil then begin
|
|
||||||
inhibitHeader := false;
|
|
||||||
if token.kind = semicolonch then
|
|
||||||
NextToken
|
|
||||||
else begin
|
|
||||||
Error(22);
|
|
||||||
SkipStatement;
|
|
||||||
end; {else}
|
|
||||||
goto 1;
|
|
||||||
end; {if}
|
|
||||||
goto 3;
|
goto 3;
|
||||||
end {else if}
|
end {else if}
|
||||||
else begin
|
else begin
|
||||||
@ -3866,7 +3852,7 @@ if isFunction then begin
|
|||||||
|
|
||||||
{local declaration}
|
{local declaration}
|
||||||
else begin
|
else begin
|
||||||
if noFDefinitions then
|
if not first then
|
||||||
Error(22);
|
Error(22);
|
||||||
ftype := fnType^.ftype; {record the type of the function}
|
ftype := fnType^.ftype; {record the type of the function}
|
||||||
while fType^.kind = definedType do
|
while fType^.kind = definedType do
|
||||||
@ -4037,7 +4023,9 @@ if isFunction then begin
|
|||||||
|
|
||||||
{handle a variable declaration}
|
{handle a variable declaration}
|
||||||
else {if not isFunction then} begin
|
else {if not isFunction then} begin
|
||||||
noFDefinitions := true;
|
if not declarationSpecifierFound then
|
||||||
|
if first then
|
||||||
|
Error(26);
|
||||||
if alignmentSpecified then
|
if alignmentSpecified then
|
||||||
if declSpecifiers.storageClass in [typedefsy,registersy] then
|
if declSpecifiers.storageClass in [typedefsy,registersy] then
|
||||||
Error(142);
|
Error(142);
|
||||||
@ -4077,17 +4065,7 @@ else {if not isFunction then} begin
|
|||||||
end; {if}
|
end; {if}
|
||||||
if (token.kind = commach) and (not doingPrototypes) then begin
|
if (token.kind = commach) and (not doingPrototypes) then begin
|
||||||
NextToken; {allow multiple variables on one line}
|
NextToken; {allow multiple variables on one line}
|
||||||
variable := nil;
|
first := false;
|
||||||
Declarator(declSpecifiers, variable, variableSpace, doingPrototypes);
|
|
||||||
if variable = nil then begin
|
|
||||||
if token.kind = semicolonch then
|
|
||||||
NextToken
|
|
||||||
else begin
|
|
||||||
Error(22);
|
|
||||||
SkipStatement;
|
|
||||||
end; {else}
|
|
||||||
goto 1;
|
|
||||||
end; {if}
|
|
||||||
goto 3;
|
goto 3;
|
||||||
end; {if}
|
end; {if}
|
||||||
if doingPrototypes then begin
|
if doingPrototypes then begin
|
||||||
|
Loading…
Reference in New Issue
Block a user