Move TypeName to be a top-level method in Parser.pas.

As of C11, type names are now used as part of the declaration syntax (in _Alignas and _Atomic specifiers), in addition to their uses in expressions. Moving the TypeName method will allow it to be called when processing declarations.
This commit is contained in:
Stephen Heumann 2020-01-05 21:45:03 -06:00
parent 3121a465f1
commit a9fb1ba482
2 changed files with 180 additions and 184 deletions

View File

@ -244,13 +244,12 @@ procedure Match (kind: tokenEnum; err: integer); extern;
{ err - error number if the expected token is not found }
procedure TypeSpecifier (doingFieldList,isConstant: boolean); extern;
procedure TypeName; extern;
{ handle a type specifier }
{ process a type name (used for casts and sizeof/_Alignof) }
{ }
{ parameters: }
{ doingFieldList - are we processing a field list? }
{ isConstant - did we already find a constsy? }
{ outputs: }
{ typeSpec - pointer to the type }
{-- External unsigned math routines ----------------------------}
@ -1410,175 +1409,6 @@ var
NextToken;
errorFound := true;
end; {Skip}
procedure TypeName;
{ find the type (used for casts and sizeof) }
{ }
{ outputs: }
{ typeSpec - pointer to the type }
var
tl,tp: typePtr; {for creating/reversing the type list}
procedure AbstractDeclarator;
{ process an abstract declarator }
{ }
{ abstract-declarator: }
{ empty-abstract-declarator }
{ nonempty-abstract-declarator }
procedure NonEmptyAbstractDeclarator;
{ process a nonempty abstract declarator }
{ }
{ nonempty-abstract-declarator: }
{ ( nonempty-abstract-declarator ) }
{ abstract-declarator ( ) }
{ abstract-declaraotr [ expression OPT ] }
{ * abstract-declarator }
var
pcount: integer; {paren counter}
tp: typePtr; {work pointer}
begin {NonEmptyAbstractDeclarator}
if token.kind = lparench then begin
NextToken;
if token.kind = rparench then begin
{create a function type}
tp := pointer(Calloc(sizeof(typeRecord)));
{tp^.size := 0;}
{tp^.saveDisp := 0;}
{tp^.isConstant := false;}
tp^.kind := functionType;
{tp^.varargs := false;}
{tp^.prototyped := false;}
{tp^.overrideKR := false;}
{tp^.parameterList := nil;}
{tp^.isPascal := false;}
{tp^.toolNum := 0;}
{tp^.dispatcher := 0;}
tp^.fType := tl;
tl := tp;
NextToken;
end {if}
else begin
{handle a perenthesized type}
if not (token.kind in [lparench,asteriskch,lbrackch]) then
begin
Error(82);
while not (token.kind in
[eofsy,lparench,asteriskch,lbrackch,rparench]) do
NextToken;
errorFound := true;
end; {if}
if token.kind in [lparench,asteriskch,lbrackch] then
NonEmptyAbstractDeclarator;
Match(rparench,12);
end; {else}
end {if token.kind = lparench}
else if token.kind = asteriskch then begin
{create a pointer type}
NextToken;
tp := pointer(Malloc(sizeof(typeRecord)));
tp^.size := cgLongSize;
tp^.saveDisp := 0;
tp^.isConstant := false;
tp^.kind := pointerType;
while token.kind in [constsy,volatilesy] do begin
if token.kind = constsy then
tp^.isConstant := true
else {if token.kind = volatilesy then}
if not (doingSizeof or doingAlignof) then
volatile := true;
NextToken;
end; {while}
AbstractDeclarator;
tp^.fType := tl;
tl := tp;
end {else if token.kind = asteriskch}
else {if token.kind = lbrackch then} begin
{create an array type}
NextToken;
if token.kind = rbrackch then
expressionValue := 0
else begin
Expression(arrayExpression, [rbrackch]);
if expressionValue <= 0 then begin
Error(45);
expressionValue := 1;
end; {if}
end; {else}
tp := pointer(Malloc(sizeof(typeRecord)));
tp^.saveDisp := 0;
tp^.kind := arrayType;
tp^.elements := expressionValue;
tp^.fType := tl;
tl := tp;
Match(rbrackch,24);
end; {else}
if token.kind = lparench then begin
{create a function type}
NextToken;
pcount := 1;
while (token.kind <> eofsy) and (pcount <> 0) do begin
if token.kind = rparench then
pcount := pcount-1
else if token.kind = lparench then
pcount := pcount+1;
NextToken;
end; {while}
tp := pointer(Calloc(sizeof(typeRecord)));
{tp^.size := 0;}
{tp.saveDisp := 0;}
{tp^.isConstant := false;}
tp^.kind := functionType;
{tp^.varargs := false;}
{tp^.prototyped := false;}
{tp^.overrideKR := false;}
{tp^.parameterList := nil;}
{tp^.isPascal := false;}
{tp^.toolNum := 0;}
{tp^.dispatcher := 0;}
tp^.fType := tl;
tl := tp;
end; {if}
end; {NonEmptyAbstractDeclarator}
begin {AbstractDeclarator}
while token.kind in [lparench,asteriskch,lbrackch] do
NonEmptyAbstractDeclarator;
end; {AbstractDeclarator}
begin {TypeName}
{read and process the type specifier}
typeSpec := wordPtr;
TypeSpecifier(false,false);
{handle the abstract-declarator part}
tl := nil; {no types so far}
AbstractDeclarator; {create the type list}
while tl <> nil do begin {reverse the list & compute array sizes}
tp := tl^.aType; {NOTE: assumes aType, pType and fType overlap in typeRecord}
tl^.aType := typeSpec;
if tl^.kind = arrayType then
tl^.size := tl^.elements * typeSpec^.size;
typeSpec := tl;
tl := tp;
end; {while}
end; {TypeName}
begin {ExpressionTree}

