LCOV - code coverage report
Current view: top level - /mnt/build/buildbot/bld/build-lcov/gcc/m2/gm2-compiler-boot - M2GenGCC.c (source / functions) Coverage Total Hit
Test: gcc.info Lines: 83.6 % 4126 3450
Test Date: 2026-02-28 14:20:25 Functions: 89.9 % 297 267
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* do not edit automatically generated by mc from M2GenGCC.  */
       2              : /* M2GenGCC.mod convert the quadruples into GCC trees.
       3              : 
       4              : Copyright (C) 2001-2026 Free Software Foundation, Inc.
       5              : Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
       6              : 
       7              : This file is part of GNU Modula-2.
       8              : 
       9              : GNU Modula-2 is free software; you can redistribute it and/or modify
      10              : it under the terms of the GNU General Public License as published by
      11              : the Free Software Foundation; either version 3, or (at your option)
      12              : any later version.
      13              : 
      14              : GNU Modula-2 is distributed in the hope that it will be useful, but
      15              : WITHOUT ANY WARRANTY; without even the implied warranty of
      16              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17              : General Public License for more details.
      18              : 
      19              : You should have received a copy of the GNU General Public License
      20              : along with GNU Modula-2; see the file COPYING3.  If not see
      21              : <http://www.gnu.org/licenses/>.  */
      22              : 
      23              : #include "config.h"
      24              : #include "system.h"
      25              : #include "gcc-consolidation.h"
      26              : 
      27              : #include <stdbool.h>
      28              : #   if !defined (PROC_D)
      29              : #      define PROC_D
      30              :        typedef void (*PROC_t) (void);
      31              :        typedef struct { PROC_t proc; } PROC;
      32              : #   endif
      33              : 
      34              : #   if !defined (TRUE)
      35              : #      define TRUE (1==1)
      36              : #   endif
      37              : 
      38              : #   if !defined (FALSE)
      39              : #      define FALSE (1==0)
      40              : #   endif
      41              : 
      42              : #   include "Gmcrts.h"
      43              : #if defined(__cplusplus)
      44              : #   undef NULL
      45              : #   define NULL 0
      46              : #endif
      47              : #define _M2GenGCC_C
      48              : 
      49              : #include "GM2GenGCC.h"
      50              : #   include "GSYSTEM.h"
      51              : #   include "GSymbolTable.h"
      52              : #   include "Gm2tree.h"
      53              : #   include "Ggcctypes.h"
      54              : #   include "GM2Batch.h"
      55              : #   include "GM2LexBuf.h"
      56              : #   include "GM2Code.h"
      57              : #   include "GM2Debug.h"
      58              : #   include "GM2Error.h"
      59              : #   include "GM2MetaError.h"
      60              : #   include "GM2Options.h"
      61              : #   include "GM2Printf.h"
      62              : #   include "GM2Quiet.h"
      63              : #   include "GM2Base.h"
      64              : #   include "GM2Bitset.h"
      65              : #   include "GNameKey.h"
      66              : #   include "GDynamicStrings.h"
      67              : #   include "GFormatStrings.h"
      68              : #   include "GM2System.h"
      69              : #   include "GM2FileName.h"
      70              : #   include "GSymbolConversion.h"
      71              : #   include "GM2StackWord.h"
      72              : #   include "GLists.h"
      73              : #   include "GM2ALU.h"
      74              : #   include "GM2GCCDeclare.h"
      75              : #   include "GM2Range.h"
      76              : #   include "Gm2builtins.h"
      77              : #   include "Gm2expr.h"
      78              : #   include "Gm2decl.h"
      79              : #   include "Gm2statement.h"
      80              : #   include "Gm2type.h"
      81              : #   include "Gm2block.h"
      82              : #   include "Gm2misc.h"
      83              : #   include "Gm2convert.h"
      84              : #   include "Gm2except.h"
      85              : #   include "GM2Quads.h"
      86              : #   include "GM2Check.h"
      87              : #   include "GM2SSA.h"
      88              : #   include "GM2Optimize.h"
      89              : #   include "GM2BasicBlock.h"
      90              : 
      91              : #   define Debugging false
      92              : #   define PriorityDebugging false
      93              : #   define CascadedDebugging false
      94              : typedef struct M2GenGCC_UnaryProcedure_p M2GenGCC_UnaryProcedure;
      95              : 
      96              : typedef struct M2GenGCC_ProcedureCardinal_p M2GenGCC_ProcedureCardinal;
      97              : 
      98              : typedef struct M2GenGCC_BinaryFunction_p M2GenGCC_BinaryFunction;
      99              : 
     100              : typedef struct M2GenGCC_UnaryFunction_p M2GenGCC_UnaryFunction;
     101              : 
     102              : #   define Verbose false
     103              : #   define DebugTokPos false
     104              : #   define DebugTokPos false
     105              : typedef void (*M2GenGCC_UnaryProcedure_t) (unsigned int);
     106              : struct M2GenGCC_UnaryProcedure_p { M2GenGCC_UnaryProcedure_t proc; };
     107              : 
     108              : typedef void (*M2GenGCC_ProcedureCardinal_t) (unsigned int);
     109              : struct M2GenGCC_ProcedureCardinal_p { M2GenGCC_ProcedureCardinal_t proc; };
     110              : 
     111              : typedef tree (*M2GenGCC_BinaryFunction_t) (location_t, tree, tree);
     112              : struct M2GenGCC_BinaryFunction_p { M2GenGCC_BinaryFunction_t proc; };
     113              : 
     114              : typedef tree (*M2GenGCC_UnaryFunction_t) (location_t, tree);
     115              : struct M2GenGCC_UnaryFunction_p { M2GenGCC_UnaryFunction_t proc; };
     116              : 
     117              : static unsigned int Memset;
     118              : static unsigned int Memcpy;
     119              : static unsigned int CurrentQuadToken;
     120              : static unsigned int UnboundedLabelNo;
     121              : static unsigned int LastLine;
     122              : static M2Quads_QuadOperator LastOperator;
     123              : static M2StackWord_StackOfWord ScopeStack;
     124              : static bool NoChange;
     125              : static unsigned int SetTemporaryNo;
     126              : static unsigned int BreakQuad;
     127              : static tree tryBlock;
     128              : static tree handlerBlock;
     129              : 
     130              : /*
     131              :    ConvertQuadsToTree - runs through the quadruple list and converts it into
     132              :                         the GCC tree structure.
     133              : */
     134              : 
     135              : extern "C" void M2GenGCC_ConvertQuadsToTree (unsigned int Start, unsigned int End);
     136              : 
     137              : /*
     138              :    ResolveConstantExpressions - resolves constant expressions from the quadruple list.
     139              :                                 It returns TRUE if one or more constants were folded.
     140              :                                 When a constant symbol value is solved, the call back
     141              :                                 p(sym) is invoked.
     142              : */
     143              : 
     144              : extern "C" bool M2GenGCC_ResolveConstantExpressions (M2GCCDeclare_WalkAction p, M2BasicBlock_BasicBlock bb);
     145              : 
     146              : /*
     147              :    GetHighFromUnbounded - returns a Tree containing the value of
     148              :                           param.HIGH.
     149              : */
     150              : 
     151              : extern "C" tree M2GenGCC_GetHighFromUnbounded (location_t location, unsigned int dim, unsigned int param);
     152              : 
     153              : /*
     154              :    StringToChar - if type=Char and str is a string (of size <= 1)
     155              :                   then convert the string into a character constant.
     156              : */
     157              : 
     158              : extern "C" tree M2GenGCC_StringToChar (tree t, unsigned int type, unsigned int str);
     159              : 
     160              : /*
     161              :    LValueToGenericPtr - returns a Tree representing symbol, sym.
     162              :                         It coerces a lvalue into an internal pointer type
     163              : */
     164              : 
     165              : extern "C" tree M2GenGCC_LValueToGenericPtr (location_t location, unsigned int sym);
     166              : 
     167              : /*
     168              :    ZConstToTypedConst - checks whether op1 and op2 are constants and
     169              :                         coerces, t, appropriately.
     170              : */
     171              : 
     172              : extern "C" tree M2GenGCC_ZConstToTypedConst (tree t, unsigned int op1, unsigned int op2);
     173              : 
     174              : /*
     175              :    PrepareCopyString - returns two trees:
     176              :                        length    number of bytes to be copied (including the nul if room)
     177              :                        srcTreeType the new string type (with the extra nul character).
     178              : 
     179              :                        Pre condition:  destStrType the dest type string.
     180              :                                        src is the original string (without a nul)
     181              :                                        to be copied.
     182              :                        Post condition: TRUE or FALSE is returned.
     183              :                                        if true length and srcTreeType will be assigned
     184              :                                        else length is set to the maximum length to be
     185              :                                             copied and srcTree is set to the max length
     186              :                                             which fits in dest.
     187              : */
     188              : 
     189              : extern "C" bool M2GenGCC_PrepareCopyString (unsigned int tokenno, tree *length, tree *srcTree, unsigned int src, unsigned int destStrType);
     190              : 
     191              : /*
     192              :    ErrorMessageDecl - emit an error message together with declaration fragments of left
     193              :                       and right if they are parameters or variables.
     194              : */
     195              : 
     196              : static void ErrorMessageDecl (unsigned int tok, const char *message_, unsigned int _message_high, unsigned int left, unsigned int right, bool iserror);
     197              : 
     198              : /*
     199              :    IsExportedGcc - returns TRUE if this symbol should be (as far as the middle/backend of GCC)
     200              :                    is concerned, exported.
     201              : */
     202              : 
     203              : static bool IsExportedGcc (unsigned int sym);
     204              : 
     205              : /*
     206              :    IsCompilingMainModule -
     207              : */
     208              : 
     209              : static bool IsCompilingMainModule (unsigned int sym);
     210              : 
     211              : /*
     212              :    CodeLastForIterator - call PerformLastForIterator allowing for
     213              :                          a non constant last iterator value.
     214              : */
     215              : 
     216              : static void CodeLastForIterator (unsigned int quad);
     217              : 
     218              : /*
     219              :    FoldLastForIterator - call PerformLastForIterator providing
     220              :                          all operands are constant and are known by GCC.
     221              : */
     222              : 
     223              : static void FoldLastForIterator (unsigned int quad, M2GCCDeclare_WalkAction p);
     224              : static void PerformLastForIterator (unsigned int quad, M2GCCDeclare_WalkAction p, bool constant);
     225              : 
     226              : /*
     227              :    CodeStatement - A multi-way decision call depending on the current
     228              :                    quadruple.
     229              : */
     230              : 
     231              : static void CodeStatement (unsigned int q);
     232              : 
     233              : /*
     234              :    FindSize - given a Modula-2 symbol sym return a gcc tree
     235              :               constant representing the storage size in bytes.
     236              : */
     237              : 
     238              : static tree FindSize (unsigned int tokenno, unsigned int sym);
     239              : 
     240              : /*
     241              :    FindType - returns the type of, Sym, if Sym is a TYPE then return Sym otherwise return GetType(Sym)
     242              : */
     243              : 
     244              : static unsigned int FindType (unsigned int Sym);
     245              : 
     246              : /*
     247              :    BuildTreeFromInterface - generates a GCC tree from an interface definition.
     248              : */
     249              : 
     250              : static tree BuildTreeFromInterface (unsigned int sym);
     251              : 
     252              : /*
     253              :    BuildTrashTreeFromInterface - generates a GCC string tree from an interface definition.
     254              : */
     255              : 
     256              : static tree BuildTrashTreeFromInterface (unsigned int sym);
     257              : 
     258              : /*
     259              :    CodeInline - InlineOp is a quadruple which has the following format:
     260              : 
     261              :                 InlineOp   NulSym  NulSym  Sym
     262              : */
     263              : 
     264              : static void CodeInline (unsigned int quad);
     265              : 
     266              : /*
     267              :    FoldStatementNote - set CurrentQuadToken to tokennno.
     268              : */
     269              : 
     270              : static void FoldStatementNote (unsigned int tokenno);
     271              : 
     272              : /*
     273              :    CodeStatementNote - set CurrentQuadToken to tokennno and
     274              :                        add a statement note.
     275              : */
     276              : 
     277              : static void CodeStatementNote (unsigned int tokenno);
     278              : 
     279              : /*
     280              :    FoldRange - attempts to fold the range test.
     281              :                --fixme-- complete this.
     282              : */
     283              : 
     284              : static void FoldRange (unsigned int tokenno, unsigned int quad, unsigned int rangeno);
     285              : 
     286              : /*
     287              :    CodeSaveException - op1 := op3(TRUE)
     288              : */
     289              : 
     290              : static void CodeSaveException (unsigned int des, unsigned int exceptionProcedure);
     291              : 
     292              : /*
     293              :    CodeRestoreException - op1 := op3(op1).
     294              : */
     295              : 
     296              : static void CodeRestoreException (unsigned int des, unsigned int exceptionProcedure);
     297              : 
     298              : /*
     299              :    PushScope -
     300              : */
     301              : 
     302              : static void PushScope (unsigned int sym);
     303              : 
     304              : /*
     305              :    PopScope -
     306              : */
     307              : 
     308              : static void PopScope (void);
     309              : 
     310              : /*
     311              :    GetActiveScope -
     312              : */
     313              : 
     314              : static unsigned int GetActiveScope (void);
     315              : 
     316              : /*
     317              :    GetCurrentScopeDescription - returns a description of the current scope.
     318              : */
     319              : 
     320              : static DynamicStrings_String GetCurrentScopeDescription (void);
     321              : 
     322              : /*
     323              :    CodeRange - encode the range test associated with op3.
     324              : */
     325              : 
     326              : static void CodeRange (unsigned int rangeId);
     327              : 
     328              : /*
     329              :    CodeError - encode the error test associated with op3.
     330              : */
     331              : 
     332              : static void CodeError (unsigned int errorId);
     333              : 
     334              : /*
     335              :    CodeModuleScope - ModuleScopeOp is a quadruple which has the following
     336              :                      format:
     337              : 
     338              :                      ModuleScopeOp  _  _  moduleSym
     339              : 
     340              :                      Its purpose is to reset the source file to another
     341              :                      file, hence all line numbers emitted with the
     342              :                      generated code will be relative to this source file.
     343              : */
     344              : 
     345              : static void CodeModuleScope (unsigned int moduleSym);
     346              : 
     347              : /*
     348              :    CodeStartModFile - StartModFileOp is a quadruple which has the following
     349              :                       format:
     350              : 
     351              :                       StartModFileOp  _  _  moduleSym
     352              : 
     353              :                       A new source file has been encountered therefore
     354              :                       set LastLine to 1.
     355              :                       Call pushGlobalScope.
     356              : */
     357              : 
     358              : static void CodeStartModFile (unsigned int moduleSym);
     359              : 
     360              : /*
     361              :    CodeStartDefFile - StartDefFileOp is a quadruple with the following
     362              :                       format:
     363              : 
     364              :                       StartDefFileOp  _  _  moduleSym
     365              : 
     366              :                       A new source file has been encountered therefore
     367              :                       set LastLine to 1.
     368              :                       Call pushGlobalScope.
     369              : */
     370              : 
     371              : static void CodeStartDefFile (unsigned int moduleSym);
     372              : 
     373              : /*
     374              :    CodeEndFile - pops the GlobalScope.
     375              : */
     376              : 
     377              : static void CodeEndFile (void);
     378              : 
     379              : /*
     380              :    CallInnerInit - produce a call to inner module initialization routine.
     381              : */
     382              : 
     383              : static void CallInnerInit (unsigned int moduleSym);
     384              : 
     385              : /*
     386              :    CallInnerFinally - produce a call to inner module finalization routine.
     387              : */
     388              : 
     389              : static void CallInnerFinally (unsigned int moduleSym);
     390              : 
     391              : /*
     392              :    CodeInitStart - emits starting code before the main BEGIN END of the
     393              :                    current module.
     394              : */
     395              : 
     396              : static void CodeInitStart (unsigned int moduleSym, bool CompilingMainModule);
     397              : 
     398              : /*
     399              :    CodeInitEnd - emits terminating code after the main BEGIN END of the
     400              :                  current module.
     401              : */
     402              : 
     403              : static void CodeInitEnd (unsigned int moduleSym, bool CompilingMainModule);
     404              : 
     405              : /*
     406              :    CodeFinallyStart - emits starting code before the main BEGIN END of the
     407              :                       current module.
     408              : */
     409              : 
     410              : static void CodeFinallyStart (unsigned int moduleSym, bool CompilingMainModule);
     411              : 
     412              : /*
     413              :    CodeFinallyEnd - emits terminating code after the main BEGIN END of the
     414              :                     current module.  It also creates the scaffold if the
     415              :                     cflag was not present.
     416              : */
     417              : 
     418              : static void CodeFinallyEnd (unsigned int moduleSym, bool CompilingMainModule);
     419              : 
     420              : /*
     421              :    GetAddressOfUnbounded - returns the address of the unbounded array contents.
     422              : */
     423              : 
     424              : static tree GetAddressOfUnbounded (location_t location, unsigned int param);
     425              : 
     426              : /*
     427              :    GetSizeOfHighFromUnbounded - returns a Tree containing the value of
     428              :                                 param.HIGH * sizeof(unboundedType).
     429              :                                 The number of legal bytes this array
     430              :                                 occupies.
     431              : */
     432              : 
     433              : static tree GetSizeOfHighFromUnbounded (unsigned int tokenno, unsigned int param);
     434              : 
     435              : /*
     436              :    MaybeDebugBuiltinAlloca - if DebugBuiltins is set
     437              :                              then call Builtins.alloca_trace
     438              :                              else call Builtins.alloca.
     439              : */
     440              : 
     441              : static tree MaybeDebugBuiltinAlloca (location_t location, unsigned int tok, tree high);
     442              : 
     443              : /*
     444              :    MaybeDebugBuiltinMemcpy - if DebugBuiltins is set
     445              :                              then call memcpy
     446              :                              else call Builtins.memcpy.
     447              : */
     448              : 
     449              : static tree MaybeDebugBuiltinMemcpy (location_t location, tree src, tree dest, tree nbytes);
     450              : 
     451              : /*
     452              :    MakeCopyUse - make a copy of the unbounded array and alter all references
     453              :                  from the old unbounded array to the new unbounded array.
     454              :                  The parameter, param, contains a RECORD
     455              :                                                      ArrayAddress: ADDRESS ;
     456              :                                                      ArrayHigh   : CARDINAL ;
     457              :                                                   END
     458              :                  we simply declare a new array of size, ArrayHigh
     459              :                  and set ArrayAddress to the address of the copy.
     460              : 
     461              :                  Remember ArrayHigh == sizeof(Array)-sizeof(typeof(array))
     462              :                           so we add 1 for the size and add 1 for a possible <nul>
     463              : */
     464              : 
     465              : static void MakeCopyUse (unsigned int tokenno, unsigned int param);
     466              : 
     467              : /*
     468              :    GetParamAddress - returns the address of parameter, param.
     469              : */
     470              : 
     471              : static tree GetParamAddress (location_t location, unsigned int proc, unsigned int param);
     472              : 
     473              : /*
     474              :    IsUnboundedWrittenTo - returns TRUE if the unbounded parameter
     475              :                           might be written to, or if -funbounded-by-reference
     476              :                           was _not_ specified.
     477              : */
     478              : 
     479              : static bool IsUnboundedWrittenTo (unsigned int proc, unsigned int param);
     480              : 
     481              : /*
     482              :    GetParamSize - returns the size in bytes of, param.
     483              : */
     484              : 
     485              : static tree GetParamSize (unsigned int tokenno, unsigned int param);
     486              : 
     487              : /*
     488              :    DoIsIntersection - jumps to, tLabel, if the ranges i1..i2  j1..j2 overlap
     489              :                       else jump to, fLabel.
     490              : */
     491              : 
     492              : static void DoIsIntersection (unsigned int tokenno, tree ta, tree tb, tree tc, tree td, DynamicStrings_String tLabel, DynamicStrings_String fLabel);
     493              : 
     494              : /*
     495              :    BuildCascadedIfThenElsif - mustCheck contains a list of variables which
     496              :                               must be checked against the address of (proc, param, i).
     497              :                               If the address matches we make a copy of the unbounded
     498              :                               parameter (proc, param) and quit further checking.
     499              : */
     500              : 
     501              : static void BuildCascadedIfThenElsif (unsigned int tokenno, Lists_List mustCheck, unsigned int proc, unsigned int param);
     502              : 
     503              : /*
     504              :    CheckUnboundedNonVarParameter - if non var unbounded parameter is written to
     505              :                                    then
     506              :                                       make a copy of the contents of this parameter
     507              :                                       and use the copy
     508              :                                    else if param
     509              :                                       is type compatible with any parameter, symv
     510              :                                       and at runtime its address matches symv
     511              :                                    then
     512              :                                       make a copy of the contents of this parameter
     513              :                                       and use the copy
     514              :                                    fi
     515              : */
     516              : 
     517              : static void CheckUnboundedNonVarParameter (unsigned int tokenno, Lists_List trashed, unsigned int proc, unsigned int param);
     518              : 
     519              : /*
     520              :    IsParameterWritten - returns TRUE if a parameter, sym, is written to.
     521              : */
     522              : 
     523              : static bool IsParameterWritten (unsigned int proc, unsigned int sym);
     524              : 
     525              : /*
     526              :    SaveNonVarUnboundedParameters - for each var parameter, symv, do
     527              :                                        not just unbounded var parameters, but _all_
     528              :                                          parameters 
     529              :                                       if symv is written to
     530              :                                       then
     531              :                                          add symv to a compile list
     532              :                                       fi
     533              :                                    done
     534              : 
     535              :                                    for each parameter of procedure, symu, do
     536              :                                       if non var unbounded parameter is written to
     537              :                                       then
     538              :                                          make a copy of the contents of this parameter
     539              :                                          and use the copy
     540              :                                       else if
     541              :                                          symu is type compatible with any parameter, symv
     542              :                                          and at runtime its address matches symv
     543              :                                       then
     544              :                                          make a copy of the contents of this parameter
     545              :                                          and use the copy
     546              :                                       fi
     547              :                                    done
     548              : */
     549              : 
     550              : static void SaveNonVarUnboundedParameters (unsigned int tokenno, unsigned int proc);
     551              : 
     552              : /*
     553              :    AutoInitVariable -
     554              : */
     555              : 
     556              : static void AutoInitVariable (location_t location, unsigned int sym);
     557              : 
     558              : /*
     559              :    AutoInitialize - scope will be a procedure, module or defimp.  All pointer
     560              :                     variables are assigned to NIL.
     561              : */
     562              : 
     563              : static void AutoInitialize (location_t location, unsigned int scope);
     564              : 
     565              : /*
     566              :    CodeNewLocalVar - Builds a new frame on the stack to contain the procedure
     567              :                      local variables.
     568              : */
     569              : 
     570              : static void CodeNewLocalVar (unsigned int tokenno, unsigned int CurrentProcedure);
     571              : 
     572              : /*
     573              :    CodeKillLocalVar - removes local variables and returns to previous scope.
     574              : */
     575              : 
     576              : static void CodeKillLocalVar (unsigned int CurrentProcedure);
     577              : 
     578              : /*
     579              :    CodeProcedureScope - start a procedure scope for CurrentProcedure.
     580              : */
     581              : 
     582              : static void CodeProcedureScope (unsigned int CurrentProcedure);
     583              : 
     584              : /*
     585              :    CodeReturnValue - places the operand into the return value space
     586              :                      allocated by the function call.
     587              : */
     588              : 
     589              : static void CodeReturnValue (unsigned int quad);
     590              : 
     591              : /*
     592              :    CodeCall - determines whether the procedure call is a direct call
     593              :               or an indirect procedure call.
     594              : */
     595              : 
     596              : static void CodeCall (unsigned int tokenno, unsigned int procedure);
     597              : 
     598              : /*
     599              :    UseBuiltin - returns a Tree containing the builtin function
     600              :                 and parameters. It should only be called if
     601              :                 CanUseBuiltin or IsProcedureBuiltinAvailable returns TRUE.
     602              : */
     603              : 
     604              : static tree UseBuiltin (unsigned int tokenno, unsigned int Sym);
     605              : 
     606              : /*
     607              :    CodeDirectCall - calls a function/procedure.
     608              : */
     609              : 
     610              : static tree CodeDirectCall (unsigned int tokenno, unsigned int procedure);
     611              : 
     612              : /*
     613              :    CodeIndirectCall - calls a function/procedure indirectly.
     614              : */
     615              : 
     616              : static tree CodeIndirectCall (unsigned int tokenno, unsigned int ProcVar);
     617              : 
     618              : /*
     619              :    ConvertTo - convert gcc tree, t, (which currently represents Modula-2 op3) into
     620              :                a symbol of, type.
     621              : */
     622              : 
     623              : static tree ConvertTo (tree t, unsigned int type, unsigned int op3);
     624              : 
     625              : /*
     626              :    ConvertRHS - convert (t, rhs) into, type.  (t, rhs) refer to the
     627              :                 same entity t is a GCC Tree and, rhs, is a Modula-2
     628              :                 symbol.  It checks for char and strings
     629              :                 first and then the remaining types.
     630              : */
     631              : 
     632              : static tree ConvertRHS (tree t, unsigned int type, unsigned int rhs);
     633              : 
     634              : /*
     635              :    IsCoerceableParameter - returns TRUE if symbol, sym, is a
     636              :                            coerceable parameter.
     637              : */
     638              : 
     639              : static bool IsCoerceableParameter (unsigned int sym);
     640              : 
     641              : /*
     642              :    IsConstProcedure - returns TRUE if, p, is a const procedure.
     643              : */
     644              : 
     645              : static bool IsConstProcedure (unsigned int p);
     646              : 
     647              : /*
     648              :    IsConstant - returns TRUE if symbol, p, is either a const or procedure.
     649              : */
     650              : 
     651              : static bool IsConstant (unsigned int p);
     652              : 
     653              : /*
     654              :    CheckConvertCoerceParameter - ensure that actual parameter is the same as the nth of callee.
     655              : */
     656              : 
     657              : static tree CheckConvertCoerceParameter (unsigned int tokenno, unsigned int nth, unsigned int callee, unsigned int actual);
     658              : 
     659              : /*
     660              :    CheckConstant - checks to see whether we should declare the constant.
     661              : */
     662              : 
     663              : static tree CheckConstant (unsigned int tokenno, unsigned int des, unsigned int expr);
     664              : 
     665              : /*
     666              :    CodeMakeAdr - code the function MAKEADR.
     667              : */
     668              : 
     669              : static void CodeMakeAdr (unsigned int q, unsigned int op1, unsigned int op2, unsigned int op3);
     670              : 
     671              : /*
     672              :    CodeBuiltinFunction - attempts to inline a function. Currently it only
     673              :                          inlines the SYSTEM function MAKEADR.
     674              : */
     675              : 
     676              : static void CodeBuiltinFunction (unsigned int q, unsigned int nth, unsigned int func, unsigned int parameter);
     677              : 
     678              : /*
     679              :    FoldMakeAdr - attempts to fold the function MAKEADR.
     680              : */
     681              : 
     682              : static void FoldMakeAdr (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int q, unsigned int op1, unsigned int op2, unsigned int op3);
     683              : 
     684              : /*
     685              :    doParam - builds the parameter, op3, which is to be passed to
     686              :              procedure, op2.  The number of the parameter is op1.
     687              : */
     688              : 
     689              : static void doParam (unsigned int paramtok, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
     690              : 
     691              : /*
     692              :    FoldBuiltin - attempts to fold the gcc builtin function.
     693              : */
     694              : 
     695              : static void FoldBuiltin (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int q);
     696              : 
     697              : /*
     698              :    FoldBuiltinFunction - attempts to inline a function. Currently it only
     699              :                          inlines the SYSTEM function MAKEADR.
     700              : */
     701              : 
     702              : static void FoldBuiltinFunction (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int q, unsigned int op1, unsigned int op2, unsigned int op3);
     703              : 
     704              : /*
     705              :    CodeParam - builds a parameter list.
     706              :                Note that we can ignore ModeOfAddr as any lvalue will
     707              :                have been created in a preceeding quadruple.
     708              : */
     709              : 
     710              : static void CodeParam (unsigned int quad);
     711              : 
     712              : /*
     713              :    Replace - replace the entry for sym in the double entry bookkeeping with sym/tree.
     714              : */
     715              : 
     716              : static void Replace (unsigned int sym, tree gcc);
     717              : 
     718              : /*
     719              :    CodeFunctValue - retrieves the function return value and assigns it
     720              :                     into a variable.
     721              : */
     722              : 
     723              : static void CodeFunctValue (location_t location, unsigned int op1);
     724              : 
     725              : /*
     726              :    FoldStringLength -
     727              : */
     728              : 
     729              : static void FoldStringLength (unsigned int quad, M2GCCDeclare_WalkAction p);
     730              : 
     731              : /*
     732              :    FoldStringConvertM2nul - attempt to assign the des with the string contents from expr.
     733              :                             It also marks the des as a m2 string which must be nul terminated.
     734              :                             The front end uses double book keeping and it is easier to have
     735              :                             different m2 string symbols each of which map onto a slightly different
     736              :                             gcc string tree.
     737              : */
     738              : 
     739              : static void FoldStringConvertM2nul (unsigned int quad, M2GCCDeclare_WalkAction p);
     740              : 
     741              : /*
     742              :    FoldStringConvertCnul -attempt to assign the des with the string contents from expr.
     743              :                           It also marks the des as a C string which must be nul terminated.
     744              : */
     745              : 
     746              : static void FoldStringConvertCnul (unsigned int quad, M2GCCDeclare_WalkAction p);
     747              : static void CodeAddr (unsigned int tokenno, unsigned int quad, unsigned int op1, unsigned int op3);
     748              : static void FoldBecomes (M2GCCDeclare_WalkAction p, M2BasicBlock_BasicBlock bb, unsigned int quad);
     749              : 
     750              : /*
     751              :    TryDeclareConst -
     752              : */
     753              : 
     754              : static void TryDeclareConst (unsigned int tokenno, unsigned int sym);
     755              : 
     756              : /*
     757              :    RemoveQuad - remove quad and ensure p (des) is called.
     758              : */
     759              : 
     760              : static void RemoveQuad (M2GCCDeclare_WalkAction p, unsigned int des, unsigned int quad);
     761              : 
     762              : /*
     763              :    DeclaredOperandsBecomes -
     764              : */
     765              : 
     766              : static bool DeclaredOperandsBecomes (M2GCCDeclare_WalkAction p, unsigned int quad);
     767              : 
     768              : /*
     769              :    TypeCheckBecomes - returns TRUE if the type check succeeds.
     770              : */
     771              : 
     772              : static bool TypeCheckBecomes (M2GCCDeclare_WalkAction p, unsigned int quad);
     773              : 
     774              : /*
     775              :    PerformFoldBecomes - attempts to fold quad.  It propagates constant strings
     776              :                         and attempts to declare des providing it is a constant
     777              :                         and expr is resolved.
     778              : */
     779              : 
     780              : static void PerformFoldBecomes (M2GCCDeclare_WalkAction p, unsigned int quad);
     781              : 
     782              : /*
     783              :    CodeTry - starts building a GCC 'try' node.
     784              : */
     785              : 
     786              : static void CodeTry (void);
     787              : 
     788              : /*
     789              :    CodeThrow - builds a GCC 'throw' node.
     790              : */
     791              : 
     792              : static void CodeThrow (unsigned int value);
     793              : static void CodeRetry (unsigned int destQuad);
     794              : static void CodeCatchBegin (void);
     795              : static void CodeCatchEnd (void);
     796              : 
     797              : /*
     798              :    DescribeTypeError -
     799              : */
     800              : 
     801              : static void DescribeTypeError (unsigned int token, unsigned int op1, unsigned int op2);
     802              : 
     803              : /*
     804              :    DefaultConvertGM2 - provides a simple mapping between
     805              :                        front end data types and GCC equivalents.
     806              :                        This is only used to aid assignment of
     807              :                        typed constants.
     808              : */
     809              : 
     810              : static tree DefaultConvertGM2 (unsigned int sym);
     811              : 
     812              : /*
     813              :    FoldConstBecomes - returns a Tree containing op3.
     814              :                       The tree will have been folded and
     815              :                       type converted if necessary.
     816              : */
     817              : 
     818              : static tree FoldConstBecomes (unsigned int tokenno, unsigned int op1, unsigned int op3);
     819              : 
     820              : /*
     821              :    checkArrayElements - return TRUE if des or expr are not arrays.
     822              :                         If they are arrays and have different number of
     823              :                         elements return FALSE, otherwise TRUE.
     824              : */
     825              : 
     826              : static bool checkArrayElements (unsigned int des, unsigned int expr, unsigned int virtpos, unsigned int despos, unsigned int exprpos);
     827              : 
     828              : /*
     829              :    CodeInitAddress -
     830              : */
     831              : 
     832              : static void CodeInitAddress (unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
     833              : 
     834              : /*
     835              :    checkRecordTypes - returns TRUE if des is not a record or if the record
     836              :                       is the same type as expr.
     837              : */
     838              : 
     839              : static bool checkRecordTypes (unsigned int des, unsigned int expr, unsigned int virtpos);
     840              : 
     841              : /*
     842              :    checkIncorrectMeta - checks to see if des and expr are assignment compatible is allows
     843              :                         generic system types to be assigned.
     844              : */
     845              : 
     846              : static bool checkIncorrectMeta (unsigned int des, unsigned int expr, unsigned int virtpos);
     847              : 
     848              : /*
     849              :    checkBecomes - returns TRUE if the checks pass.
     850              : */
     851              : 
     852              : static bool checkBecomes (unsigned int des, unsigned int expr, unsigned int virtpos, unsigned int despos, unsigned int exprpos);
     853              : 
     854              : /*
     855              :    checkDeclare - checks to see if sym is declared and if it is not then declare it.
     856              : */
     857              : 
     858              : static void checkDeclare (unsigned int sym);
     859              : 
     860              : /*
     861              :    PerformCodeBecomes -
     862              : */
     863              : 
     864              : static void PerformCodeBecomes (location_t location, unsigned int virtpos, unsigned int des, unsigned int expr);
     865              : static void CodeBecomes (unsigned int quad);
     866              : 
     867              : /*
     868              :    getrvalue -
     869              : */
     870              : 
     871              : static tree getrvalue (location_t location, unsigned int expr, unsigned int type, bool islvalue);
     872              : 
     873              : /*
     874              :    LValueToGenericPtrOrConvert - if sym is an lvalue then convert to pointer type
     875              :                                  else convert to type, type. Return the converted tree.
     876              : */
     877              : 
     878              : static tree LValueToGenericPtrOrConvert (unsigned int sym, tree type);
     879              : 
     880              : /*
     881              :    FoldBinary - check whether we can fold the binop operation.
     882              : */
     883              : 
     884              : static void FoldBinary (unsigned int tokenno, M2GCCDeclare_WalkAction p, m2expr_BuildBinProcedure binop, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
     885              : 
     886              : /*
     887              :    ConvertBinaryOperands -
     888              : */
     889              : 
     890              : static void ConvertBinaryOperands (location_t location, tree *tl, tree *tr, unsigned int type, unsigned int op2, unsigned int op3);
     891              : 
     892              : /*
     893              :    CodeBinaryCheck - encode a binary arithmetic operation.
     894              : */
     895              : 
     896              : static void CodeBinaryCheck (m2expr_BuildBinCheckProcedure binop, unsigned int quad);
     897              : 
     898              : /*
     899              :    MixTypesBinary - depending upon overflowCheck do not check pointer arithmetic.
     900              : */
     901              : 
     902              : static unsigned int MixTypesBinary (unsigned int left, unsigned int right, unsigned int tokpos, bool overflowCheck);
     903              : 
     904              : /*
     905              :    CodeBinary - encode a binary arithmetic operation.
     906              : */
     907              : 
     908              : static void CodeBinary (m2expr_BuildBinProcedure binop, unsigned int quad);
     909              : 
     910              : /*
     911              :    NoWalkProcedure -
     912              : */
     913              : 
     914              : static void NoWalkProcedure (unsigned int param __attribute__((unused)));
     915              : 
     916              : /*
     917              :    CheckBinaryExpressionTypes - returns TRUE if all expression checks pass.
     918              :                                 If the expression check fails quad is removed,
     919              :                                 the walk procedure (des) is called and NoChange is
     920              :                                 set to FALSE.
     921              : */
     922              : 
     923              : static bool CheckBinaryExpressionTypes (unsigned int quad, M2GCCDeclare_WalkAction p);
     924              : 
     925              : /*
     926              :    CheckElementSetTypes - returns TRUE if all expression checks pass.
     927              :                           If the expression check fails quad is removed,
     928              :                           the walk procedure (des) is called and NoChange is
     929              :                           set to FALSE.
     930              : */
     931              : 
     932              : static bool CheckElementSetTypes (unsigned int quad);
     933              : 
     934              : /*
     935              :    CodeBinarySet - encode a binary set AND arithmetic operation.
     936              :                    Set operands may be longer than a word.
     937              : */
     938              : 
     939              : static void CodeBinarySet (M2GenGCC_ProcedureCardinal constp, M2GenGCC_BinaryFunction binfunc, NameKey_Name wideprocname, unsigned int quad);
     940              : 
     941              : /*
     942              :    MakeTemporarySetName - returns a Name using the template _Tset%d.
     943              : */
     944              : 
     945              : static NameKey_Name MakeTemporarySetName (void);
     946              : 
     947              : /*
     948              :    SetWideBinary -
     949              : */
     950              : 
     951              : static void SetWideBinary (unsigned int tokenno, NameKey_Name wideprocname, unsigned int settype, unsigned int des, unsigned int left, unsigned int right);
     952              : 
     953              : /*
     954              :    SetWideBinaryLibrary - call wideprocname (des, left, right) passing des, left, right
     955              :                           as an array of byte.
     956              : */
     957              : 
     958              : static void SetWideBinaryLibrary (unsigned int tokenno, NameKey_Name wideprocname, unsigned int settype, unsigned int des, unsigned int left, unsigned int right);
     959              : 
     960              : /*
     961              :    SetWideBinaryBuiltin - build an builtin wideset NOT operation.
     962              : */
     963              : 
     964              : static void SetWideBinaryBuiltin (unsigned int tokenno, M2GenGCC_BinaryFunction binfunc, unsigned int des, unsigned int left, unsigned int right);
     965              : 
     966              : /*
     967              :    SetNarrowBinary - create tree consisting of:
     968              :                      result := binfunc (left, right)
     969              :                      result, left and right can be lvalues.
     970              : */
     971              : 
     972              : static void SetNarrowBinary (location_t location, M2GenGCC_BinaryFunction binfunc, unsigned int settype, unsigned int result, unsigned int left, unsigned int right);
     973              : 
     974              : /*
     975              :    CreateSetArrayParam - return a gcc tree containing value contained in an unbounded
     976              :                          array parameter.
     977              : */
     978              : 
     979              : static tree CreateSetArrayParam (location_t location, unsigned int tokenno, unsigned int value, unsigned int param);
     980              : 
     981              : /*
     982              :    CheckUnaryOperand - checks to see whether operand is using a generic type.
     983              : */
     984              : 
     985              : static bool CheckUnaryOperand (unsigned int quad, unsigned int operand);
     986              : 
     987              : /*
     988              :    UnaryOperand - returns TRUE if operand is acceptable for
     989              :                   unary operator: + -.  If FALSE
     990              :                   is returned, an error message will be generated
     991              :                   and the quad is deleted.
     992              : */
     993              : 
     994              : static bool UnaryOperand (unsigned int quad, unsigned int operand);
     995              : 
     996              : /*
     997              :    CheckBinaryOperand - checks to see whether operand is using a generic type.
     998              : */
     999              : 
    1000              : static bool CheckBinaryOperand (unsigned int quad, bool isleft, unsigned int operand, bool result);
    1001              : 
    1002              : /*
    1003              :    BinaryOperands - returns TRUE if, l, and, r, are acceptable for
    1004              :                     binary operator: + - / * and friends.  If FALSE
    1005              :                     is returned, an error message will be generated
    1006              :                     and the, quad, is deleted.
    1007              : */
    1008              : 
    1009              : static bool BinaryOperands (unsigned int quad, unsigned int l, unsigned int r);
    1010              : 
    1011              : /*
    1012              :    IsConstStr - returns TRUE if sym is a constant string or a char constant.
    1013              : */
    1014              : 
    1015              : static bool IsConstStr (unsigned int sym);
    1016              : 
    1017              : /*
    1018              :    IsConstStrKnown - returns TRUE if sym is a constant string or a char constant
    1019              :                      which is known.
    1020              : */
    1021              : 
    1022              : static bool IsConstStrKnown (unsigned int sym);
    1023              : 
    1024              : /*
    1025              :    GetStr - return a string containing a constant string value associated with sym.
    1026              :             A nul char constant will return an empty string.
    1027              : */
    1028              : 
    1029              : static DynamicStrings_String GetStr (unsigned int tokenno, unsigned int sym);
    1030              : 
    1031              : /*
    1032              :    FoldAdd - check addition for constant folding.  It checks for conststrings
    1033              :              overloading the +.
    1034              : */
    1035              : 
    1036              : static void FoldAdd (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1037              : 
    1038              : /*
    1039              :    FoldArithAdd - check arithmetic addition for constant folding.
    1040              : */
    1041              : 
    1042              : static void FoldArithAdd (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1043              : 
    1044              : /*
    1045              :    CodeAddChecked - code an addition instruction, determine whether checking
    1046              :                     is required.
    1047              : */
    1048              : 
    1049              : static void CodeAddChecked (unsigned int quad, unsigned int left, unsigned int right);
    1050              : 
    1051              : /*
    1052              :    CodeAddCheck - encode addition but check for overflow.
    1053              : */
    1054              : 
    1055              : static void CodeAddCheck (unsigned int quad, unsigned int left, unsigned int right);
    1056              : 
    1057              : /*
    1058              :    CodeAdd - encode addition.
    1059              : */
    1060              : 
    1061              : static void CodeAdd (unsigned int quad, unsigned int left, unsigned int right);
    1062              : 
    1063              : /*
    1064              :    FoldSub - check subtraction for constant folding.
    1065              : */
    1066              : 
    1067              : static void FoldSub (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1068              : 
    1069              : /*
    1070              :    CodeSubChecked - code a subtract instruction, determine whether checking
    1071              :                     is required.
    1072              : */
    1073              : 
    1074              : static void CodeSubChecked (unsigned int quad, unsigned int left, unsigned int right);
    1075              : 
    1076              : /*
    1077              :    CodeSubCheck - encode subtraction but check for overflow.
    1078              : */
    1079              : 
    1080              : static void CodeSubCheck (unsigned int quad, unsigned int left, unsigned int right);
    1081              : 
    1082              : /*
    1083              :    CodeSub - encode subtraction.
    1084              : */
    1085              : 
    1086              : static void CodeSub (unsigned int quad, unsigned int left, unsigned int right);
    1087              : 
    1088              : /*
    1089              :    FoldMult - check multiplication for constant folding.
    1090              : */
    1091              : 
    1092              : static void FoldMult (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1093              : 
    1094              : /*
    1095              :    CodeMultChecked - code a multiplication instruction, determine whether checking
    1096              :                      is required.
    1097              : */
    1098              : 
    1099              : static void CodeMultChecked (unsigned int quad, unsigned int left, unsigned int right);
    1100              : 
    1101              : /*
    1102              :    CodeMultCheck - encode multiplication but check for overflow.
    1103              : */
    1104              : 
    1105              : static void CodeMultCheck (unsigned int quad, unsigned int left, unsigned int right);
    1106              : 
    1107              : /*
    1108              :    CodeMult - encode multiplication.
    1109              : */
    1110              : 
    1111              : static void CodeMult (unsigned int quad, unsigned int left, unsigned int right);
    1112              : 
    1113              : /*
    1114              :    CodeDivM2Checked - code a divide instruction, determine whether checking
    1115              :                       is required.
    1116              : */
    1117              : 
    1118              : static void CodeDivM2Checked (unsigned int quad, unsigned int left, unsigned int right);
    1119              : 
    1120              : /*
    1121              :    CodeDivM2Check - encode addition but check for overflow.
    1122              : */
    1123              : 
    1124              : static void CodeDivM2Check (unsigned int quad, unsigned int left, unsigned int right);
    1125              : 
    1126              : /*
    1127              :    CodeModM2Checked - code a modulus instruction, determine whether checking
    1128              :                       is required.
    1129              : */
    1130              : 
    1131              : static void CodeModM2Checked (unsigned int quad, unsigned int left, unsigned int right);
    1132              : 
    1133              : /*
    1134              :    CodeModM2Check - encode addition but check for overflow.
    1135              : */
    1136              : 
    1137              : static void CodeModM2Check (unsigned int quad, unsigned int left, unsigned int right);
    1138              : 
    1139              : /*
    1140              :    BinaryOperandRealFamily -
    1141              : */
    1142              : 
    1143              : static bool BinaryOperandRealFamily (unsigned int op);
    1144              : 
    1145              : /*
    1146              :    FoldDivM2 - check division for constant folding.
    1147              : */
    1148              : 
    1149              : static void FoldDivM2 (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1150              : 
    1151              : /*
    1152              :    CodeDivM2 - encode division.
    1153              : */
    1154              : 
    1155              : static void CodeDivM2 (unsigned int quad, unsigned int left, unsigned int right);
    1156              : 
    1157              : /*
    1158              :    FoldModM2 - check modulus for constant folding.
    1159              : */
    1160              : 
    1161              : static void FoldModM2 (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1162              : 
    1163              : /*
    1164              :    CodeModM2 - encode modulus.
    1165              : */
    1166              : 
    1167              : static void CodeModM2 (unsigned int quad, unsigned int left, unsigned int right);
    1168              : 
    1169              : /*
    1170              :    FoldDivTrunc - check division for constant folding.
    1171              : */
    1172              : 
    1173              : static void FoldDivTrunc (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1174              : 
    1175              : /*
    1176              :    CodeDivTrunc - encode multiplication.
    1177              : */
    1178              : 
    1179              : static void CodeDivTrunc (unsigned int quad, unsigned int left, unsigned int right);
    1180              : 
    1181              : /*
    1182              :    FoldModTrunc - check modulus for constant folding.
    1183              : */
    1184              : 
    1185              : static void FoldModTrunc (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1186              : 
    1187              : /*
    1188              :    CodeModTrunc - encode modulus.
    1189              : */
    1190              : 
    1191              : static void CodeModTrunc (unsigned int quad, unsigned int left, unsigned int right);
    1192              : 
    1193              : /*
    1194              :    FoldDivCeil - check division for constant folding.
    1195              : */
    1196              : 
    1197              : static void FoldDivCeil (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1198              : 
    1199              : /*
    1200              :    CodeDivCeil - encode multiplication.
    1201              : */
    1202              : 
    1203              : static void CodeDivCeil (unsigned int quad, unsigned int left, unsigned int right);
    1204              : 
    1205              : /*
    1206              :    FoldModCeil - check modulus for constant folding.
    1207              : */
    1208              : 
    1209              : static void FoldModCeil (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1210              : 
    1211              : /*
    1212              :    CodeModCeil - encode multiplication.
    1213              : */
    1214              : 
    1215              : static void CodeModCeil (unsigned int quad, unsigned int left, unsigned int right);
    1216              : 
    1217              : /*
    1218              :    FoldDivFloor - check division for constant folding.
    1219              : */
    1220              : 
    1221              : static void FoldDivFloor (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1222              : 
    1223              : /*
    1224              :    CodeDivFloor - encode multiplication.
    1225              : */
    1226              : 
    1227              : static void CodeDivFloor (unsigned int quad, unsigned int left, unsigned int right);
    1228              : 
    1229              : /*
    1230              :    FoldModFloor - check modulus for constant folding.
    1231              : */
    1232              : 
    1233              : static void FoldModFloor (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1234              : 
    1235              : /*
    1236              :    CodeModFloor - encode modulus.
    1237              : */
    1238              : 
    1239              : static void CodeModFloor (unsigned int quad, unsigned int left, unsigned int right);
    1240              : 
    1241              : /*
    1242              :    FoldBuiltinConst -
    1243              : */
    1244              : 
    1245              : static void FoldBuiltinConst (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int result, unsigned int constDesc);
    1246              : 
    1247              : /*
    1248              :    FoldBuiltinTypeInfo - attempts to fold a builtin attribute value on type op2.
    1249              : */
    1250              : 
    1251              : static void FoldBuiltinTypeInfo (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1252              : 
    1253              : /*
    1254              :    FoldTBitsize - attempt to fold the standard function SYSTEM.TBITSIZE
    1255              :                   quadruple.  If the quadruple is folded it is removed.
    1256              : */
    1257              : 
    1258              : static void FoldTBitsize (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int res, unsigned int type);
    1259              : 
    1260              : /*
    1261              :    FoldStandardFunction - attempts to fold a standard function.
    1262              : */
    1263              : 
    1264              : static void FoldStandardFunction (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1265              : 
    1266              : /*
    1267              :    CodeStandardFunction -
    1268              : */
    1269              : 
    1270              : static void CodeStandardFunction (unsigned int quad, unsigned int result, unsigned int function, unsigned int param);
    1271              : 
    1272              : /*
    1273              :    CodeSavePriority - checks to see whether op2 is reachable and is directly accessible
    1274              :                       externally. If so then it saves the current interrupt priority
    1275              :                       in op1 and sets the current priority to that determined by
    1276              :                       appropriate module.
    1277              : 
    1278              :                       op1 := op3(GetModuleScope(op2))
    1279              : */
    1280              : 
    1281              : static void CodeSavePriority (unsigned int oldValue, unsigned int scopeSym, unsigned int procedureSym);
    1282              : 
    1283              : /*
    1284              :    CodeRestorePriority - checks to see whether op2 is reachable and is directly accessible
    1285              :                          externally. If so then it restores the previous interrupt priority
    1286              :                          held in op1.
    1287              : 
    1288              :                          op1 := op3(op1)
    1289              : */
    1290              : 
    1291              : static void CodeRestorePriority (unsigned int oldValue, unsigned int scopeSym, unsigned int procedureSym);
    1292              : 
    1293              : /*
    1294              :    FoldBinarySet - attempts to fold set arithmetic it removes the quad if successful.
    1295              : */
    1296              : 
    1297              : static void FoldBinarySet (unsigned int tokenno, M2GCCDeclare_WalkAction p, M2GenGCC_ProcedureCardinal op, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1298              : 
    1299              : /*
    1300              :    FoldSetOr - check whether we can fold a set arithmetic or.
    1301              : */
    1302              : 
    1303              : static void FoldSetOr (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1304              : 
    1305              : /*
    1306              :    CodeSetOr - encode set arithmetic or.
    1307              : */
    1308              : 
    1309              : static void CodeSetOr (unsigned int quad);
    1310              : 
    1311              : /*
    1312              :    FoldSetAnd - check whether we can fold a logical and.
    1313              : */
    1314              : 
    1315              : static void FoldSetAnd (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1316              : 
    1317              : /*
    1318              :    CodeSetAnd - encode set arithmetic and.
    1319              : */
    1320              : 
    1321              : static void CodeSetAnd (unsigned int quad);
    1322              : 
    1323              : /*
    1324              :    CalcHighSetBit - calculate the most significant bit used in a set starting from bit zero.
    1325              : */
    1326              : 
    1327              : static tree CalcHighSetBit (location_t location, unsigned int settype);
    1328              : 
    1329              : /*
    1330              :    CalcBitsInSet - returns the number of minimum number of bits used to represent a set.
    1331              : */
    1332              : 
    1333              : static tree CalcBitsInSet (location_t location, unsigned int settype);
    1334              : 
    1335              : /*
    1336              :    SetWideSetShiftRotate - generate a call:
    1337              :                            M2WIDESET.name (dest, src, HIGHBIT (settype), count).
    1338              : */
    1339              : 
    1340              : static void SetWideSetShiftRotate (unsigned int tokenno, NameKey_Name name, unsigned int settype, unsigned int dest, unsigned int src, unsigned int count);
    1341              : 
    1342              : /*
    1343              :    CodeNarrowSetShift -
    1344              : */
    1345              : 
    1346              : static void CodeNarrowSetShift (unsigned int tokenno, unsigned int settype, unsigned int dest, unsigned int src, unsigned int count);
    1347              : 
    1348              : /*
    1349              :    CodeNarrowSetRotate -
    1350              : */
    1351              : 
    1352              : static void CodeNarrowSetRotate (unsigned int tokenno, unsigned int settype, unsigned int dest, unsigned int src, unsigned int count);
    1353              : 
    1354              : /*
    1355              :    CodeBinarySetShiftRotate - encode a binary set arithmetic operation.
    1356              : */
    1357              : 
    1358              : static void CodeBinarySetShiftRotate (unsigned int quad, bool isshift);
    1359              : 
    1360              : /*
    1361              :    FoldSetShift - check whether we can fold a logical shift.
    1362              : */
    1363              : 
    1364              : static void FoldSetShift (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int Dest, unsigned int Src, unsigned int ShiftCount);
    1365              : 
    1366              : /*
    1367              :    CodeSetShift - encode set arithmetic shift.
    1368              : */
    1369              : 
    1370              : static void CodeSetShift (unsigned int quad);
    1371              : 
    1372              : /*
    1373              :    FoldSetRotate - check whether we can fold a logical rotate.
    1374              : */
    1375              : 
    1376              : static void FoldSetRotate (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int Dest, unsigned int Src, unsigned int RotateCount);
    1377              : 
    1378              : /*
    1379              :    CodeSetRotate - encode set arithmetic rotate.
    1380              : */
    1381              : 
    1382              : static void CodeSetRotate (unsigned int quad);
    1383              : 
    1384              : /*
    1385              :    CodeSetLogicalDifference - encode set arithmetic logical difference.
    1386              : */
    1387              : 
    1388              : static void CodeSetLogicalDifference (unsigned int quad);
    1389              : 
    1390              : /*
    1391              :    FoldSymmetricDifference - check whether we can fold a logical difference.
    1392              : */
    1393              : 
    1394              : static void FoldSymmetricDifference (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1395              : 
    1396              : /*
    1397              :    CodeSetSymmetricDifference - code set difference.
    1398              :                                 A logical xor expression.
    1399              : */
    1400              : 
    1401              : static void CodeSetSymmetricDifference (unsigned int quad);
    1402              : 
    1403              : /*
    1404              :    CodeUnarySet - encode a unary set arithmetic operation.
    1405              :                   Set operands may be longer than a word.
    1406              : */
    1407              : 
    1408              : static void CodeUnarySet (M2GenGCC_ProcedureCardinal constop, M2GenGCC_UnaryFunction unfunc, unsigned int tokenno, NameKey_Name wideprocname, unsigned int quad, unsigned int result, unsigned int expr);
    1409              : 
    1410              : /*
    1411              :    FromM2WIDESETImport - returns M2WIDESET.name.
    1412              : */
    1413              : 
    1414              : static unsigned int FromM2WIDESETImport (unsigned int tokenno, NameKey_Name name);
    1415              : 
    1416              : /*
    1417              :    SetWideUnaryLibrary - call wideprocname (result, expr) passing result and expr
    1418              :                          as an array of byte.
    1419              : */
    1420              : 
    1421              : static void SetWideUnaryLibrary (unsigned int tokenno, NameKey_Name wideprocname, unsigned int settype, unsigned int result, unsigned int expr);
    1422              : 
    1423              : /*
    1424              :    SetWideUnaryBuiltinNot - build an builtin wideset NOT operation.
    1425              : */
    1426              : 
    1427              : static void SetWideUnaryBuiltinNot (unsigned int tokenno, unsigned int result, unsigned int expr);
    1428              : 
    1429              : /*
    1430              :    SetWideUnary - either call the library wideprocname or the builtin
    1431              :                   version depending upon the optimization setting.
    1432              : */
    1433              : 
    1434              : static void SetWideUnary (unsigned int tokenno, NameKey_Name wideprocname, unsigned int settype, unsigned int result, unsigned int expr);
    1435              : 
    1436              : /*
    1437              :    SetNarrowUnary - create tree consisting of:
    1438              :                     result := unfunc (expr)
    1439              :                     result and expr can be lvalues.
    1440              : */
    1441              : 
    1442              : static void SetNarrowUnary (location_t location, M2GenGCC_UnaryFunction unfunc, unsigned int settype, unsigned int result, unsigned int expr);
    1443              : 
    1444              : /*
    1445              :    FoldIncl - check whether we can fold the InclOp.
    1446              :               result := result + (1 << expr)
    1447              : */
    1448              : 
    1449              : static void FoldIncl (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int result, unsigned int expr);
    1450              : 
    1451              : /*
    1452              :    FoldIfLess - check to see if it is possible to evaluate
    1453              :                 if op1 < op2 then goto op3.
    1454              : */
    1455              : 
    1456              : static void FoldIfLess (unsigned int tokenno, unsigned int quad, unsigned int left, unsigned int right, unsigned int destQuad);
    1457              : 
    1458              : /*
    1459              :    FoldIfGre - check to see if it is possible to evaluate
    1460              :                if op1 > op2 then goto op3.
    1461              : */
    1462              : 
    1463              : static void FoldIfGre (unsigned int tokenno, unsigned int quad, unsigned int left, unsigned int right, unsigned int destQuad);
    1464              : 
    1465              : /*
    1466              :    FoldIfLessEqu - check to see if it is possible to evaluate
    1467              :                    if op1 <= op2 then goto op3.
    1468              : */
    1469              : 
    1470              : static void FoldIfLessEqu (unsigned int tokenno, unsigned int quad, unsigned int left, unsigned int right, unsigned int destQuad);
    1471              : 
    1472              : /*
    1473              :    FoldIfGreEqu - check to see if it is possible to evaluate
    1474              :                   if op1 >= op2 then goto op3.
    1475              : */
    1476              : 
    1477              : static void FoldIfGreEqu (unsigned int tokenno, unsigned int quad, unsigned int left, unsigned int right, unsigned int destQuad);
    1478              : 
    1479              : /*
    1480              :    FoldIfIn - check whether we can fold the IfInOp
    1481              :               if op1 in op2 then goto op3
    1482              : */
    1483              : 
    1484              : static void FoldIfIn (unsigned int tokenno, unsigned int quad, unsigned int left, unsigned int right, unsigned int destQuad);
    1485              : 
    1486              : /*
    1487              :    FoldIfNotIn - check whether we can fold the IfNotInOp
    1488              :                  if not (op1 in op2) then goto op3
    1489              : */
    1490              : 
    1491              : static void FoldIfNotIn (unsigned int tokenno, unsigned int quad, unsigned int left, unsigned int right, unsigned int destQuad);
    1492              : 
    1493              : /*
    1494              :    FoldIfEqu - check to see if it is possible to evaluate
    1495              :                if op1 = op2 then goto op3.
    1496              : */
    1497              : 
    1498              : static void FoldIfEqu (unsigned int tokenno, unsigned int quad, unsigned int left, unsigned int right, unsigned int destQuad);
    1499              : 
    1500              : /*
    1501              :    FoldIfNotEqu - check to see if it is possible to evaluate
    1502              :                   if op1 # op2 then goto op3.
    1503              : */
    1504              : 
    1505              : static void FoldIfNotEqu (unsigned int tokenno, unsigned int quad, unsigned int left, unsigned int right, unsigned int destQuad);
    1506              : 
    1507              : /*
    1508              :    GetSetLimits - assigns low and high to the limits of the declared, set.
    1509              : */
    1510              : 
    1511              : static void GetSetLimits (unsigned int set, unsigned int *low, unsigned int *high);
    1512              : 
    1513              : /*
    1514              :    IsElementInRange - returns TRUE if expr references a bit in setvar
    1515              :                       which is in the range [low..high].  If expr is a
    1516              :                       variable it returns TRUE.  FALSE is returned if we
    1517              :                       know expr to be out of bounds.
    1518              : */
    1519              : 
    1520              : static bool IsElementInRange (unsigned int tokenno, unsigned int settype, unsigned int setvar, unsigned int expr);
    1521              : 
    1522              : /*
    1523              :    SetElementToBit -
    1524              : */
    1525              : 
    1526              : static tree SetElementToBit (location_t location, unsigned int settype, unsigned int expr);
    1527              : 
    1528              : /*
    1529              :    CodeNarrowIncl - result |= (1 << expr).
    1530              : */
    1531              : 
    1532              : static void CodeNarrowIncl (location_t location, unsigned int settype, unsigned int result, unsigned int expr);
    1533              : 
    1534              : /*
    1535              :    CodeNarrowExcl - result &= (~ (1 << expr)).
    1536              : */
    1537              : 
    1538              : static void CodeNarrowExcl (location_t location, unsigned int settype, unsigned int result, unsigned int expr);
    1539              : 
    1540              : /*
    1541              :    SetWideUnaryBuiltinIncl -
    1542              : */
    1543              : 
    1544              : static void SetWideUnaryBuiltinIncl (location_t location, tree dest, tree bitno);
    1545              : 
    1546              : /*
    1547              :    SetWideUnaryBuiltinExcl -
    1548              : */
    1549              : 
    1550              : static void SetWideUnaryBuiltinExcl (location_t location, tree dest, tree bitno);
    1551              : static void SetWideUnaryBuiltinInclExcl (unsigned int tokenno, unsigned int settype, unsigned int des, unsigned int expr, bool incl);
    1552              : 
    1553              : /*
    1554              :    SetWideInclExcl - generates M2WIDESET.procedurename (result, expr).
    1555              : */
    1556              : 
    1557              : static void SetWideInclExcl (unsigned int tokenno, unsigned int settype, unsigned int result, unsigned int expr, NameKey_Name procedurename);
    1558              : 
    1559              : /*
    1560              :    SetWideInclExclLibrary -
    1561              : */
    1562              : 
    1563              : static void SetWideInclExclLibrary (unsigned int tokenno, unsigned int settype, unsigned int result, unsigned int expr, NameKey_Name procedurename);
    1564              : 
    1565              : /*
    1566              :    CodeIncl - encode an InclOp:
    1567              :               result |= (1 << expr).
    1568              : */
    1569              : 
    1570              : static void CodeIncl (unsigned int quad);
    1571              : 
    1572              : /*
    1573              :    FoldExcl - check whether we can fold the InclOp.
    1574              :               result &= ~ (1 << expr).
    1575              : */
    1576              : 
    1577              : static void FoldExcl (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int result, unsigned int expr);
    1578              : 
    1579              : /*
    1580              :    CodeExcl - encode an ExclOp:
    1581              :               result &= (~ (1 << expr)).
    1582              : */
    1583              : 
    1584              : static void CodeExcl (unsigned int quad);
    1585              : 
    1586              : /*
    1587              :    FoldUnary - check whether we can fold the unop operation.
    1588              : */
    1589              : 
    1590              : static void FoldUnary (unsigned int tokenno, M2GCCDeclare_WalkAction p, m2expr_BuildUnaryProcedure unop, tree ZConstToTypedConst, unsigned int quad, unsigned int result, unsigned int expr);
    1591              : 
    1592              : /*
    1593              :    FoldUnarySet - check whether we can fold the doOp operation.
    1594              : */
    1595              : 
    1596              : static void FoldUnarySet (unsigned int tokenno, M2GCCDeclare_WalkAction p, M2GenGCC_ProcedureCardinal doOp, unsigned int quad, unsigned int result, unsigned int expr);
    1597              : 
    1598              : /*
    1599              :    CodeUnaryCheck - encode a unary arithmetic operation.
    1600              : */
    1601              : 
    1602              : static void CodeUnaryCheck (m2expr_BuildUnaryCheckProcedure unop, tree ZConstToTypedConst, unsigned int quad, unsigned int result, unsigned int expr);
    1603              : 
    1604              : /*
    1605              :    CodeUnary - encode a unary arithmetic operation.
    1606              : */
    1607              : 
    1608              : static void CodeUnary (m2expr_BuildUnaryProcedure unop, tree ZConstToTypedConst, unsigned int quad, unsigned int result, unsigned int expr);
    1609              : 
    1610              : /*
    1611              :    FoldNegate - check unary negate for constant folding.
    1612              : */
    1613              : 
    1614              : static void FoldNegate (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int result, unsigned int expr);
    1615              : 
    1616              : /*
    1617              :    CodeNegateChecked - code a negate instruction, determine whether checking
    1618              :                        is required.
    1619              : */
    1620              : 
    1621              : static void CodeNegateChecked (unsigned int quad);
    1622              : 
    1623              : /*
    1624              :    FoldSize - check unary SIZE for constant folding.
    1625              : */
    1626              : 
    1627              : static void FoldSize (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1628              : 
    1629              : /*
    1630              :    CodeSize - encode the inbuilt SIZE function.
    1631              : */
    1632              : 
    1633              : static void CodeSize (unsigned int result, unsigned int sym);
    1634              : 
    1635              : /*
    1636              :    FoldRecordField - check whether we can fold an RecordFieldOp quadruple.
    1637              :                      Very similar to FoldBinary, except that we need to
    1638              :                      hard code a few parameters to the gcc backend.
    1639              : */
    1640              : 
    1641              : static void FoldRecordField (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int result, unsigned int record, unsigned int field);
    1642              : 
    1643              : /*
    1644              :    CodeRecordField - encode a reference to a field within a record.
    1645              : */
    1646              : 
    1647              : static void CodeRecordField (unsigned int result, unsigned int record, unsigned int field);
    1648              : 
    1649              : /*
    1650              :    BuildHighFromChar -
    1651              : */
    1652              : 
    1653              : static tree BuildHighFromChar (unsigned int operand);
    1654              : 
    1655              : /*
    1656              :    SkipToArray -
    1657              : */
    1658              : 
    1659              : static unsigned int SkipToArray (unsigned int operand, unsigned int dim);
    1660              : 
    1661              : /*
    1662              :    BuildHighFromArray -
    1663              : */
    1664              : 
    1665              : static tree BuildHighFromArray (unsigned int tokenno, unsigned int dim, unsigned int operand);
    1666              : 
    1667              : /*
    1668              :    BuildHighFromSetArray -
    1669              : */
    1670              : 
    1671              : static tree BuildHighFromSetArray (unsigned int tokenno, unsigned int settype);
    1672              : 
    1673              : /*
    1674              :    BuildHighFromStaticArray -
    1675              : */
    1676              : 
    1677              : static tree BuildHighFromStaticArray (location_t location, unsigned int Type);
    1678              : 
    1679              : /*
    1680              :    BuildHighFromString -
    1681              : */
    1682              : 
    1683              : static tree BuildHighFromString (unsigned int operand);
    1684              : 
    1685              : /*
    1686              :    ResolveHigh - given an Modula-2 operand, it resolves the HIGH(operand)
    1687              :                  and returns a GCC constant symbol containing the value of
    1688              :                  HIGH(operand).
    1689              : */
    1690              : 
    1691              : static tree ResolveHigh (unsigned int tokenno, unsigned int dim, unsigned int operand);
    1692              : 
    1693              : /*
    1694              :    IsUnboundedArray - return TRUE if symbol is an unbounded array.
    1695              : */
    1696              : 
    1697              : static bool IsUnboundedArray (unsigned int sym);
    1698              : 
    1699              : /*
    1700              :    FoldHigh - if the array is not dynamic then we should be able to
    1701              :               remove the HighOp quadruple and assign op1 with
    1702              :               the known compile time HIGH(array).
    1703              : */
    1704              : 
    1705              : static void FoldHigh (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int dim, unsigned int array);
    1706              : 
    1707              : /*
    1708              :    CodeHigh - encode a unary arithmetic operation.
    1709              : */
    1710              : 
    1711              : static void CodeHigh (unsigned int result, unsigned int dim, unsigned int array);
    1712              : 
    1713              : /*
    1714              :    CodeUnbounded - codes the creation of an unbounded parameter variable.
    1715              :                    result = &array.  array can be an lvalue or rvalue.
    1716              : */
    1717              : 
    1718              : static void CodeUnbounded (unsigned int result, unsigned int array);
    1719              : 
    1720              : /*
    1721              :    AreSubrangesKnown - returns TRUE if the subranges values used within, array, are known.
    1722              : */
    1723              : 
    1724              : static bool AreSubrangesKnown (unsigned int array);
    1725              : 
    1726              : /*
    1727              :    CodeArray - res is an lvalue which will point to the array element.
    1728              : */
    1729              : 
    1730              : static void CodeArray (unsigned int res, unsigned int index, unsigned int array);
    1731              : 
    1732              : /*
    1733              :    FoldElementSizeForArray - attempts to calculate the Subscript
    1734              :                              multiplier for the index op3.
    1735              : */
    1736              : 
    1737              : static void FoldElementSizeForArray (unsigned int tokenno, unsigned int quad, M2GCCDeclare_WalkAction p, unsigned int result, unsigned int type);
    1738              : 
    1739              : /*
    1740              :    FoldElementSizeForUnbounded - Unbounded arrays only have one index,
    1741              :                                  therefore element size will be the
    1742              :                                  TSIZE(Type) where Type is defined as:
    1743              :                                  ARRAY OF Type.
    1744              : */
    1745              : 
    1746              : static void FoldElementSizeForUnbounded (unsigned int tokenno, unsigned int quad, M2GCCDeclare_WalkAction p, unsigned int result, unsigned int ArrayType);
    1747              : 
    1748              : /*
    1749              :    FoldElementSize - folds the element size for an ArraySym or UnboundedSym.
    1750              :                      ElementSize returns a constant which defines the
    1751              :                      multiplier to be multiplied by this element index.
    1752              : */
    1753              : 
    1754              : static void FoldElementSize (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int result, unsigned int type);
    1755              : 
    1756              : /*
    1757              :    PopKindTree - returns a Tree from M2ALU of the type implied by, op.
    1758              : */
    1759              : 
    1760              : static tree PopKindTree (unsigned int op, unsigned int tokenno);
    1761              : 
    1762              : /*
    1763              :    FoldConvert - attempts to fold expr to type into result
    1764              :                  providing that result and expr are constants.
    1765              :                  If required convert will alter the machine representation
    1766              :                  of expr to comply with type.
    1767              : */
    1768              : 
    1769              : static void FoldConvert (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int result, unsigned int type, unsigned int expr);
    1770              : 
    1771              : /*
    1772              :    CodeConvert - Converts, rhs, to, type, placing the result into lhs.
    1773              :                  Convert will, if need be, alter the machine representation
    1774              :                  of op3 to comply with TYPE op2.
    1775              : */
    1776              : 
    1777              : static void CodeConvert (unsigned int quad, unsigned int lhs, unsigned int type, unsigned int rhs);
    1778              : 
    1779              : /*
    1780              :    CodeCoerce - Coerce op3 to type op2 placing the result into
    1781              :                 op1.
    1782              :                 Coerce will NOT alter the machine representation
    1783              :                 of op3 to comply with TYPE op2.
    1784              :                 Therefore it _insists_ that under all circumstances that the
    1785              :                 type sizes of op1 and op3 are the same.
    1786              :                 CONVERT will perform machine manipulation to change variable
    1787              :                 types, coerce does no such thing.
    1788              : */
    1789              : 
    1790              : static void CodeCoerce (unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1791              : 
    1792              : /*
    1793              :    FoldCoerce -
    1794              : */
    1795              : 
    1796              : static void FoldCoerce (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1797              : 
    1798              : /*
    1799              :    CanConvert - returns TRUE if we can convert variable, var, to a, type.
    1800              : */
    1801              : 
    1802              : static bool CanConvert (unsigned int type, unsigned int var);
    1803              : 
    1804              : /*
    1805              :    CodeCast - Cast op3 to type op2 placing the result into op1.
    1806              :               Cast will NOT alter the machine representation
    1807              :               of op3 to comply with TYPE op2 as long as SIZE(op3)=SIZE(op2).
    1808              :               If the sizes differ then Convert is called.
    1809              : */
    1810              : 
    1811              : static void CodeCast (unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1812              : static void FoldCast (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3);
    1813              : 
    1814              : /*
    1815              :    CreateLabelProcedureN - creates a label using procedure name and
    1816              :                            an integer.
    1817              : */
    1818              : 
    1819              : static DynamicStrings_String CreateLabelProcedureN (unsigned int proc, const char *leader_, unsigned int _leader_high, unsigned int unboundedCount, unsigned int n);
    1820              : 
    1821              : /*
    1822              :    CreateLabelName - creates a namekey from quadruple, q.
    1823              : */
    1824              : 
    1825              : static DynamicStrings_String CreateLabelName (unsigned int q);
    1826              : 
    1827              : /*
    1828              :    CodeGoto - creates a jump to a labeled quadruple.
    1829              : */
    1830              : 
    1831              : static void CodeGoto (unsigned int destquad);
    1832              : 
    1833              : /*
    1834              :    CheckReferenced - checks to see whether this quadruple requires a label.
    1835              : */
    1836              : 
    1837              : static void CheckReferenced (unsigned int quad, M2Quads_QuadOperator op);
    1838              : 
    1839              : /*
    1840              :    CodeIfSetCondition - code IF left cond right then destquad for set types.
    1841              : */
    1842              : 
    1843              : static void CodeIfSetCondition (unsigned int tokenno, unsigned int left, unsigned int right, unsigned int destquad, M2GenGCC_BinaryFunction cond, NameKey_Name procedurename);
    1844              : 
    1845              : /*
    1846              :    CodeIfSetLess - code IF left < right then destquad for set types.
    1847              : */
    1848              : 
    1849              : static void CodeIfSetLess (unsigned int tokenno, unsigned int left, unsigned int right, unsigned int destquad);
    1850              : 
    1851              : /*
    1852              :    CodeIfSetLessEqu - code IF left <= right then destquad for set types.
    1853              : */
    1854              : 
    1855              : static void CodeIfSetLessEqu (unsigned int tokenno, unsigned int left, unsigned int right, unsigned int destquad);
    1856              : 
    1857              : /*
    1858              :    CodeIfSetGre - code IF left > right then destquad for set types.
    1859              : */
    1860              : 
    1861              : static void CodeIfSetGre (unsigned int tokenno, unsigned int left, unsigned int right, unsigned int destquad);
    1862              : 
    1863              : /*
    1864              :    CodeIfSetGreEqu - code IF left >= right then destquad for set types.
    1865              : */
    1866              : 
    1867              : static void CodeIfSetGreEqu (unsigned int tokenno, unsigned int left, unsigned int right, unsigned int destquad);
    1868              : 
    1869              : /*
    1870              :    PerformCodeIfLess - codes the quadruple if op1 < op2 then goto op3
    1871              : */
    1872              : 
    1873              : static void PerformCodeIfLess (unsigned int quad);
    1874              : 
    1875              : /*
    1876              :    CodeIfLess - codes the quadruple if op1 < op2 then goto op3
    1877              : */
    1878              : 
    1879              : static void CodeIfLess (unsigned int quad);
    1880              : 
    1881              : /*
    1882              :    CodeIfSetEquNarrow -
    1883              : */
    1884              : 
    1885              : static void CodeIfSetEquNarrow (location_t location, bool invertCondition, unsigned int settype, tree left, tree right, unsigned int destQuad);
    1886              : 
    1887              : /*
    1888              :    CallSetWideBoolFunction - return a tree containing a call to
    1889              :                              M2WIDESET.widefuncname (left, right, HIGHBIT (settype)).
    1890              : */
    1891              : 
    1892              : static tree CallSetWideBoolFunction (location_t location, unsigned int tokenno, NameKey_Name widefuncname, unsigned int settype, unsigned int left, unsigned int right);
    1893              : 
    1894              : /*
    1895              :    CodeIfSetEquWide - creates a statement tree:
    1896              :                       if left = right then goto destQuad.  The boolean
    1897              :                       invertCondition will check left # right.
    1898              : */
    1899              : 
    1900              : static void CodeIfSetEquWide (location_t location, unsigned int tokenno, bool invertCondition, unsigned int settype, unsigned int left, unsigned int right, unsigned int destQuad);
    1901              : 
    1902              : /*
    1903              :    CodeIfSetEquLower code a comparison between left and right and if true
    1904              :    jump to destQuad.  The invertCondition allows for the inverse test.
    1905              :    Note that if op1 and op2 are not both constants as this will have been
    1906              :    evaluated in CodeIfNotEqu.
    1907              : */
    1908              : 
    1909              : static void CodeIfSetEquLower (unsigned int tokenno, bool invertCondition, unsigned int left, unsigned int right, unsigned int destQuad);
    1910              : 
    1911              : /*
    1912              :    CodeIfSetNotEqu - codes if op1 # op2 then goto op3
    1913              : */
    1914              : 
    1915              : static void CodeIfSetNotEqu (unsigned int tokenno, unsigned int left, unsigned int right, unsigned int destQuad);
    1916              : 
    1917              : /*
    1918              :    CodeIfSetEqu - codes if op1 = op2 then goto op3
    1919              : */
    1920              : 
    1921              : static void CodeIfSetEqu (unsigned int tokenno, unsigned int left, unsigned int right, unsigned int destQuad);
    1922              : 
    1923              : /*
    1924              :    PerformCodeIfGre - codes the quadruple if op1 > op2 then goto op3
    1925              : */
    1926              : 
    1927              : static void PerformCodeIfGre (unsigned int quad);
    1928              : 
    1929              : /*
    1930              :    CodeIfGre - codes the quadruple if op1 > op2 then goto op3
    1931              : */
    1932              : 
    1933              : static void CodeIfGre (unsigned int quad);
    1934              : 
    1935              : /*
    1936              :    PerformCodeIfLessEqu - codes the quadruple if op1 <= op2 then goto op3
    1937              : */
    1938              : 
    1939              : static void PerformCodeIfLessEqu (unsigned int quad);
    1940              : 
    1941              : /*
    1942              :    CodeIfLessEqu - codes the quadruple if op1 <= op2 then goto op3
    1943              : */
    1944              : 
    1945              : static void CodeIfLessEqu (unsigned int quad);
    1946              : 
    1947              : /*
    1948              :    PerformCodeIfGreEqu - codes the quadruple if op1 >= op2 then goto op3
    1949              : */
    1950              : 
    1951              : static void PerformCodeIfGreEqu (unsigned int quad);
    1952              : 
    1953              : /*
    1954              :    CodeIfGreEqu - codes the quadruple if op1 >= op2 then goto op3
    1955              : */
    1956              : 
    1957              : static void CodeIfGreEqu (unsigned int quad);
    1958              : 
    1959              : /*
    1960              :    ComparisonMixTypes -
    1961              : */
    1962              : 
    1963              : static unsigned int ComparisonMixTypes (unsigned int varleft, unsigned int varright, unsigned int left, unsigned int right, unsigned int tokpos);
    1964              : 
    1965              : /*
    1966              :    PerformCodeIfEqu -
    1967              : */
    1968              : 
    1969              : static void PerformCodeIfEqu (unsigned int quad);
    1970              : 
    1971              : /*
    1972              :    PerformCodeIfNotEqu -
    1973              : */
    1974              : 
    1975              : static void PerformCodeIfNotEqu (unsigned int quad);
    1976              : 
    1977              : /*
    1978              :    IsValidExpressionRelOp - declare left and right constants (if they are not already declared).
    1979              :                             Check whether left and right are expression compatible.
    1980              : */
    1981              : 
    1982              : static bool IsValidExpressionRelOp (unsigned int quad, bool isin);
    1983              : 
    1984              : /*
    1985              :    CodeIfEqu - codes the quadruple if op1 = op2 then goto op3
    1986              : */
    1987              : 
    1988              : static void CodeIfEqu (unsigned int quad);
    1989              : 
    1990              : /*
    1991              :    CodeIfNotEqu - codes the quadruple if op1 # op2 then goto op3
    1992              : */
    1993              : 
    1994              : static void CodeIfNotEqu (unsigned int quad);
    1995              : 
    1996              : /*
    1997              :    MixTypes3 - returns a type compatible from, low, high, var.
    1998              : */
    1999              : 
    2000              : static unsigned int MixTypes3 (unsigned int low, unsigned int high, unsigned int var, unsigned int tokenno);
    2001              : 
    2002              : /*
    2003              :    BuildIfVarInConstValue - if var in constsetvalue then goto trueexit
    2004              : */
    2005              : 
    2006              : static void BuildIfVarInConstValue (location_t location, unsigned int tokenno, M2ALU_PtrToValue constsetvalue, unsigned int var, unsigned int trueexit);
    2007              : 
    2008              : /*
    2009              :    BuildIfNotVarInConstValue - if not (var in constsetvalue) then goto trueexit
    2010              : */
    2011              : 
    2012              : static void BuildIfNotVarInConstValue (location_t location, unsigned int tokenno, unsigned int quad, M2ALU_PtrToValue constsetvalue, unsigned int var, unsigned int trueexit);
    2013              : 
    2014              : /*
    2015              :     SetWideIfIn - if M2WIDESET.In (set, element) then goto branch end.
    2016              : */
    2017              : 
    2018              : static void SetWideIfIn (location_t location, unsigned int tokenno, bool invertCondition, unsigned int settype, unsigned int element, unsigned int set, unsigned int branch);
    2019              : 
    2020              : /*
    2021              :    CodeNarrowIfIn -
    2022              : */
    2023              : 
    2024              : static void CodeNarrowIfIn (location_t location, unsigned int settype, bool invertCondition, unsigned int element, unsigned int set, unsigned int branch);
    2025              : 
    2026              : /*
    2027              :    CodeIfInLower - code the quadruple: if element in set then goto branch.
    2028              :                    The invertCondition can be set to TRUE to handle CodeIfNotIn.
    2029              : */
    2030              : 
    2031              : static void CodeIfInLower (unsigned int tokenno, unsigned int quad, bool invertCondition, unsigned int element, unsigned int set, unsigned int branch);
    2032              : 
    2033              : /*
    2034              :    PerformCodeIfIn -
    2035              : */
    2036              : 
    2037              : static void PerformCodeIfIn (unsigned int quad, bool invert);
    2038              : 
    2039              : /*
    2040              :    CodeIfIn - code the quadruple: if element in set then goto branch.
    2041              : */
    2042              : 
    2043              : static void CodeIfIn (unsigned int quad);
    2044              : 
    2045              : /*
    2046              :    CodeIfNotIn - code the quadruple: if not (element in set) then goto branch.
    2047              : */
    2048              : 
    2049              : static void CodeIfNotIn (unsigned int quad);
    2050              : static void CodeIndrX (unsigned int quad);
    2051              : 
    2052              : /*
    2053              :    CodeXIndr - operands for XIndrOp are: left type right.
    2054              :                 *left = right.  The second operand is the type of the data being
    2055              :                 indirectly copied.
    2056              : */
    2057              : 
    2058              : static void CodeXIndr (unsigned int quad);
    2059              : 
    2060              : /*
    2061              :    InitBuiltinSyms -
    2062              : */
    2063              : 
    2064              : static void InitBuiltinSyms (unsigned int tok);
    2065              : 
    2066              : /*
    2067              :    gdbhook - a debugger convenience hook.
    2068              : */
    2069              : 
    2070              : static void gdbhook (void);
    2071              : 
    2072              : /*
    2073              :    BreakWhenQuadTranslated - to be called interactively by gdb.
    2074              : */
    2075              : 
    2076              : static void BreakWhenQuadTranslated (unsigned int quad);
    2077              : 
    2078              : /*
    2079              :    CheckBreak - if quad = BreakQuad then call gdbhook.
    2080              : */
    2081              : 
    2082              : static void CheckBreak (unsigned int quad);
    2083              : 
    2084              : /*
    2085              :    Init -
    2086              : */
    2087              : 
    2088              : static void Init (void);
    2089              : 
    2090              : 
    2091              : /*
    2092              :    ErrorMessageDecl - emit an error message together with declaration fragments of left
    2093              :                       and right if they are parameters or variables.
    2094              : */
    2095              : 
    2096           12 : static void ErrorMessageDecl (unsigned int tok, const char *message_, unsigned int _message_high, unsigned int left, unsigned int right, bool iserror)
    2097              : {
    2098           12 :   char message[_message_high+1];
    2099              : 
    2100              :   /* make a local copy of each unbounded array.  */
    2101           12 :   memcpy (message, message_, _message_high+1);
    2102              : 
    2103           12 :   M2MetaError_MetaErrorT2 (tok, (const char *) message, _message_high, left, right);
    2104           12 :   M2MetaError_MetaErrorDecl (left, iserror);
    2105           12 :   M2MetaError_MetaErrorDecl (right, iserror);
    2106           12 : }
    2107              : 
    2108              : 
    2109              : /*
    2110              :    IsExportedGcc - returns TRUE if this symbol should be (as far as the middle/backend of GCC)
    2111              :                    is concerned, exported.
    2112              : */
    2113              : 
    2114       105973 : static bool IsExportedGcc (unsigned int sym)
    2115              : {
    2116       105973 :   unsigned int scope;
    2117              : 
    2118              :   /* Has a procedure been overridden as public?  */
    2119       105973 :   if ((SymbolTable_IsProcedure (sym)) && (SymbolTable_IsPublic (sym)))
    2120              :     {
    2121              :       return true;
    2122              :     }
    2123              :   /* Check for whole program.  */
    2124        59951 :   if (M2Options_WholeProgram)
    2125              :     {
    2126        15816 :       scope = SymbolTable_GetScope (sym);
    2127        31632 :       while (scope != SymbolTable_NulSym)
    2128              :         {
    2129        15816 :           if (SymbolTable_IsDefImp (scope))
    2130              :             {
    2131        15792 :               return SymbolTable_IsExported (scope, sym);
    2132              :             }
    2133           24 :           else if (SymbolTable_IsModule (scope))
    2134              :             {
    2135              :               /* avoid dangling else.  */
    2136              :               return false;
    2137              :             }
    2138            0 :           scope = SymbolTable_GetScope (scope);
    2139              :         }
    2140            0 :       M2Error_InternalError ((const char *) "expecting scope to eventually reach a module or defimp symbol", 61);
    2141              :     }
    2142              :   else
    2143              :     {
    2144              :       /* Otherwise it is public if it were exported.  */
    2145        44135 :       return SymbolTable_IsExported (SymbolTable_GetMainModule (), sym);
    2146              :     }
    2147              :   ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2GenGCC.def", 20, 1);
    2148              :   __builtin_unreachable ();
    2149              : }
    2150              : 
    2151              : 
    2152              : /*
    2153              :    IsCompilingMainModule -
    2154              : */
    2155              : 
    2156       192836 : static bool IsCompilingMainModule (unsigned int sym)
    2157              : {
    2158       331160 :   while ((sym != SymbolTable_NulSym) && ((SymbolTable_GetMainModule ()) != sym))
    2159              :     {
    2160       138324 :       sym = SymbolTable_GetModuleScope (sym);
    2161              :     }
    2162       192836 :   return sym != SymbolTable_NulSym;
    2163              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    2164              :   __builtin_unreachable ();
    2165              : }
    2166              : 
    2167              : 
    2168              : /*
    2169              :    CodeLastForIterator - call PerformLastForIterator allowing for
    2170              :                          a non constant last iterator value.
    2171              : */
    2172              : 
    2173          792 : static void CodeLastForIterator (unsigned int quad)
    2174              : {
    2175            0 :   PerformLastForIterator (quad, (M2GCCDeclare_WalkAction) {(M2GCCDeclare_WalkAction_t) NoWalkProcedure}, false);
    2176          792 : }
    2177              : 
    2178              : 
    2179              : /*
    2180              :    FoldLastForIterator - call PerformLastForIterator providing
    2181              :                          all operands are constant and are known by GCC.
    2182              : */
    2183              : 
    2184        14950 : static void FoldLastForIterator (unsigned int quad, M2GCCDeclare_WalkAction p)
    2185              : {
    2186        14950 :   M2Quads_QuadOperator op;
    2187        14950 :   unsigned int e1;
    2188        14950 :   unsigned int e2;
    2189        14950 :   unsigned int op1;
    2190        14950 :   unsigned int tuple;
    2191        14950 :   unsigned int incr;
    2192              : 
    2193        14950 :   M2Quads_GetQuad (quad, &op, &op1, &tuple, &incr);
    2194        14950 :   M2Debug_Assert (SymbolTable_IsTuple (tuple));
    2195        14950 :   e1 = SymbolTable_GetNth (tuple, 1);
    2196        14950 :   e2 = SymbolTable_GetNth (tuple, 2);
    2197        14950 :   if (((((((SymbolTable_IsConst (op1)) && (SymbolTable_IsConst (e1))) && (SymbolTable_IsConst (e2))) && (SymbolTable_IsConst (incr))) && (SymbolConversion_GccKnowsAbout (e1))) && (SymbolConversion_GccKnowsAbout (e2))) && (SymbolConversion_GccKnowsAbout (incr)))
    2198              :     {
    2199         1702 :       PerformLastForIterator (quad, p, true);
    2200              :     }
    2201        14950 : }
    2202              : 
    2203         2494 : static void PerformLastForIterator (unsigned int quad, M2GCCDeclare_WalkAction p, bool constant)
    2204              : {
    2205         2494 :   bool success;
    2206         2494 :   bool constExpr;
    2207         2494 :   bool overflowChecking;
    2208         2494 :   M2Quads_QuadOperator op;
    2209         2494 :   unsigned int lastpos;
    2210         2494 :   unsigned int op1pos;
    2211         2494 :   unsigned int op2pos;
    2212         2494 :   unsigned int incrpos;
    2213         2494 :   unsigned int last;
    2214         2494 :   unsigned int tuple;
    2215         2494 :   unsigned int incr;
    2216         2494 :   unsigned int e1;
    2217         2494 :   unsigned int e2;
    2218         2494 :   tree lasttree;
    2219         2494 :   tree e1tree;
    2220         2494 :   tree e2tree;
    2221         2494 :   tree expr;
    2222         2494 :   tree incrtree;
    2223         2494 :   location_t location;
    2224              : 
    2225              :   /* 
    2226              :    FoldLastForIterator - generates code to calculate the last iterator value
    2227              :                          in a for loop.  It examines the increment constant
    2228              :                          and generates different code depending whether it is
    2229              :                          negative or positive.
    2230              :   */
    2231         2494 :   M2Quads_GetQuadOtok (quad, &lastpos, &op, &last, &tuple, &incr, &overflowChecking, &constExpr, &op1pos, &op2pos, &incrpos);
    2232         2494 :   M2GCCDeclare_DeclareConstant (incrpos, incr);
    2233         2494 :   lasttree = SymbolConversion_Mod2Gcc (last);
    2234         2494 :   success = true;
    2235         2494 :   if (SymbolTable_IsConst (incr))
    2236              :     {
    2237              :       /* avoid dangling else.  */
    2238         2494 :       incrtree = SymbolConversion_Mod2Gcc (incr);
    2239         2494 :       location = M2LexBuf_TokenToLocation (lastpos);
    2240         2494 :       e1 = SymbolTable_GetNth (tuple, 1);
    2241         2494 :       e2 = SymbolTable_GetNth (tuple, 2);
    2242         2494 :       e1tree = SymbolConversion_Mod2Gcc (e1);
    2243         2494 :       e2tree = SymbolConversion_Mod2Gcc (e2);
    2244         2494 :       if ((m2expr_CompareTrees (incrtree, m2expr_GetIntegerZero (location))) == 0)
    2245              :         {
    2246            6 :           M2MetaError_MetaErrorT0 (lastpos, (const char *) "the {%kFOR} loop step value must not be zero", 44);
    2247            6 :           M2MetaError_MetaErrorDecl (incr, true);
    2248            6 :           NoChange = false;
    2249            6 :           M2Quads_SubQuad (quad);
    2250            6 :           success = false;
    2251              :         }
    2252         2488 :       else if ((m2expr_CompareTrees (incrtree, m2expr_GetIntegerZero (location))) > 0)
    2253              :         {
    2254              :           /* avoid dangling else.  */
    2255              :           /* If incr > 0 then LastIterator := ((e2-e1) DIV incr) * incr + e1.  */
    2256         2278 :           expr = m2expr_BuildSub (location, e2tree, e1tree, false);
    2257         2278 :           incrtree = m2convert_BuildConvert (location, m2type_GetTreeType (expr), incrtree, false);
    2258         2278 :           if (m2expr_TreeOverflow (incrtree))
    2259              :             {
    2260            0 :               M2MetaError_MetaErrorT0 (lastpos, (const char *) "the intemediate calculation for the last iterator value in the {%kFOR} loop has caused an overflow", 98);
    2261            0 :               NoChange = false;
    2262            0 :               M2Quads_SubQuad (quad);
    2263            0 :               success = false;
    2264              :             }
    2265              :           else
    2266              :             {
    2267         2278 :               expr = m2expr_BuildDivFloor (location, expr, incrtree, false);
    2268         2278 :               expr = m2expr_BuildMult (location, expr, incrtree, false);
    2269         2278 :               expr = m2expr_BuildAdd (location, expr, e1tree, false);
    2270              :             }
    2271              :         }
    2272              :       else
    2273              :         {
    2274              :           /* avoid dangling else.  */
    2275              :           /* Else use LastIterator := e1 - ((e1-e2) DIV PositiveBy) * PositiveBy
    2276              :             to avoid unsigned div signed arithmetic.  */
    2277          210 :           expr = m2expr_BuildSub (location, e1tree, e2tree, false);
    2278          210 :           incrtree = m2convert_BuildConvert (location, m2type_GetM2ZType (), incrtree, false);
    2279          210 :           incrtree = m2expr_BuildNegate (location, incrtree, false);
    2280          210 :           incrtree = m2convert_BuildConvert (location, m2type_GetTreeType (expr), incrtree, false);
    2281          210 :           if (m2expr_TreeOverflow (incrtree))
    2282              :             {
    2283            0 :               M2MetaError_MetaErrorT0 (lastpos, (const char *) "the intemediate calculation for the last iterator value in the {%kFOR} loop has caused an overflow", 98);
    2284            0 :               NoChange = false;
    2285            0 :               M2Quads_SubQuad (quad);
    2286            0 :               success = false;
    2287              :             }
    2288              :           else
    2289              :             {
    2290          210 :               expr = m2expr_BuildSub (location, e1tree, e2tree, false);
    2291          210 :               expr = m2expr_BuildDivFloor (location, expr, incrtree, false);
    2292          210 :               expr = m2expr_BuildMult (location, expr, incrtree, false);
    2293          210 :               expr = m2expr_BuildSub (location, e1tree, expr, false);
    2294              :             }
    2295              :         }
    2296         2494 :       if (success)
    2297              :         {
    2298              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    2299         2488 :           if (SymbolTable_IsConst (last))
    2300              :             {
    2301         1696 :               SymbolConversion_AddModGcc (last, expr);
    2302         1696 :               (*p.proc) (last);
    2303         1696 :               NoChange = false;
    2304         1696 :               M2Quads_SubQuad (quad);
    2305              :             }
    2306              :           else
    2307              :             {
    2308          792 :               M2Debug_Assert (! constant);
    2309          792 :               m2statement_BuildAssignmentStatement (location, lasttree, expr);
    2310              :             }
    2311              :         }
    2312              :     }
    2313              :   else
    2314              :     {
    2315            0 :       M2MetaError_MetaErrorT1 (lastpos, (const char *) "the value {%1Ead} in the {%kBY} clause of the {%kFOR} loop must be constant", 75, incr);
    2316            0 :       M2MetaError_MetaErrorDecl (incr, true);
    2317            0 :       NoChange = false;
    2318            0 :       M2Quads_SubQuad (quad);
    2319              :     }
    2320         2494 : }
    2321              : 
    2322              : 
    2323              : /*
    2324              :    CodeStatement - A multi-way decision call depending on the current
    2325              :                    quadruple.
    2326              : */
    2327              : 
    2328      4167916 : static void CodeStatement (unsigned int q)
    2329              : {
    2330      4167916 :   M2Quads_QuadOperator op;
    2331      4167916 :   unsigned int op1;
    2332      4167916 :   unsigned int op2;
    2333      4167916 :   unsigned int op3;
    2334      4167916 :   location_t location;
    2335              : 
    2336      4167916 :   InitBuiltinSyms (M2LexBuf_BuiltinTokenNo);
    2337      4167916 :   M2Quads_GetQuad (q, &op, &op1, &op2, &op3);
    2338      4167916 :   CheckBreak (q);
    2339      4167916 :   if (op == M2Quads_StatementNoteOp)
    2340              :     {
    2341       482879 :       FoldStatementNote (op3);  /* Will change CurrentQuadToken using op3.  */
    2342              :     }
    2343              :   else
    2344              :     {
    2345      3685037 :       CurrentQuadToken = M2Quads_QuadToTokenNo (q);
    2346              :     }
    2347      4167916 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    2348      4167916 :   CheckReferenced (q, op);
    2349      4167916 :   if (M2Options_GetDebugTraceQuad ())
    2350              :     {
    2351            0 :       M2Printf_printf0 ((const char *) "building: ", 10);
    2352            0 :       M2Quads_DisplayQuad (q);
    2353              :     }
    2354      4167916 :   switch (op)
    2355              :     {
    2356       156390 :       case M2Quads_StartDefFileOp:
    2357       156390 :         CodeStartDefFile (op3);
    2358       156390 :         break;
    2359              : 
    2360        81404 :       case M2Quads_StartModFileOp:
    2361        81404 :         CodeStartModFile (op3);
    2362        81404 :         break;
    2363              : 
    2364        81812 :       case M2Quads_ModuleScopeOp:
    2365        81812 :         CodeModuleScope (op3);
    2366        81812 :         break;
    2367              : 
    2368       237794 :       case M2Quads_EndFileOp:
    2369       237794 :         CodeEndFile ();
    2370       237794 :         break;
    2371              : 
    2372        81812 :       case M2Quads_InitStartOp:
    2373        81812 :         CodeInitStart (op3, IsCompilingMainModule (op3));
    2374        81812 :         break;
    2375              : 
    2376        81812 :       case M2Quads_InitEndOp:
    2377        81812 :         CodeInitEnd (op3, IsCompilingMainModule (op3));
    2378        81812 :         break;
    2379              : 
    2380        14606 :       case M2Quads_FinallyStartOp:
    2381        14606 :         CodeFinallyStart (op3, IsCompilingMainModule (op3));
    2382        14606 :         break;
    2383              : 
    2384        14606 :       case M2Quads_FinallyEndOp:
    2385        14606 :         CodeFinallyEnd (op3, IsCompilingMainModule (op3));
    2386        14606 :         break;
    2387              : 
    2388        76755 :       case M2Quads_NewLocalVarOp:
    2389        76755 :         CodeNewLocalVar (op1, op3);
    2390        76755 :         break;
    2391              : 
    2392        76749 :       case M2Quads_KillLocalVarOp:
    2393        76749 :         CodeKillLocalVar (op3);
    2394        76749 :         break;
    2395              : 
    2396        76761 :       case M2Quads_ProcedureScopeOp:
    2397        76761 :         CodeProcedureScope (op3);
    2398        76761 :         break;
    2399              : 
    2400              :       case M2Quads_ReturnOp:
    2401              :         break;
    2402              : 
    2403        27443 :       case M2Quads_ReturnValueOp:
    2404        27443 :         CodeReturnValue (q);  /* Not used as return is achieved by KillLocalVar.  */
    2405        27443 :         break;
    2406              : 
    2407         2890 :       case M2Quads_TryOp:
    2408         2890 :         CodeTry ();
    2409         2890 :         break;
    2410              : 
    2411          320 :       case M2Quads_ThrowOp:
    2412          320 :         CodeThrow (op3);
    2413          320 :         break;
    2414              : 
    2415         2890 :       case M2Quads_CatchBeginOp:
    2416         2890 :         CodeCatchBegin ();
    2417         2890 :         break;
    2418              : 
    2419         2890 :       case M2Quads_CatchEndOp:
    2420         2890 :         CodeCatchEnd ();
    2421         2890 :         break;
    2422              : 
    2423          156 :       case M2Quads_RetryOp:
    2424          156 :         CodeRetry (op3);
    2425          156 :         break;
    2426              : 
    2427              :       case M2Quads_DummyOp:
    2428              :         break;
    2429              : 
    2430           54 :       case M2Quads_InitAddressOp:
    2431           54 :         CodeInitAddress (q, op1, op2, op3);
    2432           54 :         break;
    2433              : 
    2434       189676 :       case M2Quads_BecomesOp:
    2435       189676 :         CodeBecomes (q);
    2436       189676 :         break;
    2437              : 
    2438        34062 :       case M2Quads_ArithAddOp:
    2439        34062 :       case M2Quads_AddOp:
    2440        34062 :         CodeAddChecked (q, op2, op3);
    2441        34062 :         break;
    2442              : 
    2443        10318 :       case M2Quads_SubOp:
    2444        10318 :         CodeSubChecked (q, op2, op3);
    2445        10318 :         break;
    2446              : 
    2447        11456 :       case M2Quads_MultOp:
    2448        11456 :         CodeMultChecked (q, op2, op3);
    2449        11456 :         break;
    2450              : 
    2451         1940 :       case M2Quads_DivM2Op:
    2452         1940 :         CodeDivM2Checked (q, op2, op3);
    2453         1940 :         break;
    2454              : 
    2455         2088 :       case M2Quads_ModM2Op:
    2456         2088 :         CodeModM2Checked (q, op2, op3);
    2457         2088 :         break;
    2458              : 
    2459          734 :       case M2Quads_DivTruncOp:
    2460          734 :         CodeDivTrunc (q, op2, op3);
    2461          734 :         break;
    2462              : 
    2463            0 :       case M2Quads_ModTruncOp:
    2464            0 :         CodeModTrunc (q, op2, op3);
    2465            0 :         break;
    2466              : 
    2467            0 :       case M2Quads_DivCeilOp:
    2468            0 :         CodeDivCeil (q, op2, op3);
    2469            0 :         break;
    2470              : 
    2471            0 :       case M2Quads_ModCeilOp:
    2472            0 :         CodeModCeil (q, op2, op3);
    2473            0 :         break;
    2474              : 
    2475            0 :       case M2Quads_DivFloorOp:
    2476            0 :         CodeDivFloor (q, op2, op3);
    2477            0 :         break;
    2478              : 
    2479            0 :       case M2Quads_ModFloorOp:
    2480            0 :         CodeModFloor (q, op2, op3);
    2481            0 :         break;
    2482              : 
    2483        44711 :       case M2Quads_GotoOp:
    2484        44711 :         CodeGoto (op3);
    2485        44711 :         break;
    2486              : 
    2487         1142 :       case M2Quads_InclOp:
    2488         1142 :         CodeIncl (q);
    2489         1142 :         break;
    2490              : 
    2491          754 :       case M2Quads_ExclOp:
    2492          754 :         CodeExcl (q);
    2493          754 :         break;
    2494              : 
    2495          996 :       case M2Quads_NegateOp:
    2496          996 :         CodeNegateChecked (q);
    2497          996 :         break;
    2498              : 
    2499          792 :       case M2Quads_LastForIteratorOp:
    2500          792 :         CodeLastForIterator (q);
    2501          792 :         break;
    2502              : 
    2503          676 :       case M2Quads_LogicalShiftOp:
    2504          676 :         CodeSetShift (q);
    2505          676 :         break;
    2506              : 
    2507          406 :       case M2Quads_LogicalRotateOp:
    2508          406 :         CodeSetRotate (q);
    2509          406 :         break;
    2510              : 
    2511          686 :       case M2Quads_LogicalOrOp:
    2512          686 :         CodeSetOr (q);
    2513          686 :         break;
    2514              : 
    2515          284 :       case M2Quads_LogicalAndOp:
    2516          284 :         CodeSetAnd (q);
    2517          284 :         break;
    2518              : 
    2519          124 :       case M2Quads_LogicalXorOp:
    2520          124 :         CodeSetSymmetricDifference (q);
    2521          124 :         break;
    2522              : 
    2523           66 :       case M2Quads_LogicalDiffOp:
    2524           66 :         CodeSetLogicalDifference (q);
    2525           66 :         break;
    2526              : 
    2527         3826 :       case M2Quads_IfLessOp:
    2528         3826 :         CodeIfLess (q);
    2529         3826 :         break;
    2530              : 
    2531        20726 :       case M2Quads_IfEquOp:
    2532        20726 :         CodeIfEqu (q);
    2533        20726 :         break;
    2534              : 
    2535        32029 :       case M2Quads_IfNotEquOp:
    2536        32029 :         CodeIfNotEqu (q);
    2537        32029 :         break;
    2538              : 
    2539         7076 :       case M2Quads_IfGreEquOp:
    2540         7076 :         CodeIfGreEqu (q);
    2541         7076 :         break;
    2542              : 
    2543         5766 :       case M2Quads_IfLessEquOp:
    2544         5766 :         CodeIfLessEqu (q);
    2545         5766 :         break;
    2546              : 
    2547         4606 :       case M2Quads_IfGreOp:
    2548         4606 :         CodeIfGre (q);
    2549         4606 :         break;
    2550              : 
    2551          532 :       case M2Quads_IfInOp:
    2552          532 :         CodeIfIn (q);
    2553          532 :         break;
    2554              : 
    2555         1866 :       case M2Quads_IfNotInOp:
    2556         1866 :         CodeIfNotIn (q);
    2557         1866 :         break;
    2558              : 
    2559        16429 :       case M2Quads_IndrXOp:
    2560        16429 :         CodeIndrX (q);
    2561        16429 :         break;
    2562              : 
    2563        43222 :       case M2Quads_XIndrOp:
    2564        43222 :         CodeXIndr (q);
    2565        43222 :         break;
    2566              : 
    2567       205633 :       case M2Quads_CallOp:
    2568       205633 :         CodeCall (CurrentQuadToken, op3);
    2569       205633 :         break;
    2570              : 
    2571       580352 :       case M2Quads_ParamOp:
    2572       580352 :         CodeParam (q);
    2573       580352 :         break;
    2574              : 
    2575        66389 :       case M2Quads_FunctValueOp:
    2576        66389 :         CodeFunctValue (location, op1);
    2577        66389 :         break;
    2578              : 
    2579       184481 :       case M2Quads_AddrOp:
    2580       184481 :         CodeAddr (CurrentQuadToken, q, op1, op3);
    2581       184481 :         break;
    2582              : 
    2583            0 :       case M2Quads_SizeOp:
    2584            0 :         CodeSize (op1, op3);
    2585            0 :         break;
    2586              : 
    2587        33615 :       case M2Quads_UnboundedOp:
    2588        33615 :         CodeUnbounded (op1, op3);
    2589        33615 :         break;
    2590              : 
    2591       138682 :       case M2Quads_RecordFieldOp:
    2592       138682 :         CodeRecordField (op1, op2, op3);
    2593       138682 :         break;
    2594              : 
    2595        38823 :       case M2Quads_HighOp:
    2596        38823 :         CodeHigh (op1, op2, op3);
    2597        38823 :         break;
    2598              : 
    2599        46734 :       case M2Quads_ArrayOp:
    2600        46734 :         CodeArray (op1, op2, op3);
    2601        46734 :         break;
    2602              : 
    2603            0 :       case M2Quads_ElementSizeOp:
    2604            0 :         M2Error_InternalError ((const char *) "ElementSizeOp is expected to have been folded via constant evaluation", 69);
    2605        51722 :         break;
    2606              : 
    2607        51722 :       case M2Quads_ConvertOp:
    2608        51722 :         CodeConvert (q, op1, op2, op3);
    2609        51722 :         break;
    2610              : 
    2611         1308 :       case M2Quads_CoerceOp:
    2612         1308 :         CodeCoerce (q, op1, op2, op3);
    2613         1308 :         break;
    2614              : 
    2615          126 :       case M2Quads_CastOp:
    2616          126 :         CodeCast (q, op1, op2, op3);
    2617          126 :         break;
    2618              : 
    2619          330 :       case M2Quads_StandardFunctionOp:
    2620          330 :         CodeStandardFunction (q, op1, op2, op3);
    2621          330 :         break;
    2622              : 
    2623          420 :       case M2Quads_SavePriorityOp:
    2624          420 :         CodeSavePriority (op1, op2, op3);
    2625          420 :         break;
    2626              : 
    2627          412 :       case M2Quads_RestorePriorityOp:
    2628          412 :         CodeRestorePriority (op1, op2, op3);
    2629          412 :         break;
    2630              : 
    2631           27 :       case M2Quads_InlineOp:
    2632           27 :         CodeInline (q);
    2633           27 :         break;
    2634              : 
    2635       482879 :       case M2Quads_StatementNoteOp:
    2636       482879 :         CodeStatementNote (op3);
    2637       482879 :         break;
    2638              : 
    2639              :       case M2Quads_CodeOnOp:
    2640              :         break;
    2641              : 
    2642              :       case M2Quads_CodeOffOp:
    2643              :         break;
    2644              : 
    2645              :       case M2Quads_ProfileOnOp:
    2646              :         break;
    2647              : 
    2648              :       case M2Quads_ProfileOffOp:
    2649              :         break;
    2650              : 
    2651              :       case M2Quads_OptimizeOnOp:
    2652              :         break;
    2653              : 
    2654              :       case M2Quads_OptimizeOffOp:
    2655              :         break;
    2656              : 
    2657       797732 :       case M2Quads_RangeCheckOp:
    2658       797732 :         CodeRange (op3);  /* The following make no sense with gcc.  */
    2659       797732 :         break;
    2660              : 
    2661          965 :       case M2Quads_ErrorOp:
    2662          965 :         CodeError (op3);
    2663          965 :         break;
    2664              : 
    2665         2890 :       case M2Quads_SaveExceptionOp:
    2666         2890 :         CodeSaveException (op1, op3);
    2667         2890 :         break;
    2668              : 
    2669         2830 :       case M2Quads_RestoreExceptionOp:
    2670         2830 :         CodeRestoreException (op1, op3);
    2671         2830 :         break;
    2672              : 
    2673              : 
    2674            0 :       default:
    2675            0 :         M2Error_WriteFormat1 ((const char *) "quadruple %d not yet implemented", 32, (const unsigned char *) &q, (sizeof (q)-1));
    2676            0 :         M2Error_InternalError ((const char *) "quadruple not implemented yet", 29);
    2677      4167904 :         break;
    2678              :     }
    2679      4167904 :   LastOperator = op;
    2680      4167904 : }
    2681              : 
    2682              : 
    2683              : /*
    2684              :    FindSize - given a Modula-2 symbol sym return a gcc tree
    2685              :               constant representing the storage size in bytes.
    2686              : */
    2687              : 
    2688        29928 : static tree FindSize (unsigned int tokenno, unsigned int sym)
    2689              : {
    2690        29928 :   location_t location;
    2691              : 
    2692        29928 :   location = M2LexBuf_TokenToLocation (tokenno);
    2693        29928 :   if (SymbolTable_IsConstString (sym))
    2694              :     {
    2695         6432 :       M2Debug_Assert (SymbolTable_IsConstStringKnown (sym));
    2696         6432 :       M2ALU_PushCard (SymbolTable_GetStringLength (tokenno, sym));
    2697         6432 :       return M2ALU_PopIntegerTree ();
    2698              :     }
    2699        23496 :   else if (SymbolTable_IsSizeSolved (sym))
    2700              :     {
    2701              :       /* avoid dangling else.  */
    2702        19960 :       SymbolTable_PushSize (sym);
    2703        19960 :       return M2ALU_PopIntegerTree ();
    2704              :     }
    2705              :   else
    2706              :     {
    2707              :       /* avoid dangling else.  */
    2708         3536 :       if (SymbolConversion_GccKnowsAbout (sym))
    2709              :         {
    2710         3536 :           if ((SymbolTable_IsVar (sym)) && (SymbolTable_IsVariableSSA (sym)))
    2711              :             {
    2712            0 :               sym = SymbolTable_GetType (sym);
    2713              :             }
    2714         3536 :           M2ALU_PushIntegerTree (m2expr_BuildSize (location, SymbolConversion_Mod2Gcc (sym), false));
    2715         3536 :           SymbolTable_PopSize (sym);
    2716         3536 :           SymbolTable_PushSize (sym);
    2717         3536 :           return M2ALU_PopIntegerTree ();
    2718              :         }
    2719            0 :       else if ((SymbolTable_IsVar (sym)) && (SymbolConversion_GccKnowsAbout (SymbolTable_GetType (sym))))
    2720              :         {
    2721              :           /* avoid dangling else.  */
    2722            0 :           M2ALU_PushIntegerTree (m2expr_BuildSize (location, SymbolConversion_Mod2Gcc (SymbolTable_GetType (sym)), false));
    2723            0 :           return M2ALU_PopIntegerTree ();
    2724              :         }
    2725              :       else
    2726              :         {
    2727              :           /* avoid dangling else.  */
    2728            0 :           M2Error_InternalError ((const char *) "expecting gcc to already know about this symbol", 47);
    2729              :         }
    2730              :     }
    2731              :   ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2GenGCC.def", 20, 1);
    2732              :   __builtin_unreachable ();
    2733              : }
    2734              : 
    2735              : 
    2736              : /*
    2737              :    FindType - returns the type of, Sym, if Sym is a TYPE then return Sym otherwise return GetType(Sym)
    2738              : */
    2739              : 
    2740       244222 : static unsigned int FindType (unsigned int Sym)
    2741              : {
    2742       244222 :   if (SymbolTable_IsType (Sym))
    2743              :     {
    2744              :       return Sym;
    2745              :     }
    2746              :   else
    2747              :     {
    2748       244222 :       return SymbolTable_GetType (Sym);
    2749              :     }
    2750              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    2751              :   __builtin_unreachable ();
    2752              : }
    2753              : 
    2754              : 
    2755              : /*
    2756              :    BuildTreeFromInterface - generates a GCC tree from an interface definition.
    2757              : */
    2758              : 
    2759           54 : static tree BuildTreeFromInterface (unsigned int sym)
    2760              : {
    2761           54 :   unsigned int tok;
    2762           54 :   unsigned int i;
    2763           54 :   NameKey_Name name;
    2764           54 :   unsigned int str;
    2765           54 :   unsigned int obj;
    2766           54 :   tree gccName;
    2767           54 :   tree asmTree;
    2768              : 
    2769           54 :   asmTree = (tree) (NULL);
    2770           54 :   if (sym != SymbolTable_NulSym)
    2771              :     {
    2772              :       i = 1;
    2773           63 :       do {
    2774           63 :         SymbolTable_GetRegInterface (sym, i, &tok, &name, &str, &obj);
    2775           63 :         if (str != SymbolTable_NulSym)
    2776              :           {
    2777              :             /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    2778           33 :             if (SymbolTable_IsConstString (str))
    2779              :               {
    2780              :                 /* avoid dangling else.  */
    2781           33 :                 M2GCCDeclare_DeclareConstant (tok, obj);
    2782           33 :                 if (name == NameKey_NulName)
    2783              :                   {
    2784              :                     gccName = NULL;
    2785              :                   }
    2786              :                 else
    2787              :                   {
    2788            6 :                     gccName = m2decl_BuildCStringConstant (const_cast <const char * > (static_cast <char * > (NameKey_KeyToCharStar (name))), static_cast<int> (NameKey_LengthKey (name)));
    2789              :                   }
    2790           33 :                 asmTree = m2type_ChainOnParamValue (asmTree, gccName, M2GCCDeclare_PromoteToCString (tok, str), m2tree_skip_const_decl (SymbolConversion_Mod2Gcc (obj)));
    2791           33 :                 if (DebugTokPos)
    2792              :                   {
    2793              :                     M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "input expression", 16), tok);
    2794              :                   }
    2795              :               }
    2796              :             else
    2797              :               {
    2798            0 :                 M2MetaError_MetaErrorT1 (tok, (const char *) "a constraint to the GNU ASM statement must be a constant string and not a {%1Edv}", 81, str);
    2799              :               }
    2800              :           }
    2801           63 :         i += 1;
    2802           63 :       } while (! ((str == SymbolTable_NulSym) && (obj == SymbolTable_NulSym)));
    2803              :     }
    2804           54 :   return asmTree;
    2805              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    2806              :   __builtin_unreachable ();
    2807              : }
    2808              : 
    2809              : 
    2810              : /*
    2811              :    BuildTrashTreeFromInterface - generates a GCC string tree from an interface definition.
    2812              : */
    2813              : 
    2814           27 : static tree BuildTrashTreeFromInterface (unsigned int sym)
    2815              : {
    2816           27 :   unsigned int tok;
    2817           27 :   unsigned int i;
    2818           27 :   unsigned int str;
    2819           27 :   unsigned int obj;
    2820           27 :   NameKey_Name name;
    2821           27 :   tree asmTree;
    2822              : 
    2823           27 :   asmTree = (tree) (NULL);
    2824           27 :   if (sym != SymbolTable_NulSym)
    2825              :     {
    2826              :       i = 1;
    2827            6 :       do {
    2828            6 :         SymbolTable_GetRegInterface (sym, i, &tok, &name, &str, &obj);
    2829            6 :         if (str != SymbolTable_NulSym)
    2830              :           {
    2831              :             /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    2832            0 :             if (SymbolTable_IsConstString (str))
    2833              :               {
    2834              :                 /* avoid dangling else.  */
    2835            0 :                 asmTree = m2type_AddStringToTreeList (asmTree, M2GCCDeclare_PromoteToCString (tok, str));
    2836            0 :                 if (DebugTokPos)
    2837              :                   {
    2838              :                     M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "trash expression", 16), tok);
    2839              :                   }
    2840              :               }
    2841              :             else
    2842              :               {
    2843            0 :                 M2MetaError_MetaErrorT1 (tok, (const char *) "a constraint to the GNU ASM statement must be a constant string and not a {%1Edv}", 81, str);
    2844              :               }
    2845              :           }
    2846            6 :         i += 1;
    2847            6 :       } while (! ((str == SymbolTable_NulSym) && (obj == SymbolTable_NulSym)));
    2848              :     }
    2849           27 :   return asmTree;
    2850              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    2851              :   __builtin_unreachable ();
    2852              : }
    2853              : 
    2854              : 
    2855              : /*
    2856              :    CodeInline - InlineOp is a quadruple which has the following format:
    2857              : 
    2858              :                 InlineOp   NulSym  NulSym  Sym
    2859              : */
    2860              : 
    2861           27 : static void CodeInline (unsigned int quad)
    2862              : {
    2863           27 :   bool constExpr;
    2864           27 :   bool overflowChecking;
    2865           27 :   M2Quads_QuadOperator op;
    2866           27 :   unsigned int op1;
    2867           27 :   unsigned int op2;
    2868           27 :   unsigned int GnuAsm;
    2869           27 :   unsigned int op1pos;
    2870           27 :   unsigned int op2pos;
    2871           27 :   unsigned int op3pos;
    2872           27 :   unsigned int asmpos;
    2873           27 :   unsigned int string;
    2874           27 :   tree inputs;
    2875           27 :   tree outputs;
    2876           27 :   tree trash;
    2877           27 :   tree labels;
    2878           27 :   location_t location;
    2879              : 
    2880           27 :   M2Quads_GetQuadOtok (quad, &asmpos, &op, &op1, &op2, &GnuAsm, &overflowChecking, &constExpr, &op1pos, &op2pos, &op3pos);
    2881           27 :   location = M2LexBuf_TokenToLocation (asmpos);
    2882           27 :   inputs = BuildTreeFromInterface (SymbolTable_GetGnuAsmInput (GnuAsm));
    2883           27 :   outputs = BuildTreeFromInterface (SymbolTable_GetGnuAsmOutput (GnuAsm));
    2884           27 :   trash = BuildTrashTreeFromInterface (SymbolTable_GetGnuAsmTrash (GnuAsm));
    2885           27 :   labels = NULL;  /* At present it makes no sence for Modula-2 to jump to a label,
    2886              :                         given that labels are not allowed in Modula-2.  */
    2887           27 :   string = SymbolTable_GetGnuAsm (GnuAsm);  /* At present it makes no sence for Modula-2 to jump to a label,
    2888              :                         given that labels are not allowed in Modula-2.  */
    2889           27 :   m2statement_BuildAsm (location, M2GCCDeclare_PromoteToCString (SymbolTable_GetDeclaredMod (string), string), SymbolTable_IsGnuAsmVolatile (GnuAsm), SymbolTable_IsGnuAsmSimple (GnuAsm), inputs, outputs, trash, labels);
    2890           27 : }
    2891              : 
    2892              : 
    2893              : /*
    2894              :    FoldStatementNote - set CurrentQuadToken to tokennno.
    2895              : */
    2896              : 
    2897     10326971 : static void FoldStatementNote (unsigned int tokenno)
    2898              : {
    2899     10326971 :   CurrentQuadToken = tokenno;
    2900       482879 : }
    2901              : 
    2902              : 
    2903              : /*
    2904              :    CodeStatementNote - set CurrentQuadToken to tokennno and
    2905              :                        add a statement note.
    2906              : */
    2907              : 
    2908       482879 : static void CodeStatementNote (unsigned int tokenno)
    2909              : {
    2910       482879 :   if (Debugging)
    2911              :     {
    2912              :       M2MetaError_MetaErrorT0 (tokenno, (const char *) "{%W} statement note", 19);
    2913              :     }
    2914       482879 :   CurrentQuadToken = tokenno;
    2915       482879 :   m2block_addStmtNote (M2LexBuf_TokenToLocation (tokenno));
    2916       482879 : }
    2917              : 
    2918              : 
    2919              : /*
    2920              :    FoldRange - attempts to fold the range test.
    2921              :                --fixme-- complete this.
    2922              : */
    2923              : 
    2924     14154527 : static void FoldRange (unsigned int tokenno, unsigned int quad, unsigned int rangeno)
    2925              : {
    2926            0 :   M2Range_FoldRangeCheck (tokenno, quad, rangeno);  /* p: WalkAction;  */
    2927     14154365 : }
    2928              : 
    2929              : 
    2930              : /*
    2931              :    CodeSaveException - op1 := op3(TRUE)
    2932              : */
    2933              : 
    2934         2890 : static void CodeSaveException (unsigned int des, unsigned int exceptionProcedure)
    2935              : {
    2936         2890 :   tree functValue;
    2937         2890 :   location_t location;
    2938              : 
    2939         2890 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    2940         2890 :   m2statement_BuildParam (location, SymbolConversion_Mod2Gcc (M2Base_True));
    2941         2890 :   m2statement_BuildFunctionCallTree (location, SymbolConversion_Mod2Gcc (exceptionProcedure), SymbolConversion_Mod2Gcc (SymbolTable_GetType (exceptionProcedure)));
    2942         2890 :   functValue = m2statement_BuildFunctValue (location, SymbolConversion_Mod2Gcc (des));
    2943         2890 :   m2type_AddStatement (location, functValue);
    2944         2890 : }
    2945              : 
    2946              : 
    2947              : /*
    2948              :    CodeRestoreException - op1 := op3(op1).
    2949              : */
    2950              : 
    2951         2830 : static void CodeRestoreException (unsigned int des, unsigned int exceptionProcedure)
    2952              : {
    2953         2830 :   tree functValue;
    2954         2830 :   location_t location;
    2955              : 
    2956         2830 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    2957         2830 :   m2statement_BuildParam (location, SymbolConversion_Mod2Gcc (des));
    2958         2830 :   m2statement_BuildFunctionCallTree (location, SymbolConversion_Mod2Gcc (exceptionProcedure), SymbolConversion_Mod2Gcc (SymbolTable_GetType (exceptionProcedure)));
    2959         2830 :   functValue = m2statement_BuildFunctValue (location, SymbolConversion_Mod2Gcc (des));
    2960         2830 :   m2type_AddStatement (location, functValue);
    2961         2830 : }
    2962              : 
    2963              : 
    2964              : /*
    2965              :    PushScope -
    2966              : */
    2967              : 
    2968       396361 : static void PushScope (unsigned int sym)
    2969              : {
    2970            0 :   M2StackWord_PushWord (ScopeStack, sym);
    2971            0 : }
    2972              : 
    2973              : 
    2974              : /*
    2975              :    PopScope -
    2976              : */
    2977              : 
    2978        76749 : static void PopScope (void)
    2979              : {
    2980        76749 :   unsigned int sym;
    2981              : 
    2982        76749 :   sym = static_cast<unsigned int> (M2StackWord_PopWord (ScopeStack));
    2983        76749 :   M2Debug_Assert (sym != SymbolTable_NulSym);
    2984        76749 : }
    2985              : 
    2986              : 
    2987              : /*
    2988              :    GetActiveScope -
    2989              : */
    2990              : 
    2991         3288 : static unsigned int GetActiveScope (void)
    2992              : {
    2993         3288 :   if (M2StackWord_IsEmptyWord (ScopeStack))
    2994              :     {
    2995            0 :       M2Error_InternalError ((const char *) "not expecting scope stack to be empty", 37);
    2996              :     }
    2997         3288 :   return static_cast<unsigned int> (M2StackWord_PeepWord (ScopeStack, 1));
    2998              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    2999              :   __builtin_unreachable ();
    3000              : }
    3001              : 
    3002              : 
    3003              : /*
    3004              :    GetCurrentScopeDescription - returns a description of the current scope.
    3005              : */
    3006              : 
    3007       798697 : static DynamicStrings_String GetCurrentScopeDescription (void)
    3008              : {
    3009       798697 :   unsigned int sym;
    3010       798697 :   DynamicStrings_String n;
    3011              : 
    3012       798697 :   if (M2StackWord_IsEmptyWord (ScopeStack))
    3013              :     {
    3014            0 :       M2Error_InternalError ((const char *) "not expecting scope stack to be empty", 37);
    3015              :     }
    3016              :   else
    3017              :     {
    3018       798697 :       sym = static_cast<unsigned int> (M2StackWord_PeepWord (ScopeStack, 1));
    3019       798697 :       n = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (sym))));
    3020       798697 :       if (SymbolTable_IsDefImp (sym))
    3021              :         {
    3022         4260 :           return FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "implementation module %s", 24)), (const unsigned char *) &n, (sizeof (n)-1));
    3023              :         }
    3024       794437 :       else if (SymbolTable_IsModule (sym))
    3025              :         {
    3026              :           /* avoid dangling else.  */
    3027        53612 :           if (SymbolTable_IsInnerModule (sym))
    3028              :             {
    3029           84 :               return FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "inner module %s", 15)), (const unsigned char *) &n, (sizeof (n)-1));
    3030              :             }
    3031              :           else
    3032              :             {
    3033        53528 :               return FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "program module %s", 17)), (const unsigned char *) &n, (sizeof (n)-1));
    3034              :             }
    3035              :         }
    3036       740825 :       else if (SymbolTable_IsProcedure (sym))
    3037              :         {
    3038              :           /* avoid dangling else.  */
    3039       740825 :           if (SymbolTable_IsProcedureNested (sym))
    3040              :             {
    3041          396 :               return FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "nested procedure %s", 19)), (const unsigned char *) &n, (sizeof (n)-1));
    3042              :             }
    3043              :           else
    3044              :             {
    3045       740429 :               return FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "procedure %s", 12)), (const unsigned char *) &n, (sizeof (n)-1));
    3046              :             }
    3047              :         }
    3048              :       else
    3049              :         {
    3050              :           /* avoid dangling else.  */
    3051            0 :           M2Error_InternalError ((const char *) "unexpected scope symbol", 23);
    3052              :         }
    3053              :     }
    3054              :   ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2GenGCC.def", 20, 1);
    3055              :   __builtin_unreachable ();
    3056              : }
    3057              : 
    3058              : 
    3059              : /*
    3060              :    CodeRange - encode the range test associated with op3.
    3061              : */
    3062              : 
    3063       797732 : static void CodeRange (unsigned int rangeId)
    3064              : {
    3065       797732 :   M2Range_CodeRangeCheck (rangeId, GetCurrentScopeDescription ());
    3066       797726 : }
    3067              : 
    3068              : 
    3069              : /*
    3070              :    CodeError - encode the error test associated with op3.
    3071              : */
    3072              : 
    3073          965 : static void CodeError (unsigned int errorId)
    3074              : {
    3075              :   /* We would like to test whether this position is in the same basicblock
    3076              :       as any known entry point.  If so we could emit an error message.
    3077              :   */
    3078          965 :   m2type_AddStatement (M2LexBuf_TokenToLocation (CurrentQuadToken), M2Range_CodeErrorCheck (errorId, GetCurrentScopeDescription (), static_cast<DynamicStrings_String> (NULL)));
    3079          965 : }
    3080              : 
    3081              : 
    3082              : /*
    3083              :    CodeModuleScope - ModuleScopeOp is a quadruple which has the following
    3084              :                      format:
    3085              : 
    3086              :                      ModuleScopeOp  _  _  moduleSym
    3087              : 
    3088              :                      Its purpose is to reset the source file to another
    3089              :                      file, hence all line numbers emitted with the
    3090              :                      generated code will be relative to this source file.
    3091              : */
    3092              : 
    3093        81812 : static void CodeModuleScope (unsigned int moduleSym)
    3094              : {
    3095        81812 :   PushScope (moduleSym);
    3096        81812 : }
    3097              : 
    3098              : 
    3099              : /*
    3100              :    CodeStartModFile - StartModFileOp is a quadruple which has the following
    3101              :                       format:
    3102              : 
    3103              :                       StartModFileOp  _  _  moduleSym
    3104              : 
    3105              :                       A new source file has been encountered therefore
    3106              :                       set LastLine to 1.
    3107              :                       Call pushGlobalScope.
    3108              : */
    3109              : 
    3110        81404 : static void CodeStartModFile (unsigned int moduleSym)
    3111              : {
    3112        81404 :   m2block_pushGlobalScope ();
    3113        81404 :   LastLine = 1;
    3114        81404 :   PushScope (moduleSym);
    3115        81404 : }
    3116              : 
    3117              : 
    3118              : /*
    3119              :    CodeStartDefFile - StartDefFileOp is a quadruple with the following
    3120              :                       format:
    3121              : 
    3122              :                       StartDefFileOp  _  _  moduleSym
    3123              : 
    3124              :                       A new source file has been encountered therefore
    3125              :                       set LastLine to 1.
    3126              :                       Call pushGlobalScope.
    3127              : */
    3128              : 
    3129       156390 : static void CodeStartDefFile (unsigned int moduleSym)
    3130              : {
    3131       156390 :   m2block_pushGlobalScope ();
    3132       156390 :   PushScope (moduleSym);
    3133       156390 :   LastLine = 1;
    3134       156390 : }
    3135              : 
    3136              : 
    3137              : /*
    3138              :    CodeEndFile - pops the GlobalScope.
    3139              : */
    3140              : 
    3141       237794 : static void CodeEndFile (void)
    3142              : {
    3143       237794 :   m2block_popGlobalScope ();
    3144       237794 : }
    3145              : 
    3146              : 
    3147              : /*
    3148              :    CallInnerInit - produce a call to inner module initialization routine.
    3149              : */
    3150              : 
    3151          408 : static void CallInnerInit (unsigned int moduleSym)
    3152              : {
    3153          408 :   location_t location;
    3154          408 :   unsigned int ctor;
    3155          408 :   unsigned int init;
    3156          408 :   unsigned int fini;
    3157          408 :   unsigned int dep;
    3158              : 
    3159          408 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    3160          408 :   SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
    3161          408 :   m2statement_BuildCallInner (location, SymbolConversion_Mod2Gcc (init));
    3162          408 : }
    3163              : 
    3164              : 
    3165              : /*
    3166              :    CallInnerFinally - produce a call to inner module finalization routine.
    3167              : */
    3168              : 
    3169          264 : static void CallInnerFinally (unsigned int moduleSym)
    3170              : {
    3171          264 :   location_t location;
    3172          264 :   unsigned int ctor;
    3173          264 :   unsigned int init;
    3174          264 :   unsigned int fini;
    3175          264 :   unsigned int dep;
    3176              : 
    3177          264 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    3178          264 :   SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
    3179          264 :   m2statement_BuildCallInner (location, SymbolConversion_Mod2Gcc (fini));
    3180          264 : }
    3181              : 
    3182              : 
    3183              : /*
    3184              :    CodeInitStart - emits starting code before the main BEGIN END of the
    3185              :                    current module.
    3186              : */
    3187              : 
    3188        81812 : static void CodeInitStart (unsigned int moduleSym, bool CompilingMainModule)
    3189              : {
    3190        81812 :   location_t location;
    3191        81812 :   unsigned int ctor;
    3192        81812 :   unsigned int init;
    3193        81812 :   unsigned int fini;
    3194        81812 :   unsigned int dep;
    3195              : 
    3196        81812 :   if (CompilingMainModule || M2Options_WholeProgram)
    3197              :     {
    3198        14606 :       location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    3199        14606 :       SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
    3200        14606 :       m2statement_BuildStartFunctionCode (location, SymbolConversion_Mod2Gcc (init), IsExportedGcc (init), false);
    3201        14606 :       SymbolTable_ForeachInnerModuleDo (moduleSym, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) CallInnerInit});
    3202              :     }
    3203        81812 : }
    3204              : 
    3205              : 
    3206              : /*
    3207              :    CodeInitEnd - emits terminating code after the main BEGIN END of the
    3208              :                  current module.
    3209              : */
    3210              : 
    3211        81812 : static void CodeInitEnd (unsigned int moduleSym, bool CompilingMainModule)
    3212              : {
    3213        81812 :   location_t location;
    3214        81812 :   unsigned int ctor;
    3215        81812 :   unsigned int init;
    3216        81812 :   unsigned int fini;
    3217        81812 :   unsigned int dep;
    3218              : 
    3219        81812 :   if (CompilingMainModule || M2Options_WholeProgram)
    3220              :     {
    3221        14606 :       location = M2LexBuf_TokenToLocation (SymbolTable_GetDeclaredMod (moduleSym));
    3222        14606 :       SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
    3223        14606 :       m2block_finishFunctionDecl (location, SymbolConversion_Mod2Gcc (init));
    3224        14606 :       m2statement_BuildEndFunctionCode (location, SymbolConversion_Mod2Gcc (init), SymbolTable_IsModuleWithinProcedure (moduleSym));
    3225              :     }
    3226        81812 : }
    3227              : 
    3228              : 
    3229              : /*
    3230              :    CodeFinallyStart - emits starting code before the main BEGIN END of the
    3231              :                       current module.
    3232              : */
    3233              : 
    3234        14606 : static void CodeFinallyStart (unsigned int moduleSym, bool CompilingMainModule)
    3235              : {
    3236        14606 :   location_t location;
    3237        14606 :   unsigned int ctor;
    3238        14606 :   unsigned int init;
    3239        14606 :   unsigned int fini;
    3240        14606 :   unsigned int dep;
    3241              : 
    3242        14606 :   if (CompilingMainModule || M2Options_WholeProgram)
    3243              :     {
    3244        14606 :       location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    3245        14606 :       SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
    3246        14606 :       m2statement_BuildStartFunctionCode (location, SymbolConversion_Mod2Gcc (fini), IsExportedGcc (fini), false);
    3247        14606 :       SymbolTable_ForeachInnerModuleDo (moduleSym, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) CallInnerFinally});
    3248              :     }
    3249        14606 : }
    3250              : 
    3251              : 
    3252              : /*
    3253              :    CodeFinallyEnd - emits terminating code after the main BEGIN END of the
    3254              :                     current module.  It also creates the scaffold if the
    3255              :                     cflag was not present.
    3256              : */
    3257              : 
    3258        14606 : static void CodeFinallyEnd (unsigned int moduleSym, bool CompilingMainModule)
    3259              : {
    3260        14606 :   location_t location;
    3261        14606 :   unsigned int tokenpos;
    3262        14606 :   unsigned int ctor;
    3263        14606 :   unsigned int init;
    3264        14606 :   unsigned int fini;
    3265        14606 :   unsigned int dep;
    3266              : 
    3267        14606 :   if (CompilingMainModule || M2Options_WholeProgram)
    3268              :     {
    3269        14606 :       tokenpos = SymbolTable_GetDeclaredMod (moduleSym);
    3270        14606 :       location = M2LexBuf_TokenToLocation (tokenpos);
    3271        14606 :       SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
    3272        14606 :       m2block_finishFunctionDecl (location, SymbolConversion_Mod2Gcc (fini));
    3273        14606 :       m2statement_BuildEndFunctionCode (location, SymbolConversion_Mod2Gcc (fini), SymbolTable_IsModuleWithinProcedure (moduleSym));
    3274              :     }
    3275        14606 : }
    3276              : 
    3277              : 
    3278              : /*
    3279              :    GetAddressOfUnbounded - returns the address of the unbounded array contents.
    3280              : */
    3281              : 
    3282         5468 : static tree GetAddressOfUnbounded (location_t location, unsigned int param)
    3283              : {
    3284         5468 :   unsigned int UnboundedType;
    3285              : 
    3286         5468 :   UnboundedType = SymbolTable_GetType (param);
    3287         5468 :   M2Debug_Assert (SymbolTable_IsUnbounded (UnboundedType));
    3288         5468 :   return m2convert_BuildConvert (M2LexBuf_TokenToLocation (SymbolTable_GetDeclaredMod (param)), m2type_GetPointerType (), m2expr_BuildComponentRef (location, SymbolConversion_Mod2Gcc (param), SymbolConversion_Mod2Gcc (SymbolTable_GetUnboundedAddressOffset (UnboundedType))), false);
    3289              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    3290              :   __builtin_unreachable ();
    3291              : }
    3292              : 
    3293              : 
    3294              : /*
    3295              :    GetSizeOfHighFromUnbounded - returns a Tree containing the value of
    3296              :                                 param.HIGH * sizeof(unboundedType).
    3297              :                                 The number of legal bytes this array
    3298              :                                 occupies.
    3299              : */
    3300              : 
    3301         5468 : static tree GetSizeOfHighFromUnbounded (unsigned int tokenno, unsigned int param)
    3302              : {
    3303         5468 :   tree t;
    3304         5468 :   unsigned int UnboundedType;
    3305         5468 :   unsigned int ArrayType;
    3306         5468 :   unsigned int i;
    3307         5468 :   unsigned int n;
    3308         5468 :   location_t location;
    3309              : 
    3310         5468 :   location = M2LexBuf_TokenToLocation (tokenno);
    3311         5468 :   UnboundedType = SymbolTable_GetType (param);
    3312         5468 :   M2Debug_Assert (SymbolTable_IsUnbounded (UnboundedType));
    3313         5468 :   ArrayType = SymbolTable_GetType (UnboundedType);
    3314         5468 :   i = 1;
    3315         5468 :   n = SymbolTable_GetDimension (UnboundedType);
    3316         5468 :   t = m2expr_GetCardinalOne (location);
    3317        16494 :   while (i <= n)
    3318              :     {
    3319         5558 :       t = m2expr_BuildMult (location, m2expr_BuildAdd (location, M2GenGCC_GetHighFromUnbounded (location, i, param), m2expr_GetCardinalOne (location), false), t, false);
    3320              :       /* Remember we must add one as a[HIGH(a)] is the last accessible element of the array.  */
    3321         5558 :       i += 1;
    3322              :     }
    3323         5468 :   return m2convert_BuildConvert (location, m2type_GetCardinalType (), m2expr_BuildMult (location, t, m2convert_BuildConvert (location, m2type_GetCardinalType (), FindSize (tokenno, ArrayType), false), false), false);
    3324              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    3325              :   __builtin_unreachable ();
    3326              : }
    3327              : 
    3328              : 
    3329              : /*
    3330              :    MaybeDebugBuiltinAlloca - if DebugBuiltins is set
    3331              :                              then call Builtins.alloca_trace
    3332              :                              else call Builtins.alloca.
    3333              : */
    3334              : 
    3335         5468 : static tree MaybeDebugBuiltinAlloca (location_t location, unsigned int tok, tree high)
    3336              : {
    3337         5468 :   tree call;
    3338         5468 :   tree memptr;
    3339         5468 :   tree func;
    3340              : 
    3341         5468 :   if (M2Options_DebugBuiltins)
    3342              :     {
    3343            0 :       func = SymbolConversion_Mod2Gcc (SymbolTable_FromModuleGetSym (tok, NameKey_MakeKey ((const char *) "alloca_trace", 12), M2Batch_MakeDefinitionSource (tok, NameKey_MakeKey ((const char *) "Builtins", 8))));
    3344            0 :       call = m2builtins_BuiltInAlloca (location, high);
    3345            0 :       m2statement_SetLastFunction (call);
    3346            0 :       memptr = m2statement_BuildFunctValue (location, call);
    3347            0 :       call = m2statement_BuildCall2 (location, func, m2type_GetPointerType (), memptr, high);
    3348              :     }
    3349              :   else
    3350              :     {
    3351         5468 :       call = m2builtins_BuiltInAlloca (location, high);
    3352              :     }
    3353         5468 :   m2statement_SetLastFunction (call);
    3354         5468 :   return m2statement_BuildFunctValue (location, call);
    3355              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    3356              :   __builtin_unreachable ();
    3357              : }
    3358              : 
    3359              : 
    3360              : /*
    3361              :    MaybeDebugBuiltinMemcpy - if DebugBuiltins is set
    3362              :                              then call memcpy
    3363              :                              else call Builtins.memcpy.
    3364              : */
    3365              : 
    3366         7810 : static tree MaybeDebugBuiltinMemcpy (location_t location, tree src, tree dest, tree nbytes)
    3367              : {
    3368         7810 :   tree call;
    3369         7810 :   tree func;
    3370              : 
    3371         7810 :   if (M2Options_DebugBuiltins)
    3372              :     {
    3373            0 :       func = SymbolConversion_Mod2Gcc (Memcpy);
    3374            0 :       call = m2statement_BuildCall3 (location, func, m2type_GetPointerType (), src, dest, nbytes);
    3375              :     }
    3376              :   else
    3377              :     {
    3378         7810 :       call = m2builtins_BuiltinMemCopy (location, src, dest, nbytes);
    3379              :     }
    3380         7810 :   m2statement_SetLastFunction (call);
    3381         7810 :   return m2statement_BuildFunctValue (location, call);
    3382              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    3383              :   __builtin_unreachable ();
    3384              : }
    3385              : 
    3386              : 
    3387              : /*
    3388              :    MakeCopyUse - make a copy of the unbounded array and alter all references
    3389              :                  from the old unbounded array to the new unbounded array.
    3390              :                  The parameter, param, contains a RECORD
    3391              :                                                      ArrayAddress: ADDRESS ;
    3392              :                                                      ArrayHigh   : CARDINAL ;
    3393              :                                                   END
    3394              :                  we simply declare a new array of size, ArrayHigh
    3395              :                  and set ArrayAddress to the address of the copy.
    3396              : 
    3397              :                  Remember ArrayHigh == sizeof(Array)-sizeof(typeof(array))
    3398              :                           so we add 1 for the size and add 1 for a possible <nul>
    3399              : */
    3400              : 
    3401         5468 : static void MakeCopyUse (unsigned int tokenno, unsigned int param)
    3402              : {
    3403         5468 :   location_t location;
    3404         5468 :   unsigned int UnboundedType;
    3405         5468 :   tree Addr;
    3406         5468 :   tree High;
    3407         5468 :   tree NewArray;
    3408              : 
    3409         5468 :   location = M2LexBuf_TokenToLocation (tokenno);
    3410         5468 :   UnboundedType = SymbolTable_GetType (param);
    3411         5468 :   M2Debug_Assert (SymbolTable_IsUnbounded (UnboundedType));
    3412         5468 :   High = GetSizeOfHighFromUnbounded (tokenno, param);
    3413         5468 :   Addr = GetAddressOfUnbounded (location, param);
    3414         5468 :   NewArray = MaybeDebugBuiltinAlloca (location, tokenno, High);
    3415         5468 :   NewArray = MaybeDebugBuiltinMemcpy (location, NewArray, Addr, High);
    3416              :   /* Now assign  param.Addr := ADR(NewArray).  */
    3417         5468 :   m2statement_BuildAssignmentStatement (location, m2expr_BuildComponentRef (location, SymbolConversion_Mod2Gcc (param), SymbolConversion_Mod2Gcc (SymbolTable_GetUnboundedAddressOffset (UnboundedType))), NewArray);
    3418         5468 : }
    3419              : 
    3420              : 
    3421              : /*
    3422              :    GetParamAddress - returns the address of parameter, param.
    3423              : */
    3424              : 
    3425            0 : static tree GetParamAddress (location_t location, unsigned int proc, unsigned int param)
    3426              : {
    3427            0 :   unsigned int sym;
    3428            0 :   unsigned int type;
    3429              : 
    3430            0 :   if (SymbolTable_IsParameter (param))
    3431              :     {
    3432            0 :       type = SymbolTable_GetType (param);
    3433            0 :       sym = SymbolTable_GetLocalSym (proc, SymbolTable_GetSymName (param));
    3434            0 :       if (SymbolTable_IsUnbounded (type))
    3435              :         {
    3436            0 :           return GetAddressOfUnbounded (location, sym);
    3437              :         }
    3438              :       else
    3439              :         {
    3440            0 :           M2Debug_Assert ((SymbolTable_GetMode (sym)) == SymbolTable_LeftValue);
    3441            0 :           return SymbolConversion_Mod2Gcc (sym);
    3442              :         }
    3443              :     }
    3444              :   else
    3445              :     {
    3446            0 :       M2Debug_Assert (SymbolTable_IsVar (param));
    3447            0 :       M2Debug_Assert ((SymbolTable_GetMode (param)) == SymbolTable_LeftValue);
    3448            0 :       return SymbolConversion_Mod2Gcc (param);
    3449              :     }
    3450              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    3451              :   __builtin_unreachable ();
    3452              : }
    3453              : 
    3454              : 
    3455              : /*
    3456              :    IsUnboundedWrittenTo - returns TRUE if the unbounded parameter
    3457              :                           might be written to, or if -funbounded-by-reference
    3458              :                           was _not_ specified.
    3459              : */
    3460              : 
    3461         5468 : static bool IsUnboundedWrittenTo (unsigned int proc, unsigned int param)
    3462              : {
    3463         5468 :   DynamicStrings_String f;
    3464         5468 :   unsigned int l;
    3465         5468 :   unsigned int sym;
    3466         5468 :   NameKey_Name n1;
    3467         5468 :   NameKey_Name n2;
    3468              : 
    3469         5468 :   sym = SymbolTable_GetLocalSym (proc, SymbolTable_GetSymName (param));
    3470         5468 :   if (sym == SymbolTable_NulSym)
    3471              :     {
    3472            0 :       M2Error_InternalError ((const char *) "should find symbol in table", 27);
    3473              :     }
    3474              :   else
    3475              :     {
    3476         5468 :       if (M2Options_UnboundedByReference)
    3477              :         {
    3478            0 :           if ((! (SymbolTable_GetVarWritten (sym))) && M2Options_VerboseUnbounded)
    3479              :             {
    3480            0 :               n1 = SymbolTable_GetSymName (sym);
    3481            0 :               n2 = SymbolTable_GetSymName (proc);
    3482            0 :               f = M2LexBuf_FindFileNameFromToken (SymbolTable_GetDeclaredMod (sym), 0);
    3483            0 :               l = M2LexBuf_TokenToLineNo (SymbolTable_GetDeclaredMod (sym), 0);
    3484            0 :               M2Printf_printf4 ((const char *) "%s:%d:non VAR unbounded parameter %a in procedure %a does not need to be copied\\n", 81, (const unsigned char *) &f, (sizeof (f)-1), (const unsigned char *) &l, (sizeof (l)-1), (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
    3485              :             }
    3486            0 :           return SymbolTable_GetVarWritten (sym);
    3487              :         }
    3488              :       else
    3489              :         {
    3490              :           return true;
    3491              :         }
    3492              :     }
    3493              :   ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2GenGCC.def", 20, 1);
    3494              :   __builtin_unreachable ();
    3495              : }
    3496              : 
    3497              : 
    3498              : /*
    3499              :    GetParamSize - returns the size in bytes of, param.
    3500              : */
    3501              : 
    3502            0 : static tree GetParamSize (unsigned int tokenno, unsigned int param)
    3503              : {
    3504            0 :   M2Debug_Assert ((SymbolTable_IsVar (param)) || (SymbolTable_IsParameter (param)));
    3505            0 :   if (SymbolTable_IsUnbounded (param))
    3506              :     {
    3507            0 :       return GetSizeOfHighFromUnbounded (tokenno, param);
    3508              :     }
    3509              :   else
    3510              :     {
    3511            0 :       return m2expr_BuildSize (M2LexBuf_TokenToLocation (tokenno), SymbolConversion_Mod2Gcc (SymbolTable_GetType (param)), false);
    3512              :     }
    3513              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    3514              :   __builtin_unreachable ();
    3515              : }
    3516              : 
    3517              : 
    3518              : /*
    3519              :    DoIsIntersection - jumps to, tLabel, if the ranges i1..i2  j1..j2 overlap
    3520              :                       else jump to, fLabel.
    3521              : */
    3522              : 
    3523            0 : static void DoIsIntersection (unsigned int tokenno, tree ta, tree tb, tree tc, tree td, DynamicStrings_String tLabel, DynamicStrings_String fLabel)
    3524              : {
    3525            0 :   location_t location;
    3526              : 
    3527            0 :   location = M2LexBuf_TokenToLocation (tokenno);
    3528              :   /* 
    3529              :      if (ta>td) OR (tb<tc)
    3530              :      then
    3531              :         goto fLabel
    3532              :      else
    3533              :         goto tLabel
    3534              :      fi
    3535              :   */
    3536            0 :   m2statement_IfExprJump (location, m2expr_BuildGreaterThan (location, ta, td), reinterpret_cast <char * > (DynamicStrings_string (fLabel)));
    3537            0 :   m2statement_IfExprJump (location, m2expr_BuildLessThan (location, tb, tc), reinterpret_cast <char * > (DynamicStrings_string (fLabel)));
    3538            0 :   m2statement_BuildGoto (location, reinterpret_cast <char * > (DynamicStrings_string (tLabel)));
    3539            0 :   if (CascadedDebugging)
    3540              :     {
    3541              :       M2Printf_printf1 ((const char *) "label used %s\\n", 15, (const unsigned char *) &tLabel, (sizeof (tLabel)-1));
    3542              :       M2Printf_printf1 ((const char *) "label used %s\\n", 15, (const unsigned char *) &fLabel, (sizeof (fLabel)-1));
    3543              :     }
    3544            0 : }
    3545              : 
    3546              : 
    3547              : /*
    3548              :    BuildCascadedIfThenElsif - mustCheck contains a list of variables which
    3549              :                               must be checked against the address of (proc, param, i).
    3550              :                               If the address matches we make a copy of the unbounded
    3551              :                               parameter (proc, param) and quit further checking.
    3552              : */
    3553              : 
    3554            0 : static void BuildCascadedIfThenElsif (unsigned int tokenno, Lists_List mustCheck, unsigned int proc, unsigned int param)
    3555              : {
    3556            0 :   tree ta;
    3557            0 :   tree tb;
    3558            0 :   tree tc;
    3559            0 :   tree td;
    3560            0 :   unsigned int n;
    3561            0 :   unsigned int j;
    3562            0 :   DynamicStrings_String tLabel;
    3563            0 :   DynamicStrings_String fLabel;
    3564            0 :   DynamicStrings_String nLabel;
    3565            0 :   location_t location;
    3566              : 
    3567            0 :   location = M2LexBuf_TokenToLocation (tokenno);
    3568            0 :   n = Lists_NoOfItemsInList (mustCheck);
    3569              :   /* We want a sequence of if then elsif statements.  */
    3570            0 :   if (n > 0)
    3571              :     {
    3572            0 :       UnboundedLabelNo += 1;
    3573            0 :       j = 1;
    3574            0 :       ta = GetAddressOfUnbounded (location, param);
    3575            0 :       tb = m2convert_BuildConvert (M2LexBuf_TokenToLocation (tokenno), m2type_GetPointerType (), m2expr_BuildAddAddress (location, ta, GetSizeOfHighFromUnbounded (tokenno, param)), false);
    3576            0 :       while (j <= n)
    3577              :         {
    3578            0 :           if (j > 1)
    3579              :             {
    3580            0 :               nLabel = CreateLabelProcedureN (proc, (const char *) "n", 1, UnboundedLabelNo, j);
    3581            0 :               if (CascadedDebugging)
    3582              :                 {
    3583              :                   M2Printf_printf1 ((const char *) "label declared %s\\n", 19, (const unsigned char *) &nLabel, (sizeof (nLabel)-1));
    3584              :                 }
    3585            0 :               m2statement_DeclareLabel (location, reinterpret_cast <char * > (DynamicStrings_string (nLabel)));
    3586              :             }
    3587            0 :           tc = GetParamAddress (location, proc, Lists_GetItemFromList (mustCheck, j));
    3588            0 :           td = m2convert_BuildConvert (M2LexBuf_TokenToLocation (tokenno), m2type_GetPointerType (), m2expr_BuildAddAddress (location, tc, GetParamSize (tokenno, param)), false);
    3589            0 :           tLabel = CreateLabelProcedureN (proc, (const char *) "t", 1, UnboundedLabelNo, j+1);
    3590            0 :           fLabel = CreateLabelProcedureN (proc, (const char *) "f", 1, UnboundedLabelNo, j+1);
    3591            0 :           DoIsIntersection (tokenno, ta, tb, tc, td, tLabel, fLabel);
    3592            0 :           if (CascadedDebugging)
    3593              :             {
    3594              :               M2Printf_printf1 ((const char *) "label declared %s\\n", 19, (const unsigned char *) &tLabel, (sizeof (tLabel)-1));
    3595              :             }
    3596            0 :           m2statement_DeclareLabel (location, reinterpret_cast <char * > (DynamicStrings_string (tLabel)));
    3597            0 :           MakeCopyUse (tokenno, param);
    3598            0 :           if (j < n)
    3599              :             {
    3600            0 :               nLabel = CreateLabelProcedureN (proc, (const char *) "n", 1, UnboundedLabelNo, n+1);
    3601            0 :               m2statement_BuildGoto (location, reinterpret_cast <char * > (DynamicStrings_string (nLabel)));
    3602            0 :               if (CascadedDebugging)
    3603              :                 {
    3604              :                   M2Printf_printf1 ((const char *) "goto %s\\n", 9, (const unsigned char *) &nLabel, (sizeof (nLabel)-1));
    3605              :                 }
    3606              :             }
    3607            0 :           if (CascadedDebugging)
    3608              :             {
    3609              :               M2Printf_printf1 ((const char *) "label declared %s\\n", 19, (const unsigned char *) &fLabel, (sizeof (fLabel)-1));
    3610              :             }
    3611            0 :           m2statement_DeclareLabel (location, reinterpret_cast <char * > (DynamicStrings_string (fLabel)));
    3612            0 :           j += 1;
    3613              :         }
    3614              :     }
    3615            0 : }
    3616              : 
    3617              : 
    3618              : /*
    3619              :    CheckUnboundedNonVarParameter - if non var unbounded parameter is written to
    3620              :                                    then
    3621              :                                       make a copy of the contents of this parameter
    3622              :                                       and use the copy
    3623              :                                    else if param
    3624              :                                       is type compatible with any parameter, symv
    3625              :                                       and at runtime its address matches symv
    3626              :                                    then
    3627              :                                       make a copy of the contents of this parameter
    3628              :                                       and use the copy
    3629              :                                    fi
    3630              : */
    3631              : 
    3632         5468 : static void CheckUnboundedNonVarParameter (unsigned int tokenno, Lists_List trashed, unsigned int proc, unsigned int param)
    3633              : {
    3634         5468 :   Lists_List mustCheck;
    3635         5468 :   unsigned int paramTrashed;
    3636         5468 :   unsigned int n;
    3637         5468 :   unsigned int j;
    3638         5468 :   DynamicStrings_String f;
    3639         5468 :   unsigned int l;
    3640         5468 :   NameKey_Name n1;
    3641         5468 :   NameKey_Name n2;
    3642              : 
    3643         5468 :   if (IsUnboundedWrittenTo (proc, param))
    3644              :     {
    3645         5468 :       MakeCopyUse (tokenno, param);
    3646              :     }
    3647              :   else
    3648              :     {
    3649            0 :       Lists_InitList (&mustCheck);
    3650            0 :       n = Lists_NoOfItemsInList (trashed);
    3651            0 :       j = 1;
    3652            0 :       while (j <= n)
    3653              :         {
    3654            0 :           paramTrashed = static_cast<unsigned int> (Lists_GetItemFromList (trashed, j));
    3655            0 :           if (M2Base_IsAssignmentCompatible (SymbolTable_GetLowestType (param), SymbolTable_GetLowestType (paramTrashed)))
    3656              :             {
    3657              :               /* We must check whether this unbounded parameter has the same
    3658              :                address as the trashed parameter.  */
    3659            0 :               if (M2Options_VerboseUnbounded)
    3660              :                 {
    3661            0 :                   n1 = SymbolTable_GetSymName (paramTrashed);
    3662            0 :                   n2 = SymbolTable_GetSymName (proc);
    3663            0 :                   f = M2LexBuf_FindFileNameFromToken (SymbolTable_GetDeclaredMod (paramTrashed), 0);
    3664            0 :                   l = M2LexBuf_TokenToLineNo (SymbolTable_GetDeclaredMod (paramTrashed), 0);
    3665            0 :                   M2Printf_printf4 ((const char *) "%s:%d:must check at runtime the address of parameter, %a, in procedure, %a, whose contents will be trashed\\n", 108, (const unsigned char *) &f, (sizeof (f)-1), (const unsigned char *) &l, (sizeof (l)-1), (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
    3666            0 :                   n1 = SymbolTable_GetSymName (param);
    3667            0 :                   n2 = SymbolTable_GetSymName (paramTrashed);
    3668            0 :                   M2Printf_printf4 ((const char *) "%s:%d:against address of parameter, %a, possibly resulting in a copy of parameter, %a\\n", 87, (const unsigned char *) &f, (sizeof (f)-1), (const unsigned char *) &l, (sizeof (l)-1), (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
    3669              :                 }
    3670            0 :               Lists_PutItemIntoList (mustCheck, paramTrashed);
    3671              :             }
    3672            0 :           j += 1;
    3673              :         }
    3674              :       /* Now we build a sequence of if then { elsif then } end to check addresses.  */
    3675            0 :       BuildCascadedIfThenElsif (tokenno, mustCheck, proc, param);
    3676            0 :       Lists_KillList (&mustCheck);
    3677              :     }
    3678         5468 : }
    3679              : 
    3680              : 
    3681              : /*
    3682              :    IsParameterWritten - returns TRUE if a parameter, sym, is written to.
    3683              : */
    3684              : 
    3685        89275 : static bool IsParameterWritten (unsigned int proc, unsigned int sym)
    3686              : {
    3687        89275 :   if (SymbolTable_IsParameter (sym))
    3688              :     {
    3689        89275 :       sym = SymbolTable_GetLocalSym (proc, SymbolTable_GetSymName (sym));
    3690              :     }
    3691        89275 :   if (SymbolTable_IsVar (sym))
    3692              :     {
    3693              :       /* Unbounded arrays will appear as vars.  */
    3694        89275 :       return SymbolTable_GetVarWritten (sym);
    3695              :     }
    3696            0 :   M2Error_InternalError ((const char *) "expecting IsVar to return TRUE", 30);
    3697              :   ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2GenGCC.def", 20, 1);
    3698              :   __builtin_unreachable ();
    3699              : }
    3700              : 
    3701              : 
    3702              : /*
    3703              :    SaveNonVarUnboundedParameters - for each var parameter, symv, do
    3704              :                                        not just unbounded var parameters, but _all_
    3705              :                                          parameters 
    3706              :                                       if symv is written to
    3707              :                                       then
    3708              :                                          add symv to a compile list
    3709              :                                       fi
    3710              :                                    done
    3711              : 
    3712              :                                    for each parameter of procedure, symu, do
    3713              :                                       if non var unbounded parameter is written to
    3714              :                                       then
    3715              :                                          make a copy of the contents of this parameter
    3716              :                                          and use the copy
    3717              :                                       else if
    3718              :                                          symu is type compatible with any parameter, symv
    3719              :                                          and at runtime its address matches symv
    3720              :                                       then
    3721              :                                          make a copy of the contents of this parameter
    3722              :                                          and use the copy
    3723              :                                       fi
    3724              :                                    done
    3725              : */
    3726              : 
    3727        76755 : static void SaveNonVarUnboundedParameters (unsigned int tokenno, unsigned int proc)
    3728              : {
    3729        76755 :   unsigned int i;
    3730        76755 :   unsigned int p;
    3731        76755 :   Lists_List trashed;
    3732        76755 :   DynamicStrings_String f;
    3733        76755 :   unsigned int sym;
    3734        76755 :   unsigned int l;
    3735        76755 :   NameKey_Name n1;
    3736        76755 :   NameKey_Name n2;
    3737              : 
    3738        76755 :   Lists_InitList (&trashed);
    3739        76755 :   i = 1;
    3740        76755 :   p = SymbolTable_NoOfParamAny (proc);
    3741       242785 :   while (i <= p)
    3742              :     {
    3743        89275 :       sym = SymbolTable_GetNthParamAny (proc, i);
    3744        89275 :       if (IsParameterWritten (proc, sym))
    3745              :         {
    3746         6540 :           if (M2Options_VerboseUnbounded)
    3747              :             {
    3748            0 :               n1 = SymbolTable_GetSymName (sym);
    3749            0 :               n2 = SymbolTable_GetSymName (proc);
    3750            0 :               f = M2LexBuf_FindFileNameFromToken (SymbolTable_GetDeclaredMod (sym), 0);
    3751            0 :               l = M2LexBuf_TokenToLineNo (SymbolTable_GetDeclaredMod (sym), 0);
    3752            0 :               M2Printf_printf4 ((const char *) "%s:%d:parameter, %a, in procedure, %a, is trashed\\n", 51, (const unsigned char *) &f, (sizeof (f)-1), (const unsigned char *) &l, (sizeof (l)-1), (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
    3753              :             }
    3754         6540 :           Lists_PutItemIntoList (trashed, sym);
    3755              :         }
    3756        89275 :       i += 1;
    3757              :     }
    3758              :   /* Now see whether we need to copy any unbounded array parameters.  */
    3759        76755 :   i = 1;
    3760        76755 :   p = SymbolTable_NoOfParamAny (proc);
    3761       242785 :   while (i <= p)
    3762              :     {
    3763        89275 :       if ((SymbolTable_IsUnboundedParamAny (proc, i)) && (! (SymbolTable_IsVarParamAny (proc, i))))
    3764              :         {
    3765         5468 :           CheckUnboundedNonVarParameter (tokenno, trashed, proc, SymbolTable_GetNth (proc, i));
    3766              :         }
    3767        89275 :       i += 1;
    3768              :     }
    3769        76755 :   Lists_KillList (&trashed);
    3770        76755 : }
    3771              : 
    3772              : 
    3773              : /*
    3774              :    AutoInitVariable -
    3775              : */
    3776              : 
    3777           60 : static void AutoInitVariable (location_t location, unsigned int sym)
    3778              : {
    3779           60 :   unsigned int type;
    3780              : 
    3781           60 :   if (((! (SymbolTable_IsParameter (sym))) && (SymbolTable_IsVar (sym))) && (! (SymbolTable_IsTemporary (sym))))
    3782              :     {
    3783              :       /* PrintSym (sym) ;  */
    3784            6 :       type = SymbolTable_SkipType (SymbolTable_GetType (sym));
    3785              :       /* The type SYSTEM.ADDRESS is a pointer type.  */
    3786            6 :       if (SymbolTable_IsPointer (type))
    3787              :         {
    3788            6 :           m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (sym), m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (SymbolTable_GetType (sym)), m2expr_GetPointerZero (location), true));
    3789              :         }
    3790              :     }
    3791           60 : }
    3792              : 
    3793              : 
    3794              : /*
    3795              :    AutoInitialize - scope will be a procedure, module or defimp.  All pointer
    3796              :                     variables are assigned to NIL.
    3797              : */
    3798              : 
    3799        76755 : static void AutoInitialize (location_t location, unsigned int scope)
    3800              : {
    3801        76755 :   unsigned int i;
    3802        76755 :   unsigned int n;
    3803              : 
    3804        76755 :   if (M2Options_AutoInit)
    3805              :     {
    3806           30 :       n = SymbolTable_NoOfVariables (scope);
    3807           30 :       i = 1;
    3808           30 :       if (SymbolTable_IsProcedure (scope))
    3809              :         {
    3810              :           /* The parameters are stored as local variables.  */
    3811           30 :           i += SymbolTable_NoOfParamAny (scope);
    3812              :         }
    3813           90 :       while (i <= n)
    3814              :         {
    3815           60 :           AutoInitVariable (location, SymbolTable_GetNth (scope, i));
    3816           60 :           i += 1;
    3817              :         }
    3818              :     }
    3819        76755 : }
    3820              : 
    3821              : 
    3822              : /*
    3823              :    CodeNewLocalVar - Builds a new frame on the stack to contain the procedure
    3824              :                      local variables.
    3825              : */
    3826              : 
    3827        76755 : static void CodeNewLocalVar (unsigned int tokenno, unsigned int CurrentProcedure)
    3828              : {
    3829        76755 :   unsigned int begin;
    3830        76755 :   unsigned int end;
    3831              : 
    3832              :   /* Callee saves non var unbounded parameter contents.  */
    3833        76755 :   SaveNonVarUnboundedParameters (tokenno, CurrentProcedure);
    3834        76755 :   m2statement_BuildPushFunctionContext ();
    3835        76755 :   SymbolTable_GetProcedureBeginEnd (CurrentProcedure, &begin, &end);
    3836        76755 :   CurrentQuadToken = begin;
    3837        76755 :   m2statement_SetBeginLocation (M2LexBuf_TokenToLocation (begin));
    3838        76755 :   AutoInitialize (M2LexBuf_TokenToLocation (begin), CurrentProcedure);
    3839        76755 :   SymbolTable_ForeachProcedureDo (CurrentProcedure, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) M2Code_CodeBlock});
    3840        76755 :   SymbolTable_ForeachInnerModuleDo (CurrentProcedure, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) M2Code_CodeBlock});
    3841        76755 :   m2statement_BuildPopFunctionContext ();
    3842        76755 :   SymbolTable_ForeachInnerModuleDo (CurrentProcedure, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) CallInnerInit});
    3843        76755 : }
    3844              : 
    3845              : 
    3846              : /*
    3847              :    CodeKillLocalVar - removes local variables and returns to previous scope.
    3848              : */
    3849              : 
    3850        76749 : static void CodeKillLocalVar (unsigned int CurrentProcedure)
    3851              : {
    3852        76749 :   unsigned int begin;
    3853        76749 :   unsigned int end;
    3854        76749 :   tree proc;
    3855              : 
    3856        76749 :   SymbolTable_GetProcedureBeginEnd (CurrentProcedure, &begin, &end);
    3857        76749 :   CurrentQuadToken = end;
    3858        76749 :   proc = NULL;
    3859        76749 :   if (SymbolTable_IsCtor (CurrentProcedure))
    3860              :     {
    3861        14136 :       proc = m2decl_DeclareModuleCtor (SymbolConversion_Mod2Gcc (CurrentProcedure));
    3862              :     }
    3863        76749 :   m2statement_BuildEndFunctionCode (M2LexBuf_TokenToLocation (end), SymbolConversion_Mod2Gcc (CurrentProcedure), M2GCCDeclare_IsProcedureGccNested (CurrentProcedure));
    3864        76749 :   if ((SymbolTable_IsCtor (CurrentProcedure)) && (proc != NULL))
    3865              :     {
    3866        14136 :       m2decl_BuildModuleCtor (proc);
    3867              :     }
    3868        76749 :   M2GCCDeclare_PoisonSymbols (CurrentProcedure);
    3869        76749 :   m2block_removeStmtNote ();
    3870        76749 :   PopScope ();
    3871        76749 : }
    3872              : 
    3873              : 
    3874              : /*
    3875              :    CodeProcedureScope - start a procedure scope for CurrentProcedure.
    3876              : */
    3877              : 
    3878        76761 : static void CodeProcedureScope (unsigned int CurrentProcedure)
    3879              : {
    3880        76761 :   unsigned int begin;
    3881        76761 :   unsigned int end;
    3882              : 
    3883        76761 :   m2block_removeStmtNote ();
    3884        76761 :   SymbolTable_GetProcedureBeginEnd (CurrentProcedure, &begin, &end);
    3885        76761 :   m2statement_BuildStartFunctionCode (M2LexBuf_TokenToLocation (begin), SymbolConversion_Mod2Gcc (CurrentProcedure), IsExportedGcc (CurrentProcedure), SymbolTable_IsProcedureInline (CurrentProcedure));
    3886        76761 :   M2GCCDeclare_StartDeclareScope (CurrentProcedure);
    3887        76755 :   PushScope (CurrentProcedure);
    3888        76755 : }
    3889              : 
    3890              : 
    3891              : /*
    3892              :    CodeReturnValue - places the operand into the return value space
    3893              :                      allocated by the function call.
    3894              : */
    3895              : 
    3896        27443 : static void CodeReturnValue (unsigned int quad)
    3897              : {
    3898        27443 :   M2Quads_QuadOperator op;
    3899        27443 :   bool constExpr;
    3900        27443 :   bool overflowChecking;
    3901        27443 :   unsigned int expr;
    3902        27443 :   unsigned int none;
    3903        27443 :   unsigned int procedure;
    3904        27443 :   unsigned int combinedpos;
    3905        27443 :   unsigned int returnpos;
    3906        27443 :   unsigned int exprpos;
    3907        27443 :   unsigned int nonepos;
    3908        27443 :   unsigned int procpos;
    3909        27443 :   tree value;
    3910        27443 :   tree length;
    3911        27443 :   location_t location;
    3912              : 
    3913        27443 :   M2Quads_GetQuadOtok (quad, &returnpos, &op, &expr, &none, &procedure, &overflowChecking, &constExpr, &exprpos, &nonepos, &procpos);
    3914        27443 :   combinedpos = M2LexBuf_MakeVirtualTok (returnpos, returnpos, exprpos);
    3915        27443 :   location = M2LexBuf_TokenToLocation (combinedpos);
    3916        27443 :   M2GCCDeclare_TryDeclareConstant (exprpos, expr);  /* Checks to see whether it is a constant and declares it.  */
    3917        27443 :   M2GCCDeclare_TryDeclareConstructor (exprpos, expr);  /* Checks to see whether it is a constant and declares it.  */
    3918        27443 :   if ((SymbolTable_IsConstString (expr)) && ((SymbolTable_SkipTypeAndSubrange (SymbolTable_GetType (procedure))) != M2Base_Char))
    3919              :     {
    3920           24 :       if (! (M2GenGCC_PrepareCopyString (returnpos, &length, &value, expr, SymbolTable_GetType (procedure))))
    3921              :         {
    3922            0 :           M2MetaError_MetaErrorT3 (M2LexBuf_MakeVirtualTok (returnpos, returnpos, exprpos), (const char *) "string constant {%1Ea} is too large to be returned from procedure {%2a} via the {%3d} {%3a}", 91, expr, procedure, SymbolTable_GetType (procedure));
    3923              :         }
    3924           24 :       value = m2type_BuildArrayStringConstructor (location, SymbolConversion_Mod2Gcc (SymbolTable_GetType (procedure)), value, length);
    3925              :     }
    3926              :   else
    3927              :     {
    3928        27419 :       value = SymbolConversion_Mod2Gcc (expr);
    3929              :     }
    3930        27443 :   m2statement_BuildReturnValueCode (location, SymbolConversion_Mod2Gcc (procedure), value);
    3931        27443 : }
    3932              : 
    3933              : 
    3934              : /*
    3935              :    CodeCall - determines whether the procedure call is a direct call
    3936              :               or an indirect procedure call.
    3937              : */
    3938              : 
    3939       205633 : static void CodeCall (unsigned int tokenno, unsigned int procedure)
    3940              : {
    3941       205633 :   tree callTree;
    3942       205633 :   location_t location;
    3943              : 
    3944       205633 :   if (SymbolTable_IsProcedure (procedure))
    3945              :     {
    3946       204909 :       M2GCCDeclare_DeclareParameters (procedure);
    3947       204909 :       callTree = CodeDirectCall (tokenno, procedure);
    3948              :     }
    3949          724 :   else if (SymbolTable_IsProcType (SymbolTable_SkipType (SymbolTable_GetType (procedure))))
    3950              :     {
    3951              :       /* avoid dangling else.  */
    3952          724 :       M2GCCDeclare_DeclareParameters (SymbolTable_SkipType (SymbolTable_GetType (procedure)));
    3953          724 :       callTree = CodeIndirectCall (tokenno, procedure);
    3954          724 :       procedure = SymbolTable_SkipType (SymbolTable_GetType (procedure));
    3955              :     }
    3956              :   else
    3957              :     {
    3958              :       /* avoid dangling else.  */
    3959            0 :       M2Error_InternalError ((const char *) "expecting Procedure or ProcType", 31);
    3960              :     }
    3961       205633 :   if ((SymbolTable_GetType (procedure)) == SymbolTable_NulSym)
    3962              :     {
    3963       139244 :       location = M2LexBuf_TokenToLocation (tokenno);
    3964       139244 :       m2type_AddStatement (location, callTree);
    3965              :     }
    3966              :   /* Leave tree alone - as it will be picked up when processing FunctValue.  */
    3967       205633 : }
    3968              : 
    3969              : 
    3970              : /*
    3971              :    UseBuiltin - returns a Tree containing the builtin function
    3972              :                 and parameters. It should only be called if
    3973              :                 CanUseBuiltin or IsProcedureBuiltinAvailable returns TRUE.
    3974              : */
    3975              : 
    3976         1152 : static tree UseBuiltin (unsigned int tokenno, unsigned int Sym)
    3977              : {
    3978         1152 :   if (m2builtins_BuiltinExists (reinterpret_cast <char * > (NameKey_KeyToCharStar (SymbolTable_GetProcedureBuiltin (Sym)))))
    3979              :     {
    3980         1152 :       return m2builtins_BuildBuiltinTree (M2LexBuf_TokenToLocation (tokenno), reinterpret_cast <char * > (NameKey_KeyToCharStar (SymbolTable_GetProcedureBuiltin (Sym))));
    3981              :     }
    3982              :   else
    3983              :     {
    3984            0 :       return m2builtins_BuildBuiltinTree (M2LexBuf_TokenToLocation (tokenno), reinterpret_cast <char * > (NameKey_KeyToCharStar (SymbolTable_GetSymName (Sym))));
    3985              :     }
    3986              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    3987              :   __builtin_unreachable ();
    3988              : }
    3989              : 
    3990              : 
    3991              : /*
    3992              :    CodeDirectCall - calls a function/procedure.
    3993              : */
    3994              : 
    3995       204909 : static tree CodeDirectCall (unsigned int tokenno, unsigned int procedure)
    3996              : {
    3997       204909 :   location_t location;
    3998       204909 :   tree call;
    3999              : 
    4000       204909 :   location = M2LexBuf_TokenToLocation (tokenno);
    4001       204909 :   if (SymbolTable_IsProcedureBuiltinAvailable (procedure))
    4002              :     {
    4003              :       /* avoid dangling else.  */
    4004         1146 :       call = UseBuiltin (tokenno, procedure);
    4005         1146 :       if (call != NULL)
    4006              :         {
    4007         1146 :           call = m2statement_BuildBuiltinCallTree (call);
    4008              :         }
    4009              :     }
    4010              :   else
    4011              :     {
    4012              :       call = NULL;
    4013              :     }
    4014         1146 :   if (call == NULL)
    4015              :     {
    4016              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    4017       203763 :       if ((SymbolTable_GetType (procedure)) == SymbolTable_NulSym)
    4018              :         {
    4019       138584 :           call = m2statement_BuildProcedureCallTree (location, SymbolConversion_Mod2Gcc (procedure), NULL);
    4020              :         }
    4021              :       else
    4022              :         {
    4023        65179 :           call = m2statement_BuildProcedureCallTree (location, SymbolConversion_Mod2Gcc (procedure), SymbolConversion_Mod2Gcc (SymbolTable_GetType (procedure)));
    4024              :         }
    4025              :     }
    4026       204909 :   if ((SymbolTable_GetType (procedure)) == SymbolTable_NulSym)
    4027              :     {
    4028       138608 :       m2statement_SetLastFunction (NULL);
    4029              :     }
    4030              :   else
    4031              :     {
    4032        66301 :       m2statement_SetLastFunction (call);
    4033              :     }
    4034       204909 :   return call;
    4035              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    4036              :   __builtin_unreachable ();
    4037              : }
    4038              : 
    4039              : 
    4040              : /*
    4041              :    CodeIndirectCall - calls a function/procedure indirectly.
    4042              : */
    4043              : 
    4044          724 : static tree CodeIndirectCall (unsigned int tokenno, unsigned int ProcVar)
    4045              : {
    4046          724 :   tree ReturnType;
    4047          724 :   unsigned int proc;
    4048          724 :   location_t location;
    4049              : 
    4050          724 :   location = M2LexBuf_TokenToLocation (tokenno);
    4051          724 :   proc = SymbolTable_SkipType (SymbolTable_GetType (ProcVar));
    4052          724 :   if ((SymbolTable_GetType (proc)) == SymbolTable_NulSym)
    4053              :     {
    4054              :       ReturnType = (tree) (NULL);
    4055              :     }
    4056              :   else
    4057              :     {
    4058           88 :       ReturnType = (tree) (SymbolConversion_Mod2Gcc (SymbolTable_GetType (proc)));
    4059              :     }
    4060              :   /* Now we dereference the lvalue if necessary.  */
    4061          724 :   if ((SymbolTable_GetMode (ProcVar)) == SymbolTable_LeftValue)
    4062              :     {
    4063           68 :       return m2statement_BuildIndirectProcedureCallTree (location, m2expr_BuildIndirect (location, SymbolConversion_Mod2Gcc (ProcVar), SymbolConversion_Mod2Gcc (proc)), ReturnType);
    4064              :     }
    4065              :   else
    4066              :     {
    4067          656 :       return m2statement_BuildIndirectProcedureCallTree (location, SymbolConversion_Mod2Gcc (ProcVar), ReturnType);
    4068              :     }
    4069              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    4070              :   __builtin_unreachable ();
    4071              : }
    4072              : 
    4073              : 
    4074              : /*
    4075              :    ConvertTo - convert gcc tree, t, (which currently represents Modula-2 op3) into
    4076              :                a symbol of, type.
    4077              : */
    4078              : 
    4079        31330 : static tree ConvertTo (tree t, unsigned int type, unsigned int op3)
    4080              : {
    4081        31330 :   if ((SymbolTable_SkipType (type)) != (SymbolTable_SkipType (SymbolTable_GetType (op3))))
    4082              :     {
    4083        21514 :       if ((SymbolTable_IsConst (op3)) && (! (SymbolTable_IsConstString (op3))))
    4084              :         {
    4085         1618 :           SymbolTable_PushValue (op3);
    4086         1618 :           return m2convert_BuildConvert (M2LexBuf_TokenToLocation (SymbolTable_GetDeclaredMod (op3)), SymbolConversion_Mod2Gcc (type), t, false);
    4087              :         }
    4088              :     }
    4089              :   return t;
    4090              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    4091              :   __builtin_unreachable ();
    4092              : }
    4093              : 
    4094              : 
    4095              : /*
    4096              :    ConvertRHS - convert (t, rhs) into, type.  (t, rhs) refer to the
    4097              :                 same entity t is a GCC Tree and, rhs, is a Modula-2
    4098              :                 symbol.  It checks for char and strings
    4099              :                 first and then the remaining types.
    4100              : */
    4101              : 
    4102        31330 : static tree ConvertRHS (tree t, unsigned int type, unsigned int rhs)
    4103              : {
    4104        31330 :   t = M2GenGCC_StringToChar (SymbolConversion_Mod2Gcc (rhs), type, rhs);
    4105        31330 :   return ConvertTo (t, type, rhs);
    4106              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    4107              :   __builtin_unreachable ();
    4108              : }
    4109              : 
    4110              : 
    4111              : /*
    4112              :    IsCoerceableParameter - returns TRUE if symbol, sym, is a
    4113              :                            coerceable parameter.
    4114              : */
    4115              : 
    4116       380278 : static bool IsCoerceableParameter (unsigned int sym)
    4117              : {
    4118       380278 :   return ((((((SymbolTable_IsSet (sym)) || (((M2Base_IsOrdinalType (sym)) && (sym != M2Base_Boolean)) && (! (SymbolTable_IsEnumeration (sym))))) || (M2Base_IsComplexType (sym))) || (M2Base_IsRealType (sym))) || (M2System_IsComplexN (sym))) || (M2System_IsRealN (sym))) || (M2System_IsSetN (sym));
    4119              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    4120              :   __builtin_unreachable ();
    4121              : }
    4122              : 
    4123              : 
    4124              : /*
    4125              :    IsConstProcedure - returns TRUE if, p, is a const procedure.
    4126              : */
    4127              : 
    4128          592 : static bool IsConstProcedure (unsigned int p)
    4129              : {
    4130          592 :   return ((SymbolTable_IsConst (p)) && ((SymbolTable_GetType (p)) != SymbolTable_NulSym)) && (SymbolTable_IsProcType (SymbolTable_GetType (p)));
    4131              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    4132              :   __builtin_unreachable ();
    4133              : }
    4134              : 
    4135              : 
    4136              : /*
    4137              :    IsConstant - returns TRUE if symbol, p, is either a const or procedure.
    4138              : */
    4139              : 
    4140       853916 : static bool IsConstant (unsigned int p)
    4141              : {
    4142       853916 :   return (SymbolTable_IsConst (p)) || (SymbolTable_IsProcedure (p));
    4143              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    4144              :   __builtin_unreachable ();
    4145              : }
    4146              : 
    4147              : 
    4148              : /*
    4149              :    CheckConvertCoerceParameter - ensure that actual parameter is the same as the nth of callee.
    4150              : */
    4151              : 
    4152       513921 : static tree CheckConvertCoerceParameter (unsigned int tokenno, unsigned int nth, unsigned int callee, unsigned int actual)
    4153              : {
    4154       513921 :   unsigned int OperandType;
    4155       513921 :   unsigned int ParamType;
    4156       513921 :   location_t location;
    4157              : 
    4158       513921 :   location = M2LexBuf_TokenToLocation (tokenno);
    4159       513921 :   if ((SymbolTable_GetNthParamAny (callee, nth)) == SymbolTable_NulSym)
    4160              :     {
    4161              :       /* We reach here if the argument is being passed to a C vararg function.  */
    4162         6510 :       return SymbolConversion_Mod2Gcc (actual);
    4163              :     }
    4164              :   else
    4165              :     {
    4166       507411 :       OperandType = SymbolTable_SkipType (SymbolTable_GetType (actual));
    4167       507411 :       ParamType = SymbolTable_SkipType (SymbolTable_GetType (SymbolTable_GetNthParamAny (callee, nth)));
    4168              :     }
    4169       507411 :   if (SymbolTable_IsProcType (ParamType))
    4170              :     {
    4171        44294 :       if (((SymbolTable_IsProcedure (actual)) || (IsConstProcedure (actual))) || (OperandType == ParamType))
    4172              :         {
    4173        44230 :           return SymbolConversion_Mod2Gcc (actual);
    4174              :         }
    4175              :       else
    4176              :         {
    4177           64 :           return m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (ParamType), SymbolConversion_Mod2Gcc (actual), false);
    4178              :         }
    4179              :     }
    4180       463117 :   else if (((M2Base_IsRealType (OperandType)) && (M2Base_IsRealType (ParamType))) && (ParamType != OperandType))
    4181              :     {
    4182              :       /* avoid dangling else.  */
    4183              :       /* SHORTREAL, LONGREAL and REAL conversion during parameter passing.  */
    4184         1962 :       return m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (ParamType), SymbolConversion_Mod2Gcc (actual), false);
    4185              :     }
    4186       461155 :   else if (((OperandType != SymbolTable_NulSym) && (SymbolTable_IsSet (OperandType))) && (SymbolTable_IsConst (actual)))
    4187              :     {
    4188              :       /* avoid dangling else.  */
    4189          548 :       return m2decl_DeclareKnownConstant (location, SymbolConversion_Mod2Gcc (ParamType), SymbolConversion_Mod2Gcc (actual));
    4190              :     }
    4191       460607 :   else if ((SymbolTable_IsConst (actual)) && ((M2Base_IsOrdinalType (ParamType)) || (M2System_IsSystemType (ParamType))))
    4192              :     {
    4193              :       /* avoid dangling else.  */
    4194        80305 :       return m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (ParamType), M2GenGCC_StringToChar (SymbolConversion_Mod2Gcc (actual), ParamType, actual), false);
    4195              :     }
    4196       380302 :   else if ((SymbolTable_IsConstString (actual)) || (((OperandType != SymbolTable_NulSym) && (IsCoerceableParameter (OperandType))) && (OperandType != ParamType)))
    4197              :     {
    4198              :       /* avoid dangling else.  */
    4199         5278 :       return m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (ParamType), SymbolConversion_Mod2Gcc (actual), false);
    4200              :     }
    4201              :   else
    4202              :     {
    4203              :       /* avoid dangling else.  */
    4204       375024 :       return SymbolConversion_Mod2Gcc (actual);
    4205              :     }
    4206              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    4207              :   __builtin_unreachable ();
    4208              : }
    4209              : 
    4210              : 
    4211              : /*
    4212              :    CheckConstant - checks to see whether we should declare the constant.
    4213              : */
    4214              : 
    4215            6 : static tree CheckConstant (unsigned int tokenno, unsigned int des, unsigned int expr)
    4216              : {
    4217            6 :   location_t location;
    4218              : 
    4219            6 :   location = M2LexBuf_TokenToLocation (tokenno);
    4220            6 :   if (SymbolTable_IsProcedure (expr))
    4221              :     {
    4222            0 :       return SymbolConversion_Mod2Gcc (expr);
    4223              :     }
    4224              :   else
    4225              :     {
    4226            6 :       return m2decl_DeclareKnownConstant (location, SymbolConversion_Mod2Gcc (SymbolTable_GetType (des)), SymbolConversion_Mod2Gcc (expr));
    4227              :     }
    4228              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    4229              :   __builtin_unreachable ();
    4230              : }
    4231              : 
    4232              : 
    4233              : /*
    4234              :    CodeMakeAdr - code the function MAKEADR.
    4235              : */
    4236              : 
    4237            0 : static void CodeMakeAdr (unsigned int q, unsigned int op1, unsigned int op2, unsigned int op3)
    4238              : {
    4239            0 :   unsigned int r;
    4240            0 :   unsigned int n;
    4241            0 :   unsigned int type;
    4242            0 :   M2Quads_QuadOperator op;
    4243            0 :   tree bits;
    4244            0 :   tree max;
    4245            0 :   tree tmp;
    4246            0 :   tree res;
    4247            0 :   tree val;
    4248            0 :   location_t location;
    4249              : 
    4250            0 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    4251            0 :   n = q;
    4252            0 :   do {
    4253            0 :     if (op1 > 0)
    4254              :       {
    4255            0 :         M2GCCDeclare_DeclareConstant (CurrentQuadToken, op3);
    4256              :       }
    4257            0 :     n = M2Quads_GetNextQuad (n);
    4258            0 :     M2Quads_GetQuad (n, &op, &r, &op2, &op3);
    4259            0 :   } while (! (op == M2Quads_FunctValueOp));
    4260            0 :   n = q;
    4261            0 :   M2Quads_GetQuad (n, &op, &op1, &op2, &op3);
    4262            0 :   res = SymbolConversion_Mod2Gcc (r);
    4263            0 :   max = m2expr_GetSizeOfInBits (SymbolConversion_Mod2Gcc (M2System_Address));
    4264            0 :   bits = m2expr_GetIntegerZero (location);
    4265            0 :   val = m2expr_GetPointerZero (location);
    4266            0 :   do {
    4267            0 :     location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    4268            0 :     if ((op == M2Quads_ParamOp) && (op1 > 0))
    4269              :       {
    4270              :         /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    4271            0 :         if ((SymbolTable_GetType (op3)) == SymbolTable_NulSym)
    4272              :           {
    4273            0 :             M2Error_WriteFormat0 ((const char *) "must supply typed constants to MAKEADR", 38);
    4274              :           }
    4275              :         else
    4276              :           {
    4277            0 :             type = SymbolTable_GetType (op3);
    4278            0 :             tmp = m2convert_BuildConvert (location, m2type_GetPointerType (), SymbolConversion_Mod2Gcc (op3), false);
    4279            0 :             if ((m2expr_CompareTrees (bits, m2expr_GetIntegerZero (location))) > 0)
    4280              :               {
    4281            0 :                 tmp = m2expr_BuildLSL (location, tmp, bits, false);
    4282              :               }
    4283            0 :             bits = m2expr_BuildAdd (location, bits, m2expr_GetSizeOfInBits (SymbolConversion_Mod2Gcc (type)), false);
    4284            0 :             val = m2expr_BuildLogicalOrAddress (location, val, tmp);
    4285              :           }
    4286              :       }
    4287            0 :     M2Quads_SubQuad (n);
    4288            0 :     n = M2Quads_GetNextQuad (n);
    4289            0 :     M2Quads_GetQuad (n, &op, &op1, &op2, &op3);
    4290            0 :   } while (! (op == M2Quads_FunctValueOp));
    4291            0 :   if ((m2expr_CompareTrees (bits, max)) > 0)
    4292              :     {
    4293            0 :       M2MetaError_MetaErrorT0 (CurrentQuadToken, (const char *) "total number of bits specified as parameters to {%kMAKEADR} exceeds address width", 81);
    4294              :     }
    4295            0 :   M2Quads_SubQuad (n);
    4296            0 :   m2statement_BuildAssignmentStatement (location, res, val);
    4297            0 : }
    4298              : 
    4299              : 
    4300              : /*
    4301              :    CodeBuiltinFunction - attempts to inline a function. Currently it only
    4302              :                          inlines the SYSTEM function MAKEADR.
    4303              : */
    4304              : 
    4305        66389 : static void CodeBuiltinFunction (unsigned int q, unsigned int nth, unsigned int func, unsigned int parameter)
    4306              : {
    4307        66389 :   if (nth == 0)
    4308              :     {
    4309        66389 :       InitBuiltinSyms (M2LexBuf_BuiltinTokenNo);
    4310        66389 :       if (func == M2System_MakeAdr)
    4311              :         {
    4312            0 :           CodeMakeAdr (q, nth, func, parameter);
    4313              :         }
    4314              :     }
    4315        66389 : }
    4316              : 
    4317              : 
    4318              : /*
    4319              :    FoldMakeAdr - attempts to fold the function MAKEADR.
    4320              : */
    4321              : 
    4322           12 : static void FoldMakeAdr (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int q, unsigned int op1, unsigned int op2, unsigned int op3)
    4323              : {
    4324           12 :   bool resolved;
    4325           12 :   unsigned int r;
    4326           12 :   unsigned int n;
    4327           12 :   M2Quads_QuadOperator op;
    4328           12 :   unsigned int type;
    4329           12 :   tree bits;
    4330           12 :   tree max;
    4331           12 :   tree tmp;
    4332           12 :   tree val;
    4333           12 :   location_t location;
    4334              : 
    4335           12 :   location = M2LexBuf_TokenToLocation (tokenno);
    4336           12 :   resolved = true;
    4337           12 :   n = q;
    4338           12 :   r = op1;
    4339           24 :   do {
    4340           24 :     if (r > 0)
    4341              :       {
    4342           12 :         M2GCCDeclare_TryDeclareConstant (tokenno, op3);
    4343           12 :         if (! (SymbolConversion_GccKnowsAbout (op3)))
    4344              :           {
    4345           24 :             resolved = false;
    4346              :           }
    4347              :       }
    4348           24 :     n = M2Quads_GetNextQuad (n);
    4349           24 :     M2Quads_GetQuad (n, &op, &r, &op2, &op3);
    4350           24 :   } while (! (op == M2Quads_FunctValueOp));
    4351           12 :   if (resolved && (SymbolTable_IsConst (r)))
    4352              :     {
    4353           12 :       n = q;
    4354           12 :       M2Quads_GetQuad (n, &op, &op1, &op2, &op3);
    4355           12 :       max = m2expr_GetSizeOfInBits (SymbolConversion_Mod2Gcc (M2System_Address));
    4356           12 :       bits = m2expr_GetIntegerZero (location);
    4357           12 :       val = m2expr_GetPointerZero (location);
    4358           24 :       do {
    4359           24 :         location = M2LexBuf_TokenToLocation (tokenno);
    4360           24 :         if ((op == M2Quads_ParamOp) && (op1 > 0))
    4361              :           {
    4362              :             /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    4363           12 :             if ((SymbolTable_GetType (op3)) == SymbolTable_NulSym)
    4364              :               {
    4365            0 :                 M2MetaError_MetaErrorT0 (tokenno, (const char *) "constants passed to {%kMAKEADR} must be typed", 45);
    4366              :               }
    4367              :             else
    4368              :               {
    4369           12 :                 type = SymbolTable_GetType (op3);
    4370           12 :                 tmp = m2convert_BuildConvert (location, m2type_GetPointerType (), SymbolConversion_Mod2Gcc (op3), false);
    4371           12 :                 if ((m2expr_CompareTrees (bits, m2expr_GetIntegerZero (location))) > 0)
    4372              :                   {
    4373            0 :                     tmp = m2expr_BuildLSL (location, tmp, bits, false);
    4374              :                   }
    4375           12 :                 bits = m2expr_BuildAdd (location, bits, m2expr_GetSizeOfInBits (SymbolConversion_Mod2Gcc (type)), false);
    4376           12 :                 val = m2expr_BuildLogicalOrAddress (location, val, tmp);
    4377              :               }
    4378              :           }
    4379           24 :         M2Quads_SubQuad (n);
    4380           24 :         n = M2Quads_GetNextQuad (n);
    4381           24 :         M2Quads_GetQuad (n, &op, &op1, &op2, &op3);
    4382           24 :       } while (! (op == M2Quads_FunctValueOp));
    4383           12 :       if ((m2expr_CompareTrees (bits, max)) > 0)
    4384              :         {
    4385            0 :           M2MetaError_MetaErrorT0 (tokenno, (const char *) "total number of bits specified as parameters to {%kMAKEADR} exceeds address width", 81);
    4386              :         }
    4387           12 :       SymbolTable_PutConst (r, M2System_Address);
    4388           12 :       SymbolConversion_AddModGcc (r, m2decl_DeclareKnownConstant (location, SymbolConversion_Mod2Gcc (M2System_Address), val));
    4389           12 :       (*p.proc) (r);
    4390           12 :       NoChange = false;
    4391           12 :       M2Quads_SubQuad (n);
    4392              :     }
    4393           12 : }
    4394              : 
    4395              : 
    4396              : /*
    4397              :    doParam - builds the parameter, op3, which is to be passed to
    4398              :              procedure, op2.  The number of the parameter is op1.
    4399              : */
    4400              : 
    4401       513921 : static void doParam (unsigned int paramtok, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    4402              : {
    4403       513921 :   location_t location;
    4404              : 
    4405       513921 :   location = M2LexBuf_TokenToLocation (paramtok);
    4406       513921 :   M2GCCDeclare_DeclareConstant (paramtok, op3);
    4407       513921 :   M2GCCDeclare_DeclareConstructor (paramtok, quad, op3);
    4408       513921 :   m2statement_BuildParam (location, CheckConvertCoerceParameter (paramtok, op1, op2, op3));
    4409       513921 : }
    4410              : 
    4411              : 
    4412              : /*
    4413              :    FoldBuiltin - attempts to fold the gcc builtin function.
    4414              : */
    4415              : 
    4416        18004 : static void FoldBuiltin (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int q)
    4417              : {
    4418        18004 :   bool resolved;
    4419        18004 :   unsigned int procedure;
    4420        18004 :   unsigned int r;
    4421        18004 :   unsigned int n;
    4422        18004 :   unsigned int op1;
    4423        18004 :   unsigned int op2;
    4424        18004 :   unsigned int op3;
    4425        18004 :   M2Quads_QuadOperator op;
    4426        18004 :   tree val;
    4427        18004 :   tree call;
    4428        18004 :   location_t location;
    4429              : 
    4430        18004 :   M2Quads_GetQuad (q, &op, &op1, &op2, &op3);
    4431        18004 :   resolved = true;
    4432        18004 :   procedure = SymbolTable_NulSym;
    4433        18004 :   n = q;
    4434        18004 :   r = op1;
    4435        57036 :   do {
    4436        57036 :     if (r > 0)
    4437              :       {
    4438        21028 :         M2GCCDeclare_TryDeclareConstant (tokenno, op3);
    4439        21028 :         if (! (SymbolConversion_GccKnowsAbout (op3)))
    4440              :           {
    4441        57036 :             resolved = false;
    4442              :           }
    4443              :       }
    4444        57036 :     if ((op == M2Quads_CallOp) && (! (SymbolTable_IsProcedure (op3))))
    4445              :       {
    4446              :         /* Cannot fold an indirect procedure function call.  */
    4447              :         resolved = false;
    4448              :       }
    4449        57036 :     n = M2Quads_GetNextQuad (n);
    4450        57036 :     M2Quads_GetQuad (n, &op, &r, &op2, &op3);
    4451        57036 :   } while (! (op == M2Quads_FunctValueOp));
    4452        18004 :   if (resolved && (SymbolTable_IsConst (r)))
    4453              :     {
    4454            6 :       n = q;
    4455            6 :       M2Quads_GetQuad (n, &op, &op1, &op2, &op3);
    4456           18 :       do {
    4457           18 :         if ((op == M2Quads_ParamOp) && (op1 > 0))
    4458              :           {
    4459            6 :             doParam (tokenno, n, op1, op2, op3);
    4460              :           }
    4461           12 :         else if (op == M2Quads_CallOp)
    4462              :           {
    4463              :             /* avoid dangling else.  */
    4464            6 :             procedure = op3;
    4465              :           }
    4466           18 :         M2Quads_SubQuad (n);
    4467           18 :         n = M2Quads_GetNextQuad (n);
    4468           18 :         M2Quads_GetQuad (n, &op, &op1, &op2, &op3);
    4469           18 :       } while (! (op == M2Quads_FunctValueOp));
    4470            6 :       if (SymbolTable_IsProcedureBuiltinAvailable (procedure))
    4471              :         {
    4472            6 :           location = M2LexBuf_TokenToLocation (tokenno);
    4473            6 :           call = UseBuiltin (tokenno, procedure);
    4474            6 :           val = m2statement_BuildFunctValue (location, call);
    4475            6 :           val = m2expr_FoldAndStrip (val);
    4476            6 :           SymbolTable_PutConst (r, SymbolTable_GetType (procedure));
    4477            6 :           SymbolConversion_AddModGcc (r, m2decl_DeclareKnownConstant (location, SymbolConversion_Mod2Gcc (SymbolTable_GetType (procedure)), val));
    4478            6 :           (*p.proc) (r);
    4479            6 :           m2statement_SetLastFunction (NULL);
    4480              :         }
    4481              :       else
    4482              :         {
    4483            0 :           M2MetaError_MetaErrorT1 (tokenno, (const char *) "gcc builtin procedure {%1Ead} cannot be used in a constant expression", 69, procedure);
    4484              :         }
    4485            6 :       NoChange = false;
    4486            6 :       M2Quads_SubQuad (n);
    4487              :     }
    4488        18004 : }
    4489              : 
    4490              : 
    4491              : /*
    4492              :    FoldBuiltinFunction - attempts to inline a function. Currently it only
    4493              :                          inlines the SYSTEM function MAKEADR.
    4494              : */
    4495              : 
    4496      7490673 : static void FoldBuiltinFunction (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int q, unsigned int op1, unsigned int op2, unsigned int op3)
    4497              : {
    4498      7490673 :   if (op1 == 0)
    4499              :     {
    4500              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    4501              :       /* Must be a function as op1 is the return parameter.  */
    4502      1010107 :       if (op3 == M2System_MakeAdr)
    4503              :         {
    4504           12 :           FoldMakeAdr (tokenno, p, q, op1, op2, op3);
    4505              :         }
    4506      1010095 :       else if ((SymbolTable_IsProcedure (op3)) && (SymbolTable_IsProcedureBuiltinAvailable (op3)))
    4507              :         {
    4508              :           /* avoid dangling else.  */
    4509        18004 :           FoldBuiltin (tokenno, p, q);
    4510              :         }
    4511              :     }
    4512      7490673 : }
    4513              : 
    4514              : 
    4515              : /*
    4516              :    CodeParam - builds a parameter list.
    4517              :                Note that we can ignore ModeOfAddr as any lvalue will
    4518              :                have been created in a preceeding quadruple.
    4519              : */
    4520              : 
    4521       580352 : static void CodeParam (unsigned int quad)
    4522              : {
    4523       580352 :   unsigned int nopos;
    4524       580352 :   unsigned int procedure;
    4525       580352 :   unsigned int parameter;
    4526       580352 :   unsigned int parampos;
    4527       580352 :   unsigned int nth;
    4528       580352 :   bool compatible;
    4529       580352 :   bool constExpr;
    4530       580352 :   bool overflow;
    4531       580352 :   M2Quads_QuadOperator op;
    4532              : 
    4533       580352 :   M2Quads_GetQuadOtok (quad, &parampos, &op, &nth, &procedure, &parameter, &overflow, &constExpr, &nopos, &nopos, &nopos);
    4534       580352 :   compatible = true;
    4535       580352 :   if (nth == 0)
    4536              :     {
    4537        66389 :       CodeBuiltinFunction (quad, nth, procedure, parameter);
    4538              :     }
    4539              :   else
    4540              :     {
    4541       513963 :       if (M2Options_StrictTypeChecking)
    4542              :         {
    4543       513963 :           if (nth <= (SymbolTable_NoOfParamAny (procedure)))
    4544              :             {
    4545       507453 :               compatible = M2Check_ParameterTypeCompatible (parampos, (const char *) "parameter incompatibility when attempting to pass actual parameter {%2ad} to a {%kVAR} formal parameter {%3Ead} during call to procedure {%1ad}", 143, procedure, SymbolTable_GetNthParamAny (procedure, nth), parameter, nth, SymbolTable_IsVarParamAny (procedure, nth));
    4546              :             }
    4547              :         }
    4548       513963 :       if (((nth <= (SymbolTable_NoOfParamAny (procedure))) && (SymbolTable_IsVarParamAny (procedure, nth))) && (SymbolTable_IsConst (parameter)))
    4549              :         {
    4550            0 :           M2MetaError_MetaErrorT1 (parampos, (const char *) "cannot pass a constant {%1Ead} as a VAR parameter", 49, parameter);
    4551              :         }
    4552       513963 :       else if (SymbolTable_IsAModula2Type (parameter))
    4553              :         {
    4554              :           /* avoid dangling else.  */
    4555            0 :           M2MetaError_MetaErrorT2 (parampos, (const char *) "cannot pass a type {%1Ead} as a parameter to procedure {%2ad}", 61, parameter, procedure);
    4556              :         }
    4557       513963 :       else if (compatible)
    4558              :         {
    4559              :           /* avoid dangling else.  */
    4560       513915 :           doParam (parampos, quad, nth, procedure, parameter);
    4561              :         }
    4562              :     }
    4563       580352 : }
    4564              : 
    4565              : 
    4566              : /*
    4567              :    Replace - replace the entry for sym in the double entry bookkeeping with sym/tree.
    4568              : */
    4569              : 
    4570            0 : static void Replace (unsigned int sym, tree gcc)
    4571              : {
    4572            0 :   if (SymbolConversion_GccKnowsAbout (sym))
    4573              :     {
    4574            0 :       SymbolConversion_RemoveMod2Gcc (sym);
    4575              :     }
    4576            0 :   SymbolConversion_AddModGcc (sym, gcc);
    4577            0 : }
    4578              : 
    4579              : 
    4580              : /*
    4581              :    CodeFunctValue - retrieves the function return value and assigns it
    4582              :                     into a variable.
    4583              : */
    4584              : 
    4585        66389 : static void CodeFunctValue (location_t location, unsigned int op1)
    4586              : {
    4587        66389 :   tree call;
    4588        66389 :   tree value;
    4589              : 
    4590              :   /* 
    4591              :       operator : FunctValueOp
    4592              :       op1 : The Returned Variable
    4593              :       op3 : The Function Returning this Variable
    4594              :   */
    4595        66389 :   if (M2SSA_EnableSSA && (SymbolTable_IsVariableSSA (op1)))
    4596              :     {
    4597              :       call = m2statement_GetLastFunction ();
    4598              :       m2statement_SetLastFunction (NULL);
    4599              :       Replace (op1, call);
    4600              :     }
    4601              :   else
    4602              :     {
    4603        66389 :       value = m2statement_BuildFunctValue (location, SymbolConversion_Mod2Gcc (op1));
    4604              :       /* AddStatement (location, CheckCleanup (location, op3, value, call))  */
    4605        66389 :       m2type_AddStatement (location, value);
    4606              :     }
    4607        66389 : }
    4608              : 
    4609              : 
    4610              : /*
    4611              :    FoldStringLength -
    4612              : */
    4613              : 
    4614           72 : static void FoldStringLength (unsigned int quad, M2GCCDeclare_WalkAction p)
    4615              : {
    4616           72 :   M2Quads_QuadOperator op;
    4617           72 :   unsigned int des;
    4618           72 :   unsigned int none;
    4619           72 :   unsigned int expr;
    4620           72 :   unsigned int stroppos;
    4621           72 :   unsigned int despos;
    4622           72 :   unsigned int nonepos;
    4623           72 :   unsigned int exprpos;
    4624           72 :   bool constExpr;
    4625           72 :   bool overflowChecking;
    4626           72 :   location_t location;
    4627              : 
    4628           72 :   M2Quads_GetQuadOtok (quad, &stroppos, &op, &des, &none, &expr, &overflowChecking, &constExpr, &despos, &nonepos, &exprpos);
    4629           72 :   if ((IsConstStr (expr)) && (IsConstStrKnown (expr)))
    4630              :     {
    4631           66 :       location = M2LexBuf_TokenToLocation (stroppos);
    4632           66 :       M2ALU_PushCard (SymbolTable_GetStringLength (exprpos, expr));
    4633           66 :       SymbolConversion_AddModGcc (des, m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (SymbolTable_GetType (des)), M2ALU_PopIntegerTree (), false));
    4634          132 :       RemoveQuad (p, des, quad);
    4635              :     }
    4636           72 : }
    4637              : 
    4638              : 
    4639              : /*
    4640              :    FoldStringConvertM2nul - attempt to assign the des with the string contents from expr.
    4641              :                             It also marks the des as a m2 string which must be nul terminated.
    4642              :                             The front end uses double book keeping and it is easier to have
    4643              :                             different m2 string symbols each of which map onto a slightly different
    4644              :                             gcc string tree.
    4645              : */
    4646              : 
    4647        33949 : static void FoldStringConvertM2nul (unsigned int quad, M2GCCDeclare_WalkAction p)
    4648              : {
    4649        33949 :   M2Quads_QuadOperator op;
    4650        33949 :   unsigned int des;
    4651        33949 :   unsigned int none;
    4652        33949 :   unsigned int expr;
    4653        33949 :   unsigned int stroppos;
    4654        33949 :   unsigned int despos;
    4655        33949 :   unsigned int nonepos;
    4656        33949 :   unsigned int exprpos;
    4657        33949 :   DynamicStrings_String s;
    4658        33949 :   bool constExpr;
    4659        33949 :   bool overflowChecking;
    4660              : 
    4661        33949 :   M2Quads_GetQuadOtok (quad, &stroppos, &op, &des, &none, &expr, &overflowChecking, &constExpr, &despos, &nonepos, &exprpos);
    4662        33949 :   if ((IsConstStr (expr)) && (IsConstStrKnown (expr)))
    4663              :     {
    4664        33949 :       s = GetStr (exprpos, expr);
    4665        33949 :       SymbolTable_PutConstStringKnown (stroppos, des, NameKey_makekey (DynamicStrings_string (s)), false, true);
    4666        33949 :       M2GCCDeclare_TryDeclareConstant (despos, des);
    4667        33949 :       (*p.proc) (des);
    4668        33949 :       NoChange = false;
    4669        33949 :       M2Quads_SubQuad (quad);
    4670        33949 :       s = DynamicStrings_KillString (s);
    4671              :     }
    4672        33949 : }
    4673              : 
    4674              : 
    4675              : /*
    4676              :    FoldStringConvertCnul -attempt to assign the des with the string contents from expr.
    4677              :                           It also marks the des as a C string which must be nul terminated.
    4678              : */
    4679              : 
    4680         9583 : static void FoldStringConvertCnul (unsigned int quad, M2GCCDeclare_WalkAction p)
    4681              : {
    4682         9583 :   M2Quads_QuadOperator op;
    4683         9583 :   unsigned int des;
    4684         9583 :   unsigned int none;
    4685         9583 :   unsigned int expr;
    4686         9583 :   unsigned int stroppos;
    4687         9583 :   unsigned int despos;
    4688         9583 :   unsigned int nonepos;
    4689         9583 :   unsigned int exprpos;
    4690         9583 :   DynamicStrings_String s;
    4691         9583 :   bool constExpr;
    4692         9583 :   bool overflowChecking;
    4693              : 
    4694         9583 :   M2Quads_GetQuadOtok (quad, &stroppos, &op, &des, &none, &expr, &overflowChecking, &constExpr, &despos, &nonepos, &exprpos);
    4695         9583 :   if ((IsConstStr (expr)) && (IsConstStrKnown (expr)))
    4696              :     {
    4697         9559 :       s = GetStr (exprpos, expr);
    4698         9559 :       SymbolTable_PutConstStringKnown (stroppos, des, NameKey_makekey (DynamicStrings_string (s)), true, true);
    4699         9559 :       M2GCCDeclare_TryDeclareConstant (despos, des);
    4700         9559 :       (*p.proc) (des);
    4701         9559 :       NoChange = false;
    4702         9559 :       M2Quads_SubQuad (quad);
    4703         9559 :       s = DynamicStrings_KillString (s);
    4704              :     }
    4705         9583 : }
    4706              : 
    4707       184481 : static void CodeAddr (unsigned int tokenno, unsigned int quad, unsigned int op1, unsigned int op3)
    4708              : {
    4709       184481 :   tree value;
    4710       184481 :   unsigned int type;
    4711       184481 :   location_t location;
    4712              : 
    4713              :   /* 
    4714              :    Addr Operator - generates the address of a variable (op1 = &op3).
    4715              :   */
    4716       184481 :   if ((SymbolTable_IsConst (op3)) && (! (SymbolTable_IsConstString (op3))))
    4717              :     {
    4718            6 :       M2MetaError_MetaErrorT1 (tokenno, (const char *) "error in expression, trying to find the address of a constant {%1Ead}", 69, op3);
    4719              :     }
    4720              :   else
    4721              :     {
    4722       184475 :       if ((SymbolTable_IsConstString (op3)) && (! (SymbolTable_IsConstStringKnown (op3))))
    4723              :         {
    4724            0 :           M2Printf_printf1 ((const char *) "failure in quad: %d\\n", 21, (const unsigned char *) &quad, (sizeof (quad)-1));
    4725              :         }
    4726       184475 :       location = M2LexBuf_TokenToLocation (tokenno);
    4727       184475 :       type = SymbolTable_SkipType (SymbolTable_GetType (op3));
    4728       184475 :       M2GCCDeclare_DeclareConstant (tokenno, op3);  /* We might be asked to find the address of a constant string.  */
    4729       184475 :       M2GCCDeclare_DeclareConstructor (tokenno, quad, op3);  /* We might be asked to find the address of a constant string.  */
    4730       184475 :       if (((SymbolTable_IsConst (op3)) && (type == M2Base_Char)) || (SymbolTable_IsConstString (op3)))
    4731              :         {
    4732       168891 :           value = m2decl_BuildStringConstant (const_cast <const char * > (static_cast <char * > (NameKey_KeyToCharStar (SymbolTable_GetString (op3)))), static_cast<int> (SymbolTable_GetStringLength (tokenno, op3)));
    4733              :         }
    4734              :       else
    4735              :         {
    4736        15584 :           value = SymbolConversion_Mod2Gcc (op3);
    4737              :         }
    4738       184475 :       m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (op1), m2expr_BuildAddr (location, value, false));
    4739              :     }
    4740       184481 : }
    4741              : 
    4742      5049648 : static void FoldBecomes (M2GCCDeclare_WalkAction p, M2BasicBlock_BasicBlock bb, unsigned int quad)
    4743              : {
    4744              :   /* 
    4745              : ------------------------------------------------------------------------------
    4746              :    := Operator
    4747              : ------------------------------------------------------------------------------
    4748              :    Sym1<I> := Sym3<I>           := produces a constant
    4749              :   */
    4750      5049648 :   if (DeclaredOperandsBecomes (p, quad))
    4751              :     {
    4752       296348 :       CheckBreak (quad);
    4753       296348 :       if ((! (M2Quads_IsConditionalBooleanQuad (quad))) || (M2BasicBlock_IsBasicBlockFirst (bb)))
    4754              :         {
    4755       291284 :           if (TypeCheckBecomes (p, quad))
    4756              :             {
    4757       291284 :               PerformFoldBecomes (p, quad);
    4758              :             }
    4759              :         }
    4760              :     }
    4761      5049648 : }
    4762              : 
    4763              : 
    4764              : /*
    4765              :    TryDeclareConst -
    4766              : */
    4767              : 
    4768      5049648 : static void TryDeclareConst (unsigned int tokenno, unsigned int sym)
    4769              : {
    4770              :   /* Check whether expr is a constant literal and if so declare it.  */
    4771      5049648 :   M2GCCDeclare_TryDeclareConstant (tokenno, sym);
    4772              :   /* Check whether expr is a const constructor and if so declare it.  */
    4773      5049648 :   M2GCCDeclare_TryDeclareConstructor (tokenno, sym);
    4774      5049648 : }
    4775              : 
    4776              : 
    4777              : /*
    4778              :    RemoveQuad - remove quad and ensure p (des) is called.
    4779              : */
    4780              : 
    4781       290946 : static void RemoveQuad (M2GCCDeclare_WalkAction p, unsigned int des, unsigned int quad)
    4782              : {
    4783           66 :   (*p.proc) (des);
    4784       290946 :   NoChange = false;
    4785       290946 :   M2Quads_SubQuad (quad);
    4786            0 : }
    4787              : 
    4788              : 
    4789              : /*
    4790              :    DeclaredOperandsBecomes -
    4791              : */
    4792              : 
    4793      5049648 : static bool DeclaredOperandsBecomes (M2GCCDeclare_WalkAction p, unsigned int quad)
    4794              : {
    4795      5049648 :   unsigned int des;
    4796      5049648 :   unsigned int op2;
    4797      5049648 :   unsigned int expr;
    4798      5049648 :   bool constExpr;
    4799      5049648 :   bool overflowChecking;
    4800      5049648 :   unsigned int despos;
    4801      5049648 :   unsigned int op2pos;
    4802      5049648 :   unsigned int exprpos;
    4803      5049648 :   unsigned int becomespos;
    4804      5049648 :   M2Quads_QuadOperator op;
    4805              : 
    4806      5049648 :   M2Quads_GetQuadOtok (quad, &becomespos, &op, &des, &op2, &expr, &overflowChecking, &constExpr, &despos, &op2pos, &exprpos);
    4807      5049648 :   M2Debug_Assert (op2pos == M2LexBuf_UnknownTokenNo);
    4808      5049648 :   TryDeclareConst (exprpos, expr);
    4809      5049648 :   if ((SymbolTable_IsConst (des)) && (IsConstant (expr)))
    4810              :     {
    4811              :       /* Constant folding taking place, but have we resolved op3 yet?  */
    4812       304416 :       if (SymbolConversion_GccKnowsAbout (expr))
    4813              :         {
    4814              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    4815              :           /* RemoveSSAPlaceholder (quad, des) ;  */
    4816       296348 :           if (SymbolConversion_GccKnowsAbout (des))
    4817              :             {
    4818            0 :               M2MetaError_MetaErrorT1 (despos, (const char *) "constant {%1Ead} should not be reassigned", 41, des);
    4819            0 :               RemoveQuad (p, des, quad);
    4820            0 :               return false;
    4821              :             }
    4822              :           else
    4823              :             {
    4824              :               return true;
    4825              :             }
    4826              :         }
    4827              :     }
    4828              :   return false;
    4829              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    4830              :   __builtin_unreachable ();
    4831              : }
    4832              : 
    4833              : 
    4834              : /*
    4835              :    TypeCheckBecomes - returns TRUE if the type check succeeds.
    4836              : */
    4837              : 
    4838       291284 : static bool TypeCheckBecomes (M2GCCDeclare_WalkAction p, unsigned int quad)
    4839              : {
    4840       291284 :   unsigned int des;
    4841       291284 :   unsigned int op2;
    4842       291284 :   unsigned int expr;
    4843       291284 :   bool constExpr;
    4844       291284 :   bool overflowChecking;
    4845       291284 :   unsigned int despos;
    4846       291284 :   unsigned int op2pos;
    4847       291284 :   unsigned int exprpos;
    4848       291284 :   unsigned int becomespos;
    4849       291284 :   M2Quads_QuadOperator op;
    4850              : 
    4851       291284 :   M2Quads_GetQuadOtok (quad, &becomespos, &op, &des, &op2, &expr, &overflowChecking, &constExpr, &despos, &op2pos, &exprpos);
    4852       291284 :   M2Debug_Assert (op2pos == M2LexBuf_UnknownTokenNo);
    4853       291284 :   if (M2Options_StrictTypeChecking && (! (M2Check_AssignmentTypeCompatible (despos, (const char *) "", 0, des, expr, true))))
    4854              :     {
    4855            0 :       M2MetaError_MetaErrorT2 (M2LexBuf_MakeVirtualTok (becomespos, despos, exprpos), (const char *) "assignment check caught mismatch between {%1Ead} and {%2ad}", 59, des, expr);
    4856            0 :       RemoveQuad (p, des, quad);
    4857            0 :       return false;
    4858              :     }
    4859              :   return true;
    4860              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    4861              :   __builtin_unreachable ();
    4862              : }
    4863              : 
    4864              : 
    4865              : /*
    4866              :    PerformFoldBecomes - attempts to fold quad.  It propagates constant strings
    4867              :                         and attempts to declare des providing it is a constant
    4868              :                         and expr is resolved.
    4869              : */
    4870              : 
    4871       291284 : static void PerformFoldBecomes (M2GCCDeclare_WalkAction p, unsigned int quad)
    4872              : {
    4873       291284 :   unsigned int des;
    4874       291284 :   unsigned int op2;
    4875       291284 :   unsigned int expr;
    4876       291284 :   bool constExpr;
    4877       291284 :   bool overflowChecking;
    4878       291284 :   unsigned int despos;
    4879       291284 :   unsigned int op2pos;
    4880       291284 :   unsigned int exprpos;
    4881       291284 :   unsigned int becomespos;
    4882       291284 :   unsigned int virtpos;
    4883       291284 :   M2Quads_QuadOperator op;
    4884              : 
    4885       291284 :   M2Quads_GetQuadOtok (quad, &becomespos, &op, &des, &op2, &expr, &overflowChecking, &constExpr, &despos, &op2pos, &exprpos);
    4886       291284 :   M2Debug_Assert (op2pos == M2LexBuf_UnknownTokenNo);
    4887       291284 :   if ((SymbolTable_IsConst (des)) && (SymbolTable_IsConstString (expr)))
    4888              :     {
    4889              :       /* avoid dangling else.  */
    4890         1146 :       if ((SymbolTable_IsConstStringKnown (expr)) && (! (SymbolTable_IsConstStringKnown (des))))
    4891              :         {
    4892         1146 :           SymbolTable_CopyConstString (exprpos, des, expr);
    4893              :         }
    4894              :     }
    4895       290138 :   else if ((SymbolTable_GetType (des)) == SymbolTable_NulSym)
    4896              :     {
    4897              :       /* avoid dangling else.  */
    4898            0 :       M2Debug_Assert ((SymbolTable_GetType (expr)) != SymbolTable_NulSym);
    4899            0 :       SymbolTable_PutConst (des, SymbolTable_GetType (expr));
    4900              :     }
    4901       291284 :   if ((SymbolTable_GetType (expr)) == SymbolTable_NulSym)
    4902              :     {
    4903         1160 :       M2ALU_CheckOrResetOverflow (exprpos, SymbolConversion_Mod2Gcc (expr), M2Quads_MustCheckOverflow (quad));
    4904         1160 :       SymbolConversion_AddModGcc (des, SymbolConversion_Mod2Gcc (expr));
    4905              :     }
    4906              :   else
    4907              :     {
    4908       290124 :       if (! (SymbolConversion_GccKnowsAbout (SymbolTable_GetType (des))))
    4909              :         {
    4910          404 :           return;
    4911              :         }
    4912       289720 :       if (SymbolTable_IsProcedure (expr))
    4913              :         {
    4914           12 :           SymbolConversion_AddModGcc (des, m2convert_BuildConvert (M2LexBuf_TokenToLocation (exprpos), SymbolConversion_Mod2Gcc (SymbolTable_GetType (des)), m2expr_BuildAddr (M2LexBuf_TokenToLocation (exprpos), SymbolConversion_Mod2Gcc (expr), false), true));
    4915              :         }
    4916       289708 :       else if (SymbolTable_IsValueSolved (expr))
    4917              :         {
    4918              :           /* avoid dangling else.  */
    4919       289708 :           SymbolTable_PushValue (expr);
    4920       289708 :           if (M2ALU_IsValueTypeReal ())
    4921              :             {
    4922          504 :               M2ALU_CheckOrResetOverflow (exprpos, M2ALU_PopRealTree (), M2Quads_MustCheckOverflow (quad));
    4923          504 :               SymbolTable_PushValue (expr);
    4924          504 :               SymbolConversion_AddModGcc (des, M2ALU_PopRealTree ());
    4925              :             }
    4926       289204 :           else if (M2ALU_IsValueTypeSet ())
    4927              :             {
    4928              :               /* avoid dangling else.  */
    4929         3880 :               SymbolTable_PopValue (des);
    4930         3880 :               SymbolTable_PutConstSet (des);
    4931              :             }
    4932       285324 :           else if (((M2ALU_IsValueTypeConstructor ()) || (M2ALU_IsValueTypeArray ())) || (M2ALU_IsValueTypeRecord ()))
    4933              :             {
    4934              :               /* avoid dangling else.  */
    4935          428 :               SymbolTable_PopValue (des);
    4936          428 :               SymbolTable_PutConstructor (des);
    4937              :             }
    4938       284896 :           else if (M2ALU_IsValueTypeComplex ())
    4939              :             {
    4940              :               /* avoid dangling else.  */
    4941          330 :               M2ALU_CheckOrResetOverflow (exprpos, M2ALU_PopComplexTree (), M2Quads_MustCheckOverflow (quad));
    4942          330 :               SymbolTable_PushValue (expr);
    4943          330 :               SymbolTable_PopValue (des);
    4944              :             }
    4945              :           else
    4946              :             {
    4947              :               /* avoid dangling else.  */
    4948       284566 :               M2ALU_CheckOrResetOverflow (exprpos, M2ALU_PopIntegerTree (), M2Quads_MustCheckOverflow (quad));
    4949       284566 :               if ((SymbolTable_GetType (des)) == SymbolTable_NulSym)
    4950              :                 {
    4951            0 :                   SymbolTable_PushValue (expr);
    4952            0 :                   SymbolConversion_AddModGcc (des, M2ALU_PopIntegerTree ());
    4953              :                 }
    4954              :               else
    4955              :                 {
    4956       284566 :                   virtpos = M2LexBuf_MakeVirtualTok (becomespos, despos, exprpos);
    4957       284566 :                   SymbolTable_PushValue (expr);
    4958       284566 :                   SymbolConversion_AddModGcc (des, m2convert_BuildConvert (M2LexBuf_TokenToLocation (virtpos), SymbolConversion_Mod2Gcc (SymbolTable_GetType (des)), M2ALU_PopIntegerTree (), false));
    4959              :                 }
    4960              :             }
    4961              :         }
    4962              :       else
    4963              :         {
    4964              :           /* avoid dangling else.  */
    4965            0 :           virtpos = M2LexBuf_MakeVirtualTok (becomespos, despos, exprpos);
    4966            0 :           M2ALU_CheckOrResetOverflow (exprpos, SymbolConversion_Mod2Gcc (des), M2Quads_MustCheckOverflow (quad));
    4967            0 :           SymbolConversion_AddModGcc (des, m2convert_BuildConvert (M2LexBuf_TokenToLocation (virtpos), SymbolConversion_Mod2Gcc (SymbolTable_GetType (des)), m2decl_DeclareKnownConstant (M2LexBuf_TokenToLocation (virtpos), SymbolConversion_Mod2Gcc (SymbolTable_GetType (expr)), SymbolConversion_Mod2Gcc (expr)), false));
    4968              :         }
    4969              :     }
    4970       290880 :   RemoveQuad (p, des, quad);
    4971       290880 :   M2Debug_Assert ((m2block_RememberConstant (SymbolConversion_Mod2Gcc (des))) == (SymbolConversion_Mod2Gcc (des)));
    4972              : }
    4973              : 
    4974              : 
    4975              : /*
    4976              :    CodeTry - starts building a GCC 'try' node.
    4977              : */
    4978              : 
    4979         2890 : static void CodeTry (void)
    4980              : {
    4981         2890 :   location_t location;
    4982              : 
    4983         2890 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    4984         2890 :   handlerBlock = NULL;
    4985         2890 :   tryBlock = m2except_BuildTryBegin (location);
    4986         2890 : }
    4987              : 
    4988              : 
    4989              : /*
    4990              :    CodeThrow - builds a GCC 'throw' node.
    4991              : */
    4992              : 
    4993          320 : static void CodeThrow (unsigned int value)
    4994              : {
    4995          320 :   location_t location;
    4996              : 
    4997          320 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    4998          320 :   if (value == SymbolTable_NulSym)
    4999              :     {
    5000          210 :       m2type_AddStatement (location, m2except_BuildThrow (location, (tree) (NULL)));
    5001              :     }
    5002              :   else
    5003              :     {
    5004          110 :       M2GCCDeclare_DeclareConstant (CurrentQuadToken, value);  /* Checks to see whether it is a constant and declares it.  */
    5005          110 :       m2type_AddStatement (location, m2except_BuildThrow (location, m2convert_BuildConvert (location, m2type_GetIntegerType (), SymbolConversion_Mod2Gcc (value), false)));  /* Checks to see whether it is a constant and declares it.  */
    5006              :     }
    5007          320 : }
    5008              : 
    5009          156 : static void CodeRetry (unsigned int destQuad)
    5010              : {
    5011          156 :   location_t location;
    5012              : 
    5013          156 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    5014          156 :   m2statement_BuildGoto (location, reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (destQuad))));
    5015          156 : }
    5016              : 
    5017         2890 : static void CodeCatchBegin (void)
    5018              : {
    5019         2890 :   location_t location;
    5020              : 
    5021         2890 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    5022         2890 :   m2except_BuildTryEnd (tryBlock);
    5023         2890 :   handlerBlock = m2except_BuildCatchBegin (location);
    5024         2890 : }
    5025              : 
    5026         2890 : static void CodeCatchEnd (void)
    5027              : {
    5028         2890 :   location_t location;
    5029              : 
    5030         2890 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    5031         2890 :   tryBlock = m2except_BuildCatchEnd (location, handlerBlock, tryBlock);
    5032         2890 :   m2type_AddStatement (location, tryBlock);
    5033         2890 : }
    5034              : 
    5035              : 
    5036              : /*
    5037              :    DescribeTypeError -
    5038              : */
    5039              : 
    5040            6 : static void DescribeTypeError (unsigned int token, unsigned int op1, unsigned int op2)
    5041              : {
    5042            6 :   M2MetaError_MetaErrorT2 (token, (const char *) "incompatible set types in assignment, assignment between {%1ERad} and {%2ad}", 76, op1, op2);
    5043            6 :   M2MetaError_MetaError2 ((const char *) "set types are {%1CDtsad} and {%2Dtsad}", 38, op1, op2);
    5044            6 : }
    5045              : 
    5046              : 
    5047              : /*
    5048              :    DefaultConvertGM2 - provides a simple mapping between
    5049              :                        front end data types and GCC equivalents.
    5050              :                        This is only used to aid assignment of
    5051              :                        typed constants.
    5052              : */
    5053              : 
    5054        21303 : static tree DefaultConvertGM2 (unsigned int sym)
    5055              : {
    5056        21303 :   sym = SymbolTable_SkipType (sym);
    5057        21303 :   if (sym == M2Bitset_Bitset)
    5058              :     {
    5059            0 :       return m2type_GetWordType ();
    5060              :     }
    5061              :   else
    5062              :     {
    5063        21303 :       return SymbolConversion_Mod2Gcc (sym);
    5064              :     }
    5065              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5066              :   __builtin_unreachable ();
    5067              : }
    5068              : 
    5069              : 
    5070              : /*
    5071              :    FoldConstBecomes - returns a Tree containing op3.
    5072              :                       The tree will have been folded and
    5073              :                       type converted if necessary.
    5074              : */
    5075              : 
    5076       188786 : static tree FoldConstBecomes (unsigned int tokenno, unsigned int op1, unsigned int op3)
    5077              : {
    5078       188786 :   tree t;
    5079       188786 :   tree type;
    5080       188786 :   location_t location;
    5081              : 
    5082       188786 :   if ((SymbolTable_IsConstSet (op3)) || (((SymbolTable_SkipType (SymbolTable_GetType (op3))) != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_SkipType (SymbolTable_GetType (op3))))))
    5083              :     {
    5084         3482 :       if ((SymbolTable_SkipType (SymbolTable_GetTypeMode (op1))) != (SymbolTable_SkipType (SymbolTable_GetTypeMode (op3))))
    5085              :         {
    5086            6 :           DescribeTypeError (tokenno, op1, op3);
    5087              :           /* Assigning an errant op3 might ICE, therefore it is safer to return op1.  */
    5088            6 :           return SymbolConversion_Mod2Gcc (op1);
    5089              :         }
    5090              :     }
    5091       188780 :   location = M2LexBuf_TokenToLocation (tokenno);
    5092       188780 :   M2GCCDeclare_TryDeclareConstant (tokenno, op3);
    5093       188780 :   t = SymbolConversion_Mod2Gcc (op3);
    5094       188780 :   M2Debug_Assert (t != NULL);
    5095       188780 :   if (IsConstant (op3))
    5096              :     {
    5097              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    5098        53447 :       if (SymbolTable_IsProcedure (op3))
    5099              :         {
    5100              :           return t;
    5101              :         }
    5102        52775 :       else if (((! (SymbolTable_IsConstString (op3))) && (! (SymbolTable_IsConstSet (op3)))) && ((SymbolTable_SkipType (SymbolTable_GetType (op3))) != (SymbolTable_SkipType (SymbolTable_GetType (op1)))))
    5103              :         {
    5104              :           /* avoid dangling else.  */
    5105        21303 :           type = DefaultConvertGM2 (SymbolTable_GetType (op1));  /* do we need this now? --fixme--  */
    5106        21303 :           t = m2convert_ConvertConstantAndCheck (location, type, t);  /* do we need this now? --fixme--  */
    5107              :         }
    5108        31472 :       else if ((SymbolTable_GetType (op1)) != SymbolTable_NulSym)
    5109              :         {
    5110              :           /* avoid dangling else.  */
    5111        31472 :           t = M2GenGCC_StringToChar (SymbolConversion_Mod2Gcc (op3), SymbolTable_GetType (op1), op3);
    5112              :         }
    5113              :     }
    5114              :   return t;
    5115              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5116              :   __builtin_unreachable ();
    5117              : }
    5118              : 
    5119              : 
    5120              : /*
    5121              :    checkArrayElements - return TRUE if des or expr are not arrays.
    5122              :                         If they are arrays and have different number of
    5123              :                         elements return FALSE, otherwise TRUE.
    5124              : */
    5125              : 
    5126       188786 : static bool checkArrayElements (unsigned int des, unsigned int expr, unsigned int virtpos, unsigned int despos, unsigned int exprpos)
    5127              : {
    5128       188786 :   tree e1;
    5129       188786 :   tree e3;
    5130       188786 :   unsigned int t1;
    5131       188786 :   unsigned int t3;
    5132              : 
    5133       188786 :   t1 = SymbolTable_GetType (des);
    5134       188786 :   t3 = SymbolTable_GetType (expr);
    5135       188786 :   if ((((t1 != SymbolTable_NulSym) && (t3 != SymbolTable_NulSym)) && (SymbolTable_IsArray (SymbolTable_SkipType (SymbolTable_GetType (expr))))) && (SymbolTable_IsArray (SymbolTable_SkipType (SymbolTable_GetType (des)))))
    5136              :     {
    5137              :       /* both arrays continue checking  */
    5138          476 :       e1 = m2type_GetArrayNoOfElements (M2LexBuf_TokenToLocation (despos), SymbolConversion_Mod2Gcc (SymbolTable_SkipType (SymbolTable_GetType (des))));
    5139          476 :       e3 = m2type_GetArrayNoOfElements (M2LexBuf_TokenToLocation (exprpos), SymbolConversion_Mod2Gcc (SymbolTable_SkipType (SymbolTable_GetType (expr))));
    5140          476 :       if ((m2expr_CompareTrees (e1, e3)) != 0)
    5141              :         {
    5142            0 :           M2MetaError_MetaErrorT2 (virtpos, (const char *) "not allowed to assign array {%2Ead} to {%1ad} as they have a different number of elements", 89, des, expr);
    5143            0 :           return false;
    5144              :         }
    5145              :     }
    5146              :   return true;
    5147              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5148              :   __builtin_unreachable ();
    5149              : }
    5150              : 
    5151              : 
    5152              : /*
    5153              :    CodeInitAddress -
    5154              : */
    5155              : 
    5156           54 : static void CodeInitAddress (unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    5157              : {
    5158           54 :   location_t location;
    5159              : 
    5160           54 :   M2GCCDeclare_DeclareConstant (CurrentQuadToken, op3);  /* checks to see whether it is a constant and declares it  */
    5161           54 :   M2GCCDeclare_DeclareConstructor (CurrentQuadToken, quad, op3);  /* checks to see whether it is a constant and declares it  */
    5162           54 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    5163           54 :   M2Debug_Assert (op2 == SymbolTable_NulSym);
    5164           54 :   M2Debug_Assert ((SymbolTable_GetMode (op1)) == SymbolTable_LeftValue);
    5165           54 :   m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (op1), m2convert_BuildConvert (location, m2type_GetPointerType (), SymbolConversion_Mod2Gcc (op3), false));
    5166           54 : }
    5167              : 
    5168              : 
    5169              : /*
    5170              :    checkRecordTypes - returns TRUE if des is not a record or if the record
    5171              :                       is the same type as expr.
    5172              : */
    5173              : 
    5174       188786 : static bool checkRecordTypes (unsigned int des, unsigned int expr, unsigned int virtpos)
    5175              : {
    5176       188786 :   unsigned int t1;
    5177       188786 :   unsigned int t2;
    5178              : 
    5179       188786 :   if (((SymbolTable_GetType (des)) == SymbolTable_NulSym) || ((SymbolTable_GetMode (des)) == SymbolTable_LeftValue))
    5180              :     {
    5181        24136 :       return true;
    5182              :     }
    5183              :   else
    5184              :     {
    5185       164650 :       t1 = SymbolTable_SkipType (SymbolTable_GetType (des));
    5186       164650 :       if (SymbolTable_IsRecord (t1))
    5187              :         {
    5188              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    5189          326 :           if ((SymbolTable_GetType (expr)) == SymbolTable_NulSym)
    5190              :             {
    5191            0 :               M2MetaError_MetaErrorT2 (virtpos, (const char *) "cannot assign an operand of type {%1Ets} to a record type {%2tsa}", 65, expr, des);
    5192            0 :               return false;
    5193              :             }
    5194              :           else
    5195              :             {
    5196          326 :               t2 = SymbolTable_SkipType (SymbolTable_GetType (expr));
    5197          326 :               if (t1 == t2)
    5198              :                 {
    5199              :                   return true;
    5200              :                 }
    5201              :               else
    5202              :                 {
    5203            0 :                   M2MetaError_MetaErrorT2 (virtpos, (const char *) "cannot assign an operand of type {%1ts} to a record type {%2tsa}", 64, expr, des);
    5204            0 :                   return false;
    5205              :                 }
    5206              :             }
    5207              :         }
    5208              :     }
    5209              :   return true;
    5210              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5211              :   __builtin_unreachable ();
    5212              : }
    5213              : 
    5214              : 
    5215              : /*
    5216              :    checkIncorrectMeta - checks to see if des and expr are assignment compatible is allows
    5217              :                         generic system types to be assigned.
    5218              : */
    5219              : 
    5220       188786 : static bool checkIncorrectMeta (unsigned int des, unsigned int expr, unsigned int virtpos)
    5221              : {
    5222       188786 :   unsigned int t1;
    5223       188786 :   unsigned int t2;
    5224              : 
    5225       188786 :   t1 = SymbolTable_SkipType (SymbolTable_GetType (des));
    5226       188786 :   t2 = SymbolTable_SkipType (SymbolTable_GetType (expr));
    5227       188786 :   if ((((t1 == SymbolTable_NulSym) || ((SymbolTable_GetMode (des)) == SymbolTable_LeftValue)) || (t2 == SymbolTable_NulSym)) || ((SymbolTable_GetMode (expr)) == SymbolTable_LeftValue))
    5228              :     {
    5229        24832 :       return true;
    5230              :     }
    5231       163954 :   else if (((t1 != t2) && (! (M2System_IsGenericSystemType (t1)))) && (! (M2System_IsGenericSystemType (t2))))
    5232              :     {
    5233              :       /* avoid dangling else.  */
    5234        31180 :       if (((SymbolTable_IsArray (t1)) || (SymbolTable_IsSet (t1))) || (SymbolTable_IsRecord (t1)))
    5235              :         {
    5236           12 :           if (! (M2Base_IsAssignmentCompatible (t1, t2)))
    5237              :             {
    5238            0 :               ErrorMessageDecl (virtpos, (const char *) "illegal assignment error between {%1Etad} and {%2tad}", 53, des, expr, true);
    5239            0 :               return false;
    5240              :             }
    5241              :         }
    5242              :     }
    5243              :   return true;
    5244              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5245              :   __builtin_unreachable ();
    5246              : }
    5247              : 
    5248              : 
    5249              : /*
    5250              :    checkBecomes - returns TRUE if the checks pass.
    5251              : */
    5252              : 
    5253       188786 : static bool checkBecomes (unsigned int des, unsigned int expr, unsigned int virtpos, unsigned int despos, unsigned int exprpos)
    5254              : {
    5255       188786 :   if (((! (checkArrayElements (des, expr, virtpos, despos, exprpos))) || (! (checkRecordTypes (des, expr, virtpos)))) || (! (checkIncorrectMeta (des, expr, virtpos))))
    5256              :     {
    5257            0 :       return false;
    5258              :     }
    5259              :   return true;
    5260              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5261              :   __builtin_unreachable ();
    5262              : }
    5263              : 
    5264              : 
    5265              : /*
    5266              :    checkDeclare - checks to see if sym is declared and if it is not then declare it.
    5267              : */
    5268              : 
    5269        10880 : static void checkDeclare (unsigned int sym)
    5270              : {
    5271        10880 :   if ((sym != SymbolTable_NulSym) && (! (SymbolConversion_GccKnowsAbout (sym))))
    5272              :     {
    5273              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    5274            0 :       if ((SymbolTable_IsTemporary (sym)) && (SymbolTable_IsVariableSSA (sym)))
    5275              :         {
    5276            0 :           M2GCCDeclare_DeclareLocalVariable (sym);
    5277              :         }
    5278            0 :       else if (SymbolTable_IsProcedure (sym))
    5279              :         {
    5280              :           /* avoid dangling else.  */
    5281            0 :           M2GCCDeclare_DeclareProcedure (sym);
    5282              :         }
    5283              :     }
    5284        10880 : }
    5285              : 
    5286              : 
    5287              : /*
    5288              :    PerformCodeBecomes -
    5289              : */
    5290              : 
    5291       188786 : static void PerformCodeBecomes (location_t location, unsigned int virtpos, unsigned int des, unsigned int expr)
    5292              : {
    5293       188786 :   tree destree;
    5294       188786 :   tree exprtree;
    5295              : 
    5296       188786 :   destree = SymbolConversion_Mod2Gcc (des);
    5297       188786 :   exprtree = FoldConstBecomes (virtpos, des, expr);
    5298       188786 :   if ((SymbolTable_IsVar (des)) && (SymbolTable_IsVariableSSA (des)))
    5299              :     {
    5300            0 :       Replace (des, exprtree);
    5301              :     }
    5302       188786 :   else if (m2type_IsGccStrictTypeEquivalent (destree, exprtree))
    5303              :     {
    5304              :       /* avoid dangling else.  */
    5305       188714 :       m2statement_BuildAssignmentStatement (location, destree, exprtree);
    5306              :     }
    5307              :   else
    5308              :     {
    5309              :       /* avoid dangling else.  */
    5310           72 :       m2statement_CopyByField (location, destree, exprtree);
    5311              :     }
    5312       188786 : }
    5313              : 
    5314       189676 : static void CodeBecomes (unsigned int quad)
    5315              : {
    5316       189676 :   bool constExpr;
    5317       189676 :   bool overflowChecking;
    5318       189676 :   M2Quads_QuadOperator op;
    5319       189676 :   unsigned int des;
    5320       189676 :   unsigned int op2;
    5321       189676 :   unsigned int expr;
    5322       189676 :   unsigned int virtpos;
    5323       189676 :   unsigned int becomespos;
    5324       189676 :   unsigned int despos;
    5325       189676 :   unsigned int op2pos;
    5326       189676 :   unsigned int exprpos;
    5327       189676 :   tree length;
    5328       189676 :   tree exprt;
    5329       189676 :   location_t location;
    5330              : 
    5331              :   /* 
    5332              : ------------------------------------------------------------------------------
    5333              :    := Operator
    5334              : ------------------------------------------------------------------------------
    5335              :    Sym1<I> := Sym3<I>           := produces a constant
    5336              :    Sym1<O> := Sym3<O>           := has the effect Mem[Sym1<I>] := Mem[Sym3<I>]
    5337              :   */
    5338       189676 :   M2Quads_GetQuadOtok (quad, &becomespos, &op, &des, &op2, &expr, &overflowChecking, &constExpr, &despos, &op2pos, &exprpos);
    5339       189676 :   M2Debug_Assert (op2pos == M2LexBuf_UnknownTokenNo);
    5340       189676 :   M2GCCDeclare_DeclareConstant (exprpos, expr);  /* Check to see whether expr is a constant and declare it.  */
    5341       189676 :   M2GCCDeclare_DeclareConstructor (exprpos, quad, expr);  /* Check to see whether expr is a constant and declare it.  */
    5342       189676 :   virtpos = M2LexBuf_MakeVirtualTok (becomespos, despos, exprpos);
    5343       189676 :   location = M2LexBuf_TokenToLocation (virtpos);
    5344       189676 :   if (M2Options_StrictTypeChecking && (! (M2Check_AssignmentTypeCompatible (virtpos, (const char *) "", 0, des, expr, true))))
    5345              :     {
    5346            0 :       ErrorMessageDecl (virtpos, (const char *) "assignment check caught mismatch between {%1Ead} and {%2ad}", 59, des, expr, true);
    5347              :     }
    5348       189676 :   if ((SymbolTable_IsConstString (expr)) && (! (SymbolTable_IsConstStringKnown (expr))))
    5349              :     {
    5350            0 :       M2MetaError_MetaErrorT2 (virtpos, (const char *) "internal error: CodeBecomes {%1Aad} in quad {%2n}", 49, des, quad);
    5351              :     }
    5352       189676 :   if ((SymbolTable_IsConst (des)) && (! (SymbolConversion_GccKnowsAbout (des))))
    5353              :     {
    5354            6 :       M2GCCDeclare_ConstantKnownAndUsed (des, CheckConstant (virtpos, des, expr));
    5355              :     }
    5356       189670 :   else if ((SymbolTable_IsConstString (expr)) && ((SymbolTable_SkipTypeAndSubrange (SymbolTable_GetType (des))) != M2Base_Char))
    5357              :     {
    5358              :       /* avoid dangling else.  */
    5359          546 :       checkDeclare (des);
    5360          546 :       if (! (M2GenGCC_PrepareCopyString (becomespos, &length, &exprt, expr, SymbolTable_SkipType (SymbolTable_GetType (des)))))
    5361              :         {
    5362           12 :           ErrorMessageDecl (virtpos, (const char *) "string constant {%1Ea} is too large to be assigned to the array {%2ad}", 70, expr, des, true);
    5363              :         }
    5364          546 :       m2type_AddStatement (location, MaybeDebugBuiltinMemcpy (location, m2expr_BuildAddr (location, SymbolConversion_Mod2Gcc (des), false), m2expr_BuildAddr (location, exprt, false), length));
    5365              :     }
    5366              :   else
    5367              :     {
    5368              :       /* avoid dangling else.  */
    5369       189124 :       if ((((M2System_IsGenericSystemType (SymbolTable_SkipType (SymbolTable_GetType (des)))) != (M2System_IsGenericSystemType (SymbolTable_SkipType (SymbolTable_GetType (expr))))) || (((SymbolTable_IsUnbounded (SymbolTable_SkipType (SymbolTable_GetType (des)))) && (SymbolTable_IsUnbounded (SymbolTable_SkipType (SymbolTable_GetType (expr))))) && ((M2System_IsGenericSystemType (SymbolTable_SkipType (SymbolTable_GetType (SymbolTable_GetType (des))))) != (M2System_IsGenericSystemType (SymbolTable_SkipType (SymbolTable_GetType (SymbolTable_GetType (expr)))))))) && (! (IsConstant (expr))))
    5370              :         {
    5371          338 :           checkDeclare (des);
    5372          338 :           m2type_AddStatement (location, MaybeDebugBuiltinMemcpy (location, m2expr_BuildAddr (location, SymbolConversion_Mod2Gcc (des), false), m2expr_BuildAddr (location, SymbolConversion_Mod2Gcc (expr), false), m2expr_BuildSize (location, SymbolConversion_Mod2Gcc (des), false)));
    5373              :         }
    5374              :       else
    5375              :         {
    5376       188786 :           if (checkBecomes (des, expr, virtpos, despos, exprpos))
    5377              :             {
    5378       188786 :               PerformCodeBecomes (location, virtpos, des, expr);
    5379              :             }
    5380              :           else
    5381              :             {
    5382            0 :               M2Quads_SubQuad (quad);  /* We don't want multiple errors for the quad.  */
    5383              :             }
    5384              :         }
    5385              :     }
    5386       189676 : }
    5387              : 
    5388              : 
    5389              : /*
    5390              :    getrvalue -
    5391              : */
    5392              : 
    5393        10564 : static tree getrvalue (location_t location, unsigned int expr, unsigned int type, bool islvalue)
    5394              : {
    5395        10564 :   return m2expr_GetRValue (location, SymbolConversion_Mod2Gcc (expr), SymbolConversion_Mod2Gcc (type), islvalue);
    5396              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5397              :   __builtin_unreachable ();
    5398              : }
    5399              : 
    5400              : 
    5401              : /*
    5402              :    LValueToGenericPtrOrConvert - if sym is an lvalue then convert to pointer type
    5403              :                                  else convert to type, type. Return the converted tree.
    5404              : */
    5405              : 
    5406        18813 : static tree LValueToGenericPtrOrConvert (unsigned int sym, tree type)
    5407              : {
    5408        18813 :   tree n;
    5409        18813 :   location_t location;
    5410              : 
    5411        18813 :   n = SymbolConversion_Mod2Gcc (sym);
    5412        18813 :   location = M2LexBuf_TokenToLocation (SymbolTable_GetDeclaredMod (sym));
    5413        18813 :   if (n == NULL)
    5414              :     {
    5415            0 :       M2Error_InternalError ((const char *) "expecting symbol to be resolved", 31);
    5416              :     }
    5417        18813 :   if ((SymbolTable_GetMode (sym)) == SymbolTable_LeftValue)
    5418              :     {
    5419            0 :       n = m2convert_BuildConvert (location, m2type_GetPointerType (), n, false);
    5420              :     }
    5421              :   else
    5422              :     {
    5423        18813 :       n = m2convert_BuildConvert (location, type, n, false);
    5424              :     }
    5425        18813 :   return n;
    5426              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5427              :   __builtin_unreachable ();
    5428              : }
    5429              : 
    5430              : 
    5431              : /*
    5432              :    FoldBinary - check whether we can fold the binop operation.
    5433              : */
    5434              : 
    5435       722940 : static void FoldBinary (unsigned int tokenno, M2GCCDeclare_WalkAction p, m2expr_BuildBinProcedure binop, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    5436              : {
    5437       722940 :   tree tl;
    5438       722940 :   tree tr;
    5439       722940 :   tree tv;
    5440       722940 :   tree resType;
    5441       722940 :   location_t location;
    5442              : 
    5443              :   /* firstly ensure that constant literals are declared  */
    5444       722940 :   M2GCCDeclare_TryDeclareConstant (tokenno, op3);
    5445       722940 :   M2GCCDeclare_TryDeclareConstant (tokenno, op2);
    5446       722940 :   location = M2LexBuf_TokenToLocation (tokenno);
    5447       722940 :   if ((SymbolTable_IsConst (op2)) && (SymbolTable_IsConst (op3)))
    5448              :     {
    5449        40856 :       if ((SymbolConversion_GccKnowsAbout (op2)) && (SymbolConversion_GccKnowsAbout (op3)))
    5450              :         {
    5451              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    5452              :           /* fine, we can take advantage of this and fold constants  */
    5453        34164 :           if (SymbolTable_IsConst (op1))
    5454              :             {
    5455        34164 :               M2Debug_Assert ((M2Base_MixTypes (FindType (op3), FindType (op2), tokenno)) != SymbolTable_NulSym);
    5456        34164 :               SymbolTable_PutConst (op1, M2Base_MixTypes (FindType (op3), FindType (op2), tokenno));
    5457        34164 :               tl = M2GenGCC_LValueToGenericPtr (location, op2);
    5458        34164 :               tr = M2GenGCC_LValueToGenericPtr (location, op3);
    5459        34164 :               if ((SymbolTable_GetType (op1)) == SymbolTable_NulSym)
    5460              :                 {
    5461            0 :                   resType = m2type_GetM2ZType ();
    5462              :                 }
    5463              :               else
    5464              :                 {
    5465        34164 :                   resType = SymbolConversion_Mod2Gcc (SymbolTable_GetType (op1));
    5466              :                 }
    5467        34164 :               tl = m2convert_BuildConvert (location, resType, tl, false);
    5468        34164 :               tr = m2convert_BuildConvert (location, resType, tr, false);
    5469        34164 :               tv = (*binop.proc) (location, tl, tr, true);
    5470        34164 :               M2ALU_CheckOrResetOverflow (tokenno, tv, M2Quads_MustCheckOverflow (quad));
    5471        34152 :               SymbolConversion_AddModGcc (op1, m2decl_DeclareKnownConstant (location, resType, tv));
    5472        34152 :               (*p.proc) (op1);
    5473        34152 :               NoChange = false;
    5474        34152 :               M2Quads_SubQuad (quad);
    5475              :             }
    5476              :           /* we can still fold the expression, but not the assignment,
    5477              :                however, we will not do this here but in CodeBinary
    5478              :   */
    5479              :         }
    5480              :     }
    5481       722928 : }
    5482              : 
    5483              : 
    5484              : /*
    5485              :    ConvertBinaryOperands -
    5486              : */
    5487              : 
    5488       133505 : static void ConvertBinaryOperands (location_t location, tree *tl, tree *tr, unsigned int type, unsigned int op2, unsigned int op3)
    5489              : {
    5490       133505 :   (*tl) = NULL;
    5491       133505 :   (*tr) = NULL;
    5492       133505 :   if ((SymbolTable_GetMode (op2)) == SymbolTable_LeftValue)
    5493              :     {
    5494           90 :       (*tl) = M2GenGCC_LValueToGenericPtr (location, op2);
    5495           90 :       type = M2System_Address;
    5496              :     }
    5497       133505 :   if ((SymbolTable_GetMode (op3)) == SymbolTable_LeftValue)
    5498              :     {
    5499            0 :       (*tr) = M2GenGCC_LValueToGenericPtr (location, op3);
    5500            0 :       type = M2System_Address;
    5501              :     }
    5502       133505 :   if (((*tl) == NULL) && ((*tr) == NULL))
    5503              :     {
    5504       133415 :       (*tl) = m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (type), SymbolConversion_Mod2Gcc (op2), false);
    5505       133415 :       (*tr) = m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (type), SymbolConversion_Mod2Gcc (op3), false);
    5506              :     }
    5507           90 :   else if ((*tl) == NULL)
    5508              :     {
    5509              :       /* avoid dangling else.  */
    5510            0 :       (*tl) = m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (type), SymbolConversion_Mod2Gcc (op2), false);
    5511              :     }
    5512           90 :   else if ((*tr) == NULL)
    5513              :     {
    5514              :       /* avoid dangling else.  */
    5515           90 :       (*tr) = m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (type), SymbolConversion_Mod2Gcc (op3), false);
    5516              :     }
    5517       133505 : }
    5518              : 
    5519              : 
    5520              : /*
    5521              :    CodeBinaryCheck - encode a binary arithmetic operation.
    5522              : */
    5523              : 
    5524        48704 : static void CodeBinaryCheck (m2expr_BuildBinCheckProcedure binop, unsigned int quad)
    5525              : {
    5526        48704 :   M2Quads_QuadOperator op;
    5527        48704 :   unsigned int op1;
    5528        48704 :   unsigned int op2;
    5529        48704 :   unsigned int op3;
    5530        48704 :   unsigned int op1pos;
    5531        48704 :   unsigned int op2pos;
    5532        48704 :   unsigned int op3pos;
    5533        48704 :   unsigned int lowestType;
    5534        48704 :   unsigned int type;
    5535        48704 :   tree min;
    5536        48704 :   tree max;
    5537        48704 :   tree lowest;
    5538        48704 :   tree tv;
    5539        48704 :   tree tl;
    5540        48704 :   tree tr;
    5541        48704 :   location_t location;
    5542              : 
    5543              :   /* firstly ensure that constant literals are declared.  */
    5544        48704 :   M2Quads_GetQuadtok (quad, &op, &op1, &op2, &op3, &op1pos, &op2pos, &op3pos);
    5545        48704 :   M2GCCDeclare_DeclareConstant (op3pos, op3);
    5546        48704 :   M2GCCDeclare_DeclareConstant (op2pos, op2);
    5547        48704 :   location = M2LexBuf_TokenToLocation (op1pos);
    5548        48704 :   type = MixTypesBinary (op2, op3, op1pos, M2Quads_MustCheckOverflow (quad));
    5549        48704 :   ConvertBinaryOperands (location, &tl, &tr, type, op2, op3);
    5550        48704 :   lowestType = SymbolTable_GetLType (op1);
    5551        48704 :   lowest = SymbolConversion_Mod2Gcc (lowestType);
    5552        48704 :   if (M2Range_GetMinMax (CurrentQuadToken, lowestType, &min, &max))
    5553              :     {
    5554        45272 :       tv = (*binop.proc) (location, tl, tr, lowest, min, max);
    5555              :     }
    5556              :   else
    5557              :     {
    5558         3432 :       tv = (*binop.proc) (location, tl, tr, NULL, NULL, NULL);
    5559              :     }
    5560        48704 :   M2ALU_CheckOrResetOverflow (op1pos, tv, M2Quads_MustCheckOverflow (quad));
    5561        48704 :   if (SymbolTable_IsConst (op1))
    5562              :     {
    5563              :       /* still have a constant which was not resolved, pass it to gcc.  */
    5564            0 :       M2Debug_Assert ((M2Base_MixTypes (FindType (op3), FindType (op2), op3pos)) != SymbolTable_NulSym);
    5565            0 :       SymbolTable_PutConst (op1, M2Base_MixTypes (FindType (op3), FindType (op2), op3pos));
    5566            0 :       M2GCCDeclare_ConstantKnownAndUsed (op1, m2decl_DeclareKnownConstant (location, SymbolConversion_Mod2Gcc (SymbolTable_GetType (op3)), tv));
    5567              :     }
    5568              :   else
    5569              :     {
    5570        48704 :       if (M2SSA_EnableSSA && (SymbolTable_IsVariableSSA (op1)))
    5571              :         {
    5572              :           Replace (op1, tv);
    5573              :         }
    5574              :       else
    5575              :         {
    5576        48704 :           m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (op1), tv);
    5577              :         }
    5578              :     }
    5579        48704 : }
    5580              : 
    5581              : 
    5582              : /*
    5583              :    MixTypesBinary - depending upon overflowCheck do not check pointer arithmetic.
    5584              : */
    5585              : 
    5586        60598 : static unsigned int MixTypesBinary (unsigned int left, unsigned int right, unsigned int tokpos, bool overflowCheck)
    5587              : {
    5588        60598 :   if (! overflowCheck && ((SymbolTable_IsPointer (SymbolTable_GetTypeMode (left))) || (SymbolTable_IsPointer (SymbolTable_GetTypeMode (right)))))
    5589              :     {
    5590         8678 :       return M2System_Address;
    5591              :     }
    5592              :   else
    5593              :     {
    5594        51920 :       return M2Base_MixTypesDecl (left, right, FindType (left), FindType (right), tokpos);
    5595              :     }
    5596              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5597              :   __builtin_unreachable ();
    5598              : }
    5599              : 
    5600              : 
    5601              : /*
    5602              :    CodeBinary - encode a binary arithmetic operation.
    5603              : */
    5604              : 
    5605        11894 : static void CodeBinary (m2expr_BuildBinProcedure binop, unsigned int quad)
    5606              : {
    5607        11894 :   M2Quads_QuadOperator op;
    5608        11894 :   unsigned int op1;
    5609        11894 :   unsigned int op2;
    5610        11894 :   unsigned int op3;
    5611        11894 :   unsigned int op1pos;
    5612        11894 :   unsigned int op2pos;
    5613        11894 :   unsigned int op3pos;
    5614        11894 :   unsigned int type;
    5615        11894 :   tree tv;
    5616        11894 :   tree tl;
    5617        11894 :   tree tr;
    5618        11894 :   location_t location;
    5619              : 
    5620              :   /* firstly ensure that constant literals are declared  */
    5621        11894 :   M2Quads_GetQuadtok (quad, &op, &op1, &op2, &op3, &op1pos, &op2pos, &op3pos);
    5622        11894 :   M2GCCDeclare_DeclareConstant (op3pos, op3);
    5623        11894 :   M2GCCDeclare_DeclareConstant (op2pos, op2);
    5624        11894 :   location = M2LexBuf_TokenToLocation (op1pos);
    5625        11894 :   type = MixTypesBinary (op2, op3, op1pos, M2Quads_MustCheckOverflow (quad));
    5626        11894 :   ConvertBinaryOperands (location, &tl, &tr, type, op2, op3);
    5627        11894 :   tv = (*binop.proc) (location, tl, tr, false);
    5628        11894 :   M2ALU_CheckOrResetOverflow (op1pos, tv, M2Quads_MustCheckOverflow (quad));
    5629        11894 :   if (SymbolTable_IsConst (op1))
    5630              :     {
    5631              :       /* still have a constant which was not resolved, pass it to gcc  */
    5632            0 :       M2Debug_Assert ((M2Base_MixTypes (FindType (op3), FindType (op2), op1pos)) != SymbolTable_NulSym);
    5633            0 :       SymbolTable_PutConst (op1, M2Base_MixTypes (FindType (op3), FindType (op2), op1pos));
    5634            0 :       M2GCCDeclare_ConstantKnownAndUsed (op1, m2decl_DeclareKnownConstant (location, SymbolConversion_Mod2Gcc (SymbolTable_GetType (op3)), tv));
    5635              :     }
    5636              :   else
    5637              :     {
    5638        11894 :       if (M2SSA_EnableSSA && (SymbolTable_IsVariableSSA (op1)))
    5639              :         {
    5640              :           Replace (op1, tv);
    5641              :         }
    5642              :       else
    5643              :         {
    5644        11894 :           m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (op1), tv);
    5645              :         }
    5646              :     }
    5647        11894 : }
    5648              : 
    5649              : 
    5650              : /*
    5651              :    NoWalkProcedure -
    5652              : */
    5653              : 
    5654            0 : static void NoWalkProcedure (unsigned int param __attribute__((unused)))
    5655              : {
    5656            0 : }
    5657              : 
    5658              : 
    5659              : /*
    5660              :    CheckBinaryExpressionTypes - returns TRUE if all expression checks pass.
    5661              :                                 If the expression check fails quad is removed,
    5662              :                                 the walk procedure (des) is called and NoChange is
    5663              :                                 set to FALSE.
    5664              : */
    5665              : 
    5666         4088 : static bool CheckBinaryExpressionTypes (unsigned int quad, M2GCCDeclare_WalkAction p)
    5667              : {
    5668         4088 :   unsigned int des;
    5669         4088 :   unsigned int left;
    5670         4088 :   unsigned int right;
    5671         4088 :   bool typeChecking;
    5672         4088 :   bool constExpr;
    5673         4088 :   bool overflowChecking;
    5674         4088 :   unsigned int despos;
    5675         4088 :   unsigned int leftpos;
    5676         4088 :   unsigned int rightpos;
    5677         4088 :   unsigned int operatorpos;
    5678         4088 :   unsigned int subexprpos;
    5679         4088 :   M2Quads_QuadOperator op;
    5680              : 
    5681         4088 :   M2Quads_GetQuadOTypetok (quad, &operatorpos, &op, &des, &left, &right, &overflowChecking, &typeChecking, &constExpr, &despos, &leftpos, &rightpos);
    5682         4088 :   if ((typeChecking && (op != M2Quads_LogicalRotateOp)) && (op != M2Quads_LogicalShiftOp))
    5683              :     {
    5684         1934 :       subexprpos = M2LexBuf_MakeVirtualTok (operatorpos, leftpos, rightpos);
    5685         1934 :       if (M2Options_StrictTypeChecking && (! (M2Check_ExpressionTypeCompatible (subexprpos, (const char *) "", 0, left, right, M2Options_StrictTypeChecking, false))))
    5686              :         {
    5687            0 :           M2MetaError_MetaErrorT2 (subexprpos, (const char *) "expression mismatch between {%1Etad} and {%2tad}", 48, left, right);
    5688            0 :           NoChange = false;
    5689            0 :           M2Quads_SubQuad (quad);
    5690            0 :           (*p.proc) (des);
    5691            0 :           return false;
    5692              :         }
    5693              :     }
    5694              :   return true;
    5695              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5696              :   __builtin_unreachable ();
    5697              : }
    5698              : 
    5699              : 
    5700              : /*
    5701              :    CheckElementSetTypes - returns TRUE if all expression checks pass.
    5702              :                           If the expression check fails quad is removed,
    5703              :                           the walk procedure (des) is called and NoChange is
    5704              :                           set to FALSE.
    5705              : */
    5706              : 
    5707         2392 : static bool CheckElementSetTypes (unsigned int quad)
    5708              : {
    5709         2392 :   unsigned int righttype;
    5710         2392 :   unsigned int ignore;
    5711         2392 :   unsigned int left;
    5712         2392 :   unsigned int right;
    5713         2392 :   bool constExpr;
    5714         2392 :   bool overflowChecking;
    5715         2392 :   unsigned int ignorepos;
    5716         2392 :   unsigned int leftpos;
    5717         2392 :   unsigned int rightpos;
    5718         2392 :   unsigned int operatorpos;
    5719         2392 :   unsigned int subexprpos;
    5720         2392 :   M2Quads_QuadOperator op;
    5721              : 
    5722         2392 :   M2Quads_GetQuadOtok (quad, &operatorpos, &op, &left, &right, &ignore, &overflowChecking, &constExpr, &leftpos, &rightpos, &ignorepos);
    5723         2392 :   subexprpos = M2LexBuf_MakeVirtualTok (operatorpos, leftpos, rightpos);
    5724         2392 :   righttype = SymbolTable_GetType (right);
    5725         2392 :   if (M2Options_StrictTypeChecking && (! (M2Check_ExpressionTypeCompatible (subexprpos, (const char *) "", 0, left, right, M2Options_StrictTypeChecking, true))))
    5726              :     {
    5727            0 :       M2MetaError_MetaErrorT2 (subexprpos, (const char *) "the types used in expression {%1Etad} {%kIN} {%2tad} are incompatible", 69, left, right);
    5728            0 :       NoChange = false;
    5729            0 :       M2Quads_SubQuad (quad);
    5730            0 :       return false;
    5731              :     }
    5732         2392 :   if ((righttype == SymbolTable_NulSym) || (! (SymbolTable_IsSet (SymbolTable_SkipType (righttype)))))
    5733              :     {
    5734           12 :       M2MetaError_MetaErrorT1 (rightpos, (const char *) "the right hand side of an {%kIN} expression is expecting {%1Ead} to be a {%kSET} type and not a {%1Etadv}", 105, right);
    5735           12 :       NoChange = false;
    5736           12 :       M2Quads_SubQuad (quad);
    5737           12 :       return false;
    5738              :     }
    5739              :   return true;
    5740              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5741              :   __builtin_unreachable ();
    5742              : }
    5743              : 
    5744              : 
    5745              : /*
    5746              :    CodeBinarySet - encode a binary set AND arithmetic operation.
    5747              :                    Set operands may be longer than a word.
    5748              : */
    5749              : 
    5750         1160 : static void CodeBinarySet (M2GenGCC_ProcedureCardinal constp, M2GenGCC_BinaryFunction binfunc, NameKey_Name wideprocname, unsigned int quad)
    5751              : {
    5752         1160 :   M2Quads_QuadOperator op;
    5753         1160 :   unsigned int operatorpos;
    5754         1160 :   unsigned int combinedpos;
    5755         1160 :   unsigned int despos;
    5756         1160 :   unsigned int leftpos;
    5757         1160 :   unsigned int rightpos;
    5758         1160 :   unsigned int des;
    5759         1160 :   unsigned int left;
    5760         1160 :   unsigned int right;
    5761         1160 :   bool overflowChecking;
    5762         1160 :   bool typeChecking;
    5763         1160 :   bool constExpr;
    5764         1160 :   location_t location;
    5765         1160 :   unsigned int settype;
    5766              : 
    5767         1160 :   M2Quads_GetQuadOTypetok (quad, &operatorpos, &op, &des, &left, &right, &overflowChecking, &typeChecking, &constExpr, &despos, &leftpos, &rightpos);
    5768              :   /* Firstly ensure that constant literals are declared.  */
    5769         1160 :   M2GCCDeclare_DeclareConstant (rightpos, right);
    5770         1160 :   M2GCCDeclare_DeclareConstant (leftpos, left);
    5771         1160 :   M2GCCDeclare_DeclareConstructor (rightpos, quad, right);
    5772         1160 :   M2GCCDeclare_DeclareConstructor (leftpos, quad, left);
    5773         1160 :   if (SymbolTable_IsConst (des))
    5774              :     {
    5775            6 :       combinedpos = M2LexBuf_MakeVirtual2Tok (leftpos, rightpos);
    5776            6 :       if ((SymbolTable_IsValueSolved (left)) && (SymbolTable_IsValueSolved (right)))
    5777              :         {
    5778            6 :           M2Debug_Assert ((M2Base_MixTypes (FindType (left), FindType (right), combinedpos)) != SymbolTable_NulSym);
    5779            6 :           SymbolTable_PutConst (des, FindType (right));
    5780            6 :           SymbolTable_PushValue (left);
    5781            6 :           SymbolTable_PushValue (right);
    5782            6 :           (*constp.proc) (combinedpos);
    5783            6 :           SymbolTable_PopValue (des);
    5784            6 :           SymbolTable_PutConstSet (des);
    5785              :         }
    5786              :       else
    5787              :         {
    5788            0 :           M2MetaError_MetaErrorT0 (combinedpos, (const char *) "{%E}constant expression cannot be evaluated", 43);
    5789              :         }
    5790              :     }
    5791              :   else
    5792              :     {
    5793         1154 :       checkDeclare (des);
    5794         1154 :       settype = SymbolTable_GetLType (des);
    5795         1154 :       M2Debug_Assert (SymbolTable_IsSet (settype));
    5796         1154 :       combinedpos = M2LexBuf_MakeVirtualTok (despos, leftpos, rightpos);
    5797         1154 :       if (SymbolTable_GetSetInWord (settype))
    5798              :         {
    5799          980 :           location = M2LexBuf_TokenToLocation (combinedpos);
    5800          980 :           SetNarrowBinary (location, binfunc, settype, des, left, right);
    5801              :         }
    5802              :       else
    5803              :         {
    5804          174 :           SetWideBinary (combinedpos, wideprocname, settype, des, left, right);
    5805              :         }
    5806              :     }
    5807         1160 : }
    5808              : 
    5809              : 
    5810              : /*
    5811              :    MakeTemporarySetName - returns a Name using the template _Tset%d.
    5812              : */
    5813              : 
    5814         3288 : static NameKey_Name MakeTemporarySetName (void)
    5815              : {
    5816         3288 :   NameKey_Name name;
    5817         3288 :   DynamicStrings_String s;
    5818              : 
    5819         3288 :   SetTemporaryNo += 1;
    5820         3288 :   s = FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "_Tset%d", 7)), (const unsigned char *) &SetTemporaryNo, (sizeof (SetTemporaryNo)-1));
    5821         3288 :   name = NameKey_makekey (DynamicStrings_string (s));
    5822         3288 :   s = DynamicStrings_KillString (s);
    5823         3288 :   return name;
    5824              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5825              :   __builtin_unreachable ();
    5826              : }
    5827              : 
    5828              : 
    5829              : /*
    5830              :    SetWideBinary -
    5831              : */
    5832              : 
    5833          174 : static void SetWideBinary (unsigned int tokenno, NameKey_Name wideprocname, unsigned int settype, unsigned int des, unsigned int left, unsigned int right)
    5834              : {
    5835          174 :   if (M2Options_OptimizeSets)
    5836              :     {
    5837              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    5838           68 :       if (wideprocname == (NameKey_MakeKey ((const char *) "And", 3)))
    5839              :         {
    5840            4 :           SetWideBinaryBuiltin (tokenno, (M2GenGCC_BinaryFunction) {(M2GenGCC_BinaryFunction_t) m2expr_BuildLogicalAnd}, des, left, right);
    5841            4 :           return;
    5842              :         }
    5843           64 :       else if (wideprocname == (NameKey_MakeKey ((const char *) "Or", 2)))
    5844              :         {
    5845              :           /* avoid dangling else.  */
    5846           56 :           SetWideBinaryBuiltin (tokenno, (M2GenGCC_BinaryFunction) {(M2GenGCC_BinaryFunction_t) m2expr_BuildLogicalOr}, des, left, right);
    5847           56 :           return;
    5848              :         }
    5849              :     }
    5850          114 :   SetWideBinaryLibrary (tokenno, wideprocname, settype, des, left, right);
    5851              : }
    5852              : 
    5853              : 
    5854              : /*
    5855              :    SetWideBinaryLibrary - call wideprocname (des, left, right) passing des, left, right
    5856              :                           as an array of byte.
    5857              : */
    5858              : 
    5859          114 : static void SetWideBinaryLibrary (unsigned int tokenno, NameKey_Name wideprocname, unsigned int settype, unsigned int des, unsigned int left, unsigned int right)
    5860              : {
    5861          114 :   location_t location;
    5862          114 :   unsigned int procedure;
    5863          114 :   unsigned int param1;
    5864          114 :   unsigned int param2;
    5865          114 :   unsigned int param3;
    5866          114 :   tree highbit;
    5867          114 :   tree array1;
    5868          114 :   tree array2;
    5869          114 :   tree array3;
    5870          114 :   tree call;
    5871              : 
    5872          114 :   procedure = FromM2WIDESETImport (tokenno, wideprocname);
    5873          114 :   checkDeclare (procedure);
    5874          114 :   location = M2LexBuf_TokenToLocation (tokenno);
    5875          114 :   param1 = SymbolTable_GetNthParamAnyClosest (procedure, 1, SymbolTable_GetMainModule ());
    5876          114 :   param2 = SymbolTable_GetNthParamAnyClosest (procedure, 2, SymbolTable_GetMainModule ());
    5877          114 :   param3 = SymbolTable_GetNthParamAnyClosest (procedure, 3, SymbolTable_GetMainModule ());
    5878          114 :   array1 = CreateSetArrayParam (location, tokenno, des, param1);
    5879          114 :   array2 = CreateSetArrayParam (location, tokenno, left, param2);
    5880          114 :   array3 = CreateSetArrayParam (location, tokenno, right, param3);
    5881          114 :   highbit = m2convert_ToCardinal (location, CalcHighSetBit (location, settype));
    5882          114 :   m2statement_BuildParam (location, highbit);  /* Parameter 4.  */
    5883          114 :   m2statement_BuildParam (location, array3);  /* Parameter 3.  */
    5884          114 :   m2statement_BuildParam (location, array2);  /* Parameter 2.  */
    5885          114 :   m2statement_BuildParam (location, array1);  /* Parameter 1.  */
    5886          114 :   call = m2statement_BuildProcedureCallTree (location, SymbolConversion_Mod2Gcc (procedure), NULL);  /* Parameter 1.  */
    5887          114 :   m2statement_SetLastFunction (NULL);
    5888          114 :   m2type_AddStatement (location, call);
    5889          114 : }
    5890              : 
    5891              : 
    5892              : /*
    5893              :    SetWideBinaryBuiltin - build an builtin wideset NOT operation.
    5894              : */
    5895              : 
    5896           60 : static void SetWideBinaryBuiltin (unsigned int tokenno, M2GenGCC_BinaryFunction binfunc, unsigned int des, unsigned int left, unsigned int right)
    5897              : {
    5898           60 :   location_t location;
    5899           60 :   tree byte;
    5900           60 :   tree lhs;
    5901           60 :   tree rhs;
    5902           60 :   tree dest;
    5903           60 :   tree index;
    5904           60 :   tree high;
    5905              : 
    5906           60 :   location = M2LexBuf_TokenToLocation (tokenno);
    5907           60 :   high = ResolveHigh (tokenno, 1, des);
    5908           60 :   index = m2expr_GetIntegerZero (location);
    5909           60 :   byte = SymbolConversion_Mod2Gcc (M2System_Byte);
    5910         1512 :   do {
    5911         1512 :     rhs = m2expr_BuildArray (location, byte, getrvalue (location, right, SymbolTable_GetType (right), (SymbolTable_GetMode (right)) == SymbolTable_LeftValue), index, m2expr_GetIntegerZero (location));
    5912         1512 :     lhs = m2expr_BuildArray (location, byte, getrvalue (location, left, SymbolTable_GetType (left), (SymbolTable_GetMode (left)) == SymbolTable_LeftValue), index, m2expr_GetIntegerZero (location));
    5913         1512 :     rhs = (*binfunc.proc) (location, lhs, rhs);
    5914         1512 :     rhs = m2convert_BuildConvert (location, byte, rhs, false);
    5915         1512 :     dest = m2expr_BuildArray (location, byte, getrvalue (location, des, SymbolTable_GetType (des), (SymbolTable_GetMode (des)) == SymbolTable_LeftValue), index, m2expr_GetIntegerZero (location));
    5916         1512 :     m2statement_BuildAssignmentStatement (location, dest, rhs);
    5917         1512 :     M2ALU_PushIntegerTree (index);
    5918         1512 :     M2ALU_PushCard (1);
    5919         1512 :     M2ALU_Addn ();
    5920         1512 :     index = M2ALU_PopIntegerTree ();
    5921         1512 :   } while (! ((m2expr_CompareTrees (index, high)) > 0));
    5922           60 : }
    5923              : 
    5924              : 
    5925              : /*
    5926              :    SetNarrowBinary - create tree consisting of:
    5927              :                      result := binfunc (left, right)
    5928              :                      result, left and right can be lvalues.
    5929              : */
    5930              : 
    5931          980 : static void SetNarrowBinary (location_t location, M2GenGCC_BinaryFunction binfunc, unsigned int settype, unsigned int result, unsigned int left, unsigned int right)
    5932              : {
    5933          980 :   bool isResultL;
    5934          980 :   bool isLeftL;
    5935          980 :   bool isRightL;
    5936              : 
    5937          980 :   isResultL = (SymbolTable_GetMode (result)) == SymbolTable_LeftValue;
    5938          980 :   isLeftL = (SymbolTable_GetMode (left)) == SymbolTable_LeftValue;
    5939          980 :   isRightL = (SymbolTable_GetMode (right)) == SymbolTable_LeftValue;
    5940          980 :   m2statement_BuildAssignmentStatement (location, getrvalue (location, result, settype, isResultL), (tree) ((*binfunc.proc) (location, getrvalue (location, left, settype, isLeftL), getrvalue (location, right, settype, isRightL))));
    5941          980 : }
    5942              : 
    5943              : 
    5944              : /*
    5945              :    CreateSetArrayParam - return a gcc tree containing value contained in an unbounded
    5946              :                          array parameter.
    5947              : */
    5948              : 
    5949         3288 : static tree CreateSetArrayParam (location_t location, unsigned int tokenno, unsigned int value, unsigned int param)
    5950              : {
    5951         3288 :   tree dataAddress;
    5952         3288 :   tree designator;
    5953         3288 :   tree oarecord;
    5954         3288 :   unsigned int unbounded;
    5955         3288 :   unsigned int HighField;
    5956         3288 :   unsigned int scope;
    5957              : 
    5958         3288 :   unbounded = SymbolTable_GetType (param);
    5959         3288 :   M2Debug_Assert (SymbolTable_IsUnbounded (unbounded));
    5960         3288 :   scope = GetActiveScope ();
    5961              :   /* Declare oarecord which has a pointer and high field.  This will be passed as
    5962              :       a parameter into the runtime set procedure and appear as an ARRAY OF BYTE.  */
    5963         3288 :   oarecord = m2decl_DeclareKnownVariable (location, const_cast <const char * > (static_cast <char * > (NameKey_KeyToCharStar (MakeTemporarySetName ()))), SymbolConversion_Mod2Gcc (unbounded), false, false, true, SymbolTable_IsProcedure (scope), SymbolConversion_Mod2Gcc (scope), NULL);
    5964              :   /* Designator is oarecord.address.  */
    5965         3288 :   designator = m2expr_BuildComponentRef (location, oarecord, SymbolConversion_Mod2Gcc (SymbolTable_GetUnboundedAddressOffset (unbounded)));
    5966         3288 :   if ((SymbolTable_GetMode (value)) == SymbolTable_LeftValue)
    5967              :     {
    5968              :       /* Already pointing to the data.  */
    5969          198 :       dataAddress = SymbolConversion_Mod2Gcc (value);
    5970              :     }
    5971              :   else
    5972              :     {
    5973         3090 :       dataAddress = m2expr_BuildAddr (location, SymbolConversion_Mod2Gcc (value), false);
    5974              :     }
    5975         3288 :   m2statement_BuildAssignmentStatement (location, designator, dataAddress);
    5976         3288 :   HighField = SymbolTable_GetUnboundedHighOffset (unbounded, 1);
    5977         3288 :   designator = m2expr_BuildComponentRef (location, oarecord, SymbolConversion_Mod2Gcc (HighField));
    5978         3288 :   m2statement_BuildAssignmentStatement (location, designator, ResolveHigh (tokenno, 1, value));
    5979         3288 :   return oarecord;
    5980              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5981              :   __builtin_unreachable ();
    5982              : }
    5983              : 
    5984              : 
    5985              : /*
    5986              :    CheckUnaryOperand - checks to see whether operand is using a generic type.
    5987              : */
    5988              : 
    5989          918 : static bool CheckUnaryOperand (unsigned int quad, unsigned int operand)
    5990              : {
    5991          918 :   unsigned int type;
    5992          918 :   DynamicStrings_String s;
    5993          918 :   DynamicStrings_String op;
    5994              : 
    5995          918 :   type = SymbolTable_SkipType (SymbolTable_GetType (operand));
    5996          918 :   if ((((M2System_Word == type) || (M2System_IsWordN (type))) || (M2System_Byte == type)) || (M2System_Loc == type))
    5997              :     {
    5998            6 :       op = M2Quads_GetM2OperatorDesc (M2Quads_GetQuadOp (quad));
    5999            6 :       s = DynamicStrings_InitString ((const char *) "operand of type {%1Ets} is not allowed in an unary expression", 61);
    6000            6 :       if (op != NULL)
    6001              :         {
    6002            6 :           s = DynamicStrings_ConCatChar (s, ' ');
    6003            6 :           s = DynamicStrings_ConCat (s, DynamicStrings_Mark (op));
    6004              :         }
    6005            6 :       M2MetaError_MetaErrorStringT1 (CurrentQuadToken, s, operand);
    6006            6 :       return false;
    6007              :     }
    6008              :   return true;
    6009              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6010              :   __builtin_unreachable ();
    6011              : }
    6012              : 
    6013              : 
    6014              : /*
    6015              :    UnaryOperand - returns TRUE if operand is acceptable for
    6016              :                   unary operator: + -.  If FALSE
    6017              :                   is returned, an error message will be generated
    6018              :                   and the quad is deleted.
    6019              : */
    6020              : 
    6021          918 : static bool UnaryOperand (unsigned int quad, unsigned int operand)
    6022              : {
    6023          918 :   if (! (CheckUnaryOperand (quad, operand)))
    6024              :     {
    6025            6 :       M2Quads_SubQuad (quad);  /* We do not want multiple copies of the same error.  */
    6026            6 :       return false;  /* We do not want multiple copies of the same error.  */
    6027              :     }
    6028              :   return true;
    6029              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6030              :   __builtin_unreachable ();
    6031              : }
    6032              : 
    6033              : 
    6034              : /*
    6035              :    CheckBinaryOperand - checks to see whether operand is using a generic type.
    6036              : */
    6037              : 
    6038      1567100 : static bool CheckBinaryOperand (unsigned int quad, bool isleft, unsigned int operand, bool result)
    6039              : {
    6040      1567100 :   unsigned int type;
    6041      1567100 :   M2Quads_QuadOperator qop;
    6042      1567100 :   unsigned int op1;
    6043      1567100 :   unsigned int op2;
    6044      1567100 :   unsigned int op3;
    6045      1567100 :   unsigned int op1pos;
    6046      1567100 :   unsigned int op2pos;
    6047      1567100 :   unsigned int op3pos;
    6048      1567100 :   DynamicStrings_String s;
    6049      1567100 :   DynamicStrings_String op;
    6050              : 
    6051      1567100 :   type = SymbolTable_SkipType (SymbolTable_GetType (operand));
    6052      1567100 :   if ((((M2System_Word == type) || (M2System_IsWordN (type))) || (M2System_Byte == type)) || (M2System_Loc == type))
    6053              :     {
    6054           18 :       M2Quads_GetQuadtok (quad, &qop, &op1, &op2, &op3, &op1pos, &op2pos, &op3pos);
    6055           18 :       op = M2Quads_GetM2OperatorDesc (M2Quads_GetQuadOp (quad));
    6056           18 :       if (isleft)
    6057              :         {
    6058            6 :           s = DynamicStrings_InitString ((const char *) "left operand {%1Ea} of type {%1Ets} is not allowed in binary expression", 71);
    6059              :         }
    6060              :       else
    6061              :         {
    6062           12 :           s = DynamicStrings_InitString ((const char *) "right operand {%1Ea} of type {%1Ets} is not allowed in binary expression", 72);
    6063              :         }
    6064           18 :       if (op != NULL)
    6065              :         {
    6066           18 :           s = DynamicStrings_ConCatChar (s, ' ');
    6067           18 :           s = DynamicStrings_ConCat (s, DynamicStrings_Mark (op));
    6068              :         }
    6069           18 :       M2MetaError_MetaErrorStringT1 (op1pos, s, operand);
    6070           18 :       return false;
    6071              :     }
    6072              :   return result;
    6073              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6074              :   __builtin_unreachable ();
    6075              : }
    6076              : 
    6077              : 
    6078              : /*
    6079              :    BinaryOperands - returns TRUE if, l, and, r, are acceptable for
    6080              :                     binary operator: + - / * and friends.  If FALSE
    6081              :                     is returned, an error message will be generated
    6082              :                     and the, quad, is deleted.
    6083              : */
    6084              : 
    6085       783550 : static bool BinaryOperands (unsigned int quad, unsigned int l, unsigned int r)
    6086              : {
    6087       783550 :   bool result;
    6088              : 
    6089       783550 :   result = CheckBinaryOperand (quad, true, l, true);
    6090       783550 :   result = CheckBinaryOperand (quad, false, r, result);
    6091       783550 :   if (! result)
    6092              :     {
    6093           12 :       M2Quads_SubQuad (quad);  /* We do not want multiple copies of the same error.  */
    6094              :     }
    6095       783550 :   return result;
    6096              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6097              :   __builtin_unreachable ();
    6098              : }
    6099              : 
    6100              : 
    6101              : /*
    6102              :    IsConstStr - returns TRUE if sym is a constant string or a char constant.
    6103              : */
    6104              : 
    6105       441084 : static bool IsConstStr (unsigned int sym)
    6106              : {
    6107       441084 :   return (SymbolTable_IsConstString (sym)) || ((SymbolTable_IsConst (sym)) && ((SymbolTable_GetSType (sym)) == M2Base_Char));
    6108              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6109              :   __builtin_unreachable ();
    6110              : }
    6111              : 
    6112              : 
    6113              : /*
    6114              :    IsConstStrKnown - returns TRUE if sym is a constant string or a char constant
    6115              :                      which is known.
    6116              : */
    6117              : 
    6118        44660 : static bool IsConstStrKnown (unsigned int sym)
    6119              : {
    6120        44660 :   return ((SymbolTable_IsConstString (sym)) && (SymbolTable_IsConstStringKnown (sym))) || ((SymbolTable_IsConst (sym)) && ((SymbolTable_GetSType (sym)) == M2Base_Char));
    6121              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6122              :   __builtin_unreachable ();
    6123              : }
    6124              : 
    6125              : 
    6126              : /*
    6127              :    GetStr - return a string containing a constant string value associated with sym.
    6128              :             A nul char constant will return an empty string.
    6129              : */
    6130              : 
    6131        44492 : static DynamicStrings_String GetStr (unsigned int tokenno, unsigned int sym)
    6132              : {
    6133        44492 :   char ch;
    6134              : 
    6135        44492 :   M2Debug_Assert (SymbolTable_IsConst (sym));
    6136        44492 :   if (SymbolTable_IsConstString (sym))
    6137              :     {
    6138        44468 :       return DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetString (sym)));
    6139              :     }
    6140              :   else
    6141              :     {
    6142           24 :       M2Debug_Assert ((SymbolTable_GetSType (sym)) == M2Base_Char);
    6143           24 :       SymbolTable_PushValue (sym);
    6144           24 :       ch = M2ALU_PopChar (tokenno);
    6145           24 :       return DynamicStrings_InitStringChar (ch);
    6146              :     }
    6147              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6148              :   __builtin_unreachable ();
    6149              : }
    6150              : 
    6151              : 
    6152              : /*
    6153              :    FoldAdd - check addition for constant folding.  It checks for conststrings
    6154              :              overloading the +.
    6155              : */
    6156              : 
    6157       396940 : static void FoldAdd (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    6158              : {
    6159       396940 :   DynamicStrings_String s;
    6160              : 
    6161       396940 :   if ((IsConstStr (op2)) && (IsConstStr (op3)))
    6162              :     {
    6163              :       /* avoid dangling else.  */
    6164          540 :       if ((IsConstStrKnown (op2)) && (IsConstStrKnown (op3)))
    6165              :         {
    6166              :           /* Handle special addition for constant strings.  */
    6167          492 :           s = DynamicStrings_Dup (GetStr (tokenno, op2));
    6168          492 :           s = DynamicStrings_ConCat (s, GetStr (tokenno, op3));
    6169          492 :           SymbolTable_PutConstStringKnown (tokenno, op1, NameKey_makekey (DynamicStrings_string (s)), false, true);
    6170          492 :           M2GCCDeclare_TryDeclareConstant (tokenno, op1);
    6171          492 :           (*p.proc) (op1);
    6172          492 :           NoChange = false;
    6173          492 :           M2Quads_SubQuad (quad);
    6174          492 :           s = DynamicStrings_KillString (s);
    6175              :         }
    6176              :     }
    6177              :   else
    6178              :     {
    6179       396400 :       FoldArithAdd (tokenno, p, quad, op1, op2, op3);
    6180              :     }
    6181       396928 : }
    6182              : 
    6183              : 
    6184              : /*
    6185              :    FoldArithAdd - check arithmetic addition for constant folding.
    6186              : */
    6187              : 
    6188       396400 : static void FoldArithAdd (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    6189              : {
    6190       396400 :   if (BinaryOperands (quad, op2, op3))
    6191              :     {
    6192       396388 :       FoldBinary (tokenno, p, (m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildAdd}, quad, op1, op2, op3);
    6193              :     }
    6194       396388 : }
    6195              : 
    6196              : 
    6197              : /*
    6198              :    CodeAddChecked - code an addition instruction, determine whether checking
    6199              :                     is required.
    6200              : */
    6201              : 
    6202        34062 : static void CodeAddChecked (unsigned int quad, unsigned int left, unsigned int right)
    6203              : {
    6204        34062 :   if (M2Quads_MustCheckOverflow (quad))
    6205              :     {
    6206        22902 :       CodeAddCheck (quad, left, right);
    6207              :     }
    6208              :   else
    6209              :     {
    6210        11160 :       CodeAdd (quad, left, right);
    6211              :     }
    6212        34062 : }
    6213              : 
    6214              : 
    6215              : /*
    6216              :    CodeAddCheck - encode addition but check for overflow.
    6217              : */
    6218              : 
    6219        22902 : static void CodeAddCheck (unsigned int quad, unsigned int left, unsigned int right)
    6220              : {
    6221        22902 :   if (BinaryOperands (quad, left, right))
    6222              :     {
    6223        22902 :       CodeBinaryCheck ((m2expr_BuildBinCheckProcedure) {(m2expr_BuildBinCheckProcedure_t) m2expr_BuildAddCheck}, quad);
    6224              :     }
    6225        22902 : }
    6226              : 
    6227              : 
    6228              : /*
    6229              :    CodeAdd - encode addition.
    6230              : */
    6231              : 
    6232        11160 : static void CodeAdd (unsigned int quad, unsigned int left, unsigned int right)
    6233              : {
    6234        11160 :   if (BinaryOperands (quad, left, right))
    6235              :     {
    6236        11160 :       CodeBinary ((m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildAdd}, quad);
    6237              :     }
    6238        11160 : }
    6239              : 
    6240              : 
    6241              : /*
    6242              :    FoldSub - check subtraction for constant folding.
    6243              : */
    6244              : 
    6245       164904 : static void FoldSub (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    6246              : {
    6247       164904 :   if (BinaryOperands (quad, op2, op3))
    6248              :     {
    6249       164904 :       FoldBinary (tokenno, p, (m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildSub}, quad, op1, op2, op3);
    6250              :     }
    6251       164904 : }
    6252              : 
    6253              : 
    6254              : /*
    6255              :    CodeSubChecked - code a subtract instruction, determine whether checking
    6256              :                     is required.
    6257              : */
    6258              : 
    6259        10318 : static void CodeSubChecked (unsigned int quad, unsigned int left, unsigned int right)
    6260              : {
    6261        10318 :   if (M2Quads_MustCheckOverflow (quad))
    6262              :     {
    6263        10318 :       CodeSubCheck (quad, left, right);
    6264              :     }
    6265              :   else
    6266              :     {
    6267            0 :       CodeSub (quad, left, right);
    6268              :     }
    6269        10318 : }
    6270              : 
    6271              : 
    6272              : /*
    6273              :    CodeSubCheck - encode subtraction but check for overflow.
    6274              : */
    6275              : 
    6276        10318 : static void CodeSubCheck (unsigned int quad, unsigned int left, unsigned int right)
    6277              : {
    6278        10318 :   if (BinaryOperands (quad, left, right))
    6279              :     {
    6280        10318 :       CodeBinaryCheck ((m2expr_BuildBinCheckProcedure) {(m2expr_BuildBinCheckProcedure_t) m2expr_BuildSubCheck}, quad);
    6281              :     }
    6282        10318 : }
    6283              : 
    6284              : 
    6285              : /*
    6286              :    CodeSub - encode subtraction.
    6287              : */
    6288              : 
    6289            0 : static void CodeSub (unsigned int quad, unsigned int left, unsigned int right)
    6290              : {
    6291            0 :   if (BinaryOperands (quad, left, right))
    6292              :     {
    6293            0 :       CodeBinary ((m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildSub}, quad);
    6294              :     }
    6295            0 : }
    6296              : 
    6297              : 
    6298              : /*
    6299              :    FoldMult - check multiplication for constant folding.
    6300              : */
    6301              : 
    6302       109726 : static void FoldMult (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    6303              : {
    6304       109726 :   if (BinaryOperands (quad, op2, op3))
    6305              :     {
    6306       109726 :       FoldBinary (tokenno, p, (m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildMult}, quad, op1, op2, op3);
    6307              :     }
    6308       109726 : }
    6309              : 
    6310              : 
    6311              : /*
    6312              :    CodeMultChecked - code a multiplication instruction, determine whether checking
    6313              :                      is required.
    6314              : */
    6315              : 
    6316        11456 : static void CodeMultChecked (unsigned int quad, unsigned int left, unsigned int right)
    6317              : {
    6318        11456 :   if (M2Quads_MustCheckOverflow (quad))
    6319              :     {
    6320        11456 :       CodeMultCheck (quad, left, right);
    6321              :     }
    6322              :   else
    6323              :     {
    6324            0 :       CodeMult (quad, left, right);
    6325              :     }
    6326        11456 : }
    6327              : 
    6328              : 
    6329              : /*
    6330              :    CodeMultCheck - encode multiplication but check for overflow.
    6331              : */
    6332              : 
    6333        11456 : static void CodeMultCheck (unsigned int quad, unsigned int left, unsigned int right)
    6334              : {
    6335        11456 :   if (BinaryOperands (quad, left, right))
    6336              :     {
    6337        11456 :       CodeBinaryCheck ((m2expr_BuildBinCheckProcedure) {(m2expr_BuildBinCheckProcedure_t) m2expr_BuildMultCheck}, quad);
    6338              :     }
    6339        11456 : }
    6340              : 
    6341              : 
    6342              : /*
    6343              :    CodeMult - encode multiplication.
    6344              : */
    6345              : 
    6346            0 : static void CodeMult (unsigned int quad, unsigned int left, unsigned int right)
    6347              : {
    6348            0 :   if (BinaryOperands (quad, left, right))
    6349              :     {
    6350            0 :       CodeBinary ((m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildMult}, quad);
    6351              :     }
    6352            0 : }
    6353              : 
    6354              : 
    6355              : /*
    6356              :    CodeDivM2Checked - code a divide instruction, determine whether checking
    6357              :                       is required.
    6358              : */
    6359              : 
    6360         1940 : static void CodeDivM2Checked (unsigned int quad, unsigned int left, unsigned int right)
    6361              : {
    6362         1940 :   if (M2Quads_MustCheckOverflow (quad))
    6363              :     {
    6364         1940 :       CodeDivM2Check (quad, left, right);
    6365              :     }
    6366              :   else
    6367              :     {
    6368            0 :       CodeDivM2 (quad, left, right);
    6369              :     }
    6370         1940 : }
    6371              : 
    6372              : 
    6373              : /*
    6374              :    CodeDivM2Check - encode addition but check for overflow.
    6375              : */
    6376              : 
    6377         1940 : static void CodeDivM2Check (unsigned int quad, unsigned int left, unsigned int right)
    6378              : {
    6379         1940 :   if (BinaryOperands (quad, left, right))
    6380              :     {
    6381         1940 :       CodeBinaryCheck ((m2expr_BuildBinCheckProcedure) {(m2expr_BuildBinCheckProcedure_t) m2expr_BuildDivM2Check}, quad);
    6382              :     }
    6383         1940 : }
    6384              : 
    6385              : 
    6386              : /*
    6387              :    CodeModM2Checked - code a modulus instruction, determine whether checking
    6388              :                       is required.
    6389              : */
    6390              : 
    6391         2088 : static void CodeModM2Checked (unsigned int quad, unsigned int left, unsigned int right)
    6392              : {
    6393         2088 :   if (M2Quads_MustCheckOverflow (quad))
    6394              :     {
    6395         2088 :       CodeModM2Check (quad, left, right);
    6396              :     }
    6397              :   else
    6398              :     {
    6399            0 :       CodeModM2 (quad, left, right);
    6400              :     }
    6401         2088 : }
    6402              : 
    6403              : 
    6404              : /*
    6405              :    CodeModM2Check - encode addition but check for overflow.
    6406              : */
    6407              : 
    6408         2088 : static void CodeModM2Check (unsigned int quad, unsigned int left, unsigned int right)
    6409              : {
    6410         2088 :   if (BinaryOperands (quad, left, right))
    6411              :     {
    6412         2088 :       CodeBinaryCheck ((m2expr_BuildBinCheckProcedure) {(m2expr_BuildBinCheckProcedure_t) m2expr_BuildModM2Check}, quad);
    6413              :     }
    6414         2088 : }
    6415              : 
    6416              : 
    6417              : /*
    6418              :    BinaryOperandRealFamily -
    6419              : */
    6420              : 
    6421        47122 : static bool BinaryOperandRealFamily (unsigned int op)
    6422              : {
    6423        47122 :   unsigned int type;
    6424              : 
    6425        47122 :   type = SymbolTable_GetDType (op);
    6426        47122 :   return (((M2Base_IsComplexType (type)) || (M2System_IsComplexN (type))) || (M2Base_IsRealType (type))) || (M2System_IsRealN (type));
    6427              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6428              :   __builtin_unreachable ();
    6429              : }
    6430              : 
    6431              : 
    6432              : /*
    6433              :    FoldDivM2 - check division for constant folding.
    6434              : */
    6435              : 
    6436        14784 : static void FoldDivM2 (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    6437              : {
    6438        14784 :   if (BinaryOperands (quad, op2, op3))
    6439              :     {
    6440              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6441        14784 :       if ((BinaryOperandRealFamily (op2)) || (BinaryOperandRealFamily (op3)))
    6442              :         {
    6443            0 :           FoldBinary (tokenno, p, (m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildRDiv}, quad, op1, op2, op3);
    6444              :         }
    6445              :       else
    6446              :         {
    6447        14784 :           FoldBinary (tokenno, p, (m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildDivM2}, quad, op1, op2, op3);
    6448              :         }
    6449              :     }
    6450        14784 : }
    6451              : 
    6452              : 
    6453              : /*
    6454              :    CodeDivM2 - encode division.
    6455              : */
    6456              : 
    6457            0 : static void CodeDivM2 (unsigned int quad, unsigned int left, unsigned int right)
    6458              : {
    6459            0 :   if (BinaryOperands (quad, left, right))
    6460              :     {
    6461              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6462            0 :       if ((BinaryOperandRealFamily (left)) || (BinaryOperandRealFamily (right)))
    6463              :         {
    6464            0 :           CodeBinary ((m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildRDiv}, quad);
    6465              :         }
    6466              :       else
    6467              :         {
    6468            0 :           CodeBinary ((m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildDivM2}, quad);
    6469              :         }
    6470              :     }
    6471            0 : }
    6472              : 
    6473              : 
    6474              : /*
    6475              :    FoldModM2 - check modulus for constant folding.
    6476              : */
    6477              : 
    6478        25942 : static void FoldModM2 (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    6479              : {
    6480        25942 :   if (BinaryOperands (quad, op2, op3))
    6481              :     {
    6482        25942 :       FoldBinary (tokenno, p, (m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildModM2}, quad, op1, op2, op3);
    6483              :     }
    6484        25942 : }
    6485              : 
    6486              : 
    6487              : /*
    6488              :    CodeModM2 - encode modulus.
    6489              : */
    6490              : 
    6491            0 : static void CodeModM2 (unsigned int quad, unsigned int left, unsigned int right)
    6492              : {
    6493            0 :   if (BinaryOperands (quad, left, right))
    6494              :     {
    6495            0 :       CodeBinary ((m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildModM2}, quad);
    6496              :     }
    6497            0 : }
    6498              : 
    6499              : 
    6500              : /*
    6501              :    FoldDivTrunc - check division for constant folding.
    6502              : */
    6503              : 
    6504        11100 : static void FoldDivTrunc (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    6505              : {
    6506        11100 :   if (BinaryOperands (quad, op2, op3))
    6507              :     {
    6508              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6509        11100 :       if ((BinaryOperandRealFamily (op2)) || (BinaryOperandRealFamily (op3)))
    6510              :         {
    6511         5954 :           FoldBinary (tokenno, p, (m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildRDiv}, quad, op1, op2, op3);
    6512              :         }
    6513              :       else
    6514              :         {
    6515         5146 :           FoldBinary (tokenno, p, (m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildDivTrunc}, quad, op1, op2, op3);
    6516              :         }
    6517              :     }
    6518        11100 : }
    6519              : 
    6520              : 
    6521              : /*
    6522              :    CodeDivTrunc - encode multiplication.
    6523              : */
    6524              : 
    6525          734 : static void CodeDivTrunc (unsigned int quad, unsigned int left, unsigned int right)
    6526              : {
    6527          734 :   if (BinaryOperands (quad, left, right))
    6528              :     {
    6529              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6530          734 :       if ((BinaryOperandRealFamily (left)) || (BinaryOperandRealFamily (right)))
    6531              :         {
    6532          160 :           CodeBinary ((m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildRDiv}, quad);
    6533              :         }
    6534              :       else
    6535              :         {
    6536          574 :           CodeBinary ((m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildDivTrunc}, quad);
    6537              :         }
    6538              :     }
    6539          734 : }
    6540              : 
    6541              : 
    6542              : /*
    6543              :    FoldModTrunc - check modulus for constant folding.
    6544              : */
    6545              : 
    6546           96 : static void FoldModTrunc (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    6547              : {
    6548           96 :   if (BinaryOperands (quad, op2, op3))
    6549              :     {
    6550           96 :       FoldBinary (tokenno, p, (m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildModTrunc}, quad, op1, op2, op3);
    6551              :     }
    6552           96 : }
    6553              : 
    6554              : 
    6555              : /*
    6556              :    CodeModTrunc - encode modulus.
    6557              : */
    6558              : 
    6559            0 : static void CodeModTrunc (unsigned int quad, unsigned int left, unsigned int right)
    6560              : {
    6561            0 :   if (BinaryOperands (quad, left, right))
    6562              :     {
    6563            0 :       CodeBinary ((m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildModTrunc}, quad);
    6564              :     }
    6565            0 : }
    6566              : 
    6567              : 
    6568              : /*
    6569              :    FoldDivCeil - check division for constant folding.
    6570              : */
    6571              : 
    6572            0 : static void FoldDivCeil (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    6573              : {
    6574            0 :   if (BinaryOperands (quad, op2, op3))
    6575              :     {
    6576              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6577            0 :       if ((BinaryOperandRealFamily (op2)) || (BinaryOperandRealFamily (op3)))
    6578              :         {
    6579            0 :           FoldBinary (tokenno, p, (m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildRDiv}, quad, op1, op2, op3);
    6580              :         }
    6581              :       else
    6582              :         {
    6583            0 :           FoldBinary (tokenno, p, (m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildDivCeil}, quad, op1, op2, op3);
    6584              :         }
    6585              :     }
    6586            0 : }
    6587              : 
    6588              : 
    6589              : /*
    6590              :    CodeDivCeil - encode multiplication.
    6591              : */
    6592              : 
    6593            0 : static void CodeDivCeil (unsigned int quad, unsigned int left, unsigned int right)
    6594              : {
    6595            0 :   if (BinaryOperands (quad, left, right))
    6596              :     {
    6597              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6598            0 :       if ((BinaryOperandRealFamily (left)) || (BinaryOperandRealFamily (right)))
    6599              :         {
    6600            0 :           CodeBinary ((m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildRDiv}, quad);
    6601              :         }
    6602              :       else
    6603              :         {
    6604            0 :           CodeBinary ((m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildDivCeil}, quad);
    6605              :         }
    6606              :     }
    6607            0 : }
    6608              : 
    6609              : 
    6610              : /*
    6611              :    FoldModCeil - check modulus for constant folding.
    6612              : */
    6613              : 
    6614            0 : static void FoldModCeil (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    6615              : {
    6616            0 :   if (BinaryOperands (quad, op2, op3))
    6617              :     {
    6618            0 :       FoldBinary (tokenno, p, (m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildModCeil}, quad, op1, op2, op3);
    6619              :     }
    6620            0 : }
    6621              : 
    6622              : 
    6623              : /*
    6624              :    CodeModCeil - encode multiplication.
    6625              : */
    6626              : 
    6627            0 : static void CodeModCeil (unsigned int quad, unsigned int left, unsigned int right)
    6628              : {
    6629            0 :   if (BinaryOperands (quad, left, right))
    6630              :     {
    6631            0 :       CodeBinary ((m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildModCeil}, quad);
    6632              :     }
    6633            0 : }
    6634              : 
    6635              : 
    6636              : /*
    6637              :    FoldDivFloor - check division for constant folding.
    6638              : */
    6639              : 
    6640            0 : static void FoldDivFloor (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    6641              : {
    6642            0 :   if (BinaryOperands (quad, op2, op3))
    6643              :     {
    6644              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6645            0 :       if ((BinaryOperandRealFamily (op2)) || (BinaryOperandRealFamily (op3)))
    6646              :         {
    6647            0 :           FoldBinary (tokenno, p, (m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildRDiv}, quad, op1, op2, op3);
    6648              :         }
    6649              :       else
    6650              :         {
    6651            0 :           FoldBinary (tokenno, p, (m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildDivFloor}, quad, op1, op2, op3);
    6652              :         }
    6653              :     }
    6654            0 : }
    6655              : 
    6656              : 
    6657              : /*
    6658              :    CodeDivFloor - encode multiplication.
    6659              : */
    6660              : 
    6661            0 : static void CodeDivFloor (unsigned int quad, unsigned int left, unsigned int right)
    6662              : {
    6663            0 :   if (BinaryOperands (quad, left, right))
    6664              :     {
    6665              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6666            0 :       if ((BinaryOperandRealFamily (left)) || (BinaryOperandRealFamily (right)))
    6667              :         {
    6668            0 :           CodeBinary ((m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildRDiv}, quad);
    6669              :         }
    6670              :       else
    6671              :         {
    6672            0 :           CodeBinary ((m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildDivFloor}, quad);
    6673              :         }
    6674              :     }
    6675            0 : }
    6676              : 
    6677              : 
    6678              : /*
    6679              :    FoldModFloor - check modulus for constant folding.
    6680              : */
    6681              : 
    6682            0 : static void FoldModFloor (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    6683              : {
    6684            0 :   if (BinaryOperands (quad, op2, op3))
    6685              :     {
    6686            0 :       FoldBinary (tokenno, p, (m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildModFloor}, quad, op1, op2, op3);
    6687              :     }
    6688            0 : }
    6689              : 
    6690              : 
    6691              : /*
    6692              :    CodeModFloor - encode modulus.
    6693              : */
    6694              : 
    6695            0 : static void CodeModFloor (unsigned int quad, unsigned int left, unsigned int right)
    6696              : {
    6697            0 :   if (BinaryOperands (quad, left, right))
    6698              :     {
    6699            0 :       CodeBinary ((m2expr_BuildBinProcedure) {(m2expr_BuildBinProcedure_t) m2expr_BuildModFloor}, quad);
    6700              :     }
    6701            0 : }
    6702              : 
    6703              : 
    6704              : /*
    6705              :    FoldBuiltinConst -
    6706              : */
    6707              : 
    6708        27520 : static void FoldBuiltinConst (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int result, unsigned int constDesc)
    6709              : {
    6710        27520 :   tree value;
    6711              : 
    6712        27520 :   value = m2builtins_GetBuiltinConst (reinterpret_cast <char * > (NameKey_KeyToCharStar ((NameKey_Name) (constDesc))));
    6713        27520 :   if (value == NULL)
    6714              :     {
    6715            0 :       M2MetaError_MetaErrorT1 (tokenno, (const char *) "unknown built in constant {%1Ead}", 33, constDesc);
    6716              :     }
    6717              :   else
    6718              :     {
    6719        27520 :       SymbolConversion_AddModGcc (result, value);
    6720        27520 :       (*p.proc) (result);
    6721        27520 :       NoChange = false;
    6722        27520 :       M2Quads_SubQuad (quad);
    6723              :     }
    6724        27520 : }
    6725              : 
    6726              : 
    6727              : /*
    6728              :    FoldBuiltinTypeInfo - attempts to fold a builtin attribute value on type op2.
    6729              : */
    6730              : 
    6731          360 : static void FoldBuiltinTypeInfo (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    6732              : {
    6733          360 :   tree t;
    6734          360 :   location_t location;
    6735              : 
    6736          360 :   if ((SymbolConversion_GccKnowsAbout (op2)) && (M2GCCDeclare_CompletelyResolved (op2)))
    6737              :     {
    6738          360 :       location = M2LexBuf_TokenToLocation (tokenno);
    6739          360 :       t = m2builtins_GetBuiltinTypeInfo (location, SymbolConversion_Mod2Gcc (op2), const_cast <const char * > (static_cast <char * > (NameKey_KeyToCharStar ((NameKey_Name) (op3)))));
    6740          360 :       if (t == NULL)
    6741              :         {
    6742            0 :           M2MetaError_MetaErrorT2 (tokenno, (const char *) "unknown built in constant {%1Ead} attribute for type {%2ad}", 59, op3, op2);
    6743              :         }
    6744              :       else
    6745              :         {
    6746          360 :           SymbolConversion_AddModGcc (op1, t);
    6747          360 :           (*p.proc) (op1);
    6748          360 :           NoChange = false;
    6749          360 :           M2Quads_SubQuad (quad);
    6750              :         }
    6751              :     }
    6752          360 : }
    6753              : 
    6754              : 
    6755              : /*
    6756              :    FoldTBitsize - attempt to fold the standard function SYSTEM.TBITSIZE
    6757              :                   quadruple.  If the quadruple is folded it is removed.
    6758              : */
    6759              : 
    6760         6388 : static void FoldTBitsize (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int res, unsigned int type)
    6761              : {
    6762         6388 :   location_t location;
    6763              : 
    6764         6388 :   location = M2LexBuf_TokenToLocation (tokenno);
    6765         6388 :   if (((SymbolTable_IsType (type)) || (SymbolTable_IsVar (type))) || (SymbolTable_IsConst (type)))
    6766              :     {
    6767         6248 :       if ((SymbolTable_GetDType (type)) == SymbolTable_NulSym)
    6768              :         {
    6769            0 :           M2MetaError_MetaErrorT1 (tokenno, (const char *) "unknown type in TBITSIZE parameter {%1Ead}", 42, type);
    6770            0 :           NoChange = false;
    6771            0 :           M2Quads_SubQuad (quad);
    6772              :         }
    6773         6248 :       type = SymbolTable_GetDType (type);
    6774              :     }
    6775         6388 :   if (type != SymbolTable_NulSym)
    6776              :     {
    6777         6388 :       M2GCCDeclare_TryDeclareType (type);
    6778         6388 :       if (M2GCCDeclare_CompletelyResolved (type))
    6779              :         {
    6780         6376 :           SymbolConversion_AddModGcc (res, m2expr_BuildSystemTBitSize (location, SymbolConversion_Mod2Gcc (type)));
    6781         6376 :           (*p.proc) (res);
    6782         6376 :           NoChange = false;
    6783         6376 :           M2Quads_SubQuad (quad);
    6784              :         }
    6785              :     }
    6786         6388 : }
    6787              : 
    6788              : 
    6789              : /*
    6790              :    FoldStandardFunction - attempts to fold a standard function.
    6791              : */
    6792              : 
    6793         9444 : static void FoldStandardFunction (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    6794              : {
    6795         9444 :   DynamicStrings_String s;
    6796         9444 :   unsigned int type;
    6797         9444 :   unsigned int d;
    6798         9444 :   unsigned int result;
    6799         9444 :   location_t location;
    6800              : 
    6801         9444 :   location = M2LexBuf_TokenToLocation (tokenno);
    6802         9444 :   if ((SymbolTable_GetSymName (op2)) == (NameKey_MakeKey ((const char *) "Length", 6)))
    6803              :     {
    6804              :       /* avoid dangling else.  */
    6805            0 :       M2GCCDeclare_TryDeclareConstant (tokenno, op3);
    6806            0 :       if ((SymbolTable_IsConst (op3)) && (SymbolConversion_GccKnowsAbout (op3)))
    6807              :         {
    6808              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6809              :           /* fine, we can take advantage of this and fold constants  */
    6810            0 :           if (SymbolTable_IsConst (op1))
    6811              :             {
    6812            0 :               if (SymbolTable_IsConstString (op3))
    6813              :                 {
    6814            0 :                   SymbolConversion_AddModGcc (op1, FindSize (tokenno, op3));
    6815            0 :                   (*p.proc) (op1);
    6816            0 :                   NoChange = false;
    6817            0 :                   M2Quads_SubQuad (quad);
    6818              :                 }
    6819              :               else
    6820              :                 {
    6821            0 :                   M2MetaError_MetaErrorT1 (tokenno, (const char *) "parameter to LENGTH must be a string {%1Ead}", 44, op3);
    6822              :                 }
    6823              :             }
    6824              :           else
    6825              :             {
    6826              :               /* rewrite the quad to use becomes.  */
    6827            0 :               d = SymbolTable_GetStringLength (tokenno, op3);
    6828            0 :               s = FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "%d", 2)), (const unsigned char *) &d, (sizeof (d)-1));
    6829            0 :               result = SymbolTable_MakeConstLit (tokenno, NameKey_makekey (DynamicStrings_string (s)), M2Base_Cardinal);
    6830            0 :               s = DynamicStrings_KillString (s);
    6831            0 :               M2GCCDeclare_TryDeclareConstant (tokenno, result);
    6832            0 :               M2Quads_PutQuad (quad, M2Quads_BecomesOp, op1, SymbolTable_NulSym, result);
    6833              :             }
    6834              :         }
    6835              :     }
    6836         9444 :   else if ((SymbolTable_GetSymName (op2)) == (NameKey_MakeKey ((const char *) "CAP", 3)))
    6837              :     {
    6838              :       /* avoid dangling else.  */
    6839          766 :       M2GCCDeclare_TryDeclareConstant (tokenno, op3);
    6840          766 :       if ((SymbolTable_IsConst (op3)) && (SymbolConversion_GccKnowsAbout (op3)))
    6841              :         {
    6842              :           /* fine, we can take advantage of this and fold constants  */
    6843           24 :           if (SymbolTable_IsConst (op1))
    6844              :             {
    6845              :               /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6846           24 :               if (((SymbolTable_IsConstString (op3)) && ((SymbolTable_GetStringLength (tokenno, op3)) == 1)) || ((SymbolTable_GetType (op3)) == M2Base_Char))
    6847              :                 {
    6848           24 :                   SymbolConversion_AddModGcc (op1, m2expr_BuildCap (location, SymbolConversion_Mod2Gcc (op3)));
    6849           24 :                   (*p.proc) (op1);
    6850           24 :                   NoChange = false;
    6851           24 :                   M2Quads_SubQuad (quad);
    6852              :                 }
    6853              :               else
    6854              :                 {
    6855            0 :                   M2MetaError_MetaErrorT1 (tokenno, (const char *) "parameter to CAP must be a single character {%1Ead}", 51, op3);
    6856              :                 }
    6857              :             }
    6858              :         }
    6859              :     }
    6860         8678 :   else if ((SymbolTable_GetSymName (op2)) == (NameKey_MakeKey ((const char *) "ABS", 3)))
    6861              :     {
    6862              :       /* avoid dangling else.  */
    6863          796 :       M2GCCDeclare_TryDeclareConstant (tokenno, op3);
    6864          796 :       if ((SymbolTable_IsConst (op3)) && (SymbolConversion_GccKnowsAbout (op3)))
    6865              :         {
    6866              :           /* fine, we can take advantage of this and fold constants  */
    6867           12 :           if (SymbolTable_IsConst (op1))
    6868              :             {
    6869           12 :               SymbolConversion_AddModGcc (op1, m2expr_BuildAbs (location, SymbolConversion_Mod2Gcc (op3)));
    6870           12 :               (*p.proc) (op1);
    6871           12 :               NoChange = false;
    6872           12 :               M2Quads_SubQuad (quad);
    6873              :             }
    6874              :         }
    6875              :     }
    6876         7882 :   else if (op2 == M2Base_Im)
    6877              :     {
    6878              :       /* avoid dangling else.  */
    6879           90 :       M2GCCDeclare_TryDeclareConstant (tokenno, op3);
    6880           90 :       if ((SymbolTable_IsConst (op3)) && (SymbolConversion_GccKnowsAbout (op3)))
    6881              :         {
    6882              :           /* fine, we can take advantage of this and fold constants  */
    6883           36 :           if (SymbolTable_IsConst (op1))
    6884              :             {
    6885           36 :               SymbolConversion_AddModGcc (op1, m2expr_BuildIm (SymbolConversion_Mod2Gcc (op3)));
    6886           36 :               (*p.proc) (op1);
    6887           36 :               NoChange = false;
    6888           36 :               M2Quads_SubQuad (quad);
    6889              :             }
    6890              :         }
    6891              :     }
    6892         7792 :   else if (op2 == M2Base_Re)
    6893              :     {
    6894              :       /* avoid dangling else.  */
    6895           90 :       M2GCCDeclare_TryDeclareConstant (tokenno, op3);
    6896           90 :       if ((SymbolTable_IsConst (op3)) && (SymbolConversion_GccKnowsAbout (op3)))
    6897              :         {
    6898              :           /* fine, we can take advantage of this and fold constants  */
    6899           36 :           if (SymbolTable_IsConst (op1))
    6900              :             {
    6901           36 :               SymbolConversion_AddModGcc (op1, m2expr_BuildRe (SymbolConversion_Mod2Gcc (op3)));
    6902           36 :               (*p.proc) (op1);
    6903           36 :               NoChange = false;
    6904           36 :               M2Quads_SubQuad (quad);
    6905              :             }
    6906              :         }
    6907              :     }
    6908         7702 :   else if (op2 == M2Base_Cmplx)
    6909              :     {
    6910              :       /* avoid dangling else.  */
    6911         1314 :       M2GCCDeclare_TryDeclareConstant (tokenno, SymbolTable_GetNth (op3, 1));
    6912         1314 :       M2GCCDeclare_TryDeclareConstant (tokenno, SymbolTable_GetNth (op3, 2));
    6913         1314 :       if ((((SymbolTable_IsConst (SymbolTable_GetNth (op3, 1))) && (SymbolConversion_GccKnowsAbout (SymbolTable_GetNth (op3, 1)))) && (SymbolTable_IsConst (SymbolTable_GetNth (op3, 2)))) && (SymbolConversion_GccKnowsAbout (SymbolTable_GetNth (op3, 2))))
    6914              :         {
    6915              :           /* fine, we can take advantage of this and fold constants  */
    6916          414 :           if (SymbolTable_IsConst (op1))
    6917              :             {
    6918          414 :               type = M2Base_GetCmplxReturnType (SymbolTable_GetType (SymbolTable_GetNth (op3, 1)), SymbolTable_GetType (SymbolTable_GetNth (op3, 2)));
    6919          414 :               if (type == SymbolTable_NulSym)
    6920              :                 {
    6921            0 :                   M2MetaError_MetaErrorT2 (tokenno, (const char *) "real {%1Eatd} and imaginary {%2atd} types are incompatible", 58, SymbolTable_GetNth (op3, 1), SymbolTable_GetNth (op3, 2));
    6922              :                 }
    6923              :               else
    6924              :                 {
    6925          414 :                   SymbolConversion_AddModGcc (op1, m2expr_BuildCmplx (location, SymbolConversion_Mod2Gcc (type), SymbolConversion_Mod2Gcc (SymbolTable_GetNth (op3, 1)), SymbolConversion_Mod2Gcc (SymbolTable_GetNth (op3, 2))));
    6926          414 :                   (*p.proc) (op1);
    6927          414 :                   NoChange = false;
    6928          414 :                   M2Quads_SubQuad (quad);
    6929              :                 }
    6930              :             }
    6931              :         }
    6932              :     }
    6933         6388 :   else if (op2 == M2System_TBitSize)
    6934              :     {
    6935              :       /* avoid dangling else.  */
    6936         6388 :       FoldTBitsize (tokenno, p, quad, op1, op3);
    6937              :     }
    6938              :   else
    6939              :     {
    6940              :       /* avoid dangling else.  */
    6941            0 :       M2Error_InternalError ((const char *) "only expecting LENGTH, CAP, ABS, IM, RE", 39);
    6942              :     }
    6943         9444 : }
    6944              : 
    6945              : 
    6946              : /*
    6947              :    CodeStandardFunction -
    6948              : */
    6949              : 
    6950          330 : static void CodeStandardFunction (unsigned int quad, unsigned int result, unsigned int function, unsigned int param)
    6951              : {
    6952          330 :   unsigned int type;
    6953          330 :   location_t location;
    6954              : 
    6955          330 :   M2GCCDeclare_DeclareConstant (CurrentQuadToken, param);
    6956          330 :   M2GCCDeclare_DeclareConstructor (CurrentQuadToken, quad, param);
    6957          330 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    6958          330 :   if ((function != SymbolTable_NulSym) && ((SymbolTable_GetSymName (function)) == (NameKey_MakeKey ((const char *) "Length", 6))))
    6959              :     {
    6960              :       /* avoid dangling else.  */
    6961            0 :       if (SymbolTable_IsConst (result))
    6962              :         {
    6963            0 :           M2Error_InternalError ((const char *) "LENGTH function should already have been folded", 47);
    6964              :         }
    6965              :     }
    6966          330 :   else if ((function != SymbolTable_NulSym) && ((SymbolTable_GetSymName (function)) == (NameKey_MakeKey ((const char *) "CAP", 3))))
    6967              :     {
    6968              :       /* avoid dangling else.  */
    6969           82 :       if (SymbolTable_IsConst (result))
    6970              :         {
    6971            0 :           M2Error_InternalError ((const char *) "CAP function should already have been folded", 44);
    6972              :         }
    6973              :       else
    6974              :         {
    6975           82 :           m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (result), m2expr_BuildCap (location, SymbolConversion_Mod2Gcc (param)));
    6976              :         }
    6977              :     }
    6978          248 :   else if ((function != SymbolTable_NulSym) && ((SymbolTable_GetSymName (function)) == (NameKey_MakeKey ((const char *) "ABS", 3))))
    6979              :     {
    6980              :       /* avoid dangling else.  */
    6981          140 :       if (SymbolTable_IsConst (result))
    6982              :         {
    6983            0 :           M2Error_InternalError ((const char *) "ABS function should already have been folded", 44);
    6984              :         }
    6985              :       else
    6986              :         {
    6987          140 :           m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (result), m2expr_BuildAbs (location, SymbolConversion_Mod2Gcc (param)));
    6988              :         }
    6989              :     }
    6990          108 :   else if (function == M2Base_Im)
    6991              :     {
    6992              :       /* avoid dangling else.  */
    6993           18 :       if (SymbolTable_IsConst (result))
    6994              :         {
    6995            0 :           M2Error_InternalError ((const char *) "IM function should already have been folded", 43);
    6996              :         }
    6997              :       else
    6998              :         {
    6999           18 :           m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (result), m2expr_BuildIm (SymbolConversion_Mod2Gcc (param)));
    7000              :         }
    7001              :     }
    7002           90 :   else if (function == M2Base_Re)
    7003              :     {
    7004              :       /* avoid dangling else.  */
    7005           18 :       if (SymbolTable_IsConst (result))
    7006              :         {
    7007            0 :           M2Error_InternalError ((const char *) "RE function should already have been folded", 43);
    7008              :         }
    7009              :       else
    7010              :         {
    7011           18 :           m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (result), m2expr_BuildRe (SymbolConversion_Mod2Gcc (param)));
    7012              :         }
    7013              :     }
    7014           72 :   else if (function == M2Base_Cmplx)
    7015              :     {
    7016              :       /* avoid dangling else.  */
    7017           72 :       if (SymbolTable_IsConst (result))
    7018              :         {
    7019            0 :           M2Error_InternalError ((const char *) "CMPLX function should already have been folded", 46);
    7020              :         }
    7021              :       else
    7022              :         {
    7023           72 :           type = M2Base_GetCmplxReturnType (SymbolTable_GetType (SymbolTable_GetNth (param, 1)), SymbolTable_GetType (SymbolTable_GetNth (param, 2)));
    7024           72 :           if (type == SymbolTable_NulSym)
    7025              :             {
    7026            0 :               M2MetaError_MetaErrorT2 (CurrentQuadToken, (const char *) "real {%1Eatd} and imaginary {%2atd} types are incompatible", 58, SymbolTable_GetNth (param, 1), SymbolTable_GetNth (param, 2));
    7027              :             }
    7028              :           else
    7029              :             {
    7030           72 :               m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (result), m2expr_BuildCmplx (location, SymbolConversion_Mod2Gcc (type), SymbolConversion_Mod2Gcc (SymbolTable_GetNth (param, 1)), SymbolConversion_Mod2Gcc (SymbolTable_GetNth (param, 2))));
    7031              :             }
    7032              :         }
    7033              :     }
    7034            0 :   else if (function == M2System_TBitSize)
    7035              :     {
    7036              :       /* avoid dangling else.  */
    7037            0 :       if (SymbolTable_IsConst (result))
    7038              :         {
    7039            0 :           M2Error_InternalError ((const char *) "TBITSIZE function should already have been folded", 49);
    7040              :         }
    7041              :       else
    7042              :         {
    7043            0 :           m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (result), m2expr_BuildTBitSize (location, SymbolConversion_Mod2Gcc (param)));
    7044              :         }
    7045              :     }
    7046              :   else
    7047              :     {
    7048              :       /* avoid dangling else.  */
    7049            0 :       M2Error_InternalError ((const char *) "expecting LENGTH, CAP, ABS, IM", 30);
    7050              :     }
    7051          330 : }
    7052              : 
    7053              : 
    7054              : /*
    7055              :    CodeSavePriority - checks to see whether op2 is reachable and is directly accessible
    7056              :                       externally. If so then it saves the current interrupt priority
    7057              :                       in op1 and sets the current priority to that determined by
    7058              :                       appropriate module.
    7059              : 
    7060              :                       op1 := op3(GetModuleScope(op2))
    7061              : */
    7062              : 
    7063          420 : static void CodeSavePriority (unsigned int oldValue, unsigned int scopeSym, unsigned int procedureSym)
    7064              : {
    7065          420 :   tree funcTree;
    7066          420 :   unsigned int mod;
    7067          420 :   NameKey_Name n;
    7068          420 :   location_t location;
    7069              : 
    7070          420 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    7071          420 :   if (((SymbolTable_IsModule (scopeSym)) || (SymbolTable_IsDefImp (scopeSym))) || ((SymbolTable_IsProcedure (scopeSym)) && (SymbolTable_GetNeedSavePriority (scopeSym))))
    7072              :     {
    7073          206 :       if (SymbolTable_IsProcedure (scopeSym))
    7074              :         {
    7075          130 :           mod = SymbolTable_GetModuleScope (scopeSym);
    7076              :         }
    7077              :       else
    7078              :         {
    7079           76 :           M2Debug_Assert ((SymbolTable_IsModule (scopeSym)) || (SymbolTable_IsDefImp (scopeSym)));
    7080           76 :           mod = scopeSym;
    7081              :         }
    7082          206 :       if ((SymbolTable_GetPriority (mod)) != SymbolTable_NulSym)
    7083              :         {
    7084          206 :           if (PriorityDebugging)
    7085              :             {
    7086              :               n = SymbolTable_GetSymName (scopeSym);
    7087              :               M2Printf_printf1 ((const char *) "procedure <%a> needs to save interrupts\\n", 41, (const unsigned char *) &n, (sizeof (n)-1));
    7088              :             }
    7089          206 :           M2GCCDeclare_DeclareConstant (CurrentQuadToken, SymbolTable_GetPriority (mod));
    7090          206 :           m2statement_BuildParam (location, SymbolConversion_Mod2Gcc (SymbolTable_GetPriority (mod)));
    7091          206 :           funcTree = m2statement_BuildProcedureCallTree (location, SymbolConversion_Mod2Gcc (procedureSym), SymbolConversion_Mod2Gcc (SymbolTable_GetType (procedureSym)));
    7092          206 :           funcTree = m2statement_BuildFunctValue (location, SymbolConversion_Mod2Gcc (oldValue));
    7093          206 :           m2type_AddStatement (location, funcTree);
    7094              :         }
    7095              :     }
    7096          420 : }
    7097              : 
    7098              : 
    7099              : /*
    7100              :    CodeRestorePriority - checks to see whether op2 is reachable and is directly accessible
    7101              :                          externally. If so then it restores the previous interrupt priority
    7102              :                          held in op1.
    7103              : 
    7104              :                          op1 := op3(op1)
    7105              : */
    7106              : 
    7107          412 : static void CodeRestorePriority (unsigned int oldValue, unsigned int scopeSym, unsigned int procedureSym)
    7108              : {
    7109          412 :   tree funcTree;
    7110          412 :   unsigned int mod;
    7111          412 :   NameKey_Name n;
    7112          412 :   location_t location;
    7113              : 
    7114          412 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    7115          412 :   if (((SymbolTable_IsModule (scopeSym)) || (SymbolTable_IsDefImp (scopeSym))) || ((SymbolTable_IsProcedure (scopeSym)) && (SymbolTable_GetNeedSavePriority (scopeSym))))
    7116              :     {
    7117          198 :       if (SymbolTable_IsProcedure (scopeSym))
    7118              :         {
    7119          122 :           mod = SymbolTable_GetModuleScope (scopeSym);
    7120              :         }
    7121              :       else
    7122              :         {
    7123           76 :           M2Debug_Assert ((SymbolTable_IsModule (scopeSym)) || (SymbolTable_IsDefImp (scopeSym)));
    7124           76 :           mod = scopeSym;
    7125              :         }
    7126          198 :       if ((SymbolTable_GetPriority (mod)) != SymbolTable_NulSym)
    7127              :         {
    7128          198 :           if (PriorityDebugging)
    7129              :             {
    7130              :               n = SymbolTable_GetSymName (scopeSym);
    7131              :               M2Printf_printf1 ((const char *) "procedure <%a> needs to restore interrupts\\n", 44, (const unsigned char *) &n, (sizeof (n)-1));
    7132              :             }
    7133          198 :           m2statement_BuildParam (location, SymbolConversion_Mod2Gcc (oldValue));
    7134          198 :           funcTree = m2statement_BuildProcedureCallTree (location, SymbolConversion_Mod2Gcc (procedureSym), SymbolConversion_Mod2Gcc (SymbolTable_GetType (procedureSym)));
    7135          198 :           funcTree = m2statement_BuildFunctValue (location, SymbolConversion_Mod2Gcc (oldValue));
    7136          198 :           m2type_AddStatement (location, funcTree);
    7137              :         }
    7138              :     }
    7139          412 : }
    7140              : 
    7141              : 
    7142              : /*
    7143              :    FoldBinarySet - attempts to fold set arithmetic it removes the quad if successful.
    7144              : */
    7145              : 
    7146        70456 : static void FoldBinarySet (unsigned int tokenno, M2GCCDeclare_WalkAction p, M2GenGCC_ProcedureCardinal op, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    7147              : {
    7148        70456 :   location_t location;
    7149              : 
    7150              :   /* firstly try and ensure that constants are declared  */
    7151        70456 :   M2GCCDeclare_TryDeclareConstant (tokenno, op2);
    7152        70456 :   M2GCCDeclare_TryDeclareConstant (tokenno, op3);
    7153        70456 :   location = M2LexBuf_TokenToLocation (tokenno);
    7154        70456 :   if ((SymbolConversion_GccKnowsAbout (op2)) && (SymbolConversion_GccKnowsAbout (op3)))
    7155              :     {
    7156         4088 :       if (CheckBinaryExpressionTypes (quad, p))
    7157              :         {
    7158         4088 :           if (((((SymbolTable_IsConst (op2)) && (SymbolTable_IsConstSet (op2))) && (SymbolTable_IsConst (op3))) && (SymbolTable_IsConstSet (op3))) && (SymbolTable_IsConst (op1)))
    7159              :             {
    7160          224 :               if ((SymbolTable_IsValueSolved (op2)) && (SymbolTable_IsValueSolved (op3)))
    7161              :                 {
    7162          224 :                   M2Debug_Assert ((M2Base_MixTypes (FindType (op3), FindType (op2), tokenno)) != SymbolTable_NulSym);
    7163          224 :                   SymbolTable_PutConst (op1, M2Base_MixTypes (FindType (op3), FindType (op2), tokenno));
    7164          224 :                   SymbolTable_PushValue (op2);
    7165          224 :                   SymbolTable_PushValue (op3);
    7166          224 :                   (*op.proc) (tokenno);
    7167          224 :                   SymbolTable_PopValue (op1);
    7168          224 :                   SymbolTable_PushValue (op1);
    7169          224 :                   SymbolTable_PutConstSet (op1);
    7170          224 :                   SymbolConversion_AddModGcc (op1, m2decl_DeclareKnownConstant (location, SymbolConversion_Mod2Gcc (SymbolTable_GetType (op3)), M2ALU_PopSetTree (tokenno)));
    7171          224 :                   (*p.proc) (op1);
    7172          224 :                   NoChange = false;
    7173          224 :                   M2Quads_SubQuad (quad);
    7174              :                 }
    7175              :             }
    7176              :         }
    7177              :     }
    7178        70456 : }
    7179              : 
    7180              : 
    7181              : /*
    7182              :    FoldSetOr - check whether we can fold a set arithmetic or.
    7183              : */
    7184              : 
    7185        14562 : static void FoldSetOr (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    7186              : {
    7187            0 :   FoldBinarySet (tokenno, p, (M2GenGCC_ProcedureCardinal) {(M2GenGCC_ProcedureCardinal_t) M2ALU_SetOr}, quad, op1, op2, op3);
    7188            0 : }
    7189              : 
    7190              : 
    7191              : /*
    7192              :    CodeSetOr - encode set arithmetic or.
    7193              : */
    7194              : 
    7195          686 : static void CodeSetOr (unsigned int quad)
    7196              : {
    7197          686 :   CodeBinarySet ((M2GenGCC_ProcedureCardinal) {(M2GenGCC_ProcedureCardinal_t) M2ALU_SetOr}, (M2GenGCC_BinaryFunction) {(M2GenGCC_BinaryFunction_t) m2expr_BuildLogicalOr}, NameKey_MakeKey ((const char *) "Or", 2), quad);
    7198          686 : }
    7199              : 
    7200              : 
    7201              : /*
    7202              :    FoldSetAnd - check whether we can fold a logical and.
    7203              : */
    7204              : 
    7205         3684 : static void FoldSetAnd (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    7206              : {
    7207            0 :   FoldBinarySet (tokenno, p, (M2GenGCC_ProcedureCardinal) {(M2GenGCC_ProcedureCardinal_t) M2ALU_SetAnd}, quad, op1, op2, op3);
    7208            0 : }
    7209              : 
    7210              : 
    7211              : /*
    7212              :    CodeSetAnd - encode set arithmetic and.
    7213              : */
    7214              : 
    7215          284 : static void CodeSetAnd (unsigned int quad)
    7216              : {
    7217          284 :   CodeBinarySet ((M2GenGCC_ProcedureCardinal) {(M2GenGCC_ProcedureCardinal_t) M2ALU_SetAnd}, (M2GenGCC_BinaryFunction) {(M2GenGCC_BinaryFunction_t) m2expr_BuildLogicalAnd}, NameKey_MakeKey ((const char *) "And", 3), quad);
    7218          284 : }
    7219              : 
    7220              : 
    7221              : /*
    7222              :    CalcHighSetBit - calculate the most significant bit used in a set starting from bit zero.
    7223              : */
    7224              : 
    7225         4260 : static tree CalcHighSetBit (location_t location, unsigned int settype)
    7226              : {
    7227         4260 :   SymbolTable_PushValue (M2GCCDeclare_GetTypeMax (SymbolTable_SkipType (SymbolTable_GetType (settype))));
    7228         4260 :   M2ALU_PushIntegerTree (m2convert_BuildConvert (location, m2type_GetM2ZType (), M2ALU_PopIntegerTree (), false));
    7229         4260 :   SymbolTable_PushValue (M2GCCDeclare_GetTypeMin (SymbolTable_SkipType (SymbolTable_GetType (settype))));
    7230         4260 :   M2ALU_PushIntegerTree (m2convert_BuildConvert (location, m2type_GetM2ZType (), M2ALU_PopIntegerTree (), false));
    7231         4260 :   M2ALU_Sub ();
    7232         4260 :   return M2ALU_PopIntegerTree ();
    7233              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    7234              :   __builtin_unreachable ();
    7235              : }
    7236              : 
    7237              : 
    7238              : /*
    7239              :    CalcBitsInSet - returns the number of minimum number of bits used to represent a set.
    7240              : */
    7241              : 
    7242         3258 : static tree CalcBitsInSet (location_t location, unsigned int settype)
    7243              : {
    7244         3258 :   M2ALU_PushIntegerTree (m2convert_BuildConvert (location, m2type_GetM2ZType (), CalcHighSetBit (location, settype), false));
    7245         3258 :   M2ALU_PushCard (1);
    7246         3258 :   M2ALU_PushIntegerTree (m2convert_BuildConvert (location, m2type_GetM2ZType (), M2ALU_PopIntegerTree (), false));
    7247         3258 :   M2ALU_Addn ();
    7248         3258 :   return M2ALU_PopIntegerTree ();
    7249              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    7250              :   __builtin_unreachable ();
    7251              : }
    7252              : 
    7253              : 
    7254              : /*
    7255              :    SetWideSetShiftRotate - generate a call:
    7256              :                            M2WIDESET.name (dest, src, HIGHBIT (settype), count).
    7257              : */
    7258              : 
    7259          336 : static void SetWideSetShiftRotate (unsigned int tokenno, NameKey_Name name, unsigned int settype, unsigned int dest, unsigned int src, unsigned int count)
    7260              : {
    7261          336 :   unsigned int procedure;
    7262          336 :   unsigned int param1;
    7263          336 :   unsigned int param2;
    7264          336 :   tree array1;
    7265          336 :   tree array2;
    7266          336 :   tree call;
    7267          336 :   tree highbit;
    7268          336 :   location_t location;
    7269              : 
    7270          336 :   procedure = FromM2WIDESETImport (tokenno, name);
    7271          336 :   location = M2LexBuf_TokenToLocation (tokenno);
    7272          336 :   param1 = SymbolTable_GetNthParamAnyClosest (procedure, 1, SymbolTable_GetMainModule ());
    7273          336 :   param2 = SymbolTable_GetNthParamAnyClosest (procedure, 2, SymbolTable_GetMainModule ());
    7274          336 :   array1 = CreateSetArrayParam (location, tokenno, dest, param1);
    7275          336 :   array2 = CreateSetArrayParam (location, tokenno, src, param2);
    7276          336 :   highbit = CalcHighSetBit (location, settype);
    7277          336 :   m2statement_BuildParam (location, m2convert_ToCardinal (location, SymbolConversion_Mod2Gcc (count)));  /* Parameter 4.  */
    7278          336 :   m2statement_BuildParam (location, m2convert_ToCardinal (location, highbit));  /* Parameter 3.  */
    7279          336 :   m2statement_BuildParam (location, array2);  /* Parameter 2.  */
    7280          336 :   m2statement_BuildParam (location, array1);  /* Parameter 1.  */
    7281          336 :   call = m2statement_BuildProcedureCallTree (location, SymbolConversion_Mod2Gcc (procedure), NULL);  /* Parameter 1.  */
    7282          336 :   m2statement_SetLastFunction (NULL);
    7283          336 :   m2type_AddStatement (location, call);
    7284          336 : }
    7285              : 
    7286              : 
    7287              : /*
    7288              :    CodeNarrowSetShift -
    7289              : */
    7290              : 
    7291          472 : static void CodeNarrowSetShift (unsigned int tokenno, unsigned int settype, unsigned int dest, unsigned int src, unsigned int count)
    7292              : {
    7293          472 :   location_t location;
    7294          472 :   tree nbits;
    7295              : 
    7296          472 :   location = M2LexBuf_TokenToLocation (tokenno);
    7297          472 :   nbits = CalcBitsInSet (location, settype);
    7298          472 :   m2expr_BuildLogicalShift (location, SymbolConversion_Mod2Gcc (dest), SymbolConversion_Mod2Gcc (src), SymbolConversion_Mod2Gcc (count), nbits, false);
    7299          472 : }
    7300              : 
    7301              : 
    7302              : /*
    7303              :    CodeNarrowSetRotate -
    7304              : */
    7305              : 
    7306          274 : static void CodeNarrowSetRotate (unsigned int tokenno, unsigned int settype, unsigned int dest, unsigned int src, unsigned int count)
    7307              : {
    7308          274 :   location_t location;
    7309          274 :   tree nbits;
    7310              : 
    7311          274 :   location = M2LexBuf_TokenToLocation (tokenno);
    7312          274 :   nbits = CalcBitsInSet (location, settype);
    7313          274 :   m2expr_BuildLogicalRotate (location, SymbolConversion_Mod2Gcc (dest), SymbolConversion_Mod2Gcc (src), SymbolConversion_Mod2Gcc (count), nbits, false);
    7314          274 : }
    7315              : 
    7316              : 
    7317              : /*
    7318              :    CodeBinarySetShiftRotate - encode a binary set arithmetic operation.
    7319              : */
    7320              : 
    7321         1082 : static void CodeBinarySetShiftRotate (unsigned int quad, bool isshift)
    7322              : {
    7323         1082 :   M2Quads_QuadOperator op;
    7324         1082 :   unsigned int combined;
    7325         1082 :   unsigned int lastpos;
    7326         1082 :   unsigned int destpos;
    7327         1082 :   unsigned int srcpos;
    7328         1082 :   unsigned int countpos;
    7329         1082 :   unsigned int dest;
    7330         1082 :   unsigned int src;
    7331         1082 :   unsigned int count;
    7332         1082 :   bool overflowChecking;
    7333         1082 :   bool constExpr;
    7334         1082 :   unsigned int settype;
    7335              : 
    7336         1082 :   M2Quads_GetQuadOtok (quad, &lastpos, &op, &dest, &src, &count, &overflowChecking, &constExpr, &destpos, &srcpos, &countpos);
    7337              :   /* Firstly ensure that constant literals are declared.  */
    7338         1082 :   M2GCCDeclare_DeclareConstant (countpos, count);
    7339         1082 :   M2GCCDeclare_DeclareConstant (srcpos, src);
    7340         1082 :   M2GCCDeclare_DeclareConstructor (countpos, quad, count);
    7341         1082 :   M2GCCDeclare_DeclareConstructor (srcpos, quad, src);
    7342         1082 :   if (SymbolTable_IsConst (dest))
    7343              :     {
    7344            0 :       combined = M2LexBuf_MakeVirtual2Tok (srcpos, countpos);
    7345            0 :       if ((SymbolTable_IsValueSolved (src)) && (SymbolTable_IsValueSolved (count)))
    7346              :         {
    7347            0 :           M2Debug_Assert ((M2Base_MixTypes (FindType (count), FindType (src), combined)) != SymbolTable_NulSym);
    7348            0 :           SymbolTable_PutConst (dest, FindType (count));
    7349            0 :           SymbolTable_PushValue (src);
    7350            0 :           SymbolTable_PushValue (count);
    7351            0 :           if (isshift)
    7352              :             {
    7353            0 :               M2ALU_SetShift (combined);
    7354              :             }
    7355              :           else
    7356              :             {
    7357            0 :               M2ALU_SetRotate (combined);
    7358              :             }
    7359            0 :           SymbolTable_PopValue (dest);
    7360            0 :           SymbolTable_PutConstSet (dest);
    7361              :         }
    7362              :       else
    7363              :         {
    7364            0 :           M2MetaError_MetaErrorT0 (combined, (const char *) "{%E}constant expression cannot be evaluated", 43);
    7365              :         }
    7366              :     }
    7367              :   else
    7368              :     {
    7369         1082 :       combined = M2LexBuf_MakeVirtualTok (destpos, srcpos, countpos);
    7370         1082 :       settype = SymbolTable_GetDType (dest);
    7371         1082 :       M2Debug_Assert (SymbolTable_IsSet (settype));
    7372              :       /* Check for narrow and wide sets and call M2WIDESET if appropriate.  */
    7373         1082 :       if (SymbolTable_GetSetInWord (settype))
    7374              :         {
    7375          746 :           if (isshift)
    7376              :             {
    7377          472 :               CodeNarrowSetShift (combined, settype, dest, src, count);
    7378              :             }
    7379              :           else
    7380              :             {
    7381          274 :               CodeNarrowSetRotate (combined, settype, dest, src, count);
    7382              :             }
    7383              :         }
    7384              :       else
    7385              :         {
    7386          336 :           if (isshift)
    7387              :             {
    7388          204 :               SetWideSetShiftRotate (combined, NameKey_MakeKey ((const char *) "Shift", 5), settype, dest, src, count);
    7389              :             }
    7390              :           else
    7391              :             {
    7392          132 :               SetWideSetShiftRotate (combined, NameKey_MakeKey ((const char *) "Rotate", 6), settype, dest, src, count);
    7393              :             }
    7394              :         }
    7395              :     }
    7396         1082 : }
    7397              : 
    7398              : 
    7399              : /*
    7400              :    FoldSetShift - check whether we can fold a logical shift.
    7401              : */
    7402              : 
    7403        27654 : static void FoldSetShift (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int Dest, unsigned int Src, unsigned int ShiftCount)
    7404              : {
    7405            0 :   FoldBinarySet (tokenno, p, (M2GenGCC_ProcedureCardinal) {(M2GenGCC_ProcedureCardinal_t) M2ALU_SetShift}, quad, Dest, Src, ShiftCount);
    7406            0 : }
    7407              : 
    7408              : 
    7409              : /*
    7410              :    CodeSetShift - encode set arithmetic shift.
    7411              : */
    7412              : 
    7413          676 : static void CodeSetShift (unsigned int quad)
    7414              : {
    7415          676 :   CodeBinarySetShiftRotate (quad, true);
    7416          676 : }
    7417              : 
    7418              : 
    7419              : /*
    7420              :    FoldSetRotate - check whether we can fold a logical rotate.
    7421              : */
    7422              : 
    7423        23892 : static void FoldSetRotate (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int Dest, unsigned int Src, unsigned int RotateCount)
    7424              : {
    7425            0 :   FoldBinarySet (tokenno, p, (M2GenGCC_ProcedureCardinal) {(M2GenGCC_ProcedureCardinal_t) M2ALU_SetRotate}, quad, Dest, Src, RotateCount);
    7426            0 : }
    7427              : 
    7428              : 
    7429              : /*
    7430              :    CodeSetRotate - encode set arithmetic rotate.
    7431              : */
    7432              : 
    7433          406 : static void CodeSetRotate (unsigned int quad)
    7434              : {
    7435          406 :   CodeBinarySetShiftRotate (quad, false);
    7436          406 : }
    7437              : 
    7438              : 
    7439              : /*
    7440              :    CodeSetLogicalDifference - encode set arithmetic logical difference.
    7441              : */
    7442              : 
    7443           66 : static void CodeSetLogicalDifference (unsigned int quad)
    7444              : {
    7445           66 :   CodeBinarySet ((M2GenGCC_ProcedureCardinal) {(M2GenGCC_ProcedureCardinal_t) M2ALU_SetAnd}, (M2GenGCC_BinaryFunction) {(M2GenGCC_BinaryFunction_t) m2expr_BuildLogicalDifference}, NameKey_MakeKey ((const char *) "LogicalDifference", 17), quad);
    7446           66 : }
    7447              : 
    7448              : 
    7449              : /*
    7450              :    FoldSymmetricDifference - check whether we can fold a logical difference.
    7451              : */
    7452              : 
    7453          664 : static void FoldSymmetricDifference (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    7454              : {
    7455            0 :   FoldBinarySet (tokenno, p, (M2GenGCC_ProcedureCardinal) {(M2GenGCC_ProcedureCardinal_t) M2ALU_SetSymmetricDifference}, quad, op1, op2, op3);
    7456            0 : }
    7457              : 
    7458              : 
    7459              : /*
    7460              :    CodeSetSymmetricDifference - code set difference.
    7461              :                                 A logical xor expression.
    7462              : */
    7463              : 
    7464          124 : static void CodeSetSymmetricDifference (unsigned int quad)
    7465              : {
    7466          124 :   CodeBinarySet ((M2GenGCC_ProcedureCardinal) {(M2GenGCC_ProcedureCardinal_t) M2ALU_SetSymmetricDifference}, (M2GenGCC_BinaryFunction) {(M2GenGCC_BinaryFunction_t) m2expr_BuildSymmetricDifference}, NameKey_MakeKey ((const char *) "SymmetricDifference", 19), quad);
    7467          124 : }
    7468              : 
    7469              : 
    7470              : /*
    7471              :    CodeUnarySet - encode a unary set arithmetic operation.
    7472              :                   Set operands may be longer than a word.
    7473              : */
    7474              : 
    7475           78 : static void CodeUnarySet (M2GenGCC_ProcedureCardinal constop, M2GenGCC_UnaryFunction unfunc, unsigned int tokenno, NameKey_Name wideprocname, unsigned int quad, unsigned int result, unsigned int expr)
    7476              : {
    7477           78 :   location_t location;
    7478           78 :   unsigned int settype;
    7479              : 
    7480              :   /* Firstly ensure that constant literals are declared.  */
    7481           78 :   M2GCCDeclare_DeclareConstant (tokenno, expr);
    7482           78 :   M2GCCDeclare_DeclareConstructor (tokenno, quad, expr);
    7483           78 :   location = M2LexBuf_TokenToLocation (tokenno);
    7484           78 :   if (SymbolTable_IsConst (result))
    7485              :     {
    7486            0 :       if (SymbolTable_IsValueSolved (expr))
    7487              :         {
    7488            0 :           M2Debug_Assert ((FindType (expr)) != SymbolTable_NulSym);
    7489            0 :           SymbolTable_PutConst (result, FindType (expr));
    7490            0 :           SymbolTable_PushValue (expr);
    7491            0 :           (*constop.proc) (tokenno);
    7492            0 :           SymbolTable_PopValue (result);
    7493            0 :           SymbolTable_PushValue (result);
    7494            0 :           SymbolTable_PutConstSet (result);
    7495            0 :           M2GCCDeclare_ConstantKnownAndUsed (result, m2decl_DeclareKnownConstant (location, SymbolConversion_Mod2Gcc (SymbolTable_GetType (expr)), M2ALU_PopSetTree (tokenno)));
    7496              :         }
    7497              :       else
    7498              :         {
    7499            0 :           M2MetaError_MetaErrorT0 (tokenno, (const char *) "{%E}constant expression cannot be evaluated", 43);
    7500              :         }
    7501              :     }
    7502              :   else
    7503              :     {
    7504           78 :       checkDeclare (result);
    7505           78 :       settype = SymbolTable_GetLType (result);
    7506           78 :       M2Debug_Assert (SymbolTable_IsSet (settype));
    7507           78 :       if (SymbolTable_GetSetInWord (settype))
    7508              :         {
    7509           72 :           SetNarrowUnary (location, unfunc, settype, result, expr);
    7510              :         }
    7511              :       else
    7512              :         {
    7513            6 :           SetWideUnary (tokenno, wideprocname, settype, result, expr);
    7514              :         }
    7515              :     }
    7516           78 : }
    7517              : 
    7518              : 
    7519              : /*
    7520              :    FromM2WIDESETImport - returns M2WIDESET.name.
    7521              : */
    7522              : 
    7523         2170 : static unsigned int FromM2WIDESETImport (unsigned int tokenno, NameKey_Name name)
    7524              : {
    7525         2170 :   unsigned int sym;
    7526         2170 :   unsigned int module;
    7527              : 
    7528         2170 :   sym = SymbolTable_NulSym;
    7529         2170 :   if (M2Options_GetWideset ())
    7530              :     {
    7531              :       /* avoid dangling else.  */
    7532         2170 :       module = M2Batch_MakeDefinitionSource (tokenno, NameKey_MakeKey ((const char *) "M2WIDESET", 9));
    7533         2170 :       sym = SymbolTable_FromModuleGetSym (tokenno, name, module);
    7534         2170 :       if (SymbolTable_IsUnknown (sym))
    7535              :         {
    7536            0 :           M2MetaError_MetaErrorT2 (tokenno, (const char *) "procedure function {%1Aad} is not available from {%2ad}", 55, sym, module);
    7537              :         }
    7538              :     }
    7539              :   else
    7540              :     {
    7541            0 :       M2MetaError_MetaErrorT0 (tokenno, (const char *) "{%0A}wideset is not available due to -fno-wideset", 49);
    7542              :     }
    7543         2170 :   return sym;
    7544              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    7545              :   __builtin_unreachable ();
    7546              : }
    7547              : 
    7548              : 
    7549              : /*
    7550              :    SetWideUnaryLibrary - call wideprocname (result, expr) passing result and expr
    7551              :                          as an array of byte.
    7552              : */
    7553              : 
    7554            2 : static void SetWideUnaryLibrary (unsigned int tokenno, NameKey_Name wideprocname, unsigned int settype, unsigned int result, unsigned int expr)
    7555              : {
    7556            2 :   location_t location;
    7557            2 :   unsigned int procedure;
    7558            2 :   unsigned int param1;
    7559            2 :   unsigned int param2;
    7560            2 :   tree highbit;
    7561            2 :   tree array1;
    7562            2 :   tree array2;
    7563            2 :   tree call;
    7564              : 
    7565            2 :   procedure = FromM2WIDESETImport (tokenno, wideprocname);
    7566            2 :   checkDeclare (procedure);
    7567            2 :   location = M2LexBuf_TokenToLocation (tokenno);
    7568            2 :   highbit = m2convert_ToCardinal (location, CalcBitsInSet (location, settype));
    7569            2 :   param1 = SymbolTable_GetNthParamAnyClosest (procedure, 1, SymbolTable_GetMainModule ());
    7570            2 :   param2 = SymbolTable_GetNthParamAnyClosest (procedure, 2, SymbolTable_GetMainModule ());
    7571            2 :   array1 = CreateSetArrayParam (location, tokenno, result, param1);
    7572            2 :   array2 = CreateSetArrayParam (location, tokenno, expr, param2);
    7573            2 :   m2statement_BuildParam (location, highbit);  /* 3rd Parameter.  */
    7574            2 :   m2statement_BuildParam (location, array2);  /* 2nd Parameter.  */
    7575            2 :   m2statement_BuildParam (location, array1);  /* 1st Parameter.  */
    7576            2 :   call = m2statement_BuildProcedureCallTree (location, SymbolConversion_Mod2Gcc (procedure), NULL);  /* 1st Parameter.  */
    7577            2 :   m2statement_SetLastFunction (NULL);
    7578            2 :   m2type_AddStatement (location, call);
    7579            2 : }
    7580              : 
    7581              : 
    7582              : /*
    7583              :    SetWideUnaryBuiltinNot - build an builtin wideset NOT operation.
    7584              : */
    7585              : 
    7586            4 : static void SetWideUnaryBuiltinNot (unsigned int tokenno, unsigned int result, unsigned int expr)
    7587              : {
    7588            4 :   location_t location;
    7589            4 :   tree byte;
    7590            4 :   tree lhs;
    7591            4 :   tree rhs;
    7592            4 :   tree index;
    7593            4 :   tree high;
    7594              : 
    7595            4 :   location = M2LexBuf_TokenToLocation (tokenno);
    7596            4 :   high = ResolveHigh (tokenno, 1, result);
    7597            4 :   index = m2expr_GetIntegerZero (location);
    7598            4 :   byte = SymbolConversion_Mod2Gcc (M2System_Byte);
    7599           64 :   do {
    7600           64 :     rhs = m2expr_BuildArray (location, byte, SymbolConversion_Mod2Gcc (expr), index, m2expr_GetIntegerZero (location));
    7601           64 :     rhs = m2expr_BuildSetNegate (location, rhs);
    7602           64 :     rhs = m2convert_BuildConvert (location, byte, rhs, false);
    7603           64 :     lhs = m2expr_BuildArray (location, byte, SymbolConversion_Mod2Gcc (result), index, m2expr_GetIntegerZero (location));
    7604           64 :     m2statement_BuildAssignmentStatement (location, lhs, rhs);
    7605           64 :     M2ALU_PushIntegerTree (index);
    7606           64 :     M2ALU_PushCard (1);
    7607           64 :     M2ALU_Addn ();
    7608           64 :     index = M2ALU_PopIntegerTree ();
    7609           64 :   } while (! ((m2expr_CompareTrees (index, high)) > 0));
    7610            4 : }
    7611              : 
    7612              : 
    7613              : /*
    7614              :    SetWideUnary - either call the library wideprocname or the builtin
    7615              :                   version depending upon the optimization setting.
    7616              : */
    7617              : 
    7618            6 : static void SetWideUnary (unsigned int tokenno, NameKey_Name wideprocname, unsigned int settype, unsigned int result, unsigned int expr)
    7619              : {
    7620            6 :   if (M2Options_OptimizeSets && (wideprocname == (NameKey_MakeKey ((const char *) "Not", 3))))
    7621              :     {
    7622            4 :       SetWideUnaryBuiltinNot (tokenno, result, expr);
    7623              :     }
    7624              :   else
    7625              :     {
    7626            2 :       SetWideUnaryLibrary (tokenno, wideprocname, settype, result, expr);
    7627              :     }
    7628            6 : }
    7629              : 
    7630              : 
    7631              : /*
    7632              :    SetNarrowUnary - create tree consisting of:
    7633              :                     result := unfunc (expr)
    7634              :                     result and expr can be lvalues.
    7635              : */
    7636              : 
    7637           72 : static void SetNarrowUnary (location_t location, M2GenGCC_UnaryFunction unfunc, unsigned int settype, unsigned int result, unsigned int expr)
    7638              : {
    7639           72 :   bool isResultL;
    7640           72 :   bool isExprL;
    7641              : 
    7642           72 :   isResultL = (SymbolTable_GetMode (result)) == SymbolTable_LeftValue;
    7643           72 :   isExprL = (SymbolTable_GetMode (expr)) == SymbolTable_LeftValue;
    7644           72 :   m2statement_BuildAssignmentStatement (location, getrvalue (location, result, settype, isResultL), (tree) ((*unfunc.proc) (location, getrvalue (location, expr, settype, isExprL))));
    7645           72 : }
    7646              : 
    7647              : 
    7648              : /*
    7649              :    FoldIncl - check whether we can fold the InclOp.
    7650              :               result := result + (1 << expr)
    7651              : */
    7652              : 
    7653        27286 : static void FoldIncl (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int result, unsigned int expr)
    7654              : {
    7655              :   /* firstly ensure that constant literals are declared  */
    7656        27286 :   M2GCCDeclare_TryDeclareConstant (tokenno, expr);
    7657        27286 :   if ((SymbolTable_IsConst (result)) && (SymbolTable_IsConst (expr)))
    7658              :     {
    7659            0 :       if ((SymbolConversion_GccKnowsAbout (expr)) && (SymbolTable_IsValueSolved (result)))
    7660              :         {
    7661              :           /* fine, we can take advantage of this and fold constants  */
    7662            0 :           SymbolTable_PushValue (result);
    7663            0 :           M2ALU_AddBit (tokenno, expr);
    7664            0 :           SymbolConversion_AddModGcc (result, M2ALU_PopSetTree (tokenno));
    7665            0 :           (*p.proc) (result);
    7666            0 :           NoChange = false;
    7667            0 :           M2Quads_SubQuad (quad);
    7668              :         }
    7669              :     }
    7670        27286 : }
    7671              : 
    7672              : 
    7673              : /*
    7674              :    FoldIfLess - check to see if it is possible to evaluate
    7675              :                 if op1 < op2 then goto op3.
    7676              : */
    7677              : 
    7678        36982 : static void FoldIfLess (unsigned int tokenno, unsigned int quad, unsigned int left, unsigned int right, unsigned int destQuad)
    7679              : {
    7680              :   /* Firstly ensure that constant literals are declared.  */
    7681        36982 :   M2GCCDeclare_TryDeclareConstant (tokenno, left);
    7682        36982 :   M2GCCDeclare_TryDeclareConstant (tokenno, right);
    7683        36982 :   if ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right)))
    7684              :     {
    7685         1988 :       if ((SymbolTable_IsValueSolved (left)) && (SymbolTable_IsValueSolved (right)))
    7686              :         {
    7687              :           /* We can take advantage of the known values and evaluate the condition.  */
    7688         1988 :           SymbolTable_PushValue (left);
    7689         1988 :           SymbolTable_PushValue (right);
    7690         1988 :           if (M2ALU_Less (tokenno))
    7691              :             {
    7692          958 :               M2Quads_PutQuad (quad, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, destQuad);
    7693              :             }
    7694              :           else
    7695              :             {
    7696         1030 :               M2Quads_SubQuad (quad);
    7697              :             }
    7698         1988 :           NoChange = false;
    7699              :         }
    7700              :     }
    7701        36982 : }
    7702              : 
    7703              : 
    7704              : /*
    7705              :    FoldIfGre - check to see if it is possible to evaluate
    7706              :                if op1 > op2 then goto op3.
    7707              : */
    7708              : 
    7709        28024 : static void FoldIfGre (unsigned int tokenno, unsigned int quad, unsigned int left, unsigned int right, unsigned int destQuad)
    7710              : {
    7711              :   /* Firstly ensure that constant literals are declared.  */
    7712        28024 :   M2GCCDeclare_TryDeclareConstant (tokenno, left);
    7713        28024 :   M2GCCDeclare_TryDeclareConstant (tokenno, right);
    7714        28024 :   if ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right)))
    7715              :     {
    7716           72 :       if ((SymbolTable_IsValueSolved (left)) && (SymbolTable_IsValueSolved (right)))
    7717              :         {
    7718              :           /* We can take advantage of the known values and evaluate the condition.  */
    7719           72 :           SymbolTable_PushValue (left);
    7720           72 :           SymbolTable_PushValue (right);
    7721           72 :           if (M2ALU_Gre (tokenno))
    7722              :             {
    7723           12 :               M2Quads_PutQuad (quad, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, destQuad);
    7724              :             }
    7725              :           else
    7726              :             {
    7727           60 :               M2Quads_SubQuad (quad);
    7728              :             }
    7729           72 :           NoChange = false;
    7730              :         }
    7731              :     }
    7732        28024 : }
    7733              : 
    7734              : 
    7735              : /*
    7736              :    FoldIfLessEqu - check to see if it is possible to evaluate
    7737              :                    if op1 <= op2 then goto op3.
    7738              : */
    7739              : 
    7740        30992 : static void FoldIfLessEqu (unsigned int tokenno, unsigned int quad, unsigned int left, unsigned int right, unsigned int destQuad)
    7741              : {
    7742              :   /* Firstly ensure that constant literals are declared.  */
    7743        30992 :   M2GCCDeclare_TryDeclareConstant (tokenno, left);
    7744        30992 :   M2GCCDeclare_TryDeclareConstant (tokenno, right);
    7745        30992 :   if ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right)))
    7746              :     {
    7747           42 :       if ((SymbolTable_IsValueSolved (left)) && (SymbolTable_IsValueSolved (right)))
    7748              :         {
    7749              :           /* We can take advantage of the known values and evaluate the condition.  */
    7750           42 :           SymbolTable_PushValue (left);
    7751           42 :           SymbolTable_PushValue (right);
    7752           42 :           if (M2ALU_LessEqu (tokenno))
    7753              :             {
    7754           36 :               M2Quads_PutQuad (quad, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, destQuad);
    7755              :             }
    7756              :           else
    7757              :             {
    7758            6 :               M2Quads_SubQuad (quad);
    7759              :             }
    7760           42 :           NoChange = false;
    7761              :         }
    7762              :     }
    7763        30992 : }
    7764              : 
    7765              : 
    7766              : /*
    7767              :    FoldIfGreEqu - check to see if it is possible to evaluate
    7768              :                   if op1 >= op2 then goto op3.
    7769              : */
    7770              : 
    7771        47074 : static void FoldIfGreEqu (unsigned int tokenno, unsigned int quad, unsigned int left, unsigned int right, unsigned int destQuad)
    7772              : {
    7773              :   /* Firstly ensure that constant literals are declared.  */
    7774        47074 :   M2GCCDeclare_TryDeclareConstant (tokenno, left);
    7775        47074 :   M2GCCDeclare_TryDeclareConstant (tokenno, right);
    7776        47074 :   if ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right)))
    7777              :     {
    7778         8134 :       if ((SymbolTable_IsValueSolved (left)) && (SymbolTable_IsValueSolved (right)))
    7779              :         {
    7780              :           /* We can take advantage of the known values and evaluate the condition.  */
    7781         3820 :           SymbolTable_PushValue (left);
    7782         3820 :           SymbolTable_PushValue (right);
    7783         3820 :           if (M2ALU_GreEqu (tokenno))
    7784              :             {
    7785         3004 :               M2Quads_PutQuad (quad, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, destQuad);
    7786              :             }
    7787              :           else
    7788              :             {
    7789          816 :               M2Quads_SubQuad (quad);
    7790              :             }
    7791         3820 :           NoChange = false;
    7792              :         }
    7793              :     }
    7794        47074 : }
    7795              : 
    7796              : 
    7797              : /*
    7798              :    FoldIfIn - check whether we can fold the IfInOp
    7799              :               if op1 in op2 then goto op3
    7800              : */
    7801              : 
    7802        53404 : static void FoldIfIn (unsigned int tokenno, unsigned int quad, unsigned int left, unsigned int right, unsigned int destQuad)
    7803              : {
    7804              :   /* Firstly ensure that constant literals are declared.  */
    7805        53404 :   M2GCCDeclare_TryDeclareConstant (tokenno, left);
    7806        53404 :   M2GCCDeclare_TryDeclareConstant (tokenno, right);
    7807        53404 :   if ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right)))
    7808              :     {
    7809            0 :       if ((SymbolTable_IsValueSolved (left)) && (SymbolTable_IsValueSolved (right)))
    7810              :         {
    7811            0 :           if (CheckBinaryExpressionTypes (quad, (M2GCCDeclare_WalkAction) {(M2GCCDeclare_WalkAction_t) NoWalkProcedure}))
    7812              :             {
    7813              :               /* We can take advantage of the known values and evaluate the condition.  */
    7814            0 :               SymbolTable_PushValue (right);
    7815            0 :               if (M2ALU_SetIn (tokenno, left))
    7816              :                 {
    7817            0 :                   M2Quads_PutQuad (quad, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, destQuad);
    7818              :                 }
    7819              :               else
    7820              :                 {
    7821            0 :                   M2Quads_SubQuad (quad);
    7822              :                 }
    7823              :             }
    7824              :           else
    7825              :             {
    7826            0 :               M2Quads_SubQuad (quad);
    7827              :             }
    7828            0 :           NoChange = false;
    7829              :         }
    7830              :     }
    7831        53404 : }
    7832              : 
    7833              : 
    7834              : /*
    7835              :    FoldIfNotIn - check whether we can fold the IfNotInOp
    7836              :                  if not (op1 in op2) then goto op3
    7837              : */
    7838              : 
    7839         9056 : static void FoldIfNotIn (unsigned int tokenno, unsigned int quad, unsigned int left, unsigned int right, unsigned int destQuad)
    7840              : {
    7841              :   /* Firstly ensure that constant literals are declared.  */
    7842         9056 :   M2GCCDeclare_TryDeclareConstant (tokenno, left);
    7843         9056 :   M2GCCDeclare_TryDeclareConstant (tokenno, right);
    7844         9056 :   if ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right)))
    7845              :     {
    7846            0 :       if ((SymbolTable_IsValueSolved (left)) && (SymbolTable_IsValueSolved (right)))
    7847              :         {
    7848            0 :           if (CheckBinaryExpressionTypes (quad, (M2GCCDeclare_WalkAction) {(M2GCCDeclare_WalkAction_t) NoWalkProcedure}))
    7849              :             {
    7850              :               /* We can take advantage of the known values and evaluate the
    7851              :                condition.  */
    7852            0 :               SymbolTable_PushValue (right);
    7853            0 :               if (! (M2ALU_SetIn (tokenno, left)))
    7854              :                 {
    7855            0 :                   M2Quads_PutQuad (quad, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, destQuad);
    7856              :                 }
    7857              :               else
    7858              :                 {
    7859            0 :                   M2Quads_SubQuad (quad);
    7860              :                 }
    7861              :             }
    7862              :           else
    7863              :             {
    7864            0 :               M2Quads_SubQuad (quad);
    7865              :             }
    7866            0 :           NoChange = false;
    7867              :         }
    7868              :     }
    7869         9056 : }
    7870              : 
    7871              : 
    7872              : /*
    7873              :    FoldIfEqu - check to see if it is possible to evaluate
    7874              :                if op1 = op2 then goto op3.
    7875              : */
    7876              : 
    7877       680761 : static void FoldIfEqu (unsigned int tokenno, unsigned int quad, unsigned int left, unsigned int right, unsigned int destQuad)
    7878              : {
    7879              :   /* Firstly ensure that constant literals are declared.  */
    7880       680761 :   M2GCCDeclare_TryDeclareConstant (tokenno, left);
    7881       680761 :   M2GCCDeclare_TryDeclareConstant (tokenno, right);
    7882       680761 :   if ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right)))
    7883              :     {
    7884         1202 :       if ((SymbolTable_IsValueSolved (left)) && (SymbolTable_IsValueSolved (right)))
    7885              :         {
    7886              :           /* We can take advantage of the known values and evaluate the
    7887              :             condition.  */
    7888          722 :           SymbolTable_PushValue (left);
    7889          722 :           SymbolTable_PushValue (right);
    7890          722 :           if (M2ALU_Equ (tokenno))
    7891              :             {
    7892          392 :               M2Quads_PutQuad (quad, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, destQuad);
    7893              :             }
    7894              :           else
    7895              :             {
    7896          330 :               M2Quads_SubQuad (quad);
    7897              :             }
    7898          722 :           NoChange = false;
    7899              :         }
    7900              :     }
    7901       680761 : }
    7902              : 
    7903              : 
    7904              : /*
    7905              :    FoldIfNotEqu - check to see if it is possible to evaluate
    7906              :                   if op1 # op2 then goto op3.
    7907              : */
    7908              : 
    7909       336237 : static void FoldIfNotEqu (unsigned int tokenno, unsigned int quad, unsigned int left, unsigned int right, unsigned int destQuad)
    7910              : {
    7911              :   /* Firstly ensure that constant literals are declared.  */
    7912       336237 :   M2GCCDeclare_TryDeclareConstant (tokenno, left);
    7913       336237 :   M2GCCDeclare_TryDeclareConstant (tokenno, right);
    7914       336237 :   if ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right)))
    7915              :     {
    7916         3564 :       if ((SymbolTable_IsValueSolved (left)) && (SymbolTable_IsValueSolved (right)))
    7917              :         {
    7918              :           /* We can take advantage of the known values and evaluate the
    7919              :             condition.  */
    7920         3498 :           SymbolTable_PushValue (left);
    7921         3498 :           SymbolTable_PushValue (right);
    7922         3498 :           if (M2ALU_NotEqu (tokenno))
    7923              :             {
    7924         2654 :               M2Quads_PutQuad (quad, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, destQuad);
    7925              :             }
    7926              :           else
    7927              :             {
    7928          844 :               M2Quads_SubQuad (quad);
    7929              :             }
    7930         3498 :           NoChange = false;
    7931              :         }
    7932              :     }
    7933       336237 : }
    7934              : 
    7935              : 
    7936              : /*
    7937              :    GetSetLimits - assigns low and high to the limits of the declared, set.
    7938              : */
    7939              : 
    7940         5838 : static void GetSetLimits (unsigned int set, unsigned int *low, unsigned int *high)
    7941              : {
    7942         5838 :   unsigned int type;
    7943              : 
    7944         5838 :   type = SymbolTable_GetType (set);
    7945         5838 :   if (SymbolTable_IsSubrange (type))
    7946              :     {
    7947         4602 :       SymbolTable_GetSubrange (type, high, low);
    7948              :     }
    7949              :   else
    7950              :     {
    7951         1236 :       (*low) = M2GCCDeclare_GetTypeMin (type);
    7952         1236 :       (*high) = M2GCCDeclare_GetTypeMax (type);
    7953              :     }
    7954         5838 : }
    7955              : 
    7956              : 
    7957              : /*
    7958              :    IsElementInRange - returns TRUE if expr references a bit in setvar
    7959              :                       which is in the range [low..high].  If expr is a
    7960              :                       variable it returns TRUE.  FALSE is returned if we
    7961              :                       know expr to be out of bounds.
    7962              : */
    7963              : 
    7964         4214 : static bool IsElementInRange (unsigned int tokenno, unsigned int settype, unsigned int setvar, unsigned int expr)
    7965              : {
    7966         4214 :   unsigned int low;
    7967         4214 :   unsigned int high;
    7968              : 
    7969         4214 :   if (SymbolTable_IsConst (expr))
    7970              :     {
    7971         1630 :       GetSetLimits (settype, &low, &high);
    7972         1630 :       SymbolTable_PushValue (expr);
    7973         1630 :       SymbolTable_PushValue (high);
    7974         1630 :       if (M2ALU_Gre (tokenno))
    7975              :         {
    7976            0 :           M2MetaError_MetaErrorT1 (tokenno, (const char *) "bit exceeds the range of set {%1Eatd}", 37, setvar);
    7977            0 :           return false;
    7978              :         }
    7979         1630 :       SymbolTable_PushValue (expr);
    7980         1630 :       SymbolTable_PushValue (low);
    7981         1630 :       if (M2ALU_Less (tokenno))
    7982              :         {
    7983            6 :           M2MetaError_MetaErrorT1 (tokenno, (const char *) "bit underflows the range of set {%1Eatd}", 40, setvar);
    7984            6 :           return false;
    7985              :         }
    7986              :     }
    7987              :   return true;
    7988              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    7989              :   __builtin_unreachable ();
    7990              : }
    7991              : 
    7992              : 
    7993              : /*
    7994              :    SetElementToBit -
    7995              : */
    7996              : 
    7997         4208 : static tree SetElementToBit (location_t location, unsigned int settype, unsigned int expr)
    7998              : {
    7999         4208 :   unsigned int lowelement;
    8000         4208 :   unsigned int highelement;
    8001         4208 :   tree low;
    8002              : 
    8003         4208 :   GetSetLimits (settype, &lowelement, &highelement);
    8004         4208 :   SymbolTable_PushValue (lowelement);
    8005         4208 :   low = M2ALU_PopIntegerTree ();
    8006         4208 :   return m2expr_BuildSub (location, m2convert_ToCardinal (location, SymbolConversion_Mod2Gcc (expr)), m2convert_ToCardinal (location, low), false);
    8007              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8008              :   __builtin_unreachable ();
    8009              : }
    8010              : 
    8011              : 
    8012              : /*
    8013              :    CodeNarrowIncl - result |= (1 << expr).
    8014              : */
    8015              : 
    8016          812 : static void CodeNarrowIncl (location_t location, unsigned int settype, unsigned int result, unsigned int expr)
    8017              : {
    8018          812 :   tree bit;
    8019          812 :   bool isLvalue;
    8020              : 
    8021          812 :   bit = SetElementToBit (location, settype, expr);
    8022          812 :   isLvalue = (SymbolTable_GetMode (result)) == SymbolTable_LeftValue;
    8023          812 :   m2statement_BuildAssignmentStatement (location, getrvalue (location, result, settype, isLvalue), m2convert_ToBitset (location, m2expr_BuildLogicalOr (location, getrvalue (location, result, settype, isLvalue), m2expr_BuildLSL (location, m2expr_GetWordOne (location), bit, false))));
    8024          812 : }
    8025              : 
    8026              : 
    8027              : /*
    8028              :    CodeNarrowExcl - result &= (~ (1 << expr)).
    8029              : */
    8030              : 
    8031          556 : static void CodeNarrowExcl (location_t location, unsigned int settype, unsigned int result, unsigned int expr)
    8032              : {
    8033          556 :   tree bit;
    8034          556 :   tree mask;
    8035          556 :   bool isLvalue;
    8036              : 
    8037          556 :   bit = SetElementToBit (location, settype, expr);
    8038          556 :   mask = m2expr_BuildSetNegate (location, m2expr_BuildLSL (location, m2expr_GetWordOne (location), m2convert_ToWord (location, bit), false));
    8039          556 :   isLvalue = (SymbolTable_GetMode (result)) == SymbolTable_LeftValue;
    8040          556 :   m2statement_BuildAssignmentStatement (location, getrvalue (location, result, settype, isLvalue), m2convert_ToBitset (location, m2expr_BuildLogicalAnd (location, getrvalue (location, result, settype, isLvalue), mask)));
    8041          556 : }
    8042              : 
    8043              : 
    8044              : /*
    8045              :    SetWideUnaryBuiltinIncl -
    8046              : */
    8047              : 
    8048          128 : static void SetWideUnaryBuiltinIncl (location_t location, tree dest, tree bitno)
    8049              : {
    8050          128 :   m2statement_BuildAssignmentStatement (location, dest, m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (M2System_Byte), m2expr_BuildLogicalOr (location, dest, m2expr_BuildLSL (location, m2expr_GetWordOne (location), bitno, false)), false));
    8051          128 : }
    8052              : 
    8053              : 
    8054              : /*
    8055              :    SetWideUnaryBuiltinExcl -
    8056              : */
    8057              : 
    8058           80 : static void SetWideUnaryBuiltinExcl (location_t location, tree dest, tree bitno)
    8059              : {
    8060           80 :   tree mask;
    8061              : 
    8062           80 :   mask = m2expr_BuildSetNegate (location, m2expr_BuildLSL (location, m2expr_GetWordOne (location), m2convert_ToWord (location, bitno), false));
    8063           80 :   m2statement_BuildAssignmentStatement (location, dest, m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (M2System_Byte), m2expr_BuildLogicalAnd (location, dest, mask), false));
    8064           80 : }
    8065              : 
    8066          208 : static void SetWideUnaryBuiltinInclExcl (unsigned int tokenno, unsigned int settype, unsigned int des, unsigned int expr, bool incl)
    8067              : {
    8068          208 :   tree bitsperbyte;
    8069          208 :   tree byteno;
    8070          208 :   tree bitno;
    8071          208 :   tree dest;
    8072          208 :   tree bit;
    8073          208 :   location_t location;
    8074              : 
    8075              :   /* 
    8076              :    SetWideUnaryBuiltinIncl -
    8077              :   */
    8078          208 :   location = M2LexBuf_TokenToLocation (tokenno);
    8079          208 :   bit = m2convert_ToCardinal (location, SetElementToBit (location, settype, expr));
    8080          208 :   bitsperbyte = m2convert_ToCardinal (location, m2expr_GetSizeOfInBits (SymbolConversion_Mod2Gcc (M2System_Byte)));
    8081          208 :   byteno = m2expr_BuildDivFloor (location, bit, bitsperbyte, false);
    8082          208 :   bitno = m2expr_BuildModFloor (location, bit, bitsperbyte, false);
    8083          208 :   dest = m2expr_BuildArray (location, SymbolConversion_Mod2Gcc (M2System_Byte), getrvalue (location, des, SymbolTable_GetType (des), (SymbolTable_GetMode (des)) == SymbolTable_LeftValue), byteno, m2expr_GetIntegerZero (location));
    8084          208 :   if (incl)
    8085              :     {
    8086          128 :       SetWideUnaryBuiltinIncl (location, dest, bitno);
    8087              :     }
    8088              :   else
    8089              :     {
    8090           80 :       SetWideUnaryBuiltinExcl (location, dest, bitno);
    8091              :     }
    8092          208 : }
    8093              : 
    8094              : 
    8095              : /*
    8096              :    SetWideInclExcl - generates M2WIDESET.procedurename (result, expr).
    8097              : */
    8098              : 
    8099          528 : static void SetWideInclExcl (unsigned int tokenno, unsigned int settype, unsigned int result, unsigned int expr, NameKey_Name procedurename)
    8100              : {
    8101          528 :   if (M2Options_OptimizeSets)
    8102              :     {
    8103          208 :       if (procedurename == (NameKey_MakeKey ((const char *) "Incl", 4)))
    8104              :         {
    8105          128 :           SetWideUnaryBuiltinInclExcl (tokenno, settype, result, expr, true);
    8106              :         }
    8107           80 :       else if (procedurename == (NameKey_MakeKey ((const char *) "Excl", 4)))
    8108              :         {
    8109              :           /* avoid dangling else.  */
    8110           80 :           SetWideUnaryBuiltinInclExcl (tokenno, settype, result, expr, false);
    8111              :         }
    8112              :       else
    8113              :         {
    8114              :           /* avoid dangling else.  */
    8115            0 :           M2Error_InternalError ((const char *) "expecting Incl or Excl procedure", 32);
    8116              :         }
    8117              :     }
    8118              :   else
    8119              :     {
    8120          320 :       SetWideInclExclLibrary (tokenno, settype, result, expr, procedurename);
    8121              :     }
    8122          528 : }
    8123              : 
    8124              : 
    8125              : /*
    8126              :    SetWideInclExclLibrary -
    8127              : */
    8128              : 
    8129          320 : static void SetWideInclExclLibrary (unsigned int tokenno, unsigned int settype, unsigned int result, unsigned int expr, NameKey_Name procedurename)
    8130              : {
    8131          320 :   location_t location;
    8132          320 :   unsigned int procedure;
    8133          320 :   unsigned int setparam;
    8134          320 :   tree highbit;
    8135          320 :   tree bit;
    8136          320 :   tree setarray;
    8137          320 :   tree call;
    8138              : 
    8139          320 :   procedure = FromM2WIDESETImport (tokenno, procedurename);
    8140          320 :   location = M2LexBuf_TokenToLocation (tokenno);
    8141          320 :   bit = SetElementToBit (location, settype, expr);
    8142          320 :   highbit = m2convert_ToCardinal (location, CalcBitsInSet (location, settype));
    8143          320 :   setparam = SymbolTable_GetNthParamAnyClosest (procedure, 1, SymbolTable_GetMainModule ());
    8144          320 :   setarray = CreateSetArrayParam (location, tokenno, result, setparam);
    8145          320 :   m2statement_BuildParam (location, highbit);  /* 3rd Parameter.  */
    8146          320 :   m2statement_BuildParam (location, m2convert_ToCardinal (location, bit));  /* 2nd Parameter.  */
    8147          320 :   m2statement_BuildParam (location, setarray);  /* 1st Parameter.  */
    8148          320 :   call = m2statement_BuildProcedureCallTree (location, SymbolConversion_Mod2Gcc (procedure), NULL);  /* 1st Parameter.  */
    8149          320 :   m2statement_SetLastFunction (NULL);
    8150          320 :   m2type_AddStatement (location, call);
    8151          320 : }
    8152              : 
    8153              : 
    8154              : /*
    8155              :    CodeIncl - encode an InclOp:
    8156              :               result |= (1 << expr).
    8157              : */
    8158              : 
    8159         1142 : static void CodeIncl (unsigned int quad)
    8160              : {
    8161         1142 :   bool overflow;
    8162         1142 :   bool constExpr;
    8163         1142 :   M2Quads_QuadOperator op;
    8164         1142 :   unsigned int tokenno;
    8165         1142 :   unsigned int result;
    8166         1142 :   unsigned int expr;
    8167         1142 :   unsigned int settype;
    8168         1142 :   unsigned int nooperand;
    8169         1142 :   unsigned int nopos;
    8170         1142 :   location_t location;
    8171              : 
    8172         1142 :   M2Quads_GetQuadOtok (quad, &tokenno, &op, &result, &nooperand, &expr, &overflow, &constExpr, &nopos, &nopos, &nopos);
    8173              :   /* Firstly ensure that constant literals are declared  */
    8174         1142 :   M2GCCDeclare_DeclareConstant (tokenno, expr);
    8175         1142 :   location = M2LexBuf_TokenToLocation (tokenno);
    8176         1142 :   checkDeclare (result);
    8177         1142 :   settype = SymbolTable_GetLType (result);
    8178         1142 :   M2Debug_Assert (SymbolTable_IsSet (settype));
    8179         1142 :   if (SymbolTable_IsConst (result))
    8180              :     {
    8181            0 :       if (SymbolTable_IsConst (expr))
    8182              :         {
    8183            0 :           M2Error_InternalError ((const char *) "this quadruple should have been removed by FoldIncl", 51);
    8184              :         }
    8185              :       else
    8186              :         {
    8187            0 :           M2Error_InternalError ((const char *) "should not get to here (why are we generating <incl const, var> ?)", 66);
    8188              :         }
    8189              :     }
    8190              :   else
    8191              :     {
    8192         1142 :       if (IsElementInRange (tokenno, settype, result, expr))
    8193              :         {
    8194              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    8195         1142 :           if (SymbolTable_GetSetInWord (settype))
    8196              :             {
    8197          812 :               CodeNarrowIncl (location, settype, result, expr);
    8198              :             }
    8199              :           else
    8200              :             {
    8201          330 :               SetWideInclExcl (tokenno, settype, result, expr, NameKey_MakeKey ((const char *) "Incl", 4));
    8202              :             }
    8203              :         }
    8204              :     }
    8205         1142 : }
    8206              : 
    8207              : 
    8208              : /*
    8209              :    FoldExcl - check whether we can fold the InclOp.
    8210              :               result &= ~ (1 << expr).
    8211              : */
    8212              : 
    8213        15538 : static void FoldExcl (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int result, unsigned int expr)
    8214              : {
    8215              :   /* Firstly ensure that constant literals are declared  */
    8216        15538 :   M2GCCDeclare_TryDeclareConstant (tokenno, expr);
    8217        15538 :   if ((SymbolTable_IsConst (result)) && (SymbolTable_IsConst (expr)))
    8218              :     {
    8219            0 :       if ((SymbolConversion_GccKnowsAbout (expr)) && (SymbolTable_IsValueSolved (result)))
    8220              :         {
    8221            0 :           SymbolTable_PushValue (result);
    8222            0 :           M2ALU_SubBit (tokenno, expr);
    8223            0 :           SymbolConversion_AddModGcc (result, M2ALU_PopSetTree (tokenno));
    8224            0 :           (*p.proc) (result);
    8225            0 :           NoChange = false;
    8226            0 :           M2Quads_SubQuad (quad);
    8227              :         }
    8228              :     }
    8229        15538 : }
    8230              : 
    8231              : 
    8232              : /*
    8233              :    CodeExcl - encode an ExclOp:
    8234              :               result &= (~ (1 << expr)).
    8235              : */
    8236              : 
    8237          754 : static void CodeExcl (unsigned int quad)
    8238              : {
    8239          754 :   bool overflow;
    8240          754 :   bool constExpr;
    8241          754 :   M2Quads_QuadOperator op;
    8242          754 :   unsigned int tokenno;
    8243          754 :   unsigned int result;
    8244          754 :   unsigned int expr;
    8245          754 :   unsigned int settype;
    8246          754 :   unsigned int nooperand;
    8247          754 :   unsigned int nopos;
    8248          754 :   location_t location;
    8249              : 
    8250          754 :   M2Quads_GetQuadOtok (quad, &tokenno, &op, &result, &nooperand, &expr, &overflow, &constExpr, &nopos, &nopos, &nopos);
    8251              :   /* Firstly ensure that constant literals are declared  */
    8252          754 :   M2GCCDeclare_DeclareConstant (tokenno, expr);
    8253          754 :   location = M2LexBuf_TokenToLocation (tokenno);
    8254          754 :   checkDeclare (result);
    8255          754 :   settype = SymbolTable_GetLType (result);
    8256          754 :   M2Debug_Assert (SymbolTable_IsSet (settype));
    8257          754 :   if (SymbolTable_IsConst (result))
    8258              :     {
    8259            0 :       if (SymbolTable_IsConst (expr))
    8260              :         {
    8261            0 :           M2Error_InternalError ((const char *) "this quadruple should have been removed by FoldExcl", 51);
    8262              :         }
    8263              :       else
    8264              :         {
    8265            0 :           M2Error_InternalError ((const char *) "should not get to here (why are we generating <excl const, var> ?)", 66);
    8266              :         }
    8267              :     }
    8268              :   else
    8269              :     {
    8270          754 :       if (IsElementInRange (tokenno, settype, result, expr))
    8271              :         {
    8272              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    8273          754 :           if (SymbolTable_GetSetInWord (settype))
    8274              :             {
    8275          556 :               CodeNarrowExcl (location, settype, result, expr);
    8276              :             }
    8277              :           else
    8278              :             {
    8279          198 :               SetWideInclExcl (tokenno, settype, result, expr, NameKey_MakeKey ((const char *) "Excl", 4));
    8280              :             }
    8281              :         }
    8282              :     }
    8283          754 : }
    8284              : 
    8285              : 
    8286              : /*
    8287              :    FoldUnary - check whether we can fold the unop operation.
    8288              : */
    8289              : 
    8290        39049 : static void FoldUnary (unsigned int tokenno, M2GCCDeclare_WalkAction p, m2expr_BuildUnaryProcedure unop, tree ZConstToTypedConst, unsigned int quad, unsigned int result, unsigned int expr)
    8291              : {
    8292        39049 :   tree tv;
    8293        39049 :   location_t location;
    8294              : 
    8295              :   /* firstly ensure that any constant literal is declared  */
    8296        39049 :   M2GCCDeclare_TryDeclareConstant (tokenno, expr);
    8297        39049 :   location = M2LexBuf_TokenToLocation (tokenno);
    8298        39049 :   if (SymbolTable_IsConst (expr))
    8299              :     {
    8300        18813 :       if (SymbolConversion_GccKnowsAbout (expr))
    8301              :         {
    8302              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    8303              :           /* fine, we can take advantage of this and fold constants  */
    8304        18813 :           if (SymbolTable_IsConst (result))
    8305              :             {
    8306        18813 :               if (ZConstToTypedConst == ((tree) (NULL)))
    8307              :                 {
    8308              :                   /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    8309        18813 :                   if (((SymbolTable_GetType (expr)) == SymbolTable_NulSym) || (M2Base_IsOrdinalType (SymbolTable_SkipType (SymbolTable_GetType (expr)))))
    8310              :                     {
    8311        18369 :                       ZConstToTypedConst = m2type_GetM2ZType ();
    8312              :                     }
    8313          444 :                   else if ((M2Base_IsRealType (SymbolTable_SkipType (SymbolTable_GetType (expr)))) || (M2System_IsRealN (SymbolTable_SkipType (SymbolTable_GetType (expr)))))
    8314              :                     {
    8315              :                       /* avoid dangling else.  */
    8316          264 :                       ZConstToTypedConst = m2type_GetM2RType ();
    8317              :                     }
    8318          180 :                   else if ((M2Base_IsComplexType (SymbolTable_SkipType (SymbolTable_GetType (expr)))) || (M2System_IsComplexN (SymbolTable_SkipType (SymbolTable_GetType (expr)))))
    8319              :                     {
    8320              :                       /* avoid dangling else.  */
    8321          180 :                       ZConstToTypedConst = m2type_GetM2CType ();
    8322              :                     }
    8323              :                 }
    8324        18813 :               if ((SymbolTable_GetType (result)) == SymbolTable_NulSym)
    8325              :                 {
    8326            0 :                   SymbolTable_PutConst (result, M2Base_NegateType (SymbolTable_GetType (expr)));  /* , tokenno  */
    8327              :                 }
    8328        18813 :               tv = (*unop.proc) (location, LValueToGenericPtrOrConvert (expr, ZConstToTypedConst), false);
    8329        18813 :               M2ALU_CheckOrResetOverflow (tokenno, tv, M2Quads_MustCheckOverflow (quad));
    8330        18813 :               SymbolConversion_AddModGcc (result, m2decl_DeclareKnownConstant (location, ZConstToTypedConst, tv));
    8331        18813 :               (*p.proc) (result);
    8332        18813 :               NoChange = false;
    8333        18813 :               M2Quads_SubQuad (quad);
    8334              :             }
    8335              :           /* we can still fold the expression, but not the assignment, however, we will
    8336              :                not do this here but in CodeUnary
    8337              :   */
    8338              :         }
    8339              :     }
    8340        39049 : }
    8341              : 
    8342              : 
    8343              : /*
    8344              :    FoldUnarySet - check whether we can fold the doOp operation.
    8345              : */
    8346              : 
    8347           60 : static void FoldUnarySet (unsigned int tokenno, M2GCCDeclare_WalkAction p, M2GenGCC_ProcedureCardinal doOp, unsigned int quad, unsigned int result, unsigned int expr)
    8348              : {
    8349           60 :   location_t location;
    8350              : 
    8351              :   /* firstly try and ensure that constants are declared  */
    8352           60 :   M2GCCDeclare_TryDeclareConstant (tokenno, expr);
    8353           60 :   location = M2LexBuf_TokenToLocation (tokenno);
    8354           60 :   if (((SymbolTable_IsConst (expr)) && (SymbolTable_IsConstSet (expr))) && (SymbolTable_IsConst (result)))
    8355              :     {
    8356           60 :       if ((SymbolTable_IsValueSolved (expr)) && ((SymbolTable_GetType (expr)) != SymbolTable_NulSym))
    8357              :         {
    8358           60 :           SymbolTable_PutConst (result, FindType (expr));
    8359           60 :           SymbolTable_PushValue (expr);
    8360           60 :           (*doOp.proc) (tokenno);
    8361           60 :           SymbolTable_PopValue (result);
    8362           60 :           SymbolTable_PushValue (result);
    8363           60 :           SymbolTable_PutConstSet (result);
    8364           60 :           SymbolConversion_AddModGcc (result, m2decl_DeclareKnownConstant (location, SymbolConversion_Mod2Gcc (SymbolTable_GetType (expr)), M2ALU_PopSetTree (tokenno)));
    8365           60 :           (*p.proc) (result);
    8366           60 :           NoChange = false;
    8367           60 :           M2Quads_SubQuad (quad);
    8368              :         }
    8369              :     }
    8370           60 : }
    8371              : 
    8372              : 
    8373              : /*
    8374              :    CodeUnaryCheck - encode a unary arithmetic operation.
    8375              : */
    8376              : 
    8377          912 : static void CodeUnaryCheck (m2expr_BuildUnaryCheckProcedure unop, tree ZConstToTypedConst, unsigned int quad, unsigned int result, unsigned int expr)
    8378              : {
    8379          912 :   unsigned int lowestType;
    8380          912 :   tree min;
    8381          912 :   tree max;
    8382          912 :   tree lowest;
    8383          912 :   tree tv;
    8384          912 :   location_t location;
    8385              : 
    8386              :   /* firstly ensure that any constant literal is declared  */
    8387          912 :   M2GCCDeclare_DeclareConstant (CurrentQuadToken, expr);
    8388          912 :   M2GCCDeclare_DeclareConstructor (CurrentQuadToken, quad, expr);
    8389          912 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    8390          912 :   lowestType = SymbolTable_GetLType (result);
    8391          912 :   if (lowestType == SymbolTable_NulSym)
    8392              :     {
    8393              :       lowest = NULL;
    8394              :     }
    8395              :   else
    8396              :     {
    8397          912 :       lowest = SymbolConversion_Mod2Gcc (lowestType);
    8398              :     }
    8399          912 :   if (M2Range_GetMinMax (CurrentQuadToken, lowestType, &min, &max))
    8400              :     {
    8401          848 :       tv = (*unop.proc) (location, M2GenGCC_LValueToGenericPtr (location, expr), lowest, min, max);
    8402              :     }
    8403              :   else
    8404              :     {
    8405           64 :       tv = (*unop.proc) (location, M2GenGCC_LValueToGenericPtr (location, expr), NULL, NULL, NULL);
    8406              :     }
    8407          912 :   M2ALU_CheckOrResetOverflow (CurrentQuadToken, tv, M2Quads_MustCheckOverflow (quad));
    8408          912 :   if (SymbolTable_IsConst (result))
    8409              :     {
    8410            0 :       if (ZConstToTypedConst == ((tree) (NULL)))
    8411              :         {
    8412            0 :           ZConstToTypedConst = (tree) (SymbolConversion_Mod2Gcc (SymbolTable_GetType (expr)));
    8413              :         }
    8414              :       /* still have a constant which was not resolved, pass it to gcc  */
    8415            0 :       SymbolTable_PutConst (result, FindType (expr));
    8416            0 :       M2GCCDeclare_ConstantKnownAndUsed (result, m2decl_DeclareKnownConstant (location, ZConstToTypedConst, tv));
    8417              :     }
    8418              :   else
    8419              :     {
    8420          912 :       if (M2SSA_EnableSSA && (SymbolTable_IsVariableSSA (result)))
    8421              :         {
    8422              :           Replace (result, tv);
    8423              :         }
    8424              :       else
    8425              :         {
    8426          912 :           m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (result), tv);
    8427              :         }
    8428              :     }
    8429          912 : }
    8430              : 
    8431              : 
    8432              : /*
    8433              :    CodeUnary - encode a unary arithmetic operation.
    8434              : */
    8435              : 
    8436            0 : static void CodeUnary (m2expr_BuildUnaryProcedure unop, tree ZConstToTypedConst, unsigned int quad, unsigned int result, unsigned int expr)
    8437              : {
    8438            0 :   tree tv;
    8439            0 :   location_t location;
    8440              : 
    8441              :   /* firstly ensure that any constant literal is declared  */
    8442            0 :   M2GCCDeclare_DeclareConstant (CurrentQuadToken, expr);
    8443            0 :   M2GCCDeclare_DeclareConstructor (CurrentQuadToken, quad, expr);
    8444            0 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    8445            0 :   tv = (*unop.proc) (location, M2GenGCC_LValueToGenericPtr (location, expr), false);
    8446            0 :   M2ALU_CheckOrResetOverflow (CurrentQuadToken, tv, M2Quads_MustCheckOverflow (quad));
    8447            0 :   if (SymbolTable_IsConst (result))
    8448              :     {
    8449            0 :       if (ZConstToTypedConst == ((tree) (NULL)))
    8450              :         {
    8451            0 :           ZConstToTypedConst = (tree) (SymbolConversion_Mod2Gcc (SymbolTable_GetType (expr)));
    8452              :         }
    8453              :       /* still have a constant which was not resolved, pass it to gcc  */
    8454            0 :       SymbolTable_PutConst (result, FindType (expr));
    8455            0 :       M2GCCDeclare_ConstantKnownAndUsed (result, m2decl_DeclareKnownConstant (location, ZConstToTypedConst, tv));
    8456              :     }
    8457              :   else
    8458              :     {
    8459            0 :       if (M2SSA_EnableSSA && (SymbolTable_IsVariableSSA (result)))
    8460              :         {
    8461              :           Replace (result, tv);
    8462              :         }
    8463              :       else
    8464              :         {
    8465            0 :           m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (result), tv);
    8466              :         }
    8467              :     }
    8468            0 : }
    8469              : 
    8470              : 
    8471              : /*
    8472              :    FoldNegate - check unary negate for constant folding.
    8473              : */
    8474              : 
    8475        39109 : static void FoldNegate (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int result, unsigned int expr)
    8476              : {
    8477        39109 :   if (SymbolTable_IsConstSet (expr))
    8478              :     {
    8479           60 :       FoldUnarySet (tokenno, p, (M2GenGCC_ProcedureCardinal) {(M2GenGCC_ProcedureCardinal_t) M2ALU_SetNegate}, quad, result, expr);
    8480              :     }
    8481              :   else
    8482              :     {
    8483        39049 :       FoldUnary (tokenno, p, (m2expr_BuildUnaryProcedure) {(m2expr_BuildUnaryProcedure_t) m2expr_BuildNegate}, NULL, quad, result, expr);
    8484              :     }
    8485        39109 : }
    8486              : 
    8487              : 
    8488              : /*
    8489              :    CodeNegateChecked - code a negate instruction, determine whether checking
    8490              :                        is required.
    8491              : */
    8492              : 
    8493          996 : static void CodeNegateChecked (unsigned int quad)
    8494              : {
    8495          996 :   unsigned int operatorpos;
    8496          996 :   unsigned int resultpos;
    8497          996 :   unsigned int nopos;
    8498          996 :   unsigned int exprpos;
    8499          996 :   unsigned int result;
    8500          996 :   unsigned int noop;
    8501          996 :   unsigned int expr;
    8502          996 :   bool typeChecking;
    8503          996 :   bool constExpr;
    8504          996 :   bool overflowChecking;
    8505          996 :   M2Quads_QuadOperator op;
    8506              : 
    8507          996 :   M2Quads_GetQuadOTypetok (quad, &operatorpos, &op, &result, &noop, &expr, &overflowChecking, &typeChecking, &constExpr, &resultpos, &nopos, &exprpos);
    8508          996 :   if ((SymbolTable_IsConstSet (expr)) || (SymbolTable_IsSet (SymbolTable_GetType (expr))))
    8509              :     {
    8510           78 :       CodeUnarySet ((M2GenGCC_ProcedureCardinal) {(M2GenGCC_ProcedureCardinal_t) M2ALU_SetNegate}, (M2GenGCC_UnaryFunction) {(M2GenGCC_UnaryFunction_t) m2expr_BuildSetNegate}, operatorpos, NameKey_MakeKey ((const char *) "Not", 3), quad, result, expr);
    8511              :     }
    8512          918 :   else if (UnaryOperand (quad, expr))
    8513              :     {
    8514              :       /* avoid dangling else.  */
    8515          912 :       if (M2Quads_MustCheckOverflow (quad))
    8516              :         {
    8517          912 :           CodeUnaryCheck ((m2expr_BuildUnaryCheckProcedure) {(m2expr_BuildUnaryCheckProcedure_t) m2expr_BuildNegateCheck}, NULL, quad, result, expr);
    8518              :         }
    8519              :       else
    8520              :         {
    8521            0 :           CodeUnary ((m2expr_BuildUnaryProcedure) {(m2expr_BuildUnaryProcedure_t) m2expr_BuildNegate}, NULL, quad, result, expr);
    8522              :         }
    8523              :     }
    8524          996 : }
    8525              : 
    8526              : 
    8527              : /*
    8528              :    FoldSize - check unary SIZE for constant folding.
    8529              : */
    8530              : 
    8531         7416 : static void FoldSize (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    8532              : {
    8533         7416 :   tree t;
    8534         7416 :   location_t location;
    8535              : 
    8536         7416 :   location = M2LexBuf_TokenToLocation (tokenno);
    8537         7416 :   if ((SymbolTable_IsConst (op1)) && (M2GCCDeclare_CompletelyResolved (op3)))
    8538              :     {
    8539              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    8540         6606 :       if (op2 == SymbolTable_NulSym)
    8541              :         {
    8542         6606 :           t = m2expr_BuildSize (location, SymbolConversion_Mod2Gcc (op3), false);
    8543         6606 :           M2ALU_PushIntegerTree (t);
    8544         6606 :           SymbolTable_PopValue (op1);
    8545         6606 :           SymbolTable_PutConst (op1, M2Base_Cardinal);
    8546         6606 :           (*p.proc) (op1);
    8547         6606 :           NoChange = false;
    8548         6606 :           M2Quads_SubQuad (quad);
    8549         6606 :           t = m2block_RememberConstant (t);
    8550              :         }
    8551            0 :       else if (SymbolConversion_GccKnowsAbout (op2))
    8552              :         {
    8553              :           /* avoid dangling else.  */
    8554              :           /* ignore the chosen varients as we implement it as a C union  */
    8555            0 :           t = m2expr_BuildSize (location, SymbolConversion_Mod2Gcc (op3), false);
    8556            0 :           M2ALU_PushIntegerTree (t);
    8557            0 :           SymbolTable_PopValue (op1);
    8558            0 :           SymbolTable_PutConst (op1, M2Base_Cardinal);
    8559            0 :           (*p.proc) (op1);
    8560            0 :           NoChange = false;
    8561            0 :           M2Quads_SubQuad (quad);
    8562            0 :           t = m2block_RememberConstant (t);
    8563              :         }
    8564              :     }
    8565         7416 : }
    8566              : 
    8567              : 
    8568              : /*
    8569              :    CodeSize - encode the inbuilt SIZE function.
    8570              : */
    8571              : 
    8572            0 : static void CodeSize (unsigned int result, unsigned int sym)
    8573              : {
    8574            0 :   location_t location;
    8575              : 
    8576            0 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    8577            0 :   M2ALU_PushIntegerTree (m2expr_BuildSize (location, SymbolConversion_Mod2Gcc (sym), false));
    8578            0 :   if (SymbolTable_IsConst (result))
    8579              :     {
    8580            0 :       SymbolTable_PopValue (result);
    8581            0 :       SymbolTable_PutConst (result, M2Base_Cardinal);
    8582            0 :       SymbolTable_PushValue (result);
    8583            0 :       M2GCCDeclare_ConstantKnownAndUsed (result, m2decl_DeclareKnownConstant (location, m2type_GetIntegerType (), M2ALU_PopIntegerTree ()));
    8584              :     }
    8585              :   else
    8586              :     {
    8587            0 :       m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (result), M2ALU_PopIntegerTree ());
    8588              :     }
    8589            0 : }
    8590              : 
    8591              : 
    8592              : /*
    8593              :    FoldRecordField - check whether we can fold an RecordFieldOp quadruple.
    8594              :                      Very similar to FoldBinary, except that we need to
    8595              :                      hard code a few parameters to the gcc backend.
    8596              : */
    8597              : 
    8598            0 : static void FoldRecordField (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int result, unsigned int record, unsigned int field)
    8599              : {
    8600            0 :   unsigned int recordType;
    8601            0 :   unsigned int fieldType;
    8602            0 :   tree ptr;
    8603            0 :   location_t location;
    8604              : 
    8605            0 :   return;  /* this procedure should no longer be called  */
    8606              :   location = M2LexBuf_TokenToLocation (tokenno);
    8607              :   /* firstly ensure that any constant literal is declared  */
    8608              :   M2GCCDeclare_TryDeclareConstant (tokenno, record);
    8609              :   if ((SymbolTable_IsRecordField (record)) || (SymbolTable_IsFieldVarient (record)))
    8610              :     {
    8611              :       recordType = SymbolTable_GetType (record);
    8612              :       fieldType = SymbolTable_GetType (field);
    8613              :       if ((((((SymbolConversion_GccKnowsAbout (record)) && (SymbolConversion_GccKnowsAbout (field))) && (SymbolConversion_GccKnowsAbout (recordType))) && (SymbolConversion_GccKnowsAbout (fieldType))) && (M2GCCDeclare_CompletelyResolved (recordType))) && (M2GCCDeclare_CompletelyResolved (fieldType)))
    8614              :         {
    8615              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    8616              :           /* fine, we can take advantage of this and fold constants  */
    8617              :           if (SymbolTable_IsConst (result))
    8618              :             {
    8619              :               ptr = m2expr_BuildComponentRef (location, SymbolConversion_Mod2Gcc (record), SymbolConversion_Mod2Gcc (field));
    8620              :               if (! (SymbolTable_IsValueSolved (result)))
    8621              :                 {
    8622              :                   M2ALU_PushIntegerTree (ptr);
    8623              :                   SymbolTable_PopValue (result);
    8624              :                 }
    8625              :               SymbolTable_PutConst (result, fieldType);
    8626              :               SymbolConversion_AddModGcc (result, m2decl_DeclareKnownConstant (location, SymbolConversion_Mod2Gcc (fieldType), ptr));
    8627              :               (*p.proc) (result);
    8628              :               NoChange = false;
    8629              :               M2Quads_SubQuad (quad);
    8630              :             }
    8631              :           /* we can still fold the expression, but not the assignment, however, we will
    8632              :                not do this here but in CodeOffset
    8633              :   */
    8634              :         }
    8635              :     }
    8636              : }
    8637              : 
    8638              : 
    8639              : /*
    8640              :    CodeRecordField - encode a reference to a field within a record.
    8641              : */
    8642              : 
    8643       138682 : static void CodeRecordField (unsigned int result, unsigned int record, unsigned int field)
    8644              : {
    8645       138682 :   unsigned int recordType;
    8646       138682 :   unsigned int fieldType;
    8647       138682 :   tree ptr;
    8648       138682 :   location_t location;
    8649              : 
    8650       138682 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    8651              :   /* firstly ensure that any constant literal is declared  */
    8652       138682 :   if ((SymbolTable_IsRecordField (field)) || (SymbolTable_IsFieldVarient (field)))
    8653              :     {
    8654       138682 :       recordType = SymbolTable_GetType (record);
    8655       138682 :       fieldType = SymbolTable_GetType (field);
    8656       138682 :       if ((((((SymbolConversion_GccKnowsAbout (record)) && (SymbolConversion_GccKnowsAbout (field))) && (SymbolConversion_GccKnowsAbout (recordType))) && (SymbolConversion_GccKnowsAbout (fieldType))) && (M2GCCDeclare_CompletelyResolved (recordType))) && (M2GCCDeclare_CompletelyResolved (fieldType)))
    8657              :         {
    8658       138682 :           if ((SymbolTable_GetMode (record)) == SymbolTable_LeftValue)
    8659              :             {
    8660        46810 :               ptr = m2expr_BuildComponentRef (location, m2expr_BuildIndirect (location, SymbolConversion_Mod2Gcc (record), SymbolConversion_Mod2Gcc (recordType)), SymbolConversion_Mod2Gcc (field));
    8661              :             }
    8662              :           else
    8663              :             {
    8664        91872 :               ptr = m2expr_BuildComponentRef (location, SymbolConversion_Mod2Gcc (record), SymbolConversion_Mod2Gcc (field));
    8665              :             }
    8666       138682 :           SymbolConversion_AddModGcc (result, ptr);
    8667              :         }
    8668              :       else
    8669              :         {
    8670            0 :           M2Error_InternalError ((const char *) "symbol type should have been declared by now", 44);
    8671              :         }
    8672              :     }
    8673              :   else
    8674              :     {
    8675            0 :       M2Error_InternalError ((const char *) "not expecting this type of symbol", 33);
    8676              :     }
    8677       138682 : }
    8678              : 
    8679              : 
    8680              : /*
    8681              :    BuildHighFromChar -
    8682              : */
    8683              : 
    8684        51186 : static tree BuildHighFromChar (unsigned int operand)
    8685              : {
    8686        51186 :   location_t location;
    8687              : 
    8688        51186 :   location = M2LexBuf_TokenToLocation (SymbolTable_GetDeclaredMod (operand));
    8689        51186 :   if ((SymbolTable_IsConstString (operand)) && ((SymbolTable_IsConstStringM2nul (operand)) || (SymbolTable_IsConstStringCnul (operand))))
    8690              :     {
    8691        50118 :       return m2expr_GetCardinalOne (location);
    8692              :     }
    8693         1068 :   return m2expr_GetCardinalZero (location);
    8694              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8695              :   __builtin_unreachable ();
    8696              : }
    8697              : 
    8698              : 
    8699              : /*
    8700              :    SkipToArray -
    8701              : */
    8702              : 
    8703        20532 : static unsigned int SkipToArray (unsigned int operand, unsigned int dim)
    8704              : {
    8705        20532 :   unsigned int type;
    8706              : 
    8707        21180 :   while (dim > 1)
    8708              :     {
    8709          648 :       type = SymbolTable_SkipType (SymbolTable_GetType (operand));
    8710          648 :       if (SymbolTable_IsArray (type))
    8711              :         {
    8712          648 :           operand = type;
    8713              :         }
    8714          648 :       dim -= 1;
    8715              :     }
    8716        20532 :   return operand;
    8717              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8718              :   __builtin_unreachable ();
    8719              : }
    8720              : 
    8721              : 
    8722              : /*
    8723              :    BuildHighFromArray -
    8724              : */
    8725              : 
    8726        20532 : static tree BuildHighFromArray (unsigned int tokenno, unsigned int dim, unsigned int operand)
    8727              : {
    8728        20532 :   unsigned int Type;
    8729        20532 :   location_t location;
    8730              : 
    8731        20532 :   location = M2LexBuf_TokenToLocation (tokenno);
    8732        20532 :   Type = SymbolTable_SkipType (SymbolTable_GetType (SkipToArray (operand, dim)));
    8733        20532 :   return BuildHighFromStaticArray (location, Type);  /* dim,  */
    8734              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8735              :   __builtin_unreachable ();
    8736              : }
    8737              : 
    8738              : 
    8739              : /*
    8740              :    BuildHighFromSetArray -
    8741              : */
    8742              : 
    8743         3352 : static tree BuildHighFromSetArray (unsigned int tokenno, unsigned int settype)
    8744              : {
    8745         3352 :   location_t location;
    8746              : 
    8747         3352 :   location = M2LexBuf_TokenToLocation (tokenno);
    8748         3352 :   return BuildHighFromStaticArray (location, SymbolTable_GetSetArray (settype));
    8749              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8750              :   __builtin_unreachable ();
    8751              : }
    8752              : 
    8753              : 
    8754              : /*
    8755              :    BuildHighFromStaticArray -
    8756              : */
    8757              : 
    8758        23884 : static tree BuildHighFromStaticArray (location_t location, unsigned int Type)
    8759              : {
    8760        23884 :   unsigned int High;
    8761        23884 :   unsigned int Low;
    8762        23884 :   unsigned int Subscript;
    8763        23884 :   unsigned int Subrange;
    8764              : 
    8765        23884 :   M2Debug_Assert (SymbolTable_IsArray (Type));  /* dim,  */
    8766        23884 :   Subscript = SymbolTable_GetArraySubscript (Type);
    8767        23884 :   Subrange = SymbolTable_SkipType (SymbolTable_GetType (Subscript));
    8768        23884 :   if (SymbolTable_IsEnumeration (Subrange))
    8769              :     {
    8770              :       /* avoid dangling else.  */
    8771           96 :       M2Base_GetBaseTypeMinMax (Subrange, &Low, &High);
    8772           96 :       if (SymbolConversion_GccKnowsAbout (High))
    8773              :         {
    8774           96 :           return (tree) (SymbolConversion_Mod2Gcc (High));
    8775              :         }
    8776              :     }
    8777        23788 :   else if (SymbolTable_IsSubrange (Subrange))
    8778              :     {
    8779              :       /* avoid dangling else.  */
    8780        23788 :       SymbolTable_GetSubrange (Subrange, &High, &Low);
    8781        23788 :       if ((SymbolConversion_GccKnowsAbout (Low)) && (SymbolConversion_GccKnowsAbout (High)))
    8782              :         {
    8783        23788 :           return m2expr_BuildSub (location, SymbolConversion_Mod2Gcc (High), SymbolConversion_Mod2Gcc (Low), true);
    8784              :         }
    8785              :     }
    8786              :   else
    8787              :     {
    8788              :       /* avoid dangling else.  */
    8789            0 :       M2MetaError_MetaError1 ((const char *) "array subscript {%1EDad:for} must be a subrange or enumeration type", 67, Type);
    8790            0 :       return (tree) (NULL);
    8791              :     }
    8792            0 :   if (SymbolConversion_GccKnowsAbout (High))
    8793              :     {
    8794            0 :       return (tree) (SymbolConversion_Mod2Gcc (High));
    8795              :     }
    8796              :   else
    8797              :     {
    8798              :       return (tree) (NULL);
    8799              :     }
    8800              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8801              :   __builtin_unreachable ();
    8802              : }
    8803              : 
    8804              : 
    8805              : /*
    8806              :    BuildHighFromString -
    8807              : */
    8808              : 
    8809       898170 : static tree BuildHighFromString (unsigned int operand)
    8810              : {
    8811       898170 :   location_t location;
    8812              : 
    8813       898170 :   location = M2LexBuf_TokenToLocation (SymbolTable_GetDeclaredMod (operand));
    8814       898170 :   if ((SymbolConversion_GccKnowsAbout (operand)) && ((m2expr_StringLength (SymbolConversion_Mod2Gcc (operand))) > 0))
    8815              :     {
    8816       898170 :       return m2decl_BuildIntegerConstant (static_cast<int> ((m2expr_StringLength (SymbolConversion_Mod2Gcc (operand)))-1));
    8817              :     }
    8818              :   else
    8819              :     {
    8820            0 :       return m2expr_GetIntegerZero (location);
    8821              :     }
    8822              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8823              :   __builtin_unreachable ();
    8824              : }
    8825              : 
    8826              : 
    8827              : /*
    8828              :    ResolveHigh - given an Modula-2 operand, it resolves the HIGH(operand)
    8829              :                  and returns a GCC constant symbol containing the value of
    8830              :                  HIGH(operand).
    8831              : */
    8832              : 
    8833       980622 : static tree ResolveHigh (unsigned int tokenno, unsigned int dim, unsigned int operand)
    8834              : {
    8835       980622 :   unsigned int Type;
    8836       980622 :   location_t location;
    8837              : 
    8838       980622 :   Type = SymbolTable_SkipType (SymbolTable_GetType (operand));
    8839       980622 :   location = M2LexBuf_TokenToLocation (tokenno);
    8840       980622 :   if ((Type == M2Base_Char) && (dim == 1))
    8841              :     {
    8842        51186 :       return BuildHighFromChar (operand);
    8843              :     }
    8844       929436 :   else if ((SymbolTable_IsConstString (operand)) && (dim == 1))
    8845              :     {
    8846              :       /* avoid dangling else.  */
    8847       898170 :       return BuildHighFromString (operand);
    8848              :     }
    8849        31266 :   else if (SymbolTable_IsArray (Type))
    8850              :     {
    8851              :       /* avoid dangling else.  */
    8852        20532 :       return BuildHighFromArray (tokenno, dim, operand);
    8853              :     }
    8854        10734 :   else if (SymbolTable_IsSet (Type))
    8855              :     {
    8856              :       /* avoid dangling else.  */
    8857         3352 :       return BuildHighFromSetArray (tokenno, Type);
    8858              :     }
    8859         7382 :   else if (SymbolTable_IsUnbounded (Type))
    8860              :     {
    8861              :       /* avoid dangling else.  */
    8862         7382 :       return M2GenGCC_GetHighFromUnbounded (location, dim, operand);
    8863              :     }
    8864              :   else
    8865              :     {
    8866              :       /* avoid dangling else.  */
    8867            0 :       M2MetaError_MetaErrorT1 (tokenno, (const char *) "base procedure HIGH expects a variable of type array or a constant string or CHAR as its parameter, rather than {%1Etad}", 120, operand);
    8868            0 :       return m2expr_GetIntegerZero (location);
    8869              :     }
    8870              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8871              :   __builtin_unreachable ();
    8872              : }
    8873              : 
    8874              : 
    8875              : /*
    8876              :    IsUnboundedArray - return TRUE if symbol is an unbounded array.
    8877              : */
    8878              : 
    8879      1227993 : static bool IsUnboundedArray (unsigned int sym)
    8880              : {
    8881      1227993 :   if ((SymbolTable_IsParameter (sym)) || (SymbolTable_IsVar (sym)))
    8882              :     {
    8883       302188 :       return SymbolTable_IsUnbounded (SymbolTable_GetType (sym));
    8884              :     }
    8885              :   return false;
    8886              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8887              :   __builtin_unreachable ();
    8888              : }
    8889              : 
    8890              : 
    8891              : /*
    8892              :    FoldHigh - if the array is not dynamic then we should be able to
    8893              :               remove the HighOp quadruple and assign op1 with
    8894              :               the known compile time HIGH(array).
    8895              : */
    8896              : 
    8897      1227993 : static void FoldHigh (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int dim, unsigned int array)
    8898              : {
    8899      1227993 :   tree t;
    8900      1227993 :   location_t location;
    8901              : 
    8902              :   /* Firstly ensure that any constant literal is declared.  */
    8903      1227993 :   M2GCCDeclare_TryDeclareConstant (tokenno, array);
    8904      1227993 :   location = M2LexBuf_TokenToLocation (tokenno);
    8905      1227993 :   if (((! (IsUnboundedArray (array))) && (SymbolConversion_GccKnowsAbout (array))) && (M2GCCDeclare_CompletelyResolved (array)))
    8906              :     {
    8907       938447 :       t = ResolveHigh (tokenno, dim, array);
    8908              :       /* We can take advantage of this and fold constants.  */
    8909       938447 :       if ((SymbolTable_IsConst (op1)) && (t != ((tree) (NULL))))
    8910              :         {
    8911          208 :           SymbolTable_PutConst (op1, M2Base_Cardinal);
    8912          208 :           SymbolConversion_AddModGcc (op1, m2decl_DeclareKnownConstant (location, m2type_GetCardinalType (), m2convert_ToCardinal (location, t)));
    8913          208 :           (*p.proc) (op1);
    8914          208 :           NoChange = false;
    8915          208 :           M2Quads_SubQuad (quad);
    8916              :         }
    8917              :       /* We can still fold the expression but not the assignment,
    8918              :             we will not do this here but in CodeHigh when the result
    8919              :             can be stored.  */
    8920              :     }
    8921      1227993 : }
    8922              : 
    8923              : 
    8924              : /*
    8925              :    CodeHigh - encode a unary arithmetic operation.
    8926              : */
    8927              : 
    8928        38823 : static void CodeHigh (unsigned int result, unsigned int dim, unsigned int array)
    8929              : {
    8930        38823 :   location_t location;
    8931              : 
    8932        38823 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    8933              :   /* Firstly ensure that any constant literal is declared.  */
    8934        38823 :   M2GCCDeclare_DeclareConstant (CurrentQuadToken, array);
    8935        38823 :   if (SymbolTable_IsConst (result))
    8936              :     {
    8937              :       /* Still have a constant which was not resolved, pass it to gcc.  */
    8938           24 :       M2GCCDeclare_ConstantKnownAndUsed (result, m2decl_DeclareKnownConstant (location, m2type_GetM2ZType (), ResolveHigh (CurrentQuadToken, dim, array)));
    8939              :     }
    8940              :   else
    8941              :     {
    8942        38799 :       m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (result), m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (SymbolTable_GetType (result)), ResolveHigh (CurrentQuadToken, dim, array), false));
    8943              :     }
    8944        38823 : }
    8945              : 
    8946              : 
    8947              : /*
    8948              :    CodeUnbounded - codes the creation of an unbounded parameter variable.
    8949              :                    result = &array.  array can be an lvalue or rvalue.
    8950              : */
    8951              : 
    8952        33615 : static void CodeUnbounded (unsigned int result, unsigned int array)
    8953              : {
    8954        33615 :   tree Addr;
    8955        33615 :   location_t location;
    8956              : 
    8957        33615 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    8958        33615 :   M2GCCDeclare_DeclareConstant (CurrentQuadToken, array);
    8959        33615 :   if ((SymbolTable_IsConstString (array)) || ((SymbolTable_IsConst (array)) && ((SymbolTable_GetSType (array)) == M2Base_Char)))
    8960              :     {
    8961        24745 :       m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (result), m2expr_BuildAddr (location, M2GCCDeclare_PromoteToString (CurrentQuadToken, array), false));
    8962              :     }
    8963         8870 :   else if (SymbolTable_IsConstructor (array))
    8964              :     {
    8965              :       /* avoid dangling else.  */
    8966           12 :       m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (result), m2expr_BuildAddr (location, SymbolConversion_Mod2Gcc (array), true));
    8967              :     }
    8968         8858 :   else if (SymbolTable_IsUnbounded (SymbolTable_GetType (array)))
    8969              :     {
    8970              :       /* avoid dangling else.  */
    8971         4230 :       if ((SymbolTable_GetMode (array)) == SymbolTable_LeftValue)
    8972              :         {
    8973              :           /* We already have the address of the array, convert it to type of result.  */
    8974            0 :           Addr = m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (SymbolTable_GetType (result)), SymbolConversion_Mod2Gcc (array), false);
    8975              :         }
    8976              :       else
    8977              :         {
    8978              :           /* Access the address field from the unbounded record.  */
    8979         4230 :           Addr = m2expr_BuildComponentRef (location, SymbolConversion_Mod2Gcc (array), SymbolConversion_Mod2Gcc (SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetType (array))));
    8980              :         }
    8981              :       /* Store address in result.  */
    8982         4230 :       m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (result), Addr);
    8983              :     }
    8984         4628 :   else if ((SymbolTable_GetMode (array)) == SymbolTable_RightValue)
    8985              :     {
    8986              :       /* avoid dangling else.  */
    8987              :       /* Static array, get the address and store into result.  */
    8988         4574 :       m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (result), m2expr_BuildAddr (location, SymbolConversion_Mod2Gcc (array), false));
    8989              :     }
    8990              :   else
    8991              :     {
    8992              :       /* avoid dangling else.  */
    8993              :       /* Static array which is a left value, just copy the address into result.  */
    8994           54 :       m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (result), SymbolConversion_Mod2Gcc (array));
    8995              :     }
    8996        33615 : }
    8997              : 
    8998              : 
    8999              : /*
    9000              :    AreSubrangesKnown - returns TRUE if the subranges values used within, array, are known.
    9001              : */
    9002              : 
    9003        46734 : static bool AreSubrangesKnown (unsigned int array)
    9004              : {
    9005        46734 :   unsigned int type;
    9006        46734 :   unsigned int subscript;
    9007        46734 :   unsigned int low;
    9008        46734 :   unsigned int high;
    9009              : 
    9010        46734 :   if (SymbolConversion_GccKnowsAbout (array))
    9011              :     {
    9012        46734 :       subscript = SymbolTable_GetArraySubscript (array);
    9013        46734 :       if (subscript == SymbolTable_NulSym)
    9014              :         {
    9015            0 :           M2Error_InternalError ((const char *) "not expecting a NulSym as a subscript", 37);
    9016              :         }
    9017              :       else
    9018              :         {
    9019        46734 :           type = SymbolTable_SkipType (SymbolTable_GetType (subscript));
    9020        46734 :           low = M2GCCDeclare_GetTypeMin (type);
    9021        46734 :           high = M2GCCDeclare_GetTypeMax (type);
    9022        46734 :           return (SymbolConversion_GccKnowsAbout (low)) && (SymbolConversion_GccKnowsAbout (high));
    9023              :         }
    9024              :     }
    9025              :   else
    9026              :     {
    9027              :       return false;
    9028              :     }
    9029              :   ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2GenGCC.def", 20, 1);
    9030              :   __builtin_unreachable ();
    9031              : }
    9032              : 
    9033              : 
    9034              : /*
    9035              :    CodeArray - res is an lvalue which will point to the array element.
    9036              : */
    9037              : 
    9038        46734 : static void CodeArray (unsigned int res, unsigned int index, unsigned int array)
    9039              : {
    9040        46734 :   unsigned int resType;
    9041        46734 :   unsigned int arrayDecl;
    9042        46734 :   unsigned int type;
    9043        46734 :   unsigned int low;
    9044        46734 :   unsigned int subscript;
    9045        46734 :   tree a;
    9046        46734 :   tree ta;
    9047        46734 :   tree ti;
    9048        46734 :   tree tl;
    9049        46734 :   location_t location;
    9050              : 
    9051        46734 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    9052        46734 :   arrayDecl = SymbolTable_SkipType (SymbolTable_GetType (array));
    9053        46734 :   if (AreSubrangesKnown (arrayDecl))
    9054              :     {
    9055        46734 :       subscript = SymbolTable_GetArraySubscript (arrayDecl);
    9056        46734 :       type = SymbolTable_SkipType (SymbolTable_GetType (subscript));
    9057        46734 :       low = M2GCCDeclare_GetTypeMin (type);
    9058        46734 :       resType = SymbolTable_GetVarBackEndType (res);
    9059        46734 :       if (resType == SymbolTable_NulSym)
    9060              :         {
    9061            0 :           resType = SymbolTable_SkipType (SymbolTable_GetType (res));
    9062              :         }
    9063        46734 :       ta = SymbolConversion_Mod2Gcc (SymbolTable_SkipType (SymbolTable_GetType (arrayDecl)));
    9064        46734 :       if ((SymbolTable_GetMode (array)) == SymbolTable_LeftValue)
    9065              :         {
    9066         1640 :           a = m2expr_BuildIndirect (location, SymbolConversion_Mod2Gcc (array), SymbolConversion_Mod2Gcc (SymbolTable_SkipType (SymbolTable_GetType (array))));
    9067              :         }
    9068              :       else
    9069              :         {
    9070        45094 :           a = SymbolConversion_Mod2Gcc (array);
    9071              :         }
    9072        46734 :       if (SymbolTable_IsArrayLarge (arrayDecl))
    9073              :         {
    9074           24 :           tl = m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (type), SymbolConversion_Mod2Gcc (low), false);
    9075           24 :           ti = m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (type), SymbolConversion_Mod2Gcc (index), false);
    9076           24 :           ti = m2convert_BuildConvert (location, m2type_GetIntegerType (), m2expr_BuildSub (location, ti, tl, false), false);
    9077           24 :           tl = m2expr_GetIntegerZero (location);
    9078              :         }
    9079              :       else
    9080              :         {
    9081        46710 :           tl = m2convert_BuildConvert (location, m2type_GetIntegerType (), SymbolConversion_Mod2Gcc (low), false);
    9082        46710 :           ti = m2convert_BuildConvert (location, m2type_GetIntegerType (), SymbolConversion_Mod2Gcc (index), false);
    9083              :         }
    9084              :       /* ti := BuildConvert(location, GetIntegerType(), Mod2Gcc(high), FALSE) ;  */
    9085        46734 :       m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (res), m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (resType), m2expr_BuildAddr (location, m2expr_BuildArray (location, ta, a, ti, tl), false), false));
    9086              :     }
    9087              :   else
    9088              :     {
    9089            0 :       M2Error_InternalError ((const char *) "subranges not yet resolved", 26);
    9090              :     }
    9091        46734 : }
    9092              : 
    9093              : 
    9094              : /*
    9095              :    FoldElementSizeForArray - attempts to calculate the Subscript
    9096              :                              multiplier for the index op3.
    9097              : */
    9098              : 
    9099            0 : static void FoldElementSizeForArray (unsigned int tokenno, unsigned int quad, M2GCCDeclare_WalkAction p, unsigned int result, unsigned int type)
    9100              : {
    9101            0 :   unsigned int Subscript;
    9102            0 :   location_t location;
    9103              : 
    9104            0 :   location = M2LexBuf_TokenToLocation (tokenno);
    9105            0 :   if ((SymbolTable_IsConst (result)) && (! (SymbolConversion_GccKnowsAbout (result))))
    9106              :     {
    9107            0 :       Subscript = SymbolTable_GetArraySubscript (type);
    9108            0 :       if (SymbolTable_IsSizeSolved (Subscript))
    9109              :         {
    9110            0 :           SymbolTable_PutConst (result, M2Base_Integer);
    9111            0 :           SymbolTable_PushSize (Subscript);
    9112            0 :           SymbolConversion_AddModGcc (result, m2decl_DeclareKnownConstant (location, m2type_GetCardinalType (), m2convert_BuildConvert (location, m2type_GetCardinalType (), M2ALU_PopIntegerTree (), true)));
    9113            0 :           (*p.proc) (result);
    9114            0 :           NoChange = false;
    9115            0 :           M2Quads_SubQuad (quad);
    9116              :         }
    9117              :     }
    9118            0 : }
    9119              : 
    9120              : 
    9121              : /*
    9122              :    FoldElementSizeForUnbounded - Unbounded arrays only have one index,
    9123              :                                  therefore element size will be the
    9124              :                                  TSIZE(Type) where Type is defined as:
    9125              :                                  ARRAY OF Type.
    9126              : */
    9127              : 
    9128        10048 : static void FoldElementSizeForUnbounded (unsigned int tokenno, unsigned int quad, M2GCCDeclare_WalkAction p, unsigned int result, unsigned int ArrayType)
    9129              : {
    9130        10048 :   unsigned int Type;
    9131        10048 :   location_t location;
    9132              : 
    9133        10048 :   location = M2LexBuf_TokenToLocation (tokenno);
    9134        10048 :   if (SymbolTable_IsConst (result))
    9135              :     {
    9136              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    9137        10048 :       if (SymbolConversion_GccKnowsAbout (result))
    9138              :         {
    9139            0 :           M2Error_InternalError ((const char *) "cannot assign a value twice to a constant", 41);
    9140              :         }
    9141              :       else
    9142              :         {
    9143        10048 :           M2Debug_Assert (SymbolTable_IsUnbounded (ArrayType));
    9144        10048 :           Type = SymbolTable_GetType (ArrayType);
    9145        10048 :           if (SymbolConversion_GccKnowsAbout (Type))
    9146              :             {
    9147        10048 :               SymbolTable_PutConst (result, M2Base_Cardinal);
    9148        10048 :               SymbolConversion_AddModGcc (result, m2decl_DeclareKnownConstant (location, m2type_GetCardinalType (), m2convert_BuildConvert (location, m2type_GetCardinalType (), FindSize (tokenno, Type), true)));
    9149        10048 :               (*p.proc) (result);
    9150        10048 :               NoChange = false;
    9151        10048 :               M2Quads_SubQuad (quad);
    9152              :             }
    9153              :         }
    9154              :     }
    9155        10048 : }
    9156              : 
    9157              : 
    9158              : /*
    9159              :    FoldElementSize - folds the element size for an ArraySym or UnboundedSym.
    9160              :                      ElementSize returns a constant which defines the
    9161              :                      multiplier to be multiplied by this element index.
    9162              : */
    9163              : 
    9164        10048 : static void FoldElementSize (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int result, unsigned int type)
    9165              : {
    9166        10048 :   if (SymbolTable_IsUnbounded (type))
    9167              :     {
    9168        10048 :       FoldElementSizeForUnbounded (tokenno, quad, p, result, type);
    9169              :     }
    9170            0 :   else if (SymbolTable_IsArray (type))
    9171              :     {
    9172              :       /* avoid dangling else.  */
    9173            0 :       FoldElementSizeForArray (tokenno, quad, p, result, type);
    9174              :     }
    9175              :   else
    9176              :     {
    9177              :       /* avoid dangling else.  */
    9178            0 :       M2Error_InternalError ((const char *) "expecting UnboundedSym or ArraySym", 34);
    9179              :     }
    9180        10048 : }
    9181              : 
    9182              : 
    9183              : /*
    9184              :    PopKindTree - returns a Tree from M2ALU of the type implied by, op.
    9185              : */
    9186              : 
    9187        20172 : static tree PopKindTree (unsigned int op, unsigned int tokenno)
    9188              : {
    9189        20172 :   unsigned int type;
    9190              : 
    9191        20172 :   if ((SymbolTable_IsConst (op)) && (SymbolTable_IsConstString (op)))
    9192              :     {
    9193              :       /* Converting a nul char or char for example.  */
    9194         1832 :       return M2ALU_PopIntegerTree ();
    9195              :     }
    9196              :   else
    9197              :     {
    9198        18340 :       type = SymbolTable_SkipType (SymbolTable_GetType (op));
    9199        18340 :       if (SymbolTable_IsSet (type))
    9200              :         {
    9201            0 :           return M2ALU_PopSetTree (tokenno);
    9202              :         }
    9203        18340 :       else if (M2Base_IsRealType (type))
    9204              :         {
    9205              :           /* avoid dangling else.  */
    9206           66 :           return M2ALU_PopRealTree ();
    9207              :         }
    9208              :       else
    9209              :         {
    9210              :           /* avoid dangling else.  */
    9211        18274 :           return M2ALU_PopIntegerTree ();
    9212              :         }
    9213              :     }
    9214              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    9215              :   __builtin_unreachable ();
    9216              : }
    9217              : 
    9218              : 
    9219              : /*
    9220              :    FoldConvert - attempts to fold expr to type into result
    9221              :                  providing that result and expr are constants.
    9222              :                  If required convert will alter the machine representation
    9223              :                  of expr to comply with type.
    9224              : */
    9225              : 
    9226       360284 : static void FoldConvert (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int result, unsigned int type, unsigned int expr)
    9227              : {
    9228       360284 :   tree tl;
    9229       360284 :   location_t location;
    9230              : 
    9231       360284 :   location = M2LexBuf_TokenToLocation (tokenno);
    9232              :   /* First ensure that constant literals are declared.  */
    9233       360284 :   M2GCCDeclare_TryDeclareConstant (tokenno, expr);
    9234       360284 :   if (IsConstant (expr))
    9235              :     {
    9236       202408 :       if (((SymbolConversion_GccKnowsAbout (type)) && ((SymbolTable_IsProcedure (expr)) || (SymbolTable_IsValueSolved (expr)))) && (SymbolConversion_GccKnowsAbout (SymbolTable_SkipType (type))))
    9237              :         {
    9238              :           /* The type is known and expr is resolved so fold the convert.  */
    9239       197038 :           if (SymbolTable_IsConst (result))
    9240              :             {
    9241         6828 :               SymbolTable_PutConst (result, type);  /* Change result type just in case.  */
    9242         6828 :               tl = SymbolConversion_Mod2Gcc (SymbolTable_SkipType (type));  /* Change result type just in case.  */
    9243         6828 :               if (SymbolTable_IsProcedure (expr))
    9244              :                 {
    9245            0 :                   SymbolConversion_AddModGcc (result, m2convert_BuildConvert (location, tl, SymbolConversion_Mod2Gcc (expr), true));
    9246              :                 }
    9247              :               else
    9248              :                 {
    9249         6828 :                   SymbolTable_PushValue (expr);
    9250         6828 :                   if (SymbolTable_IsConstSet (expr))
    9251              :                     {
    9252           84 :                       if (SymbolTable_IsSet (SymbolTable_SkipType (type)))
    9253              :                         {
    9254            0 :                           M2Error_WriteFormat0 ((const char *) "cannot convert values between sets", 34);
    9255              :                         }
    9256              :                       else
    9257              :                         {
    9258           84 :                           M2ALU_PushIntegerTree (m2expr_FoldAndStrip (m2convert_BuildConvert (location, tl, M2ALU_PopSetTree (tokenno), true)));
    9259           84 :                           SymbolTable_PopValue (result);
    9260           84 :                           SymbolTable_PushValue (result);
    9261           84 :                           SymbolConversion_AddModGcc (result, M2ALU_PopIntegerTree ());
    9262              :                         }
    9263              :                     }
    9264              :                   else
    9265              :                     {
    9266         6744 :                       if (SymbolTable_IsSet (SymbolTable_SkipType (type)))
    9267              :                         {
    9268            0 :                           M2ALU_PushSetTree (tokenno, m2expr_FoldAndStrip (m2convert_BuildConvert (location, tl, PopKindTree (expr, tokenno), true)), SymbolTable_SkipType (type));
    9269            0 :                           SymbolTable_PopValue (result);
    9270            0 :                           SymbolTable_PutConstSet (result);
    9271            0 :                           SymbolTable_PushValue (result);
    9272            0 :                           SymbolConversion_AddModGcc (result, M2ALU_PopSetTree (tokenno));
    9273              :                         }
    9274         6744 :                       else if (M2Base_IsRealType (SymbolTable_SkipType (type)))
    9275              :                         {
    9276              :                           /* avoid dangling else.  */
    9277           60 :                           M2ALU_PushRealTree (m2expr_FoldAndStrip (m2convert_BuildConvert (location, tl, PopKindTree (expr, tokenno), true)));
    9278           60 :                           SymbolTable_PopValue (result);
    9279           60 :                           SymbolTable_PushValue (result);
    9280           60 :                           SymbolConversion_AddModGcc (result, PopKindTree (result, tokenno));
    9281              :                         }
    9282              :                       else
    9283              :                         {
    9284              :                           /* avoid dangling else.  */
    9285              :                           /* Let CheckOverflow catch a potential overflow rather than BuildConvert.  */
    9286         6684 :                           M2ALU_PushIntegerTree (m2expr_FoldAndStrip (m2convert_BuildConvert (location, tl, PopKindTree (expr, tokenno), false)));
    9287         6684 :                           SymbolTable_PopValue (result);
    9288         6684 :                           SymbolTable_PushValue (result);
    9289         6684 :                           M2ALU_CheckOrResetOverflow (tokenno, PopKindTree (result, tokenno), M2Quads_MustCheckOverflow (quad));
    9290         6684 :                           SymbolTable_PushValue (result);
    9291         6684 :                           SymbolConversion_AddModGcc (result, PopKindTree (result, tokenno));
    9292              :                         }
    9293              :                     }
    9294              :                 }
    9295         6828 :               (*p.proc) (result);
    9296         6828 :               NoChange = false;
    9297         6828 :               M2Quads_SubQuad (quad);
    9298              :             }
    9299              :         }
    9300              :     }
    9301       360284 : }
    9302              : 
    9303              : 
    9304              : /*
    9305              :    CodeConvert - Converts, rhs, to, type, placing the result into lhs.
    9306              :                  Convert will, if need be, alter the machine representation
    9307              :                  of op3 to comply with TYPE op2.
    9308              : */
    9309              : 
    9310        51740 : static void CodeConvert (unsigned int quad, unsigned int lhs, unsigned int type, unsigned int rhs)
    9311              : {
    9312        51740 :   tree tl;
    9313        51740 :   tree tr;
    9314        51740 :   location_t location;
    9315              : 
    9316              :   /* Firstly ensure that constant literals are declared.  */
    9317        51740 :   M2GCCDeclare_DeclareConstant (CurrentQuadToken, rhs);
    9318        51740 :   M2GCCDeclare_DeclareConstructor (CurrentQuadToken, quad, rhs);
    9319        51740 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    9320        51740 :   tl = M2GenGCC_LValueToGenericPtr (location, type);
    9321        51740 :   if (SymbolTable_IsProcedure (rhs))
    9322              :     {
    9323        31764 :       tr = m2expr_BuildAddr (location, SymbolConversion_Mod2Gcc (rhs), false);
    9324              :     }
    9325              :   else
    9326              :     {
    9327        19976 :       tr = M2GenGCC_LValueToGenericPtr (location, rhs);
    9328        19976 :       tr = ConvertRHS (tr, type, rhs);
    9329              :     }
    9330        51740 :   if (SymbolTable_IsConst (lhs))
    9331              :     {
    9332              :       /* Fine, we can take advantage of this and fold constant.  */
    9333            0 :       SymbolTable_PutConst (lhs, type);
    9334            0 :       tl = SymbolConversion_Mod2Gcc (SymbolTable_SkipType (type));
    9335            0 :       M2GCCDeclare_ConstantKnownAndUsed (lhs, m2convert_BuildConvert (location, tl, SymbolConversion_Mod2Gcc (rhs), true));
    9336              :     }
    9337              :   else
    9338              :     {
    9339        51740 :       m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (lhs), m2convert_BuildConvert (location, tl, tr, true));
    9340              :     }
    9341        51740 : }
    9342              : 
    9343              : 
    9344              : /*
    9345              :    CodeCoerce - Coerce op3 to type op2 placing the result into
    9346              :                 op1.
    9347              :                 Coerce will NOT alter the machine representation
    9348              :                 of op3 to comply with TYPE op2.
    9349              :                 Therefore it _insists_ that under all circumstances that the
    9350              :                 type sizes of op1 and op3 are the same.
    9351              :                 CONVERT will perform machine manipulation to change variable
    9352              :                 types, coerce does no such thing.
    9353              : */
    9354              : 
    9355         1416 : static void CodeCoerce (unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    9356              : {
    9357         1416 :   location_t location;
    9358              : 
    9359         1416 :   M2GCCDeclare_DeclareConstant (CurrentQuadToken, op3);  /* checks to see whether it is a constant literal and declares it  */
    9360         1416 :   M2GCCDeclare_DeclareConstructor (CurrentQuadToken, quad, op3);  /* checks to see whether it is a constant literal and declares it  */
    9361         1416 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    9362         1416 :   if (SymbolTable_IsProcedure (op3))
    9363              :     {
    9364            0 :       if (m2expr_AreConstantsEqual (FindSize (CurrentQuadToken, op1), FindSize (CurrentQuadToken, M2System_Address)))
    9365              :         {
    9366            0 :           if (SymbolTable_IsConst (op1))
    9367              :             {
    9368            0 :               M2GCCDeclare_ConstantKnownAndUsed (op1, CheckConstant (CurrentQuadToken, op1, op3));
    9369              :             }
    9370              :           else
    9371              :             {
    9372            0 :               m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (op1), SymbolConversion_Mod2Gcc (op3));
    9373              :             }
    9374              :         }
    9375              :       else
    9376              :         {
    9377            0 :           M2MetaError_MetaErrorT0 (CurrentQuadToken, (const char *) "{%E}procedure address can only be stored in an address sized operand", 68);
    9378              :         }
    9379              :     }
    9380         1416 :   else if ((SymbolTable_IsConst (op3)) || (m2expr_AreConstantsEqual (FindSize (CurrentQuadToken, op1), FindSize (CurrentQuadToken, op3))))
    9381              :     {
    9382              :       /* avoid dangling else.  */
    9383         1416 :       if (SymbolTable_IsConst (op1))
    9384              :         {
    9385            0 :           M2GCCDeclare_ConstantKnownAndUsed (op1, m2decl_DeclareKnownConstant (location, SymbolConversion_Mod2Gcc (SymbolTable_GetType (op1)), SymbolConversion_Mod2Gcc (op3)));
    9386              :         }
    9387              :       else
    9388              :         {
    9389         1416 :           M2Debug_Assert (SymbolConversion_GccKnowsAbout (op2));
    9390         1416 :           if (SymbolTable_IsConst (op3))
    9391              :             {
    9392            0 :               m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (op1), SymbolConversion_Mod2Gcc (op3));
    9393              :             }
    9394              :           else
    9395              :             {
    9396              :               /* does not work t := BuildCoerce(Mod2Gcc(op1), Mod2Gcc(op2), Mod2Gcc(op3))  */
    9397         1416 :               checkDeclare (op1);
    9398         1416 :               m2type_AddStatement (location, MaybeDebugBuiltinMemcpy (location, m2expr_BuildAddr (location, SymbolConversion_Mod2Gcc (op1), false), m2expr_BuildAddr (location, SymbolConversion_Mod2Gcc (op3), false), FindSize (CurrentQuadToken, op2)));
    9399              :             }
    9400              :         }
    9401              :     }
    9402              :   else
    9403              :     {
    9404              :       /* avoid dangling else.  */
    9405            0 :       M2MetaError_MetaErrorT0 (CurrentQuadToken, (const char *) "can only {%kCAST} objects of the same size", 42);
    9406              :     }
    9407         1416 : }
    9408              : 
    9409              : 
    9410              : /*
    9411              :    FoldCoerce -
    9412              : */
    9413              : 
    9414        11030 : static void FoldCoerce (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    9415              : {
    9416        11030 :   location_t location;
    9417              : 
    9418        11030 :   M2GCCDeclare_TryDeclareConstant (tokenno, op3);  /* checks to see whether it is a constant literal and declares it  */
    9419        11030 :   location = M2LexBuf_TokenToLocation (tokenno);  /* checks to see whether it is a constant literal and declares it  */
    9420        11030 :   if ((SymbolConversion_GccKnowsAbout (op2)) && (SymbolConversion_GccKnowsAbout (op3)))
    9421              :     {
    9422              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    9423         2178 :       if (SymbolTable_IsProcedure (op3))
    9424              :         {
    9425            0 :           if (m2expr_AreConstantsEqual (FindSize (tokenno, op1), FindSize (tokenno, M2System_Address)))
    9426              :             {
    9427              :               /* avoid dangling else.  */
    9428            0 :               if (SymbolTable_IsConst (op1))
    9429              :                 {
    9430            0 :                   SymbolConversion_AddModGcc (op1, m2decl_DeclareKnownConstant (location, SymbolConversion_Mod2Gcc (SymbolTable_GetType (op1)), SymbolConversion_Mod2Gcc (op3)));
    9431            0 :                   (*p.proc) (op1);
    9432            0 :                   NoChange = false;
    9433            0 :                   M2Quads_SubQuad (quad);
    9434              :                 }
    9435              :             }
    9436              :           else
    9437              :             {
    9438            0 :               M2MetaError_MetaErrorT0 (CurrentQuadToken, (const char *) "{%E}procedure address can only be stored in a address sized operand", 67);
    9439              :             }
    9440              :         }
    9441         2178 :       else if (SymbolTable_IsConst (op3))
    9442              :         {
    9443              :           /* avoid dangling else.  */
    9444         1248 :           if (SymbolTable_IsConst (op1))
    9445              :             {
    9446         1248 :               SymbolConversion_AddModGcc (op1, m2decl_DeclareKnownConstant (location, SymbolConversion_Mod2Gcc (SymbolTable_GetType (op1)), SymbolConversion_Mod2Gcc (op3)));
    9447         1248 :               (*p.proc) (op1);
    9448         1248 :               NoChange = false;
    9449         1248 :               M2Quads_SubQuad (quad);
    9450              :             }
    9451              :         }
    9452              :     }
    9453        11030 : }
    9454              : 
    9455              : 
    9456              : /*
    9457              :    CanConvert - returns TRUE if we can convert variable, var, to a, type.
    9458              : */
    9459              : 
    9460            0 : static bool CanConvert (unsigned int type, unsigned int var)
    9461              : {
    9462            0 :   unsigned int svar;
    9463            0 :   unsigned int stype;
    9464              : 
    9465            0 :   stype = SymbolTable_SkipType (type);
    9466            0 :   svar = SymbolTable_SkipType (SymbolTable_GetType (var));
    9467            0 :   return (((M2Base_IsBaseType (stype)) || (M2Base_IsOrdinalType (stype))) || (M2System_IsSystemType (stype))) && (((M2Base_IsBaseType (svar)) || (M2Base_IsOrdinalType (svar))) || (M2System_IsSystemType (stype)));
    9468              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    9469              :   __builtin_unreachable ();
    9470              : }
    9471              : 
    9472              : 
    9473              : /*
    9474              :    CodeCast - Cast op3 to type op2 placing the result into op1.
    9475              :               Cast will NOT alter the machine representation
    9476              :               of op3 to comply with TYPE op2 as long as SIZE(op3)=SIZE(op2).
    9477              :               If the sizes differ then Convert is called.
    9478              : */
    9479              : 
    9480          126 : static void CodeCast (unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    9481              : {
    9482          126 :   location_t location;
    9483              : 
    9484          126 :   M2GCCDeclare_DeclareConstant (CurrentQuadToken, op3);  /* checks to see whether it is a constant literal and declares it  */
    9485          126 :   M2GCCDeclare_DeclareConstructor (CurrentQuadToken, quad, op3);  /* checks to see whether it is a constant literal and declares it  */
    9486          126 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    9487          126 :   if (SymbolTable_IsProcedure (op3))
    9488              :     {
    9489            0 :       if (m2expr_AreConstantsEqual (FindSize (CurrentQuadToken, op1), FindSize (CurrentQuadToken, M2System_Address)))
    9490              :         {
    9491            0 :           if (SymbolTable_IsConst (op1))
    9492              :             {
    9493            0 :               M2GCCDeclare_ConstantKnownAndUsed (op1, CheckConstant (CurrentQuadToken, op1, op3));
    9494              :             }
    9495              :           else
    9496              :             {
    9497            0 :               m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (op1), SymbolConversion_Mod2Gcc (op3));
    9498              :             }
    9499              :         }
    9500              :       else
    9501              :         {
    9502            0 :           M2MetaError_MetaErrorT0 (CurrentQuadToken, (const char *) "{%E}procedure address can only be stored in an address sized operand", 68);
    9503              :         }
    9504              :     }
    9505          126 :   else if ((SymbolTable_IsConst (op3)) || (m2expr_AreConstantsEqual (FindSize (CurrentQuadToken, op1), FindSize (CurrentQuadToken, op3))))
    9506              :     {
    9507              :       /* avoid dangling else.  */
    9508          108 :       CodeCoerce (quad, op1, op2, op3);
    9509              :     }
    9510              :   else
    9511              :     {
    9512              :       /* avoid dangling else.  */
    9513           18 :       if (M2Options_PedanticCast && (! (CanConvert (op2, op3))))
    9514              :         {
    9515            0 :           M2MetaError_MetaError2 ((const char *) "{%WkCAST} cannot copy a variable src {%2Dad} to a destination {%1Dad} as they are of different sizes and are not ordinal or real types", 134, op1, op3);
    9516              :         }
    9517           18 :       CodeConvert (quad, op1, op2, op3);
    9518              :     }
    9519          126 : }
    9520              : 
    9521         1500 : static void FoldCast (unsigned int tokenno, M2GCCDeclare_WalkAction p, unsigned int quad, unsigned int op1, unsigned int op2, unsigned int op3)
    9522              : {
    9523              :   /* 
    9524              :    FoldCoerce -
    9525              :   */
    9526         1500 :   M2GCCDeclare_TryDeclareConstant (tokenno, op3);  /* checks to see whether it is a constant literal and declares it  */
    9527         1500 :   if ((SymbolConversion_GccKnowsAbout (op2)) && (SymbolConversion_GccKnowsAbout (op3)))  /* checks to see whether it is a constant literal and declares it  */
    9528              :     {
    9529              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    9530          234 :       if (SymbolTable_IsProcedure (op3))
    9531              :         {
    9532            0 :           if (m2expr_AreConstantsEqual (FindSize (tokenno, op1), FindSize (tokenno, M2System_Address)))
    9533              :             {
    9534            0 :               FoldCoerce (tokenno, p, quad, op1, op2, op3);
    9535              :             }
    9536              :           else
    9537              :             {
    9538            0 :               M2MetaError_MetaErrorT0 (tokenno, (const char *) "{%E}procedure address can only be stored in an address sized operand", 68);
    9539              :             }
    9540              :         }
    9541          234 :       else if (SymbolTable_IsConst (op3))
    9542              :         {
    9543              :           /* avoid dangling else.  */
    9544            0 :           FoldCoerce (tokenno, p, quad, op1, op2, op3);
    9545              :         }
    9546              :     }
    9547         1500 : }
    9548              : 
    9549              : 
    9550              : /*
    9551              :    CreateLabelProcedureN - creates a label using procedure name and
    9552              :                            an integer.
    9553              : */
    9554              : 
    9555            0 : static DynamicStrings_String CreateLabelProcedureN (unsigned int proc, const char *leader_, unsigned int _leader_high, unsigned int unboundedCount, unsigned int n)
    9556              : {
    9557            0 :   DynamicStrings_String n1;
    9558            0 :   DynamicStrings_String n2;
    9559            0 :   char leader[_leader_high+1];
    9560              : 
    9561              :   /* make a local copy of each unbounded array.  */
    9562            0 :   memcpy (leader, leader_, _leader_high+1);
    9563              : 
    9564            0 :   n1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (proc))));
    9565            0 :   n2 = DynamicStrings_Mark (DynamicStrings_InitString ((const char *) leader, _leader_high));
    9566              :   /* prefixed by .L unboundedCount and n to ensure that no Modula-2 identifiers clash  */
    9567            0 :   return FormatStrings_Sprintf4 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ".L%d.%d.unbounded.%s.%s", 23)), (const unsigned char *) &unboundedCount, (sizeof (unboundedCount)-1), (const unsigned char *) &n, (sizeof (n)-1), (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
    9568              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    9569              :   __builtin_unreachable ();
    9570            0 : }
    9571              : 
    9572              : 
    9573              : /*
    9574              :    CreateLabelName - creates a namekey from quadruple, q.
    9575              : */
    9576              : 
    9577       223394 : static DynamicStrings_String CreateLabelName (unsigned int q)
    9578              : {
    9579              :   /* Prefixed by . to ensure that no Modula-2 identifiers clash  */
    9580       223394 :   return FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ".L%d", 4)), (const unsigned char *) &q, (sizeof (q)-1));
    9581              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    9582              :   __builtin_unreachable ();
    9583              : }
    9584              : 
    9585              : 
    9586              : /*
    9587              :    CodeGoto - creates a jump to a labeled quadruple.
    9588              : */
    9589              : 
    9590        44711 : static void CodeGoto (unsigned int destquad)
    9591              : {
    9592        44711 :   location_t location;
    9593              : 
    9594        44711 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    9595        44711 :   m2statement_BuildGoto (location, reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (destquad))));
    9596        44711 : }
    9597              : 
    9598              : 
    9599              : /*
    9600              :    CheckReferenced - checks to see whether this quadruple requires a label.
    9601              : */
    9602              : 
    9603      4167916 : static void CheckReferenced (unsigned int quad, M2Quads_QuadOperator op)
    9604              : {
    9605      4167916 :   location_t location;
    9606              : 
    9607      4167916 :   location = M2LexBuf_TokenToLocation (CurrentQuadToken);
    9608              :   /* We do not create labels for procedure entries.  */
    9609      4167916 :   if (((op != M2Quads_ProcedureScopeOp) && (op != M2Quads_NewLocalVarOp)) && (M2Quads_IsReferenced (quad)))
    9610              :     {
    9611       102178 :       m2statement_DeclareLabel (location, reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (quad))));
    9612              :     }
    9613      4167916 : }
    9614              : 
    9615              : 
    9616              : /*
    9617              :    CodeIfSetCondition - code IF left cond right then destquad for set types.
    9618              : */
    9619              : 
    9620           18 : static void CodeIfSetCondition (unsigned int tokenno, unsigned int left, unsigned int right, unsigned int destquad, M2GenGCC_BinaryFunction cond, NameKey_Name procedurename)
    9621              : {
    9622           18 :   unsigned int settype;
    9623           18 :   location_t location;
    9624           18 :   tree expr;
    9625              : 
    9626           18 :   location = M2LexBuf_TokenToLocation (tokenno);
    9627           18 :   if ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right)))
    9628              :     {
    9629            0 :       M2Error_InternalError ((const char *) "this should have been folded in the calling procedure", 53);
    9630              :     }
    9631           18 :   else if (SymbolTable_IsConst (left))
    9632              :     {
    9633              :       /* avoid dangling else.  */
    9634            0 :       settype = SymbolTable_SkipType (SymbolTable_GetType (right));
    9635              :     }
    9636              :   else
    9637              :     {
    9638              :       /* avoid dangling else.  */
    9639           18 :       settype = SymbolTable_SkipType (SymbolTable_GetType (left));
    9640              :     }
    9641           18 :   if (SymbolTable_GetSetInWord (settype))
    9642              :     {
    9643              :       /* WORD size sets.  */
    9644            0 :       expr = (*cond.proc) (location, m2convert_BuildConvert (location, m2type_GetWordType (), SymbolConversion_Mod2Gcc (left), false), m2convert_BuildConvert (location, m2type_GetWordType (), SymbolConversion_Mod2Gcc (right), false));
    9645              :     }
    9646              :   else
    9647              :     {
    9648           18 :       expr = CallSetWideBoolFunction (location, tokenno, procedurename, settype, left, right);
    9649              :     }
    9650           18 :   m2statement_IfExprJump (location, expr, reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (destquad))));
    9651           18 : }
    9652              : 
    9653              : 
    9654              : /*
    9655              :    CodeIfSetLess - code IF left < right then destquad for set types.
    9656              : */
    9657              : 
    9658            6 : static void CodeIfSetLess (unsigned int tokenno, unsigned int left, unsigned int right, unsigned int destquad)
    9659              : {
    9660            6 :   CodeIfSetCondition (tokenno, left, right, destquad, (M2GenGCC_BinaryFunction) {(M2GenGCC_BinaryFunction_t) m2expr_BuildIsSubset}, NameKey_MakeKey ((const char *) "Less", 4));
    9661            6 : }
    9662              : 
    9663              : 
    9664              : /*
    9665              :    CodeIfSetLessEqu - code IF left <= right then destquad for set types.
    9666              : */
    9667              : 
    9668            6 : static void CodeIfSetLessEqu (unsigned int tokenno, unsigned int left, unsigned int right, unsigned int destquad)
    9669              : {
    9670            6 :   CodeIfSetCondition (tokenno, left, right, destquad, (M2GenGCC_BinaryFunction) {(M2GenGCC_BinaryFunction_t) m2expr_BuildIsSubset}, NameKey_MakeKey ((const char *) "LessEqu", 7));
    9671            6 : }
    9672              : 
    9673              : 
    9674              : /*
    9675              :    CodeIfSetGre - code IF left > right then destquad for set types.
    9676              : */
    9677              : 
    9678            0 : static void CodeIfSetGre (unsigned int tokenno, unsigned int left, unsigned int right, unsigned int destquad)
    9679              : {
    9680            0 :   CodeIfSetCondition (tokenno, left, right, destquad, (M2GenGCC_BinaryFunction) {(M2GenGCC_BinaryFunction_t) m2expr_BuildIsNotSubset}, NameKey_MakeKey ((const char *) "Gre", 3));
    9681            0 : }
    9682              : 
    9683              : 
    9684              : /*
    9685              :    CodeIfSetGreEqu - code IF left >= right then destquad for set types.
    9686              : */
    9687              : 
    9688            6 : static void CodeIfSetGreEqu (unsigned int tokenno, unsigned int left, unsigned int right, unsigned int destquad)
    9689              : {
    9690            6 :   CodeIfSetCondition (tokenno, left, right, destquad, (M2GenGCC_BinaryFunction) {(M2GenGCC_BinaryFunction_t) m2expr_BuildIsNotSubset}, NameKey_MakeKey ((const char *) "GreEqu", 6));
    9691            6 : }
    9692              : 
    9693              : 
    9694              : /*
    9695              :    PerformCodeIfLess - codes the quadruple if op1 < op2 then goto op3
    9696              : */
    9697              : 
    9698         3826 : static void PerformCodeIfLess (unsigned int quad)
    9699              : {
    9700         3826 :   tree tl;
    9701         3826 :   tree tr;
    9702         3826 :   location_t location;
    9703         3826 :   unsigned int left;
    9704         3826 :   unsigned int right;
    9705         3826 :   unsigned int dest;
    9706         3826 :   unsigned int combined;
    9707         3826 :   unsigned int leftpos;
    9708         3826 :   unsigned int rightpos;
    9709         3826 :   unsigned int destpos;
    9710         3826 :   bool constExpr;
    9711         3826 :   bool overflow;
    9712         3826 :   M2Quads_QuadOperator op;
    9713              : 
    9714         3826 :   M2Quads_GetQuadOtok (quad, &combined, &op, &left, &right, &dest, &overflow, &constExpr, &leftpos, &rightpos, &destpos);
    9715         3826 :   location = M2LexBuf_TokenToLocation (combined);
    9716         3826 :   if ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right)))
    9717              :     {
    9718            0 :       SymbolTable_PushValue (left);
    9719            0 :       SymbolTable_PushValue (right);
    9720            0 :       if (M2ALU_Less (CurrentQuadToken))
    9721              :         {
    9722            0 :           m2statement_BuildGoto (location, reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (dest))));
    9723              :         }
    9724              :       /* Fall through.  */
    9725              :     }
    9726         3826 :   else if ((((SymbolTable_IsConstSet (left)) || ((SymbolTable_IsVar (left)) && (SymbolTable_IsSet (SymbolTable_SkipType (SymbolTable_GetType (left)))))) || (SymbolTable_IsConstSet (right))) || ((SymbolTable_IsVar (right)) && (SymbolTable_IsSet (SymbolTable_SkipType (SymbolTable_GetType (right))))))
    9727              :     {
    9728              :       /* avoid dangling else.  */
    9729            6 :       CodeIfSetLess (combined, left, right, dest);
    9730              :     }
    9731              :   else
    9732              :     {
    9733              :       /* avoid dangling else.  */
    9734         3820 :       if ((SymbolTable_IsComposite (SymbolTable_GetType (left))) || (SymbolTable_IsComposite (SymbolTable_GetType (right))))
    9735              :         {
    9736            0 :           M2MetaError_MetaErrorT2 (combined, (const char *) "comparison tests between composite types not allowed {%1Eatd} and {%2atd}", 73, left, right);
    9737              :         }
    9738              :       else
    9739              :         {
    9740         3820 :           ConvertBinaryOperands (location, &tl, &tr, ComparisonMixTypes (left, right, SymbolTable_SkipType (SymbolTable_GetType (left)), SymbolTable_SkipType (SymbolTable_GetType (right)), combined), left, right);
    9741         3820 :           m2statement_IfExprJump (location, m2expr_BuildLessThan (location, tl, tr), reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (dest))));
    9742              :         }
    9743              :     }
    9744         3826 : }
    9745              : 
    9746              : 
    9747              : /*
    9748              :    CodeIfLess - codes the quadruple if op1 < op2 then goto op3
    9749              : */
    9750              : 
    9751         3826 : static void CodeIfLess (unsigned int quad)
    9752              : {
    9753         3826 :   if (IsValidExpressionRelOp (quad, false))
    9754              :     {
    9755         3826 :       PerformCodeIfLess (quad);
    9756              :     }
    9757         3826 : }
    9758              : 
    9759              : 
    9760              : /*
    9761              :    CodeIfSetEquNarrow -
    9762              : */
    9763              : 
    9764          724 : static void CodeIfSetEquNarrow (location_t location, bool invertCondition, unsigned int settype, tree left, tree right, unsigned int destQuad)
    9765              : {
    9766          724 :   tree condition;
    9767          724 :   tree mask;
    9768              : 
    9769              :   /* The set type fits inside a word, so mask off any unused bits.  */
    9770          724 :   mask = m2expr_BuildMask (location, CalcBitsInSet (location, settype), false);
    9771          724 :   left = m2expr_BuildLogicalAnd (location, left, mask);
    9772          724 :   right = m2expr_BuildLogicalAnd (location, right, mask);
    9773          724 :   if (invertCondition)
    9774              :     {
    9775          360 :       condition = m2expr_BuildNotEqualTo (location, left, right);
    9776              :     }
    9777              :   else
    9778              :     {
    9779          364 :       condition = m2expr_BuildEqualTo (location, left, right);
    9780              :     }
    9781          724 :   m2statement_IfExprJump (location, condition, reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (destQuad))));
    9782          724 : }
    9783              : 
    9784              : 
    9785              : /*
    9786              :    CallSetWideBoolFunction - return a tree containing a call to
    9787              :                              M2WIDESET.widefuncname (left, right, HIGHBIT (settype)).
    9788              : */
    9789              : 
    9790          552 : static tree CallSetWideBoolFunction (location_t location, unsigned int tokenno, NameKey_Name widefuncname, unsigned int settype, unsigned int left, unsigned int right)
    9791              : {
    9792          552 :   unsigned int function;
    9793          552 :   unsigned int param1;
    9794          552 :   unsigned int param2;
    9795          552 :   tree highbit;
    9796          552 :   tree array1;
    9797          552 :   tree array2;
    9798          552 :   tree call;
    9799              : 
    9800          552 :   function = FromM2WIDESETImport (tokenno, widefuncname);
    9801          552 :   checkDeclare (function);
    9802          552 :   location = M2LexBuf_TokenToLocation (tokenno);
    9803          552 :   param1 = SymbolTable_GetNthParamAnyClosest (function, 1, SymbolTable_GetMainModule ());
    9804          552 :   param2 = SymbolTable_GetNthParamAnyClosest (function, 2, SymbolTable_GetMainModule ());
    9805          552 :   array1 = CreateSetArrayParam (location, tokenno, left, param1);
    9806          552 :   array2 = CreateSetArrayParam (location, tokenno, right, param2);
    9807          552 :   highbit = m2convert_ToCardinal (location, CalcHighSetBit (location, settype));
    9808          552 :   m2statement_BuildParam (location, highbit);  /* Parameter 3.  */
    9809          552 :   m2statement_BuildParam (location, array2);  /* Parameter 2.  */
    9810          552 :   m2statement_BuildParam (location, array1);  /* Parameter 1.  */
    9811          552 :   call = m2statement_BuildProcedureCallTree (location, SymbolConversion_Mod2Gcc (function), SymbolConversion_Mod2Gcc (SymbolTable_GetType (function)));  /* Parameter 1.  */
    9812          552 :   m2statement_SetLastFunction (NULL);
    9813          552 :   return call;
    9814              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    9815              :   __builtin_unreachable ();
    9816              : }
    9817              : 
    9818              : 
    9819              : /*
    9820              :    CodeIfSetEquWide - creates a statement tree:
    9821              :                       if left = right then goto destQuad.  The boolean
    9822              :                       invertCondition will check left # right.
    9823              : */
    9824              : 
    9825          534 : static void CodeIfSetEquWide (location_t location, unsigned int tokenno, bool invertCondition, unsigned int settype, unsigned int left, unsigned int right, unsigned int destQuad)
    9826              : {
    9827          534 :   tree call;
    9828          534 :   tree expr;
    9829          534 :   tree label;
    9830              : 
    9831          534 :   call = CallSetWideBoolFunction (location, tokenno, NameKey_MakeKey ((const char *) "Equal", 5), settype, left, right);
    9832          534 :   label = static_cast<tree> (CreateLabelName (destQuad));
    9833          534 :   if (invertCondition)
    9834              :     {
    9835          240 :       expr = m2expr_BuildEqualTo (location, call, m2type_GetBooleanFalse ());
    9836              :     }
    9837              :   else
    9838              :     {
    9839          294 :       expr = m2expr_BuildNotEqualTo (location, call, m2type_GetBooleanFalse ());
    9840              :     }
    9841          534 :   m2statement_IfExprJump (location, expr, reinterpret_cast <char * > (DynamicStrings_string (static_cast<DynamicStrings_String> (label))));
    9842          534 : }
    9843              : 
    9844              : 
    9845              : /*
    9846              :    CodeIfSetEquLower code a comparison between left and right and if true
    9847              :    jump to destQuad.  The invertCondition allows for the inverse test.
    9848              :    Note that if op1 and op2 are not both constants as this will have been
    9849              :    evaluated in CodeIfNotEqu.
    9850              : */
    9851              : 
    9852         1258 : static void CodeIfSetEquLower (unsigned int tokenno, bool invertCondition, unsigned int left, unsigned int right, unsigned int destQuad)
    9853              : {
    9854         1258 :   unsigned int settype;
    9855         1258 :   location_t location;
    9856              : 
    9857         1258 :   location = M2LexBuf_TokenToLocation (tokenno);
    9858         1258 :   if ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right)))
    9859              :     {
    9860            0 :       M2Error_InternalError ((const char *) "this should have been folded by CodeIfEqu or CodeIfNotEqu", 57);
    9861              :     }
    9862         1258 :   else if (SymbolTable_IsConst (left))
    9863              :     {
    9864              :       /* avoid dangling else.  */
    9865            0 :       settype = SymbolTable_GetLType (right);
    9866              :     }
    9867              :   else
    9868              :     {
    9869              :       /* avoid dangling else.  */
    9870         1258 :       settype = SymbolTable_GetLType (left);
    9871              :     }
    9872         1258 :   if ((SymbolTable_GetLType (left)) != (SymbolTable_GetLType (right)))
    9873              :     {
    9874              :       /* This test used to occur after the GetSetInWord (settype) condition.  */
    9875            0 :       M2MetaError_MetaErrorT2 (tokenno, (const char *) "set comparison is only allowed between the same set type, the set types used by {%1Eatd} and {%2atd} are different", 114, left, right);
    9876              :     }
    9877         1258 :   if (SymbolTable_GetSetInWord (settype))
    9878              :     {
    9879              :       /* Allow sets to be compared against { } for bitset.  */
    9880          724 :       CodeIfSetEquNarrow (location, invertCondition, settype, SymbolConversion_Mod2Gcc (left), SymbolConversion_Mod2Gcc (right), destQuad);
    9881              :     }
    9882              :   else
    9883              :     {
    9884          534 :       CodeIfSetEquWide (location, tokenno, invertCondition, settype, left, right, destQuad);
    9885              :     }
    9886         1258 : }
    9887              : 
    9888              : 
    9889              : /*
    9890              :    CodeIfSetNotEqu - codes if op1 # op2 then goto op3
    9891              : */
    9892              : 
    9893          600 : static void CodeIfSetNotEqu (unsigned int tokenno, unsigned int left, unsigned int right, unsigned int destQuad)
    9894              : {
    9895            0 :   CodeIfSetEquLower (tokenno, true, left, right, destQuad);
    9896          600 : }
    9897              : 
    9898              : 
    9899              : /*
    9900              :    CodeIfSetEqu - codes if op1 = op2 then goto op3
    9901              : */
    9902              : 
    9903          658 : static void CodeIfSetEqu (unsigned int tokenno, unsigned int left, unsigned int right, unsigned int destQuad)
    9904              : {
    9905            0 :   CodeIfSetEquLower (tokenno, false, left, right, destQuad);
    9906          658 : }
    9907              : 
    9908              : 
    9909              : /*
    9910              :    PerformCodeIfGre - codes the quadruple if op1 > op2 then goto op3
    9911              : */
    9912              : 
    9913         4606 : static void PerformCodeIfGre (unsigned int quad)
    9914              : {
    9915         4606 :   tree tl;
    9916         4606 :   tree tr;
    9917         4606 :   tree condition;
    9918         4606 :   location_t location;
    9919         4606 :   unsigned int left;
    9920         4606 :   unsigned int right;
    9921         4606 :   unsigned int dest;
    9922         4606 :   unsigned int combined;
    9923         4606 :   unsigned int leftpos;
    9924         4606 :   unsigned int rightpos;
    9925         4606 :   unsigned int destpos;
    9926         4606 :   bool constExpr;
    9927         4606 :   bool overflow;
    9928         4606 :   M2Quads_QuadOperator op;
    9929              : 
    9930         4606 :   M2Quads_GetQuadOtok (quad, &combined, &op, &left, &right, &dest, &overflow, &constExpr, &leftpos, &rightpos, &destpos);
    9931         4606 :   location = M2LexBuf_TokenToLocation (combined);
    9932         4606 :   if ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right)))
    9933              :     {
    9934            0 :       SymbolTable_PushValue (left);
    9935            0 :       SymbolTable_PushValue (right);
    9936            0 :       if (M2ALU_Gre (combined))
    9937              :         {
    9938            0 :           m2statement_BuildGoto (location, reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (dest))));
    9939              :         }
    9940              :       /* fall through  */
    9941              :     }
    9942         4606 :   else if ((((SymbolTable_IsConstSet (left)) || ((SymbolTable_IsVar (left)) && (SymbolTable_IsSet (SymbolTable_SkipType (SymbolTable_GetType (left)))))) || (SymbolTable_IsConstSet (right))) || ((SymbolTable_IsVar (right)) && (SymbolTable_IsSet (SymbolTable_SkipType (SymbolTable_GetType (right))))))
    9943              :     {
    9944              :       /* avoid dangling else.  */
    9945            0 :       CodeIfSetGre (combined, left, right, dest);
    9946              :     }
    9947              :   else
    9948              :     {
    9949              :       /* avoid dangling else.  */
    9950         4606 :       if ((SymbolTable_IsComposite (SymbolTable_GetType (left))) || (SymbolTable_IsComposite (SymbolTable_GetType (right))))
    9951              :         {
    9952            0 :           M2MetaError_MetaErrorT2 (combined, (const char *) "comparison tests between composite types not allowed {%1Eatd} and {%2atd}", 73, left, right);
    9953              :         }
    9954              :       else
    9955              :         {
    9956         4606 :           ConvertBinaryOperands (location, &tl, &tr, ComparisonMixTypes (left, right, SymbolTable_SkipType (SymbolTable_GetType (left)), SymbolTable_SkipType (SymbolTable_GetType (right)), combined), left, right);
    9957         4606 :           condition = m2expr_BuildGreaterThan (location, tl, tr);
    9958         4606 :           m2statement_IfExprJump (location, condition, reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (dest))));
    9959              :         }
    9960              :     }
    9961         4606 : }
    9962              : 
    9963              : 
    9964              : /*
    9965              :    CodeIfGre - codes the quadruple if op1 > op2 then goto op3
    9966              : */
    9967              : 
    9968         4606 : static void CodeIfGre (unsigned int quad)
    9969              : {
    9970         4606 :   if (IsValidExpressionRelOp (quad, false))
    9971              :     {
    9972         4606 :       PerformCodeIfGre (quad);
    9973              :     }
    9974         4606 : }
    9975              : 
    9976              : 
    9977              : /*
    9978              :    PerformCodeIfLessEqu - codes the quadruple if op1 <= op2 then goto op3
    9979              : */
    9980              : 
    9981         5754 : static void PerformCodeIfLessEqu (unsigned int quad)
    9982              : {
    9983         5754 :   tree tl;
    9984         5754 :   tree tr;
    9985         5754 :   tree condition;
    9986         5754 :   location_t location;
    9987         5754 :   unsigned int left;
    9988         5754 :   unsigned int right;
    9989         5754 :   unsigned int dest;
    9990         5754 :   unsigned int combined;
    9991         5754 :   unsigned int leftpos;
    9992         5754 :   unsigned int rightpos;
    9993         5754 :   unsigned int destpos;
    9994         5754 :   bool constExpr;
    9995         5754 :   bool overflow;
    9996         5754 :   M2Quads_QuadOperator op;
    9997              : 
    9998         5754 :   M2Quads_GetQuadOtok (quad, &combined, &op, &left, &right, &dest, &overflow, &constExpr, &leftpos, &rightpos, &destpos);
    9999         5754 :   location = M2LexBuf_TokenToLocation (combined);
   10000         5754 :   if ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right)))
   10001              :     {
   10002            0 :       SymbolTable_PushValue (left);
   10003            0 :       SymbolTable_PushValue (right);
   10004            0 :       if (M2ALU_LessEqu (combined))
   10005              :         {
   10006            0 :           m2statement_BuildGoto (location, reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (dest))));
   10007              :         }
   10008              :       /* fall through  */
   10009              :     }
   10010         5754 :   else if ((((SymbolTable_IsConstSet (left)) || ((SymbolTable_IsVar (left)) && (SymbolTable_IsSet (SymbolTable_SkipType (SymbolTable_GetType (left)))))) || (SymbolTable_IsConstSet (right))) || ((SymbolTable_IsVar (right)) && (SymbolTable_IsSet (SymbolTable_SkipType (SymbolTable_GetType (right))))))
   10011              :     {
   10012              :       /* avoid dangling else.  */
   10013            6 :       CodeIfSetLessEqu (combined, left, right, dest);
   10014              :     }
   10015              :   else
   10016              :     {
   10017              :       /* avoid dangling else.  */
   10018         5748 :       if ((SymbolTable_IsComposite (SymbolTable_GetType (left))) || (SymbolTable_IsComposite (SymbolTable_GetType (right))))
   10019              :         {
   10020            0 :           M2MetaError_MetaErrorT2 (combined, (const char *) "comparison tests between composite types not allowed {%1Eatd} and {%2atd}", 73, left, right);
   10021              :         }
   10022              :       else
   10023              :         {
   10024         5748 :           ConvertBinaryOperands (location, &tl, &tr, ComparisonMixTypes (left, right, SymbolTable_SkipType (SymbolTable_GetType (left)), SymbolTable_SkipType (SymbolTable_GetType (right)), combined), left, right);
   10025         5748 :           condition = m2expr_BuildLessThanOrEqual (location, tl, tr);
   10026         5748 :           m2statement_IfExprJump (location, condition, reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (dest))));
   10027              :         }
   10028              :     }
   10029         5754 : }
   10030              : 
   10031              : 
   10032              : /*
   10033              :    CodeIfLessEqu - codes the quadruple if op1 <= op2 then goto op3
   10034              : */
   10035              : 
   10036         5766 : static void CodeIfLessEqu (unsigned int quad)
   10037              : {
   10038         5766 :   if (IsValidExpressionRelOp (quad, false))
   10039              :     {
   10040         5754 :       PerformCodeIfLessEqu (quad);
   10041              :     }
   10042         5766 : }
   10043              : 
   10044              : 
   10045              : /*
   10046              :    PerformCodeIfGreEqu - codes the quadruple if op1 >= op2 then goto op3
   10047              : */
   10048              : 
   10049         7070 : static void PerformCodeIfGreEqu (unsigned int quad)
   10050              : {
   10051         7070 :   tree tl;
   10052         7070 :   tree tr;
   10053         7070 :   tree condition;
   10054         7070 :   location_t location;
   10055         7070 :   unsigned int left;
   10056         7070 :   unsigned int right;
   10057         7070 :   unsigned int dest;
   10058         7070 :   unsigned int combined;
   10059         7070 :   unsigned int leftpos;
   10060         7070 :   unsigned int rightpos;
   10061         7070 :   unsigned int destpos;
   10062         7070 :   bool constExpr;
   10063         7070 :   bool overflow;
   10064         7070 :   M2Quads_QuadOperator op;
   10065              : 
   10066         7070 :   M2Quads_GetQuadOtok (quad, &combined, &op, &left, &right, &dest, &overflow, &constExpr, &leftpos, &rightpos, &destpos);
   10067         7070 :   location = M2LexBuf_TokenToLocation (combined);
   10068         7070 :   if ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right)))
   10069              :     {
   10070            0 :       SymbolTable_PushValue (left);
   10071            0 :       SymbolTable_PushValue (right);
   10072            0 :       if (M2ALU_GreEqu (combined))
   10073              :         {
   10074            0 :           m2statement_BuildGoto (location, reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (dest))));
   10075              :         }
   10076              :       /* fall through  */
   10077              :     }
   10078         7070 :   else if ((((SymbolTable_IsConstSet (left)) || ((SymbolTable_IsVar (left)) && (SymbolTable_IsSet (SymbolTable_SkipType (SymbolTable_GetType (left)))))) || (SymbolTable_IsConstSet (right))) || ((SymbolTable_IsVar (right)) && (SymbolTable_IsSet (SymbolTable_SkipType (SymbolTable_GetType (right))))))
   10079              :     {
   10080              :       /* avoid dangling else.  */
   10081            6 :       CodeIfSetGreEqu (combined, left, right, dest);
   10082              :     }
   10083              :   else
   10084              :     {
   10085              :       /* avoid dangling else.  */
   10086         7064 :       if ((SymbolTable_IsComposite (SymbolTable_GetType (left))) || (SymbolTable_IsComposite (SymbolTable_GetType (right))))
   10087              :         {
   10088            0 :           M2MetaError_MetaErrorT2 (combined, (const char *) "comparison tests between composite types not allowed {%1Eatd} and {%2atd}", 73, left, right);
   10089              :         }
   10090              :       else
   10091              :         {
   10092         7064 :           ConvertBinaryOperands (location, &tl, &tr, ComparisonMixTypes (left, right, SymbolTable_SkipType (SymbolTable_GetType (left)), SymbolTable_SkipType (SymbolTable_GetType (right)), combined), left, right);
   10093         7064 :           condition = m2expr_BuildGreaterThanOrEqual (location, tl, tr);
   10094         7064 :           m2statement_IfExprJump (location, condition, reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (dest))));
   10095              :         }
   10096              :     }
   10097         7070 : }
   10098              : 
   10099              : 
   10100              : /*
   10101              :    CodeIfGreEqu - codes the quadruple if op1 >= op2 then goto op3
   10102              : */
   10103              : 
   10104         7076 : static void CodeIfGreEqu (unsigned int quad)
   10105              : {
   10106         7076 :   if (IsValidExpressionRelOp (quad, false))
   10107              :     {
   10108         7070 :       PerformCodeIfGreEqu (quad);
   10109              :     }
   10110         7076 : }
   10111              : 
   10112              : 
   10113              : /*
   10114              :    ComparisonMixTypes -
   10115              : */
   10116              : 
   10117        72699 : static unsigned int ComparisonMixTypes (unsigned int varleft, unsigned int varright, unsigned int left, unsigned int right, unsigned int tokpos)
   10118              : {
   10119        72699 :   if (M2System_IsGenericSystemType (left))
   10120              :     {
   10121              :       return left;
   10122              :     }
   10123        72385 :   else if (M2System_IsGenericSystemType (right))
   10124              :     {
   10125              :       /* avoid dangling else.  */
   10126              :       return right;
   10127              :     }
   10128              :   else
   10129              :     {
   10130              :       /* avoid dangling else.  */
   10131        72385 :       return M2Base_MixTypesDecl (varleft, varright, left, right, tokpos);
   10132              :     }
   10133              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   10134              :   __builtin_unreachable ();
   10135              : }
   10136              : 
   10137              : 
   10138              : /*
   10139              :    PerformCodeIfEqu -
   10140              : */
   10141              : 
   10142        20708 : static void PerformCodeIfEqu (unsigned int quad)
   10143              : {
   10144        20708 :   tree tl;
   10145        20708 :   tree tr;
   10146        20708 :   tree condition;
   10147        20708 :   location_t location;
   10148        20708 :   unsigned int left;
   10149        20708 :   unsigned int right;
   10150        20708 :   unsigned int dest;
   10151        20708 :   unsigned int combined;
   10152        20708 :   unsigned int leftpos;
   10153        20708 :   unsigned int rightpos;
   10154        20708 :   unsigned int destpos;
   10155        20708 :   bool constExpr;
   10156        20708 :   bool overflow;
   10157        20708 :   M2Quads_QuadOperator op;
   10158              : 
   10159        20708 :   M2Quads_GetQuadOtok (quad, &combined, &op, &left, &right, &dest, &overflow, &constExpr, &leftpos, &rightpos, &destpos);
   10160        20708 :   location = M2LexBuf_TokenToLocation (combined);
   10161        20708 :   if ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right)))
   10162              :     {
   10163            0 :       SymbolTable_PushValue (left);
   10164            0 :       SymbolTable_PushValue (right);
   10165            0 :       if (M2ALU_Equ (combined))
   10166              :         {
   10167            0 :           m2statement_BuildGoto (location, reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (dest))));
   10168              :         }
   10169              :       /* Fall through.  */
   10170              :     }
   10171        20708 :   else if ((((SymbolTable_IsConstSet (left)) || ((SymbolTable_IsVar (left)) && (SymbolTable_IsSet (SymbolTable_SkipType (SymbolTable_GetType (left)))))) || (SymbolTable_IsConstSet (right))) || ((SymbolTable_IsVar (right)) && (SymbolTable_IsSet (SymbolTable_SkipType (SymbolTable_GetType (right))))))
   10172              :     {
   10173              :       /* avoid dangling else.  */
   10174          658 :       CodeIfSetEqu (quad, left, right, dest);
   10175              :     }
   10176              :   else
   10177              :     {
   10178              :       /* avoid dangling else.  */
   10179        20050 :       if ((SymbolTable_IsComposite (SymbolTable_GetType (left))) || (SymbolTable_IsComposite (SymbolTable_GetType (right))))
   10180              :         {
   10181            0 :           M2MetaError_MetaErrorT2 (combined, (const char *) "equality tests between composite types not allowed {%1Eatd} and {%2atd}", 71, left, right);
   10182              :         }
   10183              :       else
   10184              :         {
   10185        20050 :           ConvertBinaryOperands (location, &tl, &tr, ComparisonMixTypes (left, right, SymbolTable_SkipType (SymbolTable_GetType (left)), SymbolTable_SkipType (SymbolTable_GetType (right)), combined), left, right);
   10186        20050 :           condition = m2expr_BuildEqualTo (location, tl, tr);
   10187        20050 :           m2statement_IfExprJump (location, condition, reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (dest))));
   10188              :         }
   10189              :     }
   10190        20708 : }
   10191              : 
   10192              : 
   10193              : /*
   10194              :    PerformCodeIfNotEqu -
   10195              : */
   10196              : 
   10197        32017 : static void PerformCodeIfNotEqu (unsigned int quad)
   10198              : {
   10199        32017 :   tree tl;
   10200        32017 :   tree tr;
   10201        32017 :   tree condition;
   10202        32017 :   location_t location;
   10203        32017 :   unsigned int left;
   10204        32017 :   unsigned int right;
   10205        32017 :   unsigned int dest;
   10206        32017 :   unsigned int combined;
   10207        32017 :   unsigned int leftpos;
   10208        32017 :   unsigned int rightpos;
   10209        32017 :   unsigned int destpos;
   10210        32017 :   bool constExpr;
   10211        32017 :   bool overflow;
   10212        32017 :   M2Quads_QuadOperator op;
   10213              : 
   10214              :   /* Ensure that any remaining undeclared constant literal is declared.  */
   10215        32017 :   M2Quads_GetQuadOtok (quad, &combined, &op, &left, &right, &dest, &constExpr, &overflow, &leftpos, &rightpos, &destpos);
   10216        32017 :   location = M2LexBuf_TokenToLocation (combined);
   10217        32017 :   if ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right)))
   10218              :     {
   10219            6 :       SymbolTable_PushValue (left);
   10220            6 :       SymbolTable_PushValue (right);
   10221            6 :       if (M2ALU_NotEqu (combined))
   10222              :         {
   10223            0 :           m2statement_BuildGoto (location, reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (dest))));
   10224              :         }
   10225              :       /* Fall through.  */
   10226              :     }
   10227        32011 :   else if ((((SymbolTable_IsConstSet (left)) || ((SymbolTable_IsVar (left)) && (SymbolTable_IsSet (SymbolTable_SkipType (SymbolTable_GetType (left)))))) || (SymbolTable_IsConstSet (right))) || ((SymbolTable_IsVar (right)) && (SymbolTable_IsSet (SymbolTable_SkipType (SymbolTable_GetType (right))))))
   10228              :     {
   10229              :       /* avoid dangling else.  */
   10230          600 :       CodeIfSetNotEqu (combined, left, right, dest);
   10231              :     }
   10232              :   else
   10233              :     {
   10234              :       /* avoid dangling else.  */
   10235        31411 :       if ((SymbolTable_IsComposite (SymbolTable_GetType (left))) || (SymbolTable_IsComposite (SymbolTable_GetType (right))))
   10236              :         {
   10237            0 :           M2MetaError_MetaErrorT2 (combined, (const char *) "inequality tests between composite types not allowed {%1Eatd} and {%2atd}", 73, left, right);
   10238              :         }
   10239              :       else
   10240              :         {
   10241        31411 :           ConvertBinaryOperands (location, &tl, &tr, ComparisonMixTypes (left, right, SymbolTable_SkipType (SymbolTable_GetType (left)), SymbolTable_SkipType (SymbolTable_GetType (right)), combined), left, right);
   10242        31411 :           condition = m2expr_BuildNotEqualTo (location, tl, tr);
   10243        31411 :           m2statement_IfExprJump (location, condition, reinterpret_cast <char * > (DynamicStrings_string (CreateLabelName (dest))));
   10244              :         }
   10245              :     }
   10246        32017 : }
   10247              : 
   10248              : 
   10249              : /*
   10250              :    IsValidExpressionRelOp - declare left and right constants (if they are not already declared).
   10251              :                             Check whether left and right are expression compatible.
   10252              : */
   10253              : 
   10254        76427 : static bool IsValidExpressionRelOp (unsigned int quad, bool isin)
   10255              : {
   10256        76427 :   unsigned int left;
   10257        76427 :   unsigned int right;
   10258        76427 :   unsigned int dest;
   10259        76427 :   unsigned int combined;
   10260        76427 :   unsigned int leftpos;
   10261        76427 :   unsigned int rightpos;
   10262        76427 :   unsigned int destpos;
   10263        76427 :   bool constExpr;
   10264        76427 :   bool overflow;
   10265        76427 :   M2Quads_QuadOperator op;
   10266              : 
   10267              :   /* Ensure that any remaining undeclared constant literal is declared.  */
   10268        76427 :   M2Quads_GetQuadOtok (quad, &combined, &op, &left, &right, &dest, &constExpr, &overflow, &leftpos, &rightpos, &destpos);
   10269        76427 :   M2GCCDeclare_DeclareConstant (leftpos, left);
   10270        76427 :   M2GCCDeclare_DeclareConstant (rightpos, right);
   10271        76427 :   M2GCCDeclare_DeclareConstructor (leftpos, quad, left);
   10272        76427 :   M2GCCDeclare_DeclareConstructor (rightpos, quad, right);
   10273        76427 :   if (M2Check_ExpressionTypeCompatible (combined, (const char *) "", 0, left, right, M2Options_StrictTypeChecking, isin))
   10274              :     {
   10275              :       return true;
   10276              :     }
   10277              :   else
   10278              :     {
   10279              :       if (Verbose)
   10280              :         {
   10281              :           M2MetaError_MetaErrorT2 (combined, (const char *) "expression mismatch between {%1Etad} and {%2tad} seen during comparison", 71, left, right);
   10282              :         }
   10283              :       return false;
   10284              :     }
   10285              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   10286              :   __builtin_unreachable ();
   10287              : }
   10288              : 
   10289              : 
   10290              : /*
   10291              :    CodeIfEqu - codes the quadruple if op1 = op2 then goto op3
   10292              : */
   10293              : 
   10294        20726 : static void CodeIfEqu (unsigned int quad)
   10295              : {
   10296        20726 :   if (IsValidExpressionRelOp (quad, false))
   10297              :     {
   10298        20708 :       PerformCodeIfEqu (quad);
   10299              :     }
   10300        20726 : }
   10301              : 
   10302              : 
   10303              : /*
   10304              :    CodeIfNotEqu - codes the quadruple if op1 # op2 then goto op3
   10305              : */
   10306              : 
   10307        32029 : static void CodeIfNotEqu (unsigned int quad)
   10308              : {
   10309        32029 :   if (IsValidExpressionRelOp (quad, false))
   10310              :     {
   10311        32017 :       PerformCodeIfNotEqu (quad);
   10312              :     }
   10313        32029 : }
   10314              : 
   10315              : 
   10316              : /*
   10317              :    MixTypes3 - returns a type compatible from, low, high, var.
   10318              : */
   10319              : 
   10320          104 : static unsigned int MixTypes3 (unsigned int low, unsigned int high, unsigned int var, unsigned int tokenno)
   10321              : {
   10322          104 :   unsigned int type;
   10323              : 
   10324          104 :   type = M2Base_MixTypes (SymbolTable_SkipType (SymbolTable_GetType (low)), SymbolTable_SkipType (SymbolTable_GetType (high)), tokenno);
   10325          104 :   type = M2Base_MixTypes (type, SymbolTable_SkipType (SymbolTable_GetType (var)), tokenno);
   10326          104 :   return type;
   10327              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   10328              :   __builtin_unreachable ();
   10329              : }
   10330              : 
   10331              : 
   10332              : /*
   10333              :    BuildIfVarInConstValue - if var in constsetvalue then goto trueexit
   10334              : */
   10335              : 
   10336            6 : static void BuildIfVarInConstValue (location_t location, unsigned int tokenno, M2ALU_PtrToValue constsetvalue, unsigned int var, unsigned int trueexit)
   10337              : {
   10338            6 :   tree vt;
   10339            6 :   tree lt;
   10340            6 :   tree ht;
   10341            6 :   unsigned int type;
   10342            6 :   unsigned int low;
   10343            6 :   unsigned int high;
   10344            6 :   unsigned int n;
   10345            6 :   DynamicStrings_String truelabel;
   10346              : 
   10347            6 :   n = 1;
   10348            6 :   truelabel = static_cast<DynamicStrings_String> (DynamicStrings_string (CreateLabelName (trueexit)));
   10349           24 :   while (M2ALU_GetRange (constsetvalue, n, &low, &high))
   10350              :     {
   10351           12 :       type = MixTypes3 (low, high, var, tokenno);
   10352           12 :       ConvertBinaryOperands (location, &vt, &lt, type, var, low);
   10353           12 :       ConvertBinaryOperands (location, &ht, &lt, type, high, low);
   10354           12 :       m2expr_BuildIfInRangeGoto (location, vt, lt, ht, reinterpret_cast <char * > (truelabel));
   10355           12 :       n += 1;
   10356              :     }
   10357            6 : }
   10358              : 
   10359              : 
   10360              : /*
   10361              :    BuildIfNotVarInConstValue - if not (var in constsetvalue) then goto trueexit
   10362              : */
   10363              : 
   10364           56 : static void BuildIfNotVarInConstValue (location_t location, unsigned int tokenno, unsigned int quad, M2ALU_PtrToValue constsetvalue, unsigned int var, unsigned int trueexit)
   10365              : {
   10366           56 :   tree vt;
   10367           56 :   tree lt;
   10368           56 :   tree ht;
   10369           56 :   unsigned int type;
   10370           56 :   unsigned int low;
   10371           56 :   unsigned int high;
   10372           56 :   unsigned int n;
   10373           56 :   DynamicStrings_String falselabel;
   10374           56 :   DynamicStrings_String truelabel;
   10375              : 
   10376           56 :   truelabel = static_cast<DynamicStrings_String> (DynamicStrings_string (CreateLabelName (trueexit)));
   10377           56 :   n = 1;
   10378          204 :   while (M2ALU_GetRange (constsetvalue, n, &low, &high))
   10379              :     {
   10380           92 :       n += 1;
   10381              :     }
   10382           56 :   if (n == 2)
   10383              :     {
   10384              :       /* Only one set range, so we invert it  */
   10385           24 :       type = MixTypes3 (low, high, var, tokenno);
   10386           24 :       ConvertBinaryOperands (location, &vt, &lt, type, var, low);
   10387           24 :       ConvertBinaryOperands (location, &ht, &lt, type, high, low);
   10388           24 :       m2expr_BuildIfNotInRangeGoto (location, vt, lt, ht, reinterpret_cast <char * > (truelabel));
   10389              :     }
   10390              :   else
   10391              :     {
   10392           32 :       n = 1;
   10393           32 :       falselabel = static_cast<DynamicStrings_String> (DynamicStrings_string (FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ".Lset%d", 7)), (const unsigned char *) &quad, (sizeof (quad)-1))));
   10394          132 :       while (M2ALU_GetRange (constsetvalue, n, &low, &high))
   10395              :         {
   10396           68 :           type = MixTypes3 (low, high, var, tokenno);
   10397           68 :           ConvertBinaryOperands (location, &vt, &lt, type, var, low);
   10398           68 :           ConvertBinaryOperands (location, &ht, &lt, type, high, low);
   10399           68 :           m2expr_BuildIfInRangeGoto (location, vt, lt, ht, reinterpret_cast <char * > (falselabel));
   10400           68 :           n += 1;
   10401              :         }
   10402           32 :       m2statement_BuildGoto (location, reinterpret_cast <char * > (truelabel));
   10403           32 :       m2statement_DeclareLabel (location, reinterpret_cast <char * > (falselabel));
   10404              :     }
   10405           56 : }
   10406              : 
   10407              : 
   10408              : /*
   10409              :     SetWideIfIn - if M2WIDESET.In (set, element) then goto branch end.
   10410              : */
   10411              : 
   10412          846 : static void SetWideIfIn (location_t location, unsigned int tokenno, bool invertCondition, unsigned int settype, unsigned int element, unsigned int set, unsigned int branch)
   10413              : {
   10414          846 :   DynamicStrings_String label;
   10415          846 :   tree bit;
   10416          846 :   tree call;
   10417          846 :   tree expr;
   10418          846 :   tree setarray;
   10419          846 :   unsigned int setparam;
   10420          846 :   unsigned int procedure;
   10421              : 
   10422          846 :   procedure = FromM2WIDESETImport (tokenno, NameKey_MakeKey ((const char *) "In", 2));
   10423          846 :   setparam = SymbolTable_GetNthParamAnyClosest (procedure, 1, SymbolTable_GetMainModule ());
   10424          846 :   setarray = CreateSetArrayParam (location, tokenno, set, setparam);
   10425          846 :   bit = SetElementToBit (location, settype, element);
   10426          846 :   m2statement_BuildParam (location, m2convert_ToCardinal (location, bit));
   10427          846 :   m2statement_BuildParam (location, setarray);
   10428          846 :   call = m2statement_BuildProcedureCallTree (location, SymbolConversion_Mod2Gcc (procedure), SymbolConversion_Mod2Gcc (SymbolTable_GetType (procedure)));
   10429          846 :   m2statement_SetLastFunction (NULL);
   10430          846 :   label = CreateLabelName (branch);
   10431          846 :   if (invertCondition)
   10432              :     {
   10433          630 :       expr = m2expr_BuildEqualTo (location, call, m2type_GetBooleanFalse ());
   10434              :     }
   10435              :   else
   10436              :     {
   10437          216 :       expr = m2expr_BuildNotEqualTo (location, call, m2type_GetBooleanFalse ());
   10438              :     }
   10439          846 :   m2statement_IfExprJump (location, expr, reinterpret_cast <char * > (DynamicStrings_string (label)));
   10440          846 : }
   10441              : 
   10442              : 
   10443              : /*
   10444              :    CodeNarrowIfIn -
   10445              : */
   10446              : 
   10447         1466 : static void CodeNarrowIfIn (location_t location, unsigned int settype, bool invertCondition, unsigned int element, unsigned int set, unsigned int branch)
   10448              : {
   10449         1466 :   tree label;
   10450         1466 :   tree cond;
   10451         1466 :   tree bit;
   10452         1466 :   tree mask;
   10453         1466 :   tree bitset;
   10454              : 
   10455         1466 :   bit = m2convert_ToBitset (location, SetElementToBit (location, settype, element));
   10456         1466 :   mask = m2expr_BuildMask (location, CalcBitsInSet (location, settype), false);
   10457              :   /* Mask off only the bits we need.  */
   10458         1466 :   bitset = m2convert_ToBitset (location, m2expr_BuildLogicalAnd (location, SymbolConversion_Mod2Gcc (set), mask));
   10459         1466 :   if (invertCondition)
   10460              :     {
   10461         1162 :       cond = m2expr_BuildIfNotInSet (location, bitset, bit);
   10462              :     }
   10463              :   else
   10464              :     {
   10465          304 :       cond = m2expr_BuildIfInSet (location, bitset, bit);
   10466              :     }
   10467         1466 :   label = static_cast<tree> (CreateLabelName (branch));
   10468         1466 :   m2statement_IfExprJump (location, cond, reinterpret_cast <char * > (DynamicStrings_string (static_cast<DynamicStrings_String> (label))));
   10469         1466 : }
   10470              : 
   10471              : 
   10472              : /*
   10473              :    CodeIfInLower - code the quadruple: if element in set then goto branch.
   10474              :                    The invertCondition can be set to TRUE to handle CodeIfNotIn.
   10475              : */
   10476              : 
   10477         2392 : static void CodeIfInLower (unsigned int tokenno, unsigned int quad, bool invertCondition, unsigned int element, unsigned int set, unsigned int branch)
   10478              : {
   10479         2392 :   unsigned int settype;
   10480         2392 :   location_t location;
   10481         2392 :   M2ALU_PtrToValue constsetvalue;
   10482              : 
   10483         2392 :   location = M2LexBuf_TokenToLocation (tokenno);
   10484              :   /* Firstly ensure that any constant literal is declared.  */
   10485         2392 :   M2GCCDeclare_DeclareConstant (tokenno, set);
   10486         2392 :   M2GCCDeclare_DeclareConstant (tokenno, element);
   10487         2392 :   M2GCCDeclare_DeclareConstructor (tokenno, quad, set);
   10488         2392 :   M2GCCDeclare_DeclareConstructor (tokenno, quad, element);
   10489         2392 :   checkDeclare (set);
   10490         2392 :   checkDeclare (element);
   10491         2392 :   settype = SymbolTable_GetLType (set);
   10492         2392 :   if ((SymbolTable_IsConst (element)) && (SymbolTable_IsConst (set)))
   10493              :     {
   10494            0 :       M2Error_InternalError ((const char *) "should not get to here (if we do we should consider calling FoldIfIn)", 69);
   10495              :     }
   10496         2392 :   else if (CheckElementSetTypes (quad))
   10497              :     {
   10498              :       /* avoid dangling else.  */
   10499         2380 :       if (SymbolTable_IsConst (set))
   10500              :         {
   10501           62 :           SymbolTable_PushValue (set);
   10502           62 :           constsetvalue = M2ALU_GetValue (tokenno);
   10503           62 :           if (invertCondition)
   10504              :             {
   10505              :               /* Builds a cascaded list of if statements.  */
   10506           56 :               BuildIfNotVarInConstValue (location, tokenno, quad, constsetvalue, element, branch);
   10507              :             }
   10508              :           else
   10509              :             {
   10510              :               /* Builds a very different cascaded list of if statements.  */
   10511            6 :               BuildIfVarInConstValue (location, tokenno, constsetvalue, element, branch);
   10512              :             }
   10513              :         }
   10514              :       else
   10515              :         {
   10516         2318 :           M2Debug_Assert (SymbolTable_IsVar (set));
   10517         2318 :           if (IsElementInRange (tokenno, settype, set, element))
   10518              :             {
   10519              :               /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   10520              :               /* Check for narrow and wide sets and call M2WIDESET if appropriate.  */
   10521         2312 :               if (SymbolTable_GetSetInWord (settype))
   10522              :                 {
   10523         1466 :                   CodeNarrowIfIn (location, settype, invertCondition, element, set, branch);
   10524              :                 }
   10525              :               else
   10526              :                 {
   10527          846 :                   SetWideIfIn (location, tokenno, invertCondition, settype, element, set, branch);
   10528              :                 }
   10529              :             }
   10530              :         }
   10531              :     }
   10532         2392 : }
   10533              : 
   10534              : 
   10535              : /*
   10536              :    PerformCodeIfIn -
   10537              : */
   10538              : 
   10539         2392 : static void PerformCodeIfIn (unsigned int quad, bool invert)
   10540              : {
   10541         2392 :   M2Quads_QuadOperator op;
   10542         2392 :   unsigned int element;
   10543         2392 :   unsigned int set;
   10544         2392 :   unsigned int branch;
   10545         2392 :   unsigned int combined;
   10546         2392 :   unsigned int elementpos;
   10547         2392 :   unsigned int setpos;
   10548         2392 :   unsigned int destpos;
   10549         2392 :   bool constExpr;
   10550         2392 :   bool overflow;
   10551              : 
   10552         2392 :   M2Quads_GetQuadOtok (quad, &combined, &op, &element, &set, &branch, &overflow, &constExpr, &elementpos, &setpos, &destpos);
   10553         2392 :   CodeIfInLower (combined, quad, invert, element, set, branch);
   10554         2392 : }
   10555              : 
   10556              : 
   10557              : /*
   10558              :    CodeIfIn - code the quadruple: if element in set then goto branch.
   10559              : */
   10560              : 
   10561          532 : static void CodeIfIn (unsigned int quad)
   10562              : {
   10563          532 :   if (IsValidExpressionRelOp (quad, true))
   10564              :     {
   10565          526 :       PerformCodeIfIn (quad, false);
   10566              :     }
   10567          532 : }
   10568              : 
   10569              : 
   10570              : /*
   10571              :    CodeIfNotIn - code the quadruple: if not (element in set) then goto branch.
   10572              : */
   10573              : 
   10574         1866 : static void CodeIfNotIn (unsigned int quad)
   10575              : {
   10576         1866 :   if (IsValidExpressionRelOp (quad, true))
   10577              :     {
   10578         1866 :       PerformCodeIfIn (quad, true);
   10579              :     }
   10580         1866 : }
   10581              : 
   10582        16429 : static void CodeIndrX (unsigned int quad)
   10583              : {
   10584        16429 :   bool constExpr;
   10585        16429 :   bool overflowChecking;
   10586        16429 :   M2Quads_QuadOperator op;
   10587        16429 :   unsigned int tokenno;
   10588        16429 :   unsigned int left;
   10589        16429 :   unsigned int type;
   10590        16429 :   unsigned int right;
   10591        16429 :   unsigned int leftpos;
   10592        16429 :   unsigned int rightpos;
   10593        16429 :   unsigned int typepos;
   10594        16429 :   unsigned int indrxpos;
   10595        16429 :   location_t location;
   10596              : 
   10597              :   /* 
   10598              : ------------------------------------------------------------------------------
   10599              :    IndrX Operator           a = *b
   10600              : ------------------------------------------------------------------------------
   10601              :    Sym1<X>   IndrX   Sym2<I>     Meaning     Mem[Sym1<I>] := Mem[constant]
   10602              :    Sym1<X>   IndrX   Sym2<X>     Meaning     Mem[Sym1<I>] := Mem[Mem[Sym3<I>]]
   10603              : 
   10604              :    (op2 is the type of the data being indirectly copied)
   10605              :   */
   10606        16429 :   M2Quads_GetQuadOtok (quad, &indrxpos, &op, &left, &type, &right, &overflowChecking, &constExpr, &leftpos, &typepos, &rightpos);
   10607        16429 :   tokenno = M2LexBuf_MakeVirtualTok (indrxpos, leftpos, rightpos);
   10608        16429 :   location = M2LexBuf_TokenToLocation (tokenno);
   10609              :   /* 
   10610              :       Follow the Quadruple rules:
   10611              :   */
   10612        16429 :   M2GCCDeclare_DeclareConstant (rightpos, right);  /* Checks to see whether it is a constant
   10613              :                                            and if necessary declare it.  */
   10614        16429 :   M2GCCDeclare_DeclareConstructor (rightpos, quad, right);  /* Checks to see whether it is a constant
   10615              :                                            and if necessary declare it.  */
   10616        16429 :   if (SymbolTable_IsConstString (right))
   10617              :     {
   10618            0 :       M2Error_InternalError ((const char *) "not expecting to index through a constant string", 48);
   10619              :     }
   10620        16429 :   else if (M2Options_StrictTypeChecking && (! (M2Check_AssignmentTypeCompatible (indrxpos, (const char *) "", 0, left, SymbolTable_GetType (right), true))))
   10621              :     {
   10622              :       /* avoid dangling else.  */
   10623            0 :       M2MetaError_MetaErrorT2 (tokenno, (const char *) "assignment check caught mismatch between {%1Ead} and {%2ad}", 59, left, right);
   10624            0 :       M2Quads_SubQuad (quad);
   10625              :     }
   10626              :   else
   10627              :     {
   10628              :       /* avoid dangling else.  */
   10629              :       /* 
   10630              :          Mem[op1] := Mem[Mem[op3]]
   10631              :   */
   10632        16429 :       m2statement_BuildAssignmentStatement (location, SymbolConversion_Mod2Gcc (left), m2expr_BuildIndirect (location, SymbolConversion_Mod2Gcc (right), SymbolConversion_Mod2Gcc (type)));
   10633              :     }
   10634        16429 : }
   10635              : 
   10636              : 
   10637              : /*
   10638              :    CodeXIndr - operands for XIndrOp are: left type right.
   10639              :                 *left = right.  The second operand is the type of the data being
   10640              :                 indirectly copied.
   10641              : */
   10642              : 
   10643        43222 : static void CodeXIndr (unsigned int quad)
   10644              : {
   10645        43222 :   bool constExpr;
   10646        43222 :   bool overflowChecking;
   10647        43222 :   M2Quads_QuadOperator op;
   10648        43222 :   unsigned int tokenno;
   10649        43222 :   unsigned int left;
   10650        43222 :   unsigned int type;
   10651        43222 :   unsigned int right;
   10652        43222 :   unsigned int leftpos;
   10653        43222 :   unsigned int rightpos;
   10654        43222 :   unsigned int typepos;
   10655        43222 :   unsigned int xindrpos;
   10656        43222 :   tree length;
   10657        43222 :   tree newstr;
   10658        43222 :   location_t location;
   10659              : 
   10660        43222 :   M2Quads_GetQuadOtok (quad, &xindrpos, &op, &left, &type, &right, &overflowChecking, &constExpr, &leftpos, &typepos, &rightpos);
   10661        43222 :   tokenno = M2LexBuf_MakeVirtualTok (xindrpos, leftpos, rightpos);
   10662        43222 :   location = M2LexBuf_TokenToLocation (tokenno);
   10663        43222 :   type = SymbolTable_SkipType (type);
   10664        43222 :   M2GCCDeclare_DeclareConstant (rightpos, right);
   10665        43222 :   M2GCCDeclare_DeclareConstructor (rightpos, quad, right);
   10666        43222 :   if (M2Options_StrictTypeChecking && (! (M2Check_AssignmentTypeCompatible (xindrpos, (const char *) "", 0, SymbolTable_GetType (left), right, true))))
   10667              :     {
   10668            0 :       M2MetaError_MetaErrorT2 (tokenno, (const char *) "assignment check caught mismatch between {%1Ead} and {%2ad}", 59, left, right);
   10669            0 :       M2Quads_SubQuad (quad);
   10670              :     }
   10671        43222 :   if (SymbolTable_IsProcType (SymbolTable_SkipType (type)))
   10672              :     {
   10673        31814 :       m2statement_BuildAssignmentStatement (location, m2expr_BuildIndirect (location, SymbolConversion_Mod2Gcc (left), m2type_GetPointerType ()), SymbolConversion_Mod2Gcc (right));
   10674              :     }
   10675        11408 :   else if (((SymbolTable_IsConstString (right)) && ((SymbolTable_GetStringLength (rightpos, right)) == 0)) && ((SymbolTable_GetMode (left)) == SymbolTable_LeftValue))
   10676              :     {
   10677              :       /* avoid dangling else.  */
   10678              :       /* 
   10679              :          no need to check for type errors,
   10680              :          but we handle nul string as a special case as back end
   10681              :          complains if we pass through a "" and ask it to copy the
   10682              :          contents.
   10683              :   */
   10684           12 :       m2statement_BuildAssignmentStatement (location, m2expr_BuildIndirect (location, M2GenGCC_LValueToGenericPtr (location, left), SymbolConversion_Mod2Gcc (M2Base_Char)), M2GenGCC_StringToChar (SymbolConversion_Mod2Gcc (right), M2Base_Char, right));
   10685              :     }
   10686        11396 :   else if ((SymbolTable_IsConstString (right)) && ((SymbolTable_SkipTypeAndSubrange (SymbolTable_GetType (left))) != M2Base_Char))
   10687              :     {
   10688              :       /* avoid dangling else.  */
   10689           42 :       if (! (M2GenGCC_PrepareCopyString (tokenno, &length, &newstr, right, type)))
   10690              :         {
   10691            0 :           M2MetaError_MetaErrorT2 (M2LexBuf_MakeVirtualTok (xindrpos, leftpos, rightpos), (const char *) "string constant {%1Ea} is too large to be assigned to the array {%2ad}", 70, right, left);
   10692              :         }
   10693           42 :       m2type_AddStatement (location, MaybeDebugBuiltinMemcpy (location, SymbolConversion_Mod2Gcc (left), m2expr_BuildAddr (location, newstr, false), length));
   10694              :     }
   10695              :   else
   10696              :     {
   10697              :       /* avoid dangling else.  */
   10698        11354 :       m2statement_BuildAssignmentStatement (location, m2expr_BuildIndirect (location, SymbolConversion_Mod2Gcc (left), SymbolConversion_Mod2Gcc (type)), ConvertRHS (SymbolConversion_Mod2Gcc (right), type, right));
   10699              :     }
   10700        43222 : }
   10701              : 
   10702              : 
   10703              : /*
   10704              :    InitBuiltinSyms -
   10705              : */
   10706              : 
   10707     95647870 : static void InitBuiltinSyms (unsigned int tok)
   10708              : {
   10709     95647870 :   if (Memset == SymbolTable_NulSym)
   10710              :     {
   10711        13940 :       Memset = SymbolTable_FromModuleGetSym (tok, NameKey_MakeKey ((const char *) "memset", 6), M2Batch_MakeDefinitionSource (tok, NameKey_MakeKey ((const char *) "Builtins", 8)));
   10712              :     }
   10713     95647870 :   if (Memcpy == SymbolTable_NulSym)
   10714              :     {
   10715        13940 :       Memcpy = SymbolTable_FromModuleGetSym (tok, NameKey_MakeKey ((const char *) "memcpy", 6), M2Batch_MakeDefinitionSource (tok, NameKey_MakeKey ((const char *) "Builtins", 8)));
   10716              :     }
   10717     95647870 : }
   10718              : 
   10719              : 
   10720              : /*
   10721              :    gdbhook - a debugger convenience hook.
   10722              : */
   10723              : 
   10724            0 : static void gdbhook (void)
   10725              : {
   10726            0 : }
   10727              : 
   10728              : 
   10729              : /*
   10730              :    BreakWhenQuadTranslated - to be called interactively by gdb.
   10731              : */
   10732              : 
   10733        14952 : static void BreakWhenQuadTranslated (unsigned int quad)
   10734              : {
   10735        14952 :   BreakQuad = quad;
   10736            0 : }
   10737              : 
   10738              : 
   10739              : /*
   10740              :    CheckBreak - if quad = BreakQuad then call gdbhook.
   10741              : */
   10742              : 
   10743            0 : static void CheckBreak (unsigned int quad)
   10744              : {
   10745            0 :   if (quad == BreakQuad)
   10746              :     {
   10747            0 :       gdbhook ();
   10748              :     }
   10749            0 : }
   10750              : 
   10751              : 
   10752              : /*
   10753              :    Init -
   10754              : */
   10755              : 
   10756        14952 : static void Init (void)
   10757              : {
   10758              :   /* You might want to add the option -fm2-debug-trace=quad to cc1gm2 if
   10759              :       contenplating interactively debugging cc1gm2 using the scheme below.  */
   10760        14952 :   BreakWhenQuadTranslated (0);  /* Disable the interactive quad watch.  */
   10761              :   /* To examine when a quad is about to be converted into a gimple tree
   10762              :       run cc1gm2 from gdb and set a break point on gdbhook.
   10763              :       (gdb) break gdbhook
   10764              :       (gdb) run
   10765              :       Now below interactively call BreakWhenQuadTranslated with the quad
   10766              :       under investigation.  */
   10767        14952 :   gdbhook ();
   10768              :   /* Now is the time to interactively call gdb, for example:
   10769              :       (gdb) print BreakWhenQuadTranslated (1234)
   10770              :       (gdb) cont
   10771              :       and you will arrive at gdbhook when this quad is about to be translated.  */
   10772        14952 :   Memset = SymbolTable_NulSym;
   10773        14952 :   Memcpy = SymbolTable_NulSym;
   10774        14952 :   UnboundedLabelNo = 0;
   10775        14952 :   CurrentQuadToken = 0;
   10776        14952 :   SetTemporaryNo = 0;
   10777        14952 :   ScopeStack = M2StackWord_InitStackWord ();
   10778        14952 : }
   10779              : 
   10780              : 
   10781              : /*
   10782              :    ConvertQuadsToTree - runs through the quadruple list and converts it into
   10783              :                         the GCC tree structure.
   10784              : */
   10785              : 
   10786       397657 : extern "C" void M2GenGCC_ConvertQuadsToTree (unsigned int Start, unsigned int End)
   10787              : {
   10788      4167916 :   do {
   10789      4167916 :     CodeStatement (Start);
   10790      4167904 :     Start = M2Quads_GetNextQuad (Start);
   10791      4167904 :   } while (! ((Start > End) || (Start == 0)));
   10792       397645 : }
   10793              : 
   10794              : 
   10795              : /*
   10796              :    ResolveConstantExpressions - resolves constant expressions from the quadruple list.
   10797              :                                 It returns TRUE if one or more constants were folded.
   10798              :                                 When a constant symbol value is solved, the call back
   10799              :                                 p(sym) is invoked.
   10800              : */
   10801              : 
   10802     91413565 : extern "C" bool M2GenGCC_ResolveConstantExpressions (M2GCCDeclare_WalkAction p, M2BasicBlock_BasicBlock bb)
   10803              : {
   10804     91413565 :   unsigned int tokenno;
   10805     91413565 :   unsigned int quad;
   10806     91413565 :   M2Quads_QuadOperator op;
   10807     91413565 :   unsigned int op1;
   10808     91413565 :   unsigned int op2;
   10809     91413565 :   unsigned int op3;
   10810     91413565 :   unsigned int op1pos;
   10811     91413565 :   unsigned int op2pos;
   10812     91413565 :   unsigned int op3pos;
   10813     91413565 :   bool Changed;
   10814     91413565 :   unsigned int start;
   10815     91413565 :   unsigned int end;
   10816              : 
   10817     91413565 :   InitBuiltinSyms (M2LexBuf_BuiltinTokenNo);
   10818     91413565 :   start = M2BasicBlock_GetBasicBlockStart (bb);
   10819     91413565 :   end = M2BasicBlock_GetBasicBlockEnd (bb);
   10820     91413565 :   Changed = false;
   10821     91554856 :   do {
   10822     91554856 :     NoChange = true;
   10823     91554856 :     quad = start;
   10824    261742897 :     while ((quad <= end) && (quad != 0))
   10825              :       {
   10826    170188215 :         tokenno = CurrentQuadToken;
   10827    170188215 :         if (tokenno == 0)
   10828              :           {
   10829      3433316 :             tokenno = M2Quads_QuadToTokenNo (quad);
   10830              :           }
   10831    170188215 :         if (M2Options_GetDebugTraceQuad ())
   10832              :           {
   10833            0 :             M2Printf_printf0 ((const char *) "examining fold: ", 16);
   10834            0 :             M2Quads_DisplayQuad (quad);
   10835              :           }
   10836    170188215 :         M2Quads_GetQuadtok (quad, &op, &op1, &op2, &op3, &op1pos, &op2pos, &op3pos);
   10837    170188215 :         switch (op)
   10838              :           {
   10839         9444 :             case M2Quads_StandardFunctionOp:
   10840         9444 :               FoldStandardFunction (tokenno, p, quad, op1, op2, op3);
   10841         9444 :               break;
   10842              : 
   10843        27520 :             case M2Quads_BuiltinConstOp:
   10844        27520 :               FoldBuiltinConst (tokenno, p, quad, op1, op3);
   10845        27520 :               break;
   10846              : 
   10847          360 :             case M2Quads_BuiltinTypeInfoOp:
   10848          360 :               FoldBuiltinTypeInfo (tokenno, p, quad, op1, op2, op3);
   10849          360 :               break;
   10850              : 
   10851        14562 :             case M2Quads_LogicalOrOp:
   10852        14562 :               FoldSetOr (tokenno, p, quad, op1, op2, op3);
   10853        14562 :               break;
   10854              : 
   10855         3684 :             case M2Quads_LogicalAndOp:
   10856         3684 :               FoldSetAnd (tokenno, p, quad, op1, op2, op3);
   10857         3684 :               break;
   10858              : 
   10859          664 :             case M2Quads_LogicalXorOp:
   10860          664 :               FoldSymmetricDifference (tokenno, p, quad, op1, op2, op3);
   10861          664 :               break;
   10862              : 
   10863      5049648 :             case M2Quads_BecomesOp:
   10864      5049648 :               FoldBecomes (p, bb, quad);
   10865      5049648 :               break;
   10866              : 
   10867            0 :             case M2Quads_ArithAddOp:
   10868            0 :               FoldArithAdd (op1pos, p, quad, op1, op2, op3);
   10869            0 :               break;
   10870              : 
   10871       396940 :             case M2Quads_AddOp:
   10872       396940 :               FoldAdd (op1pos, p, quad, op1, op2, op3);
   10873       396940 :               break;
   10874              : 
   10875       164904 :             case M2Quads_SubOp:
   10876       164904 :               FoldSub (op1pos, p, quad, op1, op2, op3);
   10877       164904 :               break;
   10878              : 
   10879       109726 :             case M2Quads_MultOp:
   10880       109726 :               FoldMult (op1pos, p, quad, op1, op2, op3);
   10881       109726 :               break;
   10882              : 
   10883        14784 :             case M2Quads_DivM2Op:
   10884        14784 :               FoldDivM2 (op1pos, p, quad, op1, op2, op3);
   10885        14784 :               break;
   10886              : 
   10887        25942 :             case M2Quads_ModM2Op:
   10888        25942 :               FoldModM2 (op1pos, p, quad, op1, op2, op3);
   10889        25942 :               break;
   10890              : 
   10891        11100 :             case M2Quads_DivTruncOp:
   10892        11100 :               FoldDivTrunc (op1pos, p, quad, op1, op2, op3);
   10893        11100 :               break;
   10894              : 
   10895           96 :             case M2Quads_ModTruncOp:
   10896           96 :               FoldModTrunc (op1pos, p, quad, op1, op2, op3);
   10897           96 :               break;
   10898              : 
   10899            0 :             case M2Quads_DivCeilOp:
   10900            0 :               FoldDivCeil (op1pos, p, quad, op1, op2, op3);
   10901            0 :               break;
   10902              : 
   10903            0 :             case M2Quads_ModCeilOp:
   10904            0 :               FoldModCeil (op1pos, p, quad, op1, op2, op3);
   10905            0 :               break;
   10906              : 
   10907            0 :             case M2Quads_DivFloorOp:
   10908            0 :               FoldDivFloor (op1pos, p, quad, op1, op2, op3);
   10909            0 :               break;
   10910              : 
   10911            0 :             case M2Quads_ModFloorOp:
   10912            0 :               FoldModFloor (op1pos, p, quad, op1, op2, op3);
   10913            0 :               break;
   10914              : 
   10915        39109 :             case M2Quads_NegateOp:
   10916        39109 :               FoldNegate (op1pos, p, quad, op1, op3);
   10917        39109 :               break;
   10918              : 
   10919         7416 :             case M2Quads_SizeOp:
   10920         7416 :               FoldSize (tokenno, p, quad, op1, op2, op3);
   10921         7416 :               break;
   10922              : 
   10923              :             case M2Quads_RecordFieldOp:
   10924              :               FoldRecordField (tokenno, p, quad, op1, op2, op3);
   10925              :               break;
   10926              : 
   10927      1227993 :             case M2Quads_HighOp:
   10928      1227993 :               FoldHigh (tokenno, p, quad, op1, op2, op3);
   10929      1227993 :               break;
   10930              : 
   10931        10048 :             case M2Quads_ElementSizeOp:
   10932        10048 :               FoldElementSize (tokenno, p, quad, op1, op2);
   10933        10048 :               break;
   10934              : 
   10935       360284 :             case M2Quads_ConvertOp:
   10936       360284 :               FoldConvert (tokenno, p, quad, op1, op2, op3);
   10937       360284 :               break;
   10938              : 
   10939        11030 :             case M2Quads_CoerceOp:
   10940        11030 :               FoldCoerce (tokenno, p, quad, op1, op2, op3);
   10941        11030 :               break;
   10942              : 
   10943         1500 :             case M2Quads_CastOp:
   10944         1500 :               FoldCast (tokenno, p, quad, op1, op2, op3);
   10945         1500 :               break;
   10946              : 
   10947        27286 :             case M2Quads_InclOp:
   10948        27286 :               FoldIncl (tokenno, p, quad, op1, op3);
   10949        27286 :               break;
   10950              : 
   10951        15538 :             case M2Quads_ExclOp:
   10952        15538 :               FoldExcl (tokenno, p, quad, op1, op3);
   10953        15538 :               break;
   10954              : 
   10955       680761 :             case M2Quads_IfEquOp:
   10956       680761 :               FoldIfEqu (tokenno, quad, op1, op2, op3);
   10957       680761 :               break;
   10958              : 
   10959       336237 :             case M2Quads_IfNotEquOp:
   10960       336237 :               FoldIfNotEqu (tokenno, quad, op1, op2, op3);
   10961       336237 :               break;
   10962              : 
   10963        36982 :             case M2Quads_IfLessOp:
   10964        36982 :               FoldIfLess (tokenno, quad, op1, op2, op3);
   10965        36982 :               break;
   10966              : 
   10967        30992 :             case M2Quads_IfLessEquOp:
   10968        30992 :               FoldIfLessEqu (tokenno, quad, op1, op2, op3);
   10969        30992 :               break;
   10970              : 
   10971        28024 :             case M2Quads_IfGreOp:
   10972        28024 :               FoldIfGre (tokenno, quad, op1, op2, op3);
   10973        28024 :               break;
   10974              : 
   10975        47074 :             case M2Quads_IfGreEquOp:
   10976        47074 :               FoldIfGreEqu (tokenno, quad, op1, op2, op3);
   10977        47074 :               break;
   10978              : 
   10979        53404 :             case M2Quads_IfInOp:
   10980        53404 :               FoldIfIn (tokenno, quad, op1, op2, op3);
   10981        53404 :               break;
   10982              : 
   10983         9056 :             case M2Quads_IfNotInOp:
   10984         9056 :               FoldIfNotIn (tokenno, quad, op1, op2, op3);
   10985         9056 :               break;
   10986              : 
   10987        27654 :             case M2Quads_LogicalShiftOp:
   10988        27654 :               FoldSetShift (tokenno, p, quad, op1, op2, op3);
   10989        27654 :               break;
   10990              : 
   10991        23892 :             case M2Quads_LogicalRotateOp:
   10992        23892 :               FoldSetRotate (tokenno, p, quad, op1, op2, op3);
   10993        23892 :               break;
   10994              : 
   10995      7490673 :             case M2Quads_ParamOp:
   10996      7490673 :               FoldBuiltinFunction (tokenno, p, quad, op1, op2, op3);
   10997      7490673 :               break;
   10998              : 
   10999     14154527 :             case M2Quads_RangeCheckOp:
   11000     14154527 :               FoldRange (tokenno, quad, op3);
   11001     14154527 :               break;
   11002              : 
   11003      9844092 :             case M2Quads_StatementNoteOp:
   11004      9844092 :               FoldStatementNote (op3);
   11005      9844092 :               break;
   11006              : 
   11007           72 :             case M2Quads_StringLengthOp:
   11008           72 :               FoldStringLength (quad, p);
   11009           72 :               break;
   11010              : 
   11011        33949 :             case M2Quads_StringConvertM2nulOp:
   11012        33949 :               FoldStringConvertM2nul (quad, p);
   11013        33949 :               break;
   11014              : 
   11015         9583 :             case M2Quads_StringConvertCnulOp:
   11016         9583 :               FoldStringConvertCnul (quad, p);
   11017         9583 :               break;
   11018              : 
   11019        14950 :             case M2Quads_LastForIteratorOp:
   11020        14950 :               FoldLastForIterator (quad, p);
   11021        14950 :               break;
   11022              : 
   11023              : 
   11024              :             default:
   11025              :               break;
   11026              :           }
   11027              :         /* Ignore quadruple as it is not associated with a constant expression.  */
   11028    170188041 :         quad = M2Quads_GetNextQuad (quad);
   11029              :       }
   11030     91554682 :     if (! NoChange)
   11031              :       {
   11032       141291 :         Changed = true;
   11033              :       }
   11034     91554682 :   } while (! (NoChange));
   11035     91413391 :   return Changed;
   11036              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   11037              :   __builtin_unreachable ();
   11038              : }
   11039              : 
   11040              : 
   11041              : /*
   11042              :    GetHighFromUnbounded - returns a Tree containing the value of
   11043              :                           param.HIGH.
   11044              : */
   11045              : 
   11046        21618 : extern "C" tree M2GenGCC_GetHighFromUnbounded (location_t location, unsigned int dim, unsigned int param)
   11047              : {
   11048        21618 :   unsigned int UnboundedType;
   11049        21618 :   unsigned int ArrayType;
   11050        21618 :   unsigned int HighField;
   11051        21618 :   tree HighTree;
   11052        21618 :   unsigned int accessibleDim;
   11053              : 
   11054              :   /* remainingDim : CARDINAL ;  */
   11055        21618 :   UnboundedType = SymbolTable_GetType (param);
   11056        21618 :   M2Debug_Assert (SymbolTable_IsUnbounded (UnboundedType));
   11057        21618 :   ArrayType = SymbolTable_GetType (UnboundedType);
   11058        21618 :   HighField = SymbolTable_GetUnboundedHighOffset (UnboundedType, dim);
   11059        21618 :   if (HighField == SymbolTable_NulSym)
   11060              :     {
   11061              :       /* It might be a dynamic array of static arrays,
   11062              :          so lets see if there is an earlier dimension available.  */
   11063              :       accessibleDim = dim;
   11064            0 :       while ((HighField == SymbolTable_NulSym) && (accessibleDim > 1))
   11065              :         {
   11066            0 :           accessibleDim -= 1;
   11067            0 :           HighField = SymbolTable_GetUnboundedHighOffset (UnboundedType, accessibleDim);
   11068              :         }
   11069            0 :       if (HighField == SymbolTable_NulSym)
   11070              :         {
   11071            0 :           M2MetaError_MetaError1 ((const char *) "{%EkHIGH} dimension number {%1N} for array does not exist", 57, dim);
   11072            0 :           return m2expr_GetCardinalZero (location);
   11073              :         }
   11074              :       else
   11075              :         {
   11076            0 :           HighTree = BuildHighFromStaticArray (location, ArrayType);  /* remainingDim,  */
   11077            0 :           if (HighTree == NULL)
   11078              :             {
   11079            0 :               M2MetaError_MetaError1 ((const char *) "{%EkHIGH} dimension number {%1N} for array does not exist", 57, dim);
   11080            0 :               return m2expr_GetCardinalZero (location);
   11081              :             }
   11082              :           return HighTree;
   11083              :         }
   11084              :     }
   11085              :   else
   11086              :     {
   11087        21618 :       return m2expr_BuildComponentRef (location, SymbolConversion_Mod2Gcc (param), SymbolConversion_Mod2Gcc (HighField));
   11088              :     }
   11089              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   11090              :   __builtin_unreachable ();
   11091              : }
   11092              : 
   11093              : 
   11094              : /*
   11095              :    StringToChar - if type=Char and str is a string (of size <= 1)
   11096              :                   then convert the string into a character constant.
   11097              : */
   11098              : 
   11099      1143257 : extern "C" tree M2GenGCC_StringToChar (tree t, unsigned int type, unsigned int str)
   11100              : {
   11101      1143257 :   DynamicStrings_String s;
   11102      1143257 :   NameKey_Name n;
   11103      1143257 :   unsigned int tokenno;
   11104      1143257 :   location_t location;
   11105              : 
   11106      1143257 :   tokenno = SymbolTable_GetDeclaredMod (str);
   11107      1143257 :   location = M2LexBuf_TokenToLocation (tokenno);
   11108      1143257 :   type = SymbolTable_SkipType (type);
   11109      1143257 :   if ((type == M2Base_Char) && (SymbolTable_IsConstString (str)))
   11110              :     {
   11111        12552 :       M2Debug_Assert (SymbolTable_IsConstStringKnown (str));
   11112        12552 :       if ((SymbolTable_GetStringLength (tokenno, str)) == 0)
   11113              :         {
   11114          108 :           s = DynamicStrings_InitString ((const char *) "", 0);
   11115          108 :           t = m2type_BuildCharConstant (location, reinterpret_cast <const char * > (s));
   11116          108 :           s = DynamicStrings_KillString (s);
   11117              :         }
   11118        12444 :       else if ((SymbolTable_GetStringLength (tokenno, str)) > 1)
   11119              :         {
   11120              :           /* avoid dangling else.  */
   11121            0 :           n = SymbolTable_GetSymName (str);
   11122            0 :           M2Error_WriteFormat1 ((const char *) "type incompatibility, attempting to use a string ('%a') when a CHAR is expected", 79, (const unsigned char *) &n, (sizeof (n)-1));
   11123            0 :           s = DynamicStrings_InitString ((const char *) "", 0);  /* Do something safe.  */
   11124            0 :           t = m2type_BuildCharConstant (location, reinterpret_cast <const char * > (s));  /* Do something safe.  */
   11125              :         }
   11126        12552 :       s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetString (str)));
   11127        12552 :       s = DynamicStrings_Slice (s, 0, 1);
   11128        12552 :       t = m2type_BuildCharConstant (location, const_cast <const char * > (static_cast <char * > (DynamicStrings_string (s))));
   11129        12552 :       s = DynamicStrings_KillString (s);
   11130              :     }
   11131      1143257 :   return t;
   11132              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   11133              :   __builtin_unreachable ();
   11134              : }
   11135              : 
   11136              : 
   11137              : /*
   11138              :    LValueToGenericPtr - returns a Tree representing symbol, sym.
   11139              :                         It coerces a lvalue into an internal pointer type
   11140              : */
   11141              : 
   11142       529808 : extern "C" tree M2GenGCC_LValueToGenericPtr (location_t location, unsigned int sym)
   11143              : {
   11144       529808 :   tree t;
   11145              : 
   11146       529808 :   t = SymbolConversion_Mod2Gcc (sym);
   11147       529808 :   if (t == NULL)
   11148              :     {
   11149            0 :       M2Error_InternalError ((const char *) "expecting symbol to be resolved", 31);
   11150              :     }
   11151       529808 :   if ((SymbolTable_GetMode (sym)) == SymbolTable_LeftValue)
   11152              :     {
   11153          540 :       t = m2convert_BuildConvert (location, m2type_GetPointerType (), t, false);
   11154              :     }
   11155       529808 :   return t;
   11156              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   11157              :   __builtin_unreachable ();
   11158              : }
   11159              : 
   11160              : 
   11161              : /*
   11162              :    ZConstToTypedConst - checks whether op1 and op2 are constants and
   11163              :                         coerces, t, appropriately.
   11164              : */
   11165              : 
   11166         8464 : extern "C" tree M2GenGCC_ZConstToTypedConst (tree t, unsigned int op1, unsigned int op2)
   11167              : {
   11168         8464 :   location_t location;
   11169              : 
   11170         8464 :   location = M2LexBuf_TokenToLocation (SymbolTable_GetDeclaredMod (op2));
   11171         8464 :   if ((SymbolTable_IsConst (op1)) && (SymbolTable_IsConst (op2)))
   11172              :     {
   11173              :       /* leave, Z type, alone  */
   11174              :       return t;
   11175              :     }
   11176         4028 :   else if (SymbolTable_IsConst (op1))
   11177              :     {
   11178              :       /* avoid dangling else.  */
   11179         2752 :       if ((SymbolTable_GetMode (op2)) == SymbolTable_LeftValue)
   11180              :         {
   11181              :           /* convert, Z type const into type of non constant operand  */
   11182            0 :           return m2convert_BuildConvert (location, m2type_GetPointerType (), t, false);
   11183              :         }
   11184              :       else
   11185              :         {
   11186              :           /* convert, Z type const into type of non constant operand  */
   11187         2752 :           return m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (FindType (op2)), t, false);
   11188              :         }
   11189              :     }
   11190         1276 :   else if (SymbolTable_IsConst (op2))
   11191              :     {
   11192              :       /* avoid dangling else.  */
   11193            0 :       if ((SymbolTable_GetMode (op1)) == SymbolTable_LeftValue)
   11194              :         {
   11195              :           /* convert, Z type const into type of non constant operand  */
   11196            0 :           return m2convert_BuildConvert (location, m2type_GetPointerType (), t, false);
   11197              :         }
   11198              :       else
   11199              :         {
   11200              :           /* convert, Z type const into type of non constant operand  */
   11201            0 :           return m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (FindType (op1)), t, false);
   11202              :         }
   11203              :     }
   11204              :   else
   11205              :     {
   11206              :       /* avoid dangling else.  */
   11207              :       /* neither operands are constants, leave alone  */
   11208              :       return t;
   11209              :     }
   11210              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   11211              :   __builtin_unreachable ();
   11212              : }
   11213              : 
   11214              : 
   11215              : /*
   11216              :    PrepareCopyString - returns two trees:
   11217              :                        length    number of bytes to be copied (including the nul if room)
   11218              :                        srcTreeType the new string type (with the extra nul character).
   11219              : 
   11220              :                        Pre condition:  destStrType the dest type string.
   11221              :                                        src is the original string (without a nul)
   11222              :                                        to be copied.
   11223              :                        Post condition: TRUE or FALSE is returned.
   11224              :                                        if true length and srcTreeType will be assigned
   11225              :                                        else length is set to the maximum length to be
   11226              :                                             copied and srcTree is set to the max length
   11227              :                                             which fits in dest.
   11228              : */
   11229              : 
   11230         3312 : extern "C" bool M2GenGCC_PrepareCopyString (unsigned int tokenno, tree *length, tree *srcTree, unsigned int src, unsigned int destStrType)
   11231              : {
   11232         3312 :   location_t location;
   11233         3312 :   int intLength;
   11234              : 
   11235         3312 :   location = M2LexBuf_TokenToLocation (tokenno);
   11236         3312 :   M2Debug_Assert (SymbolTable_IsArray (SymbolTable_SkipType (destStrType)));
   11237              :   /* Handle string assignments:
   11238              :       VAR
   11239              :          str: ARRAY [0..10] OF CHAR ;
   11240              :          ch : CHAR ;
   11241              : 
   11242              :          str := 'abcde' but not ch := 'a'
   11243              :   */
   11244         3312 :   if ((SymbolTable_GetType (src)) == M2Base_Char)
   11245              :     {
   11246              :       /* avoid dangling else.  */
   11247              :       /* 
   11248              :        *  Create string from char and add nul to the end, nul is
   11249              :        *  added by BuildStringConstant.  In modula-2 an array must
   11250              :        *  have at least one element.
   11251              :   */
   11252          192 :       (*length) = m2expr_GetIntegerOne (location);
   11253          192 :       M2ALU_PushIntegerTree (FindSize (tokenno, src));
   11254          192 :       M2ALU_PushIntegerTree (FindSize (tokenno, destStrType));
   11255          192 :       if (M2ALU_Less (tokenno))
   11256              :         {
   11257              :           /* There is room for the extra <nul> character.  */
   11258          156 :           (*length) = m2expr_BuildAdd (location, (*length), m2expr_GetIntegerOne (location), false);
   11259              :         }
   11260              :     }
   11261              :   else
   11262              :     {
   11263         3120 :       M2ALU_PushIntegerTree (FindSize (tokenno, src));
   11264         3120 :       M2ALU_PushIntegerTree (FindSize (tokenno, destStrType));
   11265         3120 :       if (M2ALU_Less (tokenno))
   11266              :         {
   11267              :           /* There is room for the extra <nul> character.  */
   11268         2952 :           (*length) = m2expr_BuildAdd (location, FindSize (tokenno, src), m2expr_GetIntegerOne (location), false);
   11269         2952 :           (*srcTree) = SymbolConversion_Mod2Gcc (src);
   11270              :         }
   11271              :       else
   11272              :         {
   11273              :           /* We need to truncate the <nul> at least.  */
   11274          168 :           (*length) = FindSize (tokenno, destStrType);
   11275          168 :           M2ALU_PushIntegerTree (FindSize (tokenno, src));
   11276          168 :           M2ALU_PushIntegerTree ((*length));
   11277              :           /* Greater or Equal so return max characters in the array.  */
   11278          168 :           if (M2ALU_Gre (tokenno))
   11279              :             {
   11280              :               /* Create a new string without non nul characters to be gimple safe.
   11281              :                But return FALSE indicating an overflow.  */
   11282           12 :               intLength = m2expr_GetCstInteger ((*length));
   11283           12 :               (*srcTree) = m2decl_BuildStringConstant (const_cast <const char * > (static_cast <char * > (NameKey_KeyToCharStar (SymbolTable_GetString (src)))), intLength);
   11284           12 :               (*srcTree) = m2convert_ConvertString (SymbolConversion_Mod2Gcc (destStrType), (*srcTree));
   11285           12 :               return false;
   11286              :             }
   11287              :         }
   11288              :     }
   11289         3300 :   intLength = m2expr_GetCstInteger ((*length));
   11290         3300 :   (*srcTree) = m2decl_BuildStringConstant (const_cast <const char * > (static_cast <char * > (NameKey_KeyToCharStar (SymbolTable_GetString (src)))), intLength);
   11291         3300 :   (*srcTree) = m2convert_ConvertString (SymbolConversion_Mod2Gcc (destStrType), (*srcTree));
   11292         3300 :   return true;
   11293              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   11294              :   __builtin_unreachable ();
   11295              : }
   11296              : 
   11297        14952 : extern "C" void _M2_M2GenGCC_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
   11298              : {
   11299        14952 :   Init ();
   11300        14952 : }
   11301              : 
   11302            0 : extern "C" void _M2_M2GenGCC_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
   11303              : {
   11304            0 : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.