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