From 3121a465f157dcc00646ecfeeb27c316ce4dae7f Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 5 Jan 2020 18:09:26 -0600 Subject: [PATCH] Implement the _Alignof operator (from C11). In ORCA/C, the alignment of all object types is 1. --- Expression.pas | 31 ++++++++++++++++++++++++------- Scanner.pas | 1 + Table.asm | 4 ++-- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/Expression.pas b/Expression.pas index 8efd4be..1acb0ce 100644 --- a/Expression.pas +++ b/Expression.pas @@ -576,6 +576,7 @@ label 1,2,3; var done,done2: boolean; {for loop termination} doingSizeof: boolean; {used to test for a sizeof operator} + doingAlignof: boolean; {used to test for an _Alignof operator} expectingTerm: boolean; {should the next token be a term?} opStack: tokenPtr; {operation stack} parenCount: integer; {# of open parenthesis} @@ -1228,6 +1229,7 @@ var opplusplus, {postfix ++} opminusminus, {postfix --} sizeofsy, {sizeof} + _Alignofsy, {_Alignof (erroneous uses)} castoper, {(type)} typedef, {(type-name)} tildech, {~} @@ -1254,6 +1256,15 @@ var end; {else} op^.left := nil; end {if sizeofsy} + + else if op^.token.kind = _Alignofsy then begin + {error case: operand of _Alignof is not a parenthesized type-name} + Error(36); + op^.token.kind := ulongConst; + op^.token.class := longConstant; + op^.token.lval := 1; + dispose(op^.left); + end {else if _Alignofsy} else if op^.token.kind = castoper then begin class := op^.left^.token.class; @@ -1486,7 +1497,7 @@ var if token.kind = constsy then tp^.isConstant := true else {if token.kind = volatilesy then} - if not doingSizeof then + if not (doingSizeof or doingAlignof) then volatile := true; NextToken; end; {while} @@ -1659,11 +1670,14 @@ if token.kind in startExpression then begin doublesy,compsy,extendedsy,voidsy,enumsy,structsy,unionsy, typedef,constsy,volatilesy,signedsy] then begin doingSizeof := false; + doingAlignof := false; if opStack <> nil then if opStack^.token.kind = sizeofsy then - doingSizeof := true; + doingSizeof := true + else if opStack^.token.kind = _Alignofsy then + doingAlignof := true; TypeName; - if doingSizeof then begin + if doingSizeof or doingAlignof then begin {handle a sizeof operator} op := opStack; @@ -1676,10 +1690,13 @@ if token.kind in startExpression then begin sp^.right := nil; sp^.token.kind := ulongconst; sp^.token.class := longConstant; - sp^.token.lval := typeSpec^.size; + if doingSizeof then + sp^.token.lval := typeSpec^.size + else {if doingAlignof then} + sp^.token.lval := 1; with typeSpec^ do if (size = 0) or ((kind = arrayType) and (elements = 0)) then - Error(49); + Error(133); sp^.next := stack; stack := sp; expectingTerm := false; @@ -1743,7 +1760,7 @@ if token.kind in startExpression then begin errorFound := true; end; {if} if token.kind in {make sure we get what we want} - [plusplusop,minusminusop,sizeofsy,tildech,excch, + [plusplusop,minusminusop,sizeofsy,_Alignofsy,tildech,excch, uasterisk,uminus,uand] then begin if not expectingTerm then begin Error(38); @@ -3999,7 +4016,7 @@ startTerm := [ident,intconst,uintconst,longconst,ulongconst,doubleconst, stringconst]; startExpression:= startTerm + [lparench,asteriskch,andch,plusch,minusch,excch,tildech,sizeofsy, - plusplusop,minusminusop,typedef]; + plusplusop,minusminusop,typedef,_Alignofsy]; end; {InitExpression} end. diff --git a/Scanner.pas b/Scanner.pas index dcd8cd4..a9b9354 100644 --- a/Scanner.pas +++ b/Scanner.pas @@ -647,6 +647,7 @@ if list or (numErr <> 0) then begin 130: msg := @'lint: invalid shift count'; 131: msg := @'numeric constant is too long'; 132: msg := @'static assertion failed'; + 133: msg := @'incomplete or function types may not be used here'; otherwise: Error(57); end; {case} writeln(msg^); diff --git a/Table.asm b/Table.asm index 06a0e38..2120516 100644 --- a/Table.asm +++ b/Table.asm @@ -359,7 +359,7 @@ icp start in comming priority for expression dc i1'200' doubleconst dc i1'200' stringconst dc i1'200' _Alignassy - dc i1'200' _Alignofsy + dc i1'16' _Alignofsy dc i1'200' _Atomicsy dc i1'200' _Boolsy dc i1'200' _Complexsy @@ -524,7 +524,7 @@ isp start in stack priority for expression dc i1'0' doubleconst dc i1'0' stringconst dc i1'0' _Alignassy - dc i1'0' _Alignofsy + dc i1'16' _Alignofsy dc i1'0' _Atomicsy dc i1'0' _Boolsy dc i1'0' _Complexsy