mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2024-09-28 10:54:30 +00:00
Implement C11 _Static_assert mechanism.
This allows code to contain static assertions (checked at compile time).
This commit is contained in:
parent
0184e3db7b
commit
6f2eb301e5
3
CC.pas
3
CC.pas
@ -113,7 +113,8 @@ while token.kind <> eofsy do begin {compile the program}
|
|||||||
unsignedsy,signedsy,intsy,longsy,charsy,shortsy,
|
unsignedsy,signedsy,intsy,longsy,charsy,shortsy,
|
||||||
floatsy,doublesy,compsy,extendedsy,enumsy,
|
floatsy,doublesy,compsy,extendedsy,enumsy,
|
||||||
structsy,unionsy,typedef,voidsy,inlinesy,volatilesy,
|
structsy,unionsy,typedef,voidsy,inlinesy,volatilesy,
|
||||||
constsy,ident,asmsy,pascalsy,asmsy,segmentsy])
|
constsy,ident,asmsy,pascalsy,asmsy,segmentsy,
|
||||||
|
_Static_assertsy])
|
||||||
then
|
then
|
||||||
DoDeclaration(false, false)
|
DoDeclaration(false, false)
|
||||||
else begin
|
else begin
|
||||||
|
@ -14,10 +14,17 @@
|
|||||||
#undef assert
|
#undef assert
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void __assert(char *, int, char *);
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
#define assert(expression) (expression) ? ((void) 0) : (__assert(__FILE__, __LINE__, #expression))
|
#define assert(expression) (expression) ? ((void) 0) : (__assert(__FILE__, __LINE__, #expression))
|
||||||
#else
|
#else
|
||||||
#define assert(expression) ((void) 0)
|
#define assert(expression) ((void) 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef __assert__
|
||||||
|
#define __assert__
|
||||||
|
|
||||||
|
extern void __assert(char *, int, char *);
|
||||||
|
|
||||||
|
#define static_assert _Static_assert
|
||||||
|
|
||||||
|
#endif
|
||||||
|
51
Parser.pas
51
Parser.pas
@ -607,7 +607,7 @@ var
|
|||||||
and (token.kind in [autosy,registersy,unsignedsy,signedsy,intsy,longsy,
|
and (token.kind in [autosy,registersy,unsignedsy,signedsy,intsy,longsy,
|
||||||
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]) then begin
|
externsy,staticsy,typedefsy,_Static_assertsy]) then begin
|
||||||
DoDeclaration(false, true)
|
DoDeclaration(false, true)
|
||||||
end {if}
|
end {if}
|
||||||
else if token.kind <> semicolonch then begin
|
else if token.kind <> semicolonch then begin
|
||||||
@ -2513,6 +2513,25 @@ useGlobalPool := luseGlobalPool; {restore useGlobalPool}
|
|||||||
end; {Initializer}
|
end; {Initializer}
|
||||||
|
|
||||||
|
|
||||||
|
procedure DoStaticAssert;
|
||||||
|
|
||||||
|
{ process a static assertion }
|
||||||
|
|
||||||
|
begin {DoStaticAssert}
|
||||||
|
NextToken;
|
||||||
|
Match(lparench, 13);
|
||||||
|
Expression(arrayExpression, [commach]);
|
||||||
|
if (expressionType = nil) or (expressionType^.kind <> scalarType) then
|
||||||
|
Error(18)
|
||||||
|
else if expressionValue = 0 then
|
||||||
|
Error(132);
|
||||||
|
Match(commach, 86);
|
||||||
|
Match(stringconst, 83);
|
||||||
|
Match(rparench, 12);
|
||||||
|
Match(semicolonch, 22);
|
||||||
|
end; {DoStaticAssert}
|
||||||
|
|
||||||
|
|
||||||
procedure TypeSpecifier {doingFieldList,isConstant: boolean};
|
procedure TypeSpecifier {doingFieldList,isConstant: boolean};
|
||||||
|
|
||||||
{ handle a type specifier }
|
{ handle a type specifier }
|
||||||
@ -2551,7 +2570,9 @@ var
|
|||||||
{ }
|
{ }
|
||||||
{ parameters }
|
{ parameters }
|
||||||
{ tp - place to store the type pointer }
|
{ tp - place to store the type pointer }
|
||||||
|
|
||||||
|
label 1;
|
||||||
|
|
||||||
var
|
var
|
||||||
bitDisp: integer; {current bit disp}
|
bitDisp: integer; {current bit disp}
|
||||||
disp: longint; {current byte disp}
|
disp: longint; {current byte disp}
|
||||||
@ -2575,15 +2596,14 @@ var
|
|||||||
maxDisp := 0;
|
maxDisp := 0;
|
||||||
didFlexibleArray := false;
|
didFlexibleArray := false;
|
||||||
fl := nil; {nothing in the field list, yet}
|
fl := nil; {nothing in the field list, yet}
|
||||||
{check for no declarations}
|
|
||||||
if not (token.kind in [unsignedsy,signedsy,intsy,longsy,charsy,shortsy,
|
|
||||||
floatsy,doublesy,compsy,extendedsy,enumsy,structsy,unionsy,typedefsy,
|
|
||||||
typedef,voidsy,constsy,volatilesy]) then
|
|
||||||
Error(26);
|
|
||||||
{while there are entries in the field list...}
|
{while there are entries in the field list...}
|
||||||
while token.kind in [unsignedsy,signedsy,intsy,longsy,charsy,shortsy,floatsy,
|
1: while token.kind in [unsignedsy,signedsy,intsy,longsy,charsy,shortsy,floatsy,
|
||||||
doublesy,compsy,extendedsy,enumsy,structsy,unionsy,typedefsy,typedef,
|
doublesy,compsy,extendedsy,enumsy,structsy,unionsy,typedefsy,typedef,
|
||||||
voidsy,constsy,volatilesy] do begin
|
voidsy,constsy,volatilesy,_Static_assertsy] do begin
|
||||||
|
if token.kind = _Static_assertsy then begin
|
||||||
|
DoStaticAssert;
|
||||||
|
goto 1;
|
||||||
|
end; {if}
|
||||||
typeSpec := wordPtr; {default type specifier is an integer}
|
typeSpec := wordPtr; {default type specifier is an integer}
|
||||||
TypeSpecifier(true,false); {get the type specifier}
|
TypeSpecifier(true,false); {get the type specifier}
|
||||||
if not skipDeclarator then
|
if not skipDeclarator then
|
||||||
@ -2689,7 +2709,9 @@ var
|
|||||||
else
|
else
|
||||||
tp^.size := maxDisp;
|
tp^.size := maxDisp;
|
||||||
tp^.fieldList := ufl;
|
tp^.fieldList := ufl;
|
||||||
end; {if}
|
end {if}
|
||||||
|
else
|
||||||
|
Error(26); {error if no named declarations}
|
||||||
storageClass := lStorageClass; {restore default storage class}
|
storageClass := lStorageClass; {restore default storage class}
|
||||||
isForwardDeclared := lisForwardDeclared; {restore the forward flag}
|
isForwardDeclared := lisForwardDeclared; {restore the forward flag}
|
||||||
doingParameters := ldoingParameters; {restore the parameters flag}
|
doingParameters := ldoingParameters; {restore the parameters flag}
|
||||||
@ -3052,7 +3074,7 @@ procedure DoDeclaration {doingPrototypes, autoOrRegisterOnly: boolean};
|
|||||||
{ parameters: }
|
{ parameters: }
|
||||||
{ doingPrototypes - are we processing a parameter list? }
|
{ doingPrototypes - are we processing a parameter list? }
|
||||||
|
|
||||||
label 1,2,3;
|
label 1,2,3,4;
|
||||||
|
|
||||||
var
|
var
|
||||||
done: boolean; {for loop termination}
|
done: boolean; {for loop termination}
|
||||||
@ -3279,6 +3301,10 @@ var
|
|||||||
|
|
||||||
|
|
||||||
begin {DoDeclaration}
|
begin {DoDeclaration}
|
||||||
|
if token.kind = _Static_assertsy then begin
|
||||||
|
DoStaticAssert;
|
||||||
|
goto 4;
|
||||||
|
end; {if}
|
||||||
lDoingParameters := doingParameters; {record the status}
|
lDoingParameters := doingParameters; {record the status}
|
||||||
noFDefinitions := false; {are function definitions inhibited?}
|
noFDefinitions := false; {are function definitions inhibited?}
|
||||||
typeFound := false; {no explicit type found, yet}
|
typeFound := false; {no explicit type found, yet}
|
||||||
@ -3718,6 +3744,7 @@ else {if not isFunction then} begin
|
|||||||
doingParameters := lDoingParameters; {restore the status}
|
doingParameters := lDoingParameters; {restore the status}
|
||||||
useGlobalPool := lUseGlobalPool;
|
useGlobalPool := lUseGlobalPool;
|
||||||
inhibitHeader := false;
|
inhibitHeader := false;
|
||||||
|
4:
|
||||||
end; {DoDeclaration}
|
end; {DoDeclaration}
|
||||||
|
|
||||||
|
|
||||||
@ -3745,7 +3772,7 @@ case statementList^.kind of
|
|||||||
unsignedsy,signedsy,intsy,longsy,charsy,shortsy,
|
unsignedsy,signedsy,intsy,longsy,charsy,shortsy,
|
||||||
floatsy,doublesy,compsy,extendedsy,enumsy,
|
floatsy,doublesy,compsy,extendedsy,enumsy,
|
||||||
structsy,unionsy,typedef,voidsy,volatilesy,
|
structsy,unionsy,typedef,voidsy,volatilesy,
|
||||||
constsy])
|
constsy,_Static_assertsy])
|
||||||
then begin
|
then begin
|
||||||
hasStatementNext := false;
|
hasStatementNext := false;
|
||||||
if token.kind <> typedef then
|
if token.kind <> typedef then
|
||||||
|
@ -646,6 +646,7 @@ if list or (numErr <> 0) then begin
|
|||||||
129: msg := @'lint: division by zero';
|
129: msg := @'lint: division by zero';
|
||||||
130: msg := @'lint: invalid shift count';
|
130: msg := @'lint: invalid shift count';
|
||||||
131: msg := @'numeric constant is too long';
|
131: msg := @'numeric constant is too long';
|
||||||
|
132: msg := @'static assertion failed';
|
||||||
otherwise: Error(57);
|
otherwise: Error(57);
|
||||||
end; {case}
|
end; {case}
|
||||||
writeln(msg^);
|
writeln(msg^);
|
||||||
|
Loading…
Reference in New Issue
Block a user