View File

@ -41,6 +41,14 @@ procedure DoStatement;
{ process a statement from a function }
procedure TypeName;
{ process a type name (used for casts and sizeof/_Alignof) }
{ }
{ outputs: }
{ typeSpec - pointer to the type }
procedure AutoInit (variable: identPtr; line: integer);
{ generate code to initialize an auto variable }
@ -68,15 +76,6 @@ procedure TermParser;
{ shut down the parser }
procedure TypeSpecifier (doingFieldList,isConstant: boolean);
{ handle a type specifier }
{ }
{ parameters: }
{ doingFieldList - are we processing a field list? }
{ isConstant - did we already find a constsy? }
{---------------------------------------------------------------}
implementation
@ -2532,7 +2531,7 @@ Match(semicolonch, 22);
end; {DoStaticAssert}
procedure TypeSpecifier {doingFieldList,isConstant: boolean};
procedure TypeSpecifier (doingFieldList,isConstant: boolean);
{ handle a type specifier }
{ }
@ -3748,6 +3747,173 @@ inhibitHeader := false;
end; {DoDeclaration}
procedure TypeName;
{ process a type name (used for casts and sizeof/_Alignof) }
{ }
{ outputs: }
{ typeSpec - pointer to the type }
var
tl,tp: typePtr; {for creating/reversing the type list}
procedure AbstractDeclarator;
{ process an abstract declarator }
{ }
{ abstract-declarator: }
{ empty-abstract-declarator }
{ nonempty-abstract-declarator }
procedure NonEmptyAbstractDeclarator;
{ process a nonempty abstract declarator }
{ }
{ nonempty-abstract-declarator: }
{ ( nonempty-abstract-declarator ) }
{ abstract-declarator ( ) }
{ abstract-declaraotr [ expression OPT ] }
{ * abstract-declarator }
var
pcount: integer; {paren counter}
tp: typePtr; {work pointer}
begin {NonEmptyAbstractDeclarator}
if token.kind = lparench then begin
NextToken;
if token.kind = rparench then begin
{create a function type}
tp := pointer(Calloc(sizeof(typeRecord)));
{tp^.size := 0;}
{tp^.saveDisp := 0;}
{tp^.isConstant := false;}
tp^.kind := functionType;
{tp^.varargs := false;}
{tp^.prototyped := false;}
{tp^.overrideKR := false;}
{tp^.parameterList := nil;}
{tp^.isPascal := false;}
{tp^.toolNum := 0;}
{tp^.dispatcher := 0;}
tp^.fType := tl;
tl := tp;
NextToken;
end {if}
else begin
{handle a perenthesized type}
if not (token.kind in [lparench,asteriskch,lbrackch]) then
begin
Error(82);
while not (token.kind in
[eofsy,lparench,asteriskch,lbrackch,rparench]) do
NextToken;
end; {if}
if token.kind in [lparench,asteriskch,lbrackch] then
NonEmptyAbstractDeclarator;
Match(rparench,12);
end; {else}
end {if token.kind = lparench}
else if token.kind = asteriskch then begin
{create a pointer type}
NextToken;
tp := pointer(Malloc(sizeof(typeRecord)));
tp^.size := cgLongSize;
tp^.saveDisp := 0;
tp^.isConstant := false;
tp^.kind := pointerType;
while token.kind in [constsy,volatilesy] do begin
if token.kind = constsy then
tp^.isConstant := true
else {if token.kind = volatilesy then}
volatile := true;
NextToken;
end; {while}
AbstractDeclarator;
tp^.fType := tl;
tl := tp;
end {else if token.kind = asteriskch}
else {if token.kind = lbrackch then} begin
{create an array type}
NextToken;
if token.kind = rbrackch then
expressionValue := 0
else begin
Expression(arrayExpression, [rbrackch]);
if expressionValue <= 0 then begin
Error(45);
expressionValue := 1;
end; {if}
end; {else}
tp := pointer(Malloc(sizeof(typeRecord)));
tp^.saveDisp := 0;
tp^.kind := arrayType;
tp^.elements := expressionValue;
tp^.fType := tl;
tl := tp;
Match(rbrackch,24);
end; {else}
if token.kind = lparench then begin
{create a function type}
NextToken;
pcount := 1;
while (token.kind <> eofsy) and (pcount <> 0) do begin
if token.kind = rparench then
pcount := pcount-1
else if token.kind = lparench then
pcount := pcount+1;
NextToken;
end; {while}
tp := pointer(Calloc(sizeof(typeRecord)));
{tp^.size := 0;}
{tp.saveDisp := 0;}
{tp^.isConstant := false;}
tp^.kind := functionType;
{tp^.varargs := false;}
{tp^.prototyped := false;}
{tp^.overrideKR := false;}
{tp^.parameterList := nil;}
{tp^.isPascal := false;}
{tp^.toolNum := 0;}
{tp^.dispatcher := 0;}
tp^.fType := tl;
tl := tp;
end; {if}
end; {NonEmptyAbstractDeclarator}
begin {AbstractDeclarator}
while token.kind in [lparench,asteriskch,lbrackch] do
NonEmptyAbstractDeclarator;
end; {AbstractDeclarator}
begin {TypeName}
{read and process the type specifier}
typeSpec := wordPtr;
TypeSpecifier(false,false);
{handle the abstract-declarator part}
tl := nil; {no types so far}
AbstractDeclarator; {create the type list}
while tl <> nil do begin {reverse the list & compute array sizes}
tp := tl^.aType; {NOTE: assumes aType, pType and fType overlap in typeRecord}
tl^.aType := typeSpec;
if tl^.kind = arrayType then
tl^.size := tl^.elements * typeSpec^.size;
typeSpec := tl;
tl := tp;
end; {while}
end; {TypeName}
procedure DoStatement;
{ process a statement from a function }