mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2024-12-22 07:30:54 +00:00
Handle storage class specifiers in DeclarationSpecifiers.
_Thread_local is recognized but gives a "not supported" error. It could arguably be 'supported' trivially by saying the execution of an ORCA/C program is just one thread and so no special handling is needed, but that likely isn't what someone using it would expect. There would be a possible issue if a "static" or "typedef" storage class specifier occurred after a type specifier that required memory to be allocated for it, because that memory conceptually might be in the local pool, but static objects are processed at the end of the translation unit, so their types need to stick around. In practice, this should not occur, because the local pool isn't currently used for much (in particular, not for statements or declarations in the body of a function). We give an error in case this somehow might occur. In combination with preceding commits, this fixes #14. Declaration specifiers can now appear in any order, as required by the C standards.
This commit is contained in:
parent
fbe44e1852
commit
df029ce06f
67
Parser.pas
67
Parser.pas
@ -164,6 +164,7 @@ var
|
|||||||
skipDeclarator: boolean; {for enum,struct,union with no declarator}
|
skipDeclarator: boolean; {for enum,struct,union with no declarator}
|
||||||
statementList: statementPtr; {list of open statements}
|
statementList: statementPtr; {list of open statements}
|
||||||
savedVolatile: boolean; {saved copy of volatile}
|
savedVolatile: boolean; {saved copy of volatile}
|
||||||
|
doingForLoopClause1: boolean; {doing the first clause of a for loop?}
|
||||||
|
|
||||||
{parameter processing variables}
|
{parameter processing variables}
|
||||||
{------------------------------}
|
{------------------------------}
|
||||||
@ -615,7 +616,9 @@ var
|
|||||||
charsy,shortsy,floatsy,doublesy,compsy,extendedsy,enumsy,
|
charsy,shortsy,floatsy,doublesy,compsy,extendedsy,enumsy,
|
||||||
structsy,unionsy,typedef,voidsy,volatilesy,constsy,
|
structsy,unionsy,typedef,voidsy,volatilesy,constsy,
|
||||||
externsy,staticsy,typedefsy,_Static_assertsy]) then begin
|
externsy,staticsy,typedefsy,_Static_assertsy]) then begin
|
||||||
DoDeclaration(false, true)
|
doingForLoopClause1 := true;
|
||||||
|
DoDeclaration(false, true);
|
||||||
|
doingForLoopClause1 := false;
|
||||||
end {if}
|
end {if}
|
||||||
else if token.kind <> semicolonch then begin
|
else if token.kind <> semicolonch then begin
|
||||||
Expression(normalExpression, [semicolonch]);
|
Expression(normalExpression, [semicolonch]);
|
||||||
@ -2801,6 +2804,41 @@ typeSpecifiers := [];
|
|||||||
typeDone := false;
|
typeDone := false;
|
||||||
while token.kind in allowedTokens do begin
|
while token.kind in allowedTokens do begin
|
||||||
case token.kind of
|
case token.kind of
|
||||||
|
{storage class specifiers}
|
||||||
|
autosy,externsy,registersy,staticsy,typedefsy: begin
|
||||||
|
if storageClass <> ident then begin
|
||||||
|
if typeDone or (typeSpecifiers <> []) then
|
||||||
|
Error(9)
|
||||||
|
else
|
||||||
|
Error(26);
|
||||||
|
end; {if}
|
||||||
|
storageClass := token.kind;
|
||||||
|
if not doingFunction then
|
||||||
|
if token.kind = autosy then
|
||||||
|
Error(62);
|
||||||
|
if doingParameters then begin
|
||||||
|
if token.kind <> registersy then
|
||||||
|
Error(87);
|
||||||
|
end {if}
|
||||||
|
else if storageClass in [staticsy,typedefsy] then begin
|
||||||
|
{Error if we may have allocated type info in local pool.}
|
||||||
|
{This should not come up with current use of MM pools. }
|
||||||
|
if not useGlobalPool then
|
||||||
|
if typeDone then
|
||||||
|
Error(57);
|
||||||
|
useGlobalPool := true;
|
||||||
|
end; {else if}
|
||||||
|
if doingForLoopClause1 then
|
||||||
|
if not (storageClass in [autosy,registersy]) then
|
||||||
|
Error(127);
|
||||||
|
NextToken;
|
||||||
|
end;
|
||||||
|
|
||||||
|
_Thread_localsy: begin
|
||||||
|
Error(139);
|
||||||
|
NextToken;
|
||||||
|
end;
|
||||||
|
|
||||||
{function specifiers}
|
{function specifiers}
|
||||||
inlinesy,_Noreturnsy,asmsy,pascalsy: begin
|
inlinesy,_Noreturnsy,asmsy,pascalsy: begin
|
||||||
myFunctionSpecifiers := myFunctionSpecifiers + [token.kind];
|
myFunctionSpecifiers := myFunctionSpecifiers + [token.kind];
|
||||||
@ -3337,33 +3375,13 @@ if token.kind in [constsy,volatilesy] {handle leading constsy, volatile}
|
|||||||
NextToken;
|
NextToken;
|
||||||
end; {while}
|
end; {while}
|
||||||
end; {if}
|
end; {if}
|
||||||
storageClass := ident; {handle a StorageClassSpecifier}
|
|
||||||
lUseGlobalPool := useGlobalPool;
|
lUseGlobalPool := useGlobalPool;
|
||||||
if token.kind in [autosy,externsy,registersy,staticsy,typedefsy] then begin
|
storageClass := ident;
|
||||||
typeFound := true;
|
|
||||||
storageClass := token.kind;
|
|
||||||
if not doingFunction then
|
|
||||||
if token.kind = autosy then
|
|
||||||
Error(62);
|
|
||||||
if doingParameters then begin
|
|
||||||
if token.kind <> registersy then
|
|
||||||
Error(87);
|
|
||||||
end {if}
|
|
||||||
else if storageClass in [staticsy,typedefsy] then
|
|
||||||
useGlobalPool := true;
|
|
||||||
if autoOrRegisterOnly then
|
|
||||||
if not (storageClass in [autosy,registersy]) then
|
|
||||||
Error(127);
|
|
||||||
NextToken;
|
|
||||||
end; {if}
|
|
||||||
typeSpec := wordPtr; {default type specifier is an integer}
|
typeSpec := wordPtr; {default type specifier is an integer}
|
||||||
{handle a TypeSpecifier/declarator}
|
{handle a TypeSpecifier/declarator}
|
||||||
if token.kind in
|
if token.kind in declarationSpecifiersElement then begin
|
||||||
specifierQualifierListElement+[inlinesy,_Noreturnsy,pascalsy,asmsy] then
|
|
||||||
begin
|
|
||||||
typeFound := true;
|
typeFound := true;
|
||||||
DeclarationSpecifiers(foundConstsy,
|
DeclarationSpecifiers(foundConstsy, declarationSpecifiersElement);
|
||||||
specifierQualifierListElement+[inlinesy,_Noreturnsy,pascalsy,asmsy]);
|
|
||||||
isPascal := pascalsy in functionSpecifiers;
|
isPascal := pascalsy in functionSpecifiers;
|
||||||
isAsm := asmsy in functionSpecifiers;
|
isAsm := asmsy in functionSpecifiers;
|
||||||
isInline := inlinesy in functionSpecifiers;
|
isInline := inlinesy in functionSpecifiers;
|
||||||
@ -4302,6 +4320,7 @@ lastLine := 0; {no pc_lnm generated yet}
|
|||||||
nameFound := false; {no pc_nam generated yet}
|
nameFound := false; {no pc_nam generated yet}
|
||||||
statementList := nil; {no open statements}
|
statementList := nil; {no open statements}
|
||||||
codegenStarted := false; {code generator is not started}
|
codegenStarted := false; {code generator is not started}
|
||||||
|
doingForLoopClause1 := false; {not doing a for loop}
|
||||||
|
|
||||||
{init syntactic classes of tokens}
|
{init syntactic classes of tokens}
|
||||||
{See C17 section 6.7 ff.}
|
{See C17 section 6.7 ff.}
|
||||||
|
@ -653,6 +653,7 @@ if list or (numErr <> 0) then begin
|
|||||||
136: msg := @'complex or imaginary types are not supported by ORCA/C';
|
136: msg := @'complex or imaginary types are not supported by ORCA/C';
|
||||||
137: msg := @'atomic types are not supported by ORCA/C';
|
137: msg := @'atomic types are not supported by ORCA/C';
|
||||||
138: msg := @'unsupported alignment';
|
138: msg := @'unsupported alignment';
|
||||||
|
139: msg := @'thread-local storage is not supported by ORCA/C';
|
||||||
otherwise: Error(57);
|
otherwise: Error(57);
|
||||||
end; {case}
|
end; {case}
|
||||||
writeln(msg^);
|
writeln(msg^);
|
||||||
|
Loading…
Reference in New Issue
Block a user