Allow "static inline" function declarations.

This should give C99-compatible behavior, as far as it goes. The functions aren't actually inlined, but that's just a quality-of-implementation issue. No C standard requires actual inlining.

Non-static inline functions are still not supported. The C99 semantics for them are more complicated, and they're less widely used, so they're a lower priority for now.

The "inline" function specifier can currently only come after the "static" storage class specifier. This relates to a broader issue where not all legal orderings of declaration specifiers are supported.

Since "inline" was already treated as a keyword in ORCA/C, this shouldn't create any extra compatibility issues for C89 code.
This commit is contained in:
Stephen Heumann 2017-06-18 01:32:54 -05:00
parent 6ea43d34a1
commit 227731a1a8
3 changed files with 15 additions and 4 deletions

2
CC.pas
View File

@ -112,7 +112,7 @@ while token.kind <> eofsy do begin {compile the program}
else if (token.kind in [autosy,externsy,registersy,staticsy,typedefsy,
unsignedsy,signedsy,intsy,longsy,charsy,shortsy,
floatsy,doublesy,compsy,extendedsy,enumsy,
structsy,unionsy,typedef,voidsy,volatilesy,
structsy,unionsy,typedef,voidsy,inlinesy,volatilesy,
constsy,ident,asmsy,pascalsy,asmsy,segmentsy])
then
DoDeclaration(false)

View File

@ -2965,6 +2965,7 @@ var
fName: stringPtr; {for forming uppercase names}
i: integer; {loop variable}
isAsm: boolean; {has the asm modifier been used?}
isInline: boolean; {has the inline specifier been used?}
lDoingParameters: boolean; {local copy of doingParameters}
lisPascal: boolean; {local copy of isPascal}
lp,tlp,tlp2: identPtr; {for tracing parameter list}
@ -3217,11 +3218,14 @@ if token.kind in [autosy,externsy,registersy,staticsy,typedefsy] then begin
end; {if}
isAsm := false;
isPascal := false;
while token.kind in [pascalsy,asmsy] do begin
isInline := false;
while token.kind in [pascalsy,asmsy,inlinesy] do begin
if token.kind = pascalsy then
isPascal := true
else
isAsm := true;
else if token.kind = asmsy then
isAsm := true
else {if token.kind = inlinesy then}
isInline := true;
NextToken;
end; {while}
lisPascal := isPascal;
@ -3291,6 +3295,9 @@ if isFunction then begin
SkipStatement;
goto 1;
end; {if}
if isInline then
if storageClass <> staticsy then
Error(120);
if isPascal then begin {reverse prototyped parameters}
p1 := fnType^.parameterList;
if p1 <> nil then begin
@ -3533,6 +3540,8 @@ else {if not isFunction then} begin
functionType: begin tp^.isPascal := true; tp := nil; end;
end; {case}
end; {if}
if isInline then
Error(119);
if token.kind = eqch then begin
if storageClass = typedefsy then
Error(52);

View File

@ -600,6 +600,8 @@ if list or (numErr <> 0) then begin
116: msg := @'missing field name';
117: msg := @'field cannot have incomplete type';
118: msg := @'flexible array must be last member of structure';
119: msg := @'inline specifier is only allowed on functions';
120: msg := @'non-static inline functions are not supported';
otherwise: Error(57);
end; {case}
writeln(msg^);