LCOV - code coverage report
Current view: top level - /mnt/build/buildbot/bld/build-lcov/gcc/m2/gm2-compiler-boot - M2Quads.c (source / functions) Coverage Total Hit
Test: gcc.info Lines: 76.3 % 6825 5208
Test Date: 2026-04-20 14:57:17 Functions: 85.2 % 445 379
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* do not edit automatically generated by mc from M2Quads.  */
       2              : /* M2Quads.mod generates quadruples.
       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 "GStorage.h"
      43              : #   include "Gmcrts.h"
      44              : #if defined(__cplusplus)
      45              : #   undef NULL
      46              : #   define NULL 0
      47              : #endif
      48              : #define _M2Quads_C
      49              : 
      50              : #include "GM2Quads.h"
      51              : #   include "GStorage.h"
      52              : #   include "GM2Debug.h"
      53              : #   include "GNameKey.h"
      54              : #   include "GFormatStrings.h"
      55              : #   include "GM2DebugStack.h"
      56              : #   include "GStrLib.h"
      57              : #   include "GM2Scaffold.h"
      58              : #   include "GM2MetaError.h"
      59              : #   include "GDynamicStrings.h"
      60              : #   include "GSymbolTable.h"
      61              : #   include "GM2Batch.h"
      62              : #   include "GM2GCCDeclare.h"
      63              : #   include "GFifoQueue.h"
      64              : #   include "GM2Comp.h"
      65              : #   include "GM2LexBuf.h"
      66              : #   include "GM2Error.h"
      67              : #   include "GM2Printf.h"
      68              : #   include "GM2Reserved.h"
      69              : #   include "GM2Base.h"
      70              : #   include "GM2System.h"
      71              : #   include "GM2Size.h"
      72              : #   include "GM2Bitset.h"
      73              : #   include "GM2ALU.h"
      74              : #   include "GLists.h"
      75              : #   include "GM2Options.h"
      76              : #   include "GM2LangDump.h"
      77              : #   include "GM2Pass.h"
      78              : #   include "GM2StackAddress.h"
      79              : #   include "GM2StackWord.h"
      80              : #   include "GIndexing.h"
      81              : #   include "GM2Range.h"
      82              : #   include "GM2CaseList.h"
      83              : #   include "GPCSymBuild.h"
      84              : #   include "Gm2builtins.h"
      85              : #   include "GSymbolConversion.h"
      86              : #   include "GM2Diagnostic.h"
      87              : #   include "GFIO.h"
      88              : #   include "GSFIO.h"
      89              : #   include "GStdIO.h"
      90              : #   include "GM2StackSpell.h"
      91              : 
      92              : #   define DebugStackOn true
      93              : #   define DebugVarients false
      94              : #   define DebugTokPos false
      95              : typedef struct M2Quads__T1_r M2Quads__T1;
      96              : 
      97              : typedef M2Quads__T1 *M2Quads_ConstructorFrame;
      98              : 
      99              : typedef struct M2Quads__T2_r M2Quads__T2;
     100              : 
     101              : typedef M2Quads__T2 *M2Quads_BoolFrame;
     102              : 
     103              : typedef struct M2Quads__T3_r M2Quads__T3;
     104              : 
     105              : typedef M2Quads__T3 *M2Quads_QuadFrame;
     106              : 
     107              : typedef struct M2Quads__T4_r M2Quads__T4;
     108              : 
     109              : typedef M2Quads__T4 *M2Quads_WithFrame;
     110              : 
     111              : typedef struct M2Quads__T5_r M2Quads__T5;
     112              : 
     113              : typedef M2Quads__T5 *M2Quads_ForLoopInfo;
     114              : 
     115              : typedef struct M2Quads__T6_r M2Quads__T6;
     116              : 
     117              : typedef M2Quads__T6 *M2Quads_LineNote;
     118              : 
     119              : #   define DebugAsmTokPos false
     120              : struct M2Quads__T1_r {
     121              :                        unsigned int type;
     122              :                        unsigned int index;
     123              :                      };
     124              : 
     125              : struct M2Quads__T2_r {
     126              :                        unsigned int TrueExit;
     127              :                        unsigned int FalseExit;
     128              :                        unsigned int Unbounded;
     129              :                        bool BooleanOp;
     130              :                        unsigned int Dimension;
     131              :                        unsigned int ReadWrite;
     132              :                        unsigned int name;
     133              :                        unsigned int RangeDep;
     134              :                        DynamicStrings_String Annotation;
     135              :                        unsigned int tokenno;
     136              :                      };
     137              : 
     138              : struct M2Quads__T3_r {
     139              :                        M2Quads_QuadOperator Operator;
     140              :                        unsigned int Operand1;
     141              :                        unsigned int Operand2;
     142              :                        unsigned int Operand3;
     143              :                        unsigned int Trash;
     144              :                        unsigned int Next;
     145              :                        unsigned int LineNo;
     146              :                        unsigned int TokenNo;
     147              :                        unsigned int NoOfTimesReferenced;
     148              :                        bool ConstExpr;
     149              :                        bool CheckType;
     150              :                        bool CheckOverflow;
     151              :                        unsigned int op1pos;
     152              :                        unsigned int op2pos;
     153              :                        unsigned int op3pos;
     154              :                      };
     155              : 
     156              : struct M2Quads__T4_r {
     157              :                        unsigned int RecordSym;
     158              :                        unsigned int RecordType;
     159              :                        unsigned int RecordRef;
     160              :                        unsigned int rw;
     161              :                        unsigned int RecordTokPos;
     162              :                      };
     163              : 
     164              : struct M2Quads__T5_r {
     165              :                        unsigned int IncrementQuad;
     166              :                        unsigned int StartOfForLoop;
     167              :                        unsigned int EndOfForLoop;
     168              :                        unsigned int ForLoopIndex;
     169              :                        unsigned int IndexTok;
     170              :                      };
     171              : 
     172              : struct M2Quads__T6_r {
     173              :                        unsigned int Line;
     174              :                        NameKey_Name File;
     175              :                        M2Quads_LineNote Next;
     176              :                      };
     177              : 
     178              : static M2StackAddress_StackOfAddress ConstructorStack;
     179              : static M2StackAddress_StackOfAddress LineStack;
     180              : static M2StackAddress_StackOfAddress BoolStack;
     181              : static M2StackAddress_StackOfAddress WithStack;
     182              : static M2StackWord_StackOfWord TryStack;
     183              : static M2StackWord_StackOfWord CatchStack;
     184              : static M2StackWord_StackOfWord ExceptStack;
     185              : static M2StackWord_StackOfWord ConstExprStack;
     186              : static M2StackWord_StackOfWord ConstParamStack;
     187              : static M2StackWord_StackOfWord AutoStack;
     188              : static M2StackWord_StackOfWord RepeatStack;
     189              : static M2StackWord_StackOfWord WhileStack;
     190              : static M2StackWord_StackOfWord ForStack;
     191              : static M2StackWord_StackOfWord ExitStack;
     192              : static M2StackWord_StackOfWord ReturnStack;
     193              : static M2StackWord_StackOfWord PriorityStack;
     194              : static bool SuppressWith;
     195              : static Indexing_Index QuadArray;
     196              : static unsigned int NextQuad;
     197              : static unsigned int FreeList;
     198              : static unsigned int CurrentProc;
     199              : static unsigned int InitQuad;
     200              : static unsigned int LastQuadNo;
     201              : static NameKey_Name ArithPlusTok;
     202              : static NameKey_Name LogicalOrTok;
     203              : static NameKey_Name LogicalAndTok;
     204              : static NameKey_Name LogicalXorTok;
     205              : static NameKey_Name LogicalDifferenceTok;
     206              : static bool InConstExpression;
     207              : static bool InConstParameters;
     208              : static bool IsAutoOn;
     209              : static bool MustNotCheckBounds;
     210              : static Indexing_Index ForInfo;
     211              : static unsigned int GrowInitialization;
     212              : static bool BuildingHigh;
     213              : static bool BuildingSize;
     214              : static bool QuadrupleGeneration;
     215              : static M2Quads_LineNote FreeLineList;
     216              : static Lists_List VarientFields;
     217              : static unsigned int VarientFieldNo;
     218              : static unsigned int NoOfQuads;
     219              : static unsigned int Head;
     220              : static M2Diagnostic_Diagnostic QuadMemDiag;
     221              : static unsigned int BreakQuad;
     222              : 
     223              : /*
     224              :    SetOptionCoding - builds a code quadruple if the profiling
     225              :                      option was given to the compiler.
     226              : */
     227              : 
     228              : extern "C" void M2Quads_SetOptionCoding (bool b);
     229              : 
     230              : /*
     231              :    SetOptionProfiling - builds a profile quadruple if the profiling
     232              :                         option was given to the compiler.
     233              : */
     234              : 
     235              : extern "C" void M2Quads_SetOptionProfiling (bool b);
     236              : 
     237              : /*
     238              :    SetOptionOptimizing - builds a quadruple to say that the optimization option
     239              :                          has been found in a comment.
     240              : */
     241              : 
     242              : extern "C" void M2Quads_SetOptionOptimizing (bool b);
     243              : 
     244              : /*
     245              :    Opposite - returns the opposite comparison operator.
     246              : */
     247              : 
     248              : extern "C" M2Quads_QuadOperator M2Quads_Opposite (M2Quads_QuadOperator Operator);
     249              : 
     250              : /*
     251              :    IsReferenced - returns true if QuadNo is referenced by another quadruple.
     252              : */
     253              : 
     254              : extern "C" bool M2Quads_IsReferenced (unsigned int QuadNo);
     255              : 
     256              : /*
     257              :    IsBackReference - returns TRUE if quadruple, q, is referenced from a quad further on.
     258              : */
     259              : 
     260              : extern "C" bool M2Quads_IsBackReference (unsigned int q);
     261              : 
     262              : /*
     263              :    IsUnConditional - returns true if QuadNo is an unconditional jump.
     264              : */
     265              : 
     266              : extern "C" bool M2Quads_IsUnConditional (unsigned int QuadNo);
     267              : 
     268              : /*
     269              :    IsConditional - returns true if QuadNo is a conditional jump.
     270              : */
     271              : 
     272              : extern "C" bool M2Quads_IsConditional (unsigned int QuadNo);
     273              : 
     274              : /*
     275              :    IsBackReferenceConditional - returns TRUE if quadruple, q, is referenced from
     276              :                                 a conditional quad further on.
     277              : */
     278              : 
     279              : extern "C" bool M2Quads_IsBackReferenceConditional (unsigned int q);
     280              : 
     281              : /*
     282              :    IsGoto - returns true if QuadNo is a goto operation.
     283              : */
     284              : 
     285              : extern "C" bool M2Quads_IsGoto (unsigned int QuadNo);
     286              : 
     287              : /*
     288              :    IsCall - returns true if QuadNo is a call operation.
     289              : */
     290              : 
     291              : extern "C" bool M2Quads_IsCall (unsigned int QuadNo);
     292              : 
     293              : /*
     294              :    IsReturn - returns true if QuadNo is a return operation.
     295              : */
     296              : 
     297              : extern "C" bool M2Quads_IsReturn (unsigned int QuadNo);
     298              : 
     299              : /*
     300              :    IsProcedureScope - returns true if QuadNo is a ProcedureScope operation.
     301              : */
     302              : 
     303              : extern "C" bool M2Quads_IsProcedureScope (unsigned int QuadNo);
     304              : 
     305              : /*
     306              :    IsNewLocalVar - returns true if QuadNo is a NewLocalVar operation.
     307              : */
     308              : 
     309              : extern "C" bool M2Quads_IsNewLocalVar (unsigned int QuadNo);
     310              : 
     311              : /*
     312              :    IsKillLocalVar - returns true if QuadNo is a KillLocalVar operation.
     313              : */
     314              : 
     315              : extern "C" bool M2Quads_IsKillLocalVar (unsigned int QuadNo);
     316              : 
     317              : /*
     318              :    IsCatchBegin - returns true if QuadNo is a catch begin quad.
     319              : */
     320              : 
     321              : extern "C" bool M2Quads_IsCatchBegin (unsigned int QuadNo);
     322              : 
     323              : /*
     324              :    IsCatchEnd - returns true if QuadNo is a catch end quad.
     325              : */
     326              : 
     327              : extern "C" bool M2Quads_IsCatchEnd (unsigned int QuadNo);
     328              : 
     329              : /*
     330              :    IsInitStart - returns true if QuadNo is a init start quad.
     331              : */
     332              : 
     333              : extern "C" bool M2Quads_IsInitStart (unsigned int QuadNo);
     334              : 
     335              : /*
     336              :    IsInitEnd - returns true if QuadNo is a init end quad.
     337              : */
     338              : 
     339              : extern "C" bool M2Quads_IsInitEnd (unsigned int QuadNo);
     340              : 
     341              : /*
     342              :    IsFinallyStart - returns true if QuadNo is a finally start quad.
     343              : */
     344              : 
     345              : extern "C" bool M2Quads_IsFinallyStart (unsigned int QuadNo);
     346              : 
     347              : /*
     348              :    IsFinallyEnd - returns true if QuadNo is a finally end quad.
     349              : */
     350              : 
     351              : extern "C" bool M2Quads_IsFinallyEnd (unsigned int QuadNo);
     352              : 
     353              : /*
     354              :    IsBecomes - return TRUE if QuadNo is a BecomesOp.
     355              : */
     356              : 
     357              : extern "C" bool M2Quads_IsBecomes (unsigned int QuadNo);
     358              : 
     359              : /*
     360              :    IsDummy - return TRUE if QuadNo is a DummyOp.
     361              : */
     362              : 
     363              : extern "C" bool M2Quads_IsDummy (unsigned int QuadNo);
     364              : 
     365              : /*
     366              :    IsQuadConstExpr - returns TRUE if QuadNo is part of a constant expression.
     367              : */
     368              : 
     369              : extern "C" bool M2Quads_IsQuadConstExpr (unsigned int QuadNo);
     370              : 
     371              : /*
     372              :    SetQuadConstExpr - sets the constexpr field to value.
     373              : */
     374              : 
     375              : extern "C" void M2Quads_SetQuadConstExpr (unsigned int QuadNo, bool value);
     376              : 
     377              : /*
     378              :    GetQuadDest - returns the jump destination associated with quad.
     379              : */
     380              : 
     381              : extern "C" unsigned int M2Quads_GetQuadDest (unsigned int QuadNo);
     382              : 
     383              : /*
     384              :    GetQuadOp1 - returns the 1st operand associated with quad.
     385              : */
     386              : 
     387              : extern "C" unsigned int M2Quads_GetQuadOp1 (unsigned int QuadNo);
     388              : 
     389              : /*
     390              :    GetQuadOp2 - returns the 2nd operand associated with quad.
     391              : */
     392              : 
     393              : extern "C" unsigned int M2Quads_GetQuadOp2 (unsigned int QuadNo);
     394              : 
     395              : /*
     396              :    GetQuadOp3 - returns the 3rd operand associated with quad.
     397              : */
     398              : 
     399              : extern "C" unsigned int M2Quads_GetQuadOp3 (unsigned int QuadNo);
     400              : 
     401              : /*
     402              :    IsInitialisingConst - returns TRUE if the quadruple is setting
     403              :                          a const (op1) with a value.
     404              : */
     405              : 
     406              : extern "C" bool M2Quads_IsInitialisingConst (unsigned int QuadNo);
     407              : 
     408              : /*
     409              :    IsConstQuad - return TRUE if the quadruple is marked as a constexpr.
     410              : */
     411              : 
     412              : extern "C" bool M2Quads_IsConstQuad (unsigned int quad);
     413              : 
     414              : /*
     415              :    IsConditionalBooleanQuad - return TRUE if operand 1 is a boolean result.
     416              : */
     417              : 
     418              : extern "C" bool M2Quads_IsConditionalBooleanQuad (unsigned int quad);
     419              : 
     420              : /*
     421              :    IsOptimizeOn - returns true if the Optimize flag was true at QuadNo.
     422              : */
     423              : 
     424              : extern "C" bool M2Quads_IsOptimizeOn (unsigned int QuadNo);
     425              : 
     426              : /*
     427              :    IsProfileOn - returns true if the Profile flag was true at QuadNo.
     428              : */
     429              : 
     430              : extern "C" bool M2Quads_IsProfileOn (unsigned int QuadNo);
     431              : 
     432              : /*
     433              :    IsCodeOn - returns true if the Code flag was true at QuadNo.
     434              : */
     435              : 
     436              : extern "C" bool M2Quads_IsCodeOn (unsigned int QuadNo);
     437              : 
     438              : /*
     439              :    IsPseudoQuad - returns true if QuadNo is a compiler directive.
     440              :                   ie code, profile and optimize.
     441              :                      StartFile, EndFile,
     442              : */
     443              : 
     444              : extern "C" bool M2Quads_IsPseudoQuad (unsigned int QuadNo);
     445              : 
     446              : /*
     447              :    IsDefOrModFile - returns TRUE if QuadNo is a start of Module or Def file
     448              :                     directive.
     449              : */
     450              : 
     451              : extern "C" bool M2Quads_IsDefOrModFile (unsigned int QuadNo);
     452              : 
     453              : /*
     454              :    DumpQuadruples - dump all quadruples providing the -fq, -fdump-lang-quad,
     455              :                     -fdump-lang-quad= or -fdump-lang-all were issued to the
     456              :                     command line.
     457              : */
     458              : 
     459              : extern "C" void M2Quads_DumpQuadruples (const char *title_, unsigned int _title_high);
     460              : 
     461              : /*
     462              :    DisplayQuadRange - displays all quads in list range, start..end.
     463              : */
     464              : 
     465              : extern "C" void M2Quads_DisplayQuadRange (unsigned int scope, unsigned int start, unsigned int end);
     466              : 
     467              : /*
     468              :    DisplayQuad - displays a quadruple, QuadNo.
     469              : */
     470              : 
     471              : extern "C" void M2Quads_DisplayQuad (unsigned int QuadNo);
     472              : 
     473              : /*
     474              :    GetLastFileQuad - returns the Quadruple number of the last StartDefFile or
     475              :                      StartModFile quadruple.
     476              : */
     477              : 
     478              : extern "C" unsigned int M2Quads_GetLastFileQuad (unsigned int QuadNo);
     479              : 
     480              : /*
     481              :    GetLastQuadNo - returns the last quadruple number referenced
     482              :                    by a GetQuad.
     483              : */
     484              : 
     485              : extern "C" unsigned int M2Quads_GetLastQuadNo (void);
     486              : 
     487              : /*
     488              :    QuadToTokenNo - Converts a QuadNo into the approprate token number of the
     489              :                    source file, the line number is returned.
     490              : 
     491              :                    This may be used to yield an idea where abouts in the
     492              :                    source file the code generetion is
     493              :                    processing.
     494              : */
     495              : 
     496              : extern "C" unsigned int M2Quads_QuadToTokenNo (unsigned int QuadNo);
     497              : 
     498              : /*
     499              :    QuadToLineNo - Converts a QuadNo into the approprate line number of the
     500              :                   source file, the line number is returned.
     501              : 
     502              :                   This may be used to yield an idea where abouts in the
     503              :                   source file the code generetion is
     504              :                   processing.
     505              : */
     506              : 
     507              : extern "C" unsigned int M2Quads_QuadToLineNo (unsigned int QuadNo);
     508              : 
     509              : /*
     510              :    GetQuad - returns the Quadruple QuadNo.
     511              : */
     512              : 
     513              : extern "C" void M2Quads_GetQuad (unsigned int QuadNo, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3);
     514              : 
     515              : /*
     516              :    GetQuadOp - returns the operator for quad.
     517              : */
     518              : 
     519              : extern "C" M2Quads_QuadOperator M2Quads_GetQuadOp (unsigned int quad);
     520              : 
     521              : /*
     522              :    GetM2OperatorDesc - returns the Modula-2 string associated with the quad operator
     523              :                        (if possible).  It returns NIL if no there is not an obvious match
     524              :                        in Modula-2.  It is assummed that the string will be used during
     525              :                        construction of error messages and therefore keywords are
     526              :                        wrapped with a format specifier.
     527              : */
     528              : 
     529              : extern "C" DynamicStrings_String M2Quads_GetM2OperatorDesc (M2Quads_QuadOperator op);
     530              : 
     531              : /*
     532              :    GetQuadtok - returns the Quadruple QuadNo.
     533              : */
     534              : 
     535              : extern "C" void M2Quads_GetQuadtok (unsigned int QuadNo, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3, unsigned int *Op1Pos, unsigned int *Op2Pos, unsigned int *Op3Pos);
     536              : 
     537              : /*
     538              :    GetQuadOtok - returns the Quadruple QuadNo.
     539              : */
     540              : 
     541              : extern "C" void M2Quads_GetQuadOtok (unsigned int QuadNo, unsigned int *tok, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3, bool *overflowChecking, bool *constExpr, unsigned int *Op1Pos, unsigned int *Op2Pos, unsigned int *Op3Pos);
     542              : 
     543              : /*
     544              :    GetQuadOTypetok - returns the fields associated with quadruple QuadNo.
     545              : */
     546              : 
     547              : extern "C" void M2Quads_GetQuadOTypetok (unsigned int QuadNo, unsigned int *tok, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3, bool *overflowChecking, bool *typeChecking, bool *constExpr, unsigned int *Op1Pos, unsigned int *Op2Pos, unsigned int *Op3Pos);
     548              : 
     549              : /*
     550              :    PutQuadOtok - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
     551              :                  sets a boolean to determinine whether overflow should be checked.
     552              : */
     553              : 
     554              : extern "C" void M2Quads_PutQuadOtok (unsigned int QuadNo, unsigned int tok, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflowChecking, bool constExpr, unsigned int Op1Pos, unsigned int Op2Pos, unsigned int Op3Pos);
     555              : 
     556              : /*
     557              :    PutQuad - overwrites a quadruple QuadNo with Op, Oper1, Oper2, Oper3
     558              : */
     559              : 
     560              : extern "C" void M2Quads_PutQuad (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3);
     561              : 
     562              : /*
     563              :    GetFirstQuad - returns the first quadruple.
     564              : */
     565              : 
     566              : extern "C" unsigned int M2Quads_GetFirstQuad (void);
     567              : 
     568              : /*
     569              :    GetNextQuad - returns the Quadruple number following QuadNo.
     570              : */
     571              : 
     572              : extern "C" unsigned int M2Quads_GetNextQuad (unsigned int QuadNo);
     573              : 
     574              : /*
     575              :    GetRealQuad - returns the Quadruple number of the real quadruple
     576              :                  at QuadNo or beyond.
     577              : */
     578              : 
     579              : extern "C" unsigned int M2Quads_GetRealQuad (unsigned int QuadNo);
     580              : 
     581              : /*
     582              :    SubQuad - subtracts a quadruple QuadNo from a list Head.
     583              : */
     584              : 
     585              : extern "C" void M2Quads_SubQuad (unsigned int QuadNo);
     586              : 
     587              : /*
     588              :    EraseQuad - erases a quadruple QuadNo, the quadruple is still in the list
     589              :                but wiped clean.
     590              : */
     591              : 
     592              : extern "C" void M2Quads_EraseQuad (unsigned int QuadNo);
     593              : 
     594              : /*
     595              :    CountQuads - returns the number of quadruples.
     596              : */
     597              : 
     598              : extern "C" unsigned int M2Quads_CountQuads (void);
     599              : 
     600              : /*
     601              :    BuildScaffold - generate the main, init, finish functions if
     602              :                    no -c and this is the application module.
     603              : */
     604              : 
     605              : extern "C" void M2Quads_BuildScaffold (unsigned int tok, unsigned int moduleSym);
     606              : 
     607              : /*
     608              :    StartBuildDefFile - generates a StartFileDefOp quadruple indicating the file
     609              :                        that has produced the subsequent quadruples.
     610              :                        The code generator uses the StartDefFileOp quadruples
     611              :                        to relate any error to the appropriate file.
     612              : 
     613              : 
     614              :                        Entry                   Exit
     615              :                        =====                   ====
     616              : 
     617              : 
     618              :                 Ptr ->                                        <- Ptr
     619              :                        +------------+          +------------+
     620              :                        | ModuleName |          | ModuleName |
     621              :                        |------------|          |------------|
     622              : 
     623              : 
     624              :                        Quadruples Produced
     625              : 
     626              :                        q     StartDefFileOp  _  _  ModuleSym
     627              : */
     628              : 
     629              : extern "C" void M2Quads_StartBuildDefFile (unsigned int tok);
     630              : 
     631              : /*
     632              :    StartBuildModFile - generates a StartModFileOp quadruple indicating the file
     633              :                        that has produced the subsequent quadruples.
     634              :                        The code generator uses the StartModFileOp quadruples
     635              :                        to relate any error to the appropriate file.
     636              : 
     637              : 
     638              :                        Entry                   Exit
     639              :                        =====                   ====
     640              : 
     641              : 
     642              :                 Ptr ->                                        <- Ptr
     643              :                        +------------+          +------------+
     644              :                        | ModuleName |          | ModuleName |
     645              :                        |------------|          |------------|
     646              : 
     647              : 
     648              :                        Quadruples Produced
     649              : 
     650              :                        q     StartModFileOp  lineno  filename  ModuleSym
     651              : */
     652              : 
     653              : extern "C" void M2Quads_StartBuildModFile (unsigned int tok);
     654              : 
     655              : /*
     656              :    EndBuildFile - generates an EndFileOp quadruple indicating the file
     657              :                   that has produced the previous quadruples has ended.
     658              : 
     659              :                   Entry                   Exit
     660              :                   =====                   ====
     661              : 
     662              : 
     663              :            Ptr ->                                        <- Ptr
     664              :                   +------------+          +------------+
     665              :                   | ModuleName |          | ModuleName |
     666              :                   |------------|          |------------|
     667              : 
     668              : 
     669              :                   Quadruples Produced
     670              : 
     671              :                   q     EndFileOp  _  _  ModuleSym
     672              : */
     673              : 
     674              : extern "C" void M2Quads_EndBuildFile (unsigned int tok);
     675              : 
     676              : /*
     677              :    StartBuildInit - Sets the start of initialization code of the
     678              :                     current module to the next quadruple.
     679              : */
     680              : 
     681              : extern "C" void M2Quads_StartBuildInit (unsigned int tok);
     682              : 
     683              : /*
     684              :    EndBuildInit - Sets the end initialization code of a module.
     685              : */
     686              : 
     687              : extern "C" void M2Quads_EndBuildInit (unsigned int tok);
     688              : 
     689              : /*
     690              :    StartBuildFinally - Sets the start of finalization code of the
     691              :                        current module to the next quadruple.
     692              : */
     693              : 
     694              : extern "C" void M2Quads_StartBuildFinally (unsigned int tok);
     695              : 
     696              : /*
     697              :    EndBuildFinally - Sets the end finalization code of a module.
     698              : */
     699              : 
     700              : extern "C" void M2Quads_EndBuildFinally (unsigned int tok);
     701              : 
     702              : /*
     703              :    BuildExceptInitial - adds an CatchBeginOp, CatchEndOp quadruple
     704              :                         in the current block.
     705              : */
     706              : 
     707              : extern "C" void M2Quads_BuildExceptInitial (unsigned int tok);
     708              : 
     709              : /*
     710              :    BuildExceptFinally - adds an ExceptOp quadruple in a modules
     711              :                         finally block.
     712              : */
     713              : 
     714              : extern "C" void M2Quads_BuildExceptFinally (unsigned int tok);
     715              : 
     716              : /*
     717              :    BuildExceptProcedure - adds an ExceptOp quadruple in a procedure
     718              :                           block.
     719              : */
     720              : 
     721              : extern "C" void M2Quads_BuildExceptProcedure (unsigned int tok);
     722              : 
     723              : /*
     724              :    BuildRetry - adds an RetryOp quadruple.
     725              : */
     726              : 
     727              : extern "C" void M2Quads_BuildRetry (unsigned int tok);
     728              : 
     729              : /*
     730              :    BuildReThrow - creates a ThrowOp _ _ NulSym, indicating that
     731              :                   the exception needs to be rethrown.  The stack
     732              :                   is unaltered.
     733              : */
     734              : 
     735              : extern "C" void M2Quads_BuildReThrow (unsigned int tokenno);
     736              : 
     737              : /*
     738              :    StartBuildInnerInit - Sets the start of initialization code of the
     739              :                          inner module to the next quadruple.
     740              : */
     741              : 
     742              : extern "C" void M2Quads_StartBuildInnerInit (unsigned int tok);
     743              : 
     744              : /*
     745              :    EndBuildInnerInit - Sets the end initialization code of a module.
     746              : */
     747              : 
     748              : extern "C" void M2Quads_EndBuildInnerInit (unsigned int tok);
     749              : 
     750              : /*
     751              :    BuildBuiltinConst - makes reference to a builtin constant within gm2.
     752              : 
     753              :                               Entry                 Exit
     754              : 
     755              :                        Ptr ->
     756              :                               +------------+        +------------+
     757              :                               | Ident      |        | Sym        |
     758              :                               |------------|        |------------|
     759              : 
     760              :                        Quadruple produced:
     761              : 
     762              :                        q    Sym  BuiltinConstOp  Ident
     763              : */
     764              : 
     765              : extern "C" void M2Quads_BuildBuiltinConst (void);
     766              : 
     767              : /*
     768              :    BuildBuiltinTypeInfo - make reference to a builtin typeinfo function
     769              :                           within gm2.
     770              : 
     771              :                                  Entry                 Exit
     772              : 
     773              :                           Ptr ->
     774              :                                  +-------------+
     775              :                                  | Type        |
     776              :                                  |-------------|       +------------+
     777              :                                  | Ident       |       | Sym        |
     778              :                                  |-------------|       |------------|
     779              : 
     780              :                           Quadruple produced:
     781              : 
     782              :                           q    Sym  BuiltinTypeInfoOp  Type Ident
     783              : */
     784              : 
     785              : extern "C" void M2Quads_BuildBuiltinTypeInfo (void);
     786              : 
     787              : /*
     788              :    BuildAssignment - Builds an assignment from the values given on the
     789              :                      quad stack. Either an assignment to an
     790              :                      arithmetic expression or an assignment to a
     791              :                      boolean expression.  This procedure should not
     792              :                      be called in CONST declarations.
     793              :                      The Stack is expected to contain:
     794              : 
     795              : 
     796              :        Either
     797              : 
     798              :                      Entry                   Exit
     799              :                      =====                   ====
     800              : 
     801              :               Ptr ->
     802              :                      +------------+
     803              :                      | Expression |
     804              :                      |------------|
     805              :                      | Designator |
     806              :                      |------------|          +------------+
     807              :                      |            |          |            |  <- Ptr
     808              :                      |------------|          |------------|
     809              : 
     810              : 
     811              :                      Quadruples Produced
     812              : 
     813              :                      q     BecomesOp  Designator  _  Expression
     814              : 
     815              :        OR
     816              : 
     817              :                      Entry                   Exit
     818              :                      =====                   ====
     819              : 
     820              :               Ptr ->
     821              :                      +------------+
     822              :                      | True |False|
     823              :                      |------------|
     824              :                      | Designator |
     825              :                      |------------|          +------------+
     826              :                      |            |          |            |  <- Ptr
     827              :                      |------------|          |------------|
     828              : 
     829              : 
     830              :                      Quadruples Produced
     831              : 
     832              :                      q     BecomesOp  Designator  _  TRUE
     833              :                      q+1   GotoOp                    q+3
     834              :                      q+2   BecomesOp  Designator  _  FALSE
     835              : 
     836              : */
     837              : 
     838              : extern "C" void M2Quads_BuildAssignment (unsigned int becomesTokNo);
     839              : 
     840              : /*
     841              :    BuildAssignConstant - used to create constant in the CONST declaration.
     842              :                          The stack is expected to contain:
     843              : 
     844              :        Either
     845              : 
     846              :                      Entry                   Exit
     847              :                      =====                   ====
     848              : 
     849              :               Ptr ->
     850              :                      +------------+
     851              :                      | Expression |
     852              :                      |------------|
     853              :                      | Designator |
     854              :                      |------------|          +------------+
     855              :                      |            |          |            |  <- Ptr
     856              :                      |------------|          |------------|
     857              : 
     858              : 
     859              :                      Quadruples Produced
     860              : 
     861              :                      q     BecomesOp  Designator  _  Expression
     862              : 
     863              :        OR
     864              : 
     865              :                      Entry                   Exit
     866              :                      =====                   ====
     867              : 
     868              :               Ptr ->
     869              :                      +------------+
     870              :                      | True |False|
     871              :                      |------------|
     872              :                      | Designator |
     873              :                      |------------|          +------------+
     874              :                      |            |          |            |  <- Ptr
     875              :                      |------------|          |------------|
     876              : 
     877              : 
     878              :                      Quadruples Produced
     879              : 
     880              :                      q     BecomesOp  Designator  _  TRUE
     881              :                      q+1   GotoOp                    q+3
     882              :                      q+2   BecomesOp  Designator  _  FALSE
     883              : */
     884              : 
     885              : extern "C" void M2Quads_BuildAssignConstant (unsigned int equalsTokNo);
     886              : 
     887              : /*
     888              :    BuildAlignment - builds an assignment to an alignment constant.
     889              : 
     890              :                     The Stack is expected to contain:
     891              : 
     892              : 
     893              :                             Entry                   Exit
     894              :                             =====                   ====
     895              : 
     896              :                     Ptr ->
     897              :                             +---------------+
     898              :                             | Expression    |
     899              :                             |---------------|
     900              :                             | bytealignment |
     901              :                             |---------------|       empty
     902              : */
     903              : 
     904              : extern "C" void M2Quads_BuildAlignment (unsigned int tokno);
     905              : 
     906              : /*
     907              :    BuildBitLength - builds an assignment to a bit length constant.
     908              : 
     909              :                     The Stack is expected to contain:
     910              : 
     911              : 
     912              :                            Entry                   Exit
     913              :                            =====                   ====
     914              : 
     915              :                     Ptr ->
     916              :                            +------------+
     917              :                            | Expression |
     918              :                            |------------|          empty
     919              : */
     920              : 
     921              : extern "C" void M2Quads_BuildBitLength (unsigned int tokno);
     922              : 
     923              : /*
     924              :    BuildPragmaField - builds an assignment to an alignment constant.
     925              : 
     926              :                       The Stack is expected to contain:
     927              : 
     928              : 
     929              :                       Entry                   Exit
     930              :                       =====                   ====
     931              : 
     932              :                Ptr ->
     933              :                       +------------+
     934              :                       | Expression |
     935              :                       |------------|          empty
     936              : */
     937              : 
     938              : extern "C" void M2Quads_BuildPragmaField (void);
     939              : 
     940              : /*
     941              :    BuildDefaultFieldAlignment - builds an assignment to an alignment constant.
     942              : 
     943              :                                 The Stack is expected to contain:
     944              : 
     945              : 
     946              :                                        Entry                   Exit
     947              :                                        =====                   ====
     948              : 
     949              :                                 Ptr ->
     950              :                                        +------------+
     951              :                                        | Expression |
     952              :                                        |------------|          empty
     953              : */
     954              : 
     955              : extern "C" void M2Quads_BuildDefaultFieldAlignment (void);
     956              : 
     957              : /*
     958              :    BuildRepeat - Builds the repeat statement from the quad stack.
     959              :                  The Stack is expected to contain:
     960              : 
     961              : 
     962              :                  Entry                   Exit
     963              :                  =====                   ====
     964              : 
     965              : 
     966              :                  Empty
     967              :                                                         <- Ptr
     968              :                                          +------------+
     969              :                                          | RepeatQuad |
     970              :                                          |------------|
     971              : 
     972              : */
     973              : 
     974              : extern "C" void M2Quads_BuildRepeat (void);
     975              : 
     976              : /*
     977              :    BuildUntil - Builds the until part of the repeat statement
     978              :                 from the quad stack.
     979              :                 The Stack is expected to contain:
     980              : 
     981              : 
     982              :                 Entry                   Exit
     983              :                 =====                   ====
     984              : 
     985              :         Ptr ->
     986              :                 +------------+
     987              :                 | t   | f    |
     988              :                 |------------|
     989              :                 | RepeatQuad |          Empty
     990              :                 |------------|
     991              : */
     992              : 
     993              : extern "C" void M2Quads_BuildUntil (void);
     994              : 
     995              : /*
     996              :    BuildWhile - Builds the While part of the While statement
     997              :                 from the quad stack.
     998              :                 The Stack is expected to contain:
     999              : 
    1000              : 
    1001              :                 Entry                   Exit
    1002              :                 =====                   ====
    1003              : 
    1004              :                                                        <- Ptr
    1005              :                                         |------------|
    1006              :                 Empty                   | WhileQuad  |
    1007              :                                         |------------|
    1008              : */
    1009              : 
    1010              : extern "C" void M2Quads_BuildWhile (void);
    1011              : 
    1012              : /*
    1013              :    BuildDoWhile - Builds the Do part of the while statement
    1014              :                   from the quad stack.
    1015              :                   The Stack is expected to contain:
    1016              : 
    1017              : 
    1018              :                   Entry                   Exit
    1019              :                   =====                   ====
    1020              : 
    1021              :           Ptr ->
    1022              :                   +------------+          +------------+
    1023              :                   | t   | f    |          | 0    | f   |
    1024              :                   |------------|          |------------|
    1025              :                   | WhileQuad  |          | WhileQuad  |
    1026              :                   |------------|          |------------|
    1027              : 
    1028              :                   Quadruples
    1029              : 
    1030              :                   BackPatch t exit to the NextQuad
    1031              : */
    1032              : 
    1033              : extern "C" void M2Quads_BuildDoWhile (void);
    1034              : 
    1035              : /*
    1036              :    BuildEndWhile - Builds the end part of the while statement
    1037              :                    from the quad stack.
    1038              :                    The Stack is expected to contain:
    1039              : 
    1040              : 
    1041              :                    Entry                   Exit
    1042              :                    =====                   ====
    1043              : 
    1044              :            Ptr ->
    1045              :                    +------------+
    1046              :                    | t   | f    |
    1047              :                    |------------|
    1048              :                    | WhileQuad  |          Empty
    1049              :                    |------------|
    1050              : 
    1051              :                    Quadruples
    1052              : 
    1053              :                    q    GotoOp  WhileQuad
    1054              :                    False exit is backpatched with q+1
    1055              : */
    1056              : 
    1057              : extern "C" void M2Quads_BuildEndWhile (int reltokpos);
    1058              : 
    1059              : /*
    1060              :    BuildLoop - Builds the Loop part of the Loop statement
    1061              :                from the quad stack.
    1062              :                The Stack is expected to contain:
    1063              : 
    1064              : 
    1065              :                Entry                   Exit
    1066              :                =====                   ====
    1067              : 
    1068              :                                                       <- Ptr
    1069              :                Empty                   +------------+
    1070              :                                        | LoopQuad   |
    1071              :                                        |------------|
    1072              : */
    1073              : 
    1074              : extern "C" void M2Quads_BuildLoop (void);
    1075              : 
    1076              : /*
    1077              :    BuildExit - Builds the Exit part of the Loop statement.
    1078              : */
    1079              : 
    1080              : extern "C" void M2Quads_BuildExit (void);
    1081              : 
    1082              : /*
    1083              :    BuildEndLoop - Builds the End part of the Loop statement
    1084              :                   from the quad stack.
    1085              :                   The Stack is expected to contain:
    1086              : 
    1087              : 
    1088              :                   Entry                   Exit
    1089              :                   =====                   ====
    1090              : 
    1091              :           Ptr ->
    1092              :                   +------------+
    1093              :                   | LoopQuad   |          Empty
    1094              :                   |------------|
    1095              : 
    1096              :                   Quadruples
    1097              : 
    1098              :                   Goto  _  _  LoopQuad
    1099              : */
    1100              : 
    1101              : extern "C" void M2Quads_BuildEndLoop (void);
    1102              : 
    1103              : /*
    1104              :    BuildThenIf - Builds the Then part of the If statement
    1105              :                  from the quad stack.
    1106              :                  The Stack is expected to contain:
    1107              : 
    1108              : 
    1109              :                  Entry                   Exit
    1110              :                  =====                   ====
    1111              : 
    1112              :          Ptr ->                                          <- Ptr
    1113              :                  +------------+          +------------+
    1114              :                  | t   | f    |          | 0    | f   |
    1115              :                  |------------|          |------------|
    1116              : 
    1117              :                  Quadruples
    1118              : 
    1119              :                  The true exit is BackPatched to point to
    1120              :                  the NextQuad.
    1121              : */
    1122              : 
    1123              : extern "C" void M2Quads_BuildThenIf (void);
    1124              : 
    1125              : /*
    1126              :    BuildElse - Builds the Else part of the If statement
    1127              :                from the quad stack.
    1128              :                The Stack is expected to contain:
    1129              : 
    1130              : 
    1131              :                Entry                   Exit
    1132              :                =====                   ====
    1133              : 
    1134              :        Ptr ->
    1135              :                +------------+          +------------+
    1136              :                | t   | f    |          | t+q  | 0   |
    1137              :                |------------|          |------------|
    1138              : 
    1139              :                Quadruples
    1140              : 
    1141              :                q    GotoOp  _  _  0
    1142              :                q+1  <- BackPatched from f
    1143              : */
    1144              : 
    1145              : extern "C" void M2Quads_BuildElse (void);
    1146              : 
    1147              : /*
    1148              :    BuildEndIf - Builds the End part of the If statement
    1149              :                 from the quad stack.
    1150              :                 The Stack is expected to contain:
    1151              : 
    1152              : 
    1153              :                 Entry                   Exit
    1154              :                 =====                   ====
    1155              : 
    1156              :         Ptr ->
    1157              :                 +------------+
    1158              :                 | t   | f    |          Empty
    1159              :                 |------------|
    1160              : 
    1161              :                 Quadruples
    1162              : 
    1163              :                 Both t and f are backpatched to point to the NextQuad
    1164              : */
    1165              : 
    1166              : extern "C" void M2Quads_BuildEndIf (void);
    1167              : 
    1168              : /*
    1169              :    BuildElsif1 - Builds the Elsif part of the If statement
    1170              :                  from the quad stack.
    1171              :                  The Stack is expected to contain:
    1172              : 
    1173              : 
    1174              :                  Entry                   Exit
    1175              :                  =====                   ====
    1176              : 
    1177              :          Ptr ->
    1178              :                  +------------+          +------------+
    1179              :                  | t   | f    |          | t+q  | 0   |
    1180              :                  |------------|          |------------|
    1181              : 
    1182              :                  Quadruples
    1183              : 
    1184              :                  q    GotoOp  _  _  0
    1185              :                  q+1  <- BackPatched from f
    1186              : */
    1187              : 
    1188              : extern "C" void M2Quads_BuildElsif1 (void);
    1189              : 
    1190              : /*
    1191              :    BuildElsif2 - Builds the Elsif until part of the If statement
    1192              :                  from the quad stack.
    1193              :                  The Stack is expected to contain:
    1194              : 
    1195              : 
    1196              :                  Entry                   Exit
    1197              :                  =====                   ====
    1198              : 
    1199              :           Ptr ->
    1200              :                  +--------------+
    1201              :                  | 0    | f1    |                            <- Ptr
    1202              :                  |--------------|          +---------------+
    1203              :                  | t2   | f2    |          | t2    | f1+f2 |
    1204              :                  |--------------|          |---------------|
    1205              : */
    1206              : 
    1207              : extern "C" void M2Quads_BuildElsif2 (void);
    1208              : 
    1209              : /*
    1210              :    BuildForToByDo - Builds the For To By Do part of the For statement
    1211              :                     from the quad stack.
    1212              :                     The Stack is expected to contain:
    1213              : 
    1214              : 
    1215              :                     Entry                   Exit
    1216              :                     =====                   ====
    1217              : 
    1218              :                                                                <- Ptr
    1219              :                                             +----------------+
    1220              :              Ptr ->                         | RangeId        |
    1221              :                     +----------------+      |----------------|
    1222              :                     | BySym | ByType |      | ForQuad        |
    1223              :                     |----------------|      |----------------|
    1224              :                     | e2             |      | LastValue      |
    1225              :                     |----------------|      |----------------|
    1226              :                     | e1             |      | BySym | ByType |
    1227              :                     |----------------|      |----------------|
    1228              :                     | Ident          |      | IdentSym       |
    1229              :                     |----------------|      |----------------|
    1230              : 
    1231              : 
    1232              :                     x := e1 ;
    1233              :                     Note that LASTVALUE is calculated during M2GenGCC
    1234              :                          after all the types have been resolved.
    1235              :                     LASTVALUE := ((e2-e1) DIV BySym) * BySym + e1
    1236              :                     IF BySym<0
    1237              :                     THEN
    1238              :                        IF e1<e2
    1239              :                        THEN
    1240              :                           goto exit
    1241              :                        END
    1242              :                     ELSE
    1243              :                        IF e1>e2
    1244              :                        THEN
    1245              :                           goto exit
    1246              :                        END
    1247              :                     END ;
    1248              :                     LOOP
    1249              :                        body
    1250              :                        IF x=LASTVALUE
    1251              :                        THEN
    1252              :                           goto exit
    1253              :                        END ;
    1254              :                        INC(x, BySym)
    1255              :                     END
    1256              : 
    1257              :                     Quadruples:
    1258              : 
    1259              :                     q     BecomesOp  IdentSym  _  e1
    1260              :                     q+    LastForIteratorOp  LastValue  := ((e1-e2) DIV by) * by + e1
    1261              :                     q+1   if >=      by        0  q+..2
    1262              :                     q+2   GotoOp                  q+3
    1263              :                     q+3   If >=      e1  e2       q+5
    1264              :                     q+4   GotoOp                  exit
    1265              :                     q+5   ..
    1266              :                     q+..1 Goto                    q+..5
    1267              :                     q+..2 If >=      e2  e1       q+..4
    1268              :                     q+..3 GotoOp                  exit
    1269              :                     q+..4 ..
    1270              : 
    1271              :                     The For Loop is regarded:
    1272              : 
    1273              :                     For ident := e1 To e2 By by Do
    1274              : 
    1275              :                     End
    1276              : */
    1277              : 
    1278              : extern "C" void M2Quads_BuildForToByDo (void);
    1279              : 
    1280              : /*
    1281              :    BuildPseudoBy - Builds the Non existant part of the By
    1282              :                    clause of the For statement
    1283              :                    from the quad stack.
    1284              :                    The Stack is expected to contain:
    1285              : 
    1286              : 
    1287              :                    Entry                   Exit
    1288              :                    =====                   ====
    1289              : 
    1290              :                                                            <- Ptr
    1291              :                                            +------------+
    1292              :             Ptr ->                         | BySym | t  |
    1293              :                    +------------+          |------------|
    1294              :                    | e    | t   |          | e     | t  |
    1295              :                    |------------|          |------------|
    1296              : */
    1297              : 
    1298              : extern "C" void M2Quads_BuildPseudoBy (void);
    1299              : 
    1300              : /*
    1301              :    BuildEndFor - Builds the End part of the For statement
    1302              :                  from the quad stack.
    1303              :                  The Stack is expected to contain:
    1304              : 
    1305              : 
    1306              :                  Entry                   Exit
    1307              :                  =====                   ====
    1308              : 
    1309              :          Ptr ->
    1310              :                  +----------------+
    1311              :                  | RangeId        |
    1312              :                  |----------------|
    1313              :                  | ForQuad        |
    1314              :                  |----------------|
    1315              :                  | LastValue      |
    1316              :                  |----------------|
    1317              :                  | BySym | ByType |
    1318              :                  |----------------|
    1319              :                  | IdSym          |      Empty
    1320              :                  |----------------|
    1321              : */
    1322              : 
    1323              : extern "C" void M2Quads_BuildEndFor (unsigned int endpostok);
    1324              : 
    1325              : /*
    1326              :    BuildCaseStart - starts the case statement.
    1327              :                     It initializes a backpatch list on the compile
    1328              :                     time stack, the list is used to contain all
    1329              :                     case break points. The list is later backpatched
    1330              :                     and contains all positions of the case statement
    1331              :                     which jump to the end of the case statement.
    1332              :                     The stack also contains room for a boolean
    1333              :                     expression, this is needed to allow , operator
    1334              :                     in the CaseField alternatives.
    1335              : 
    1336              :                     The Stack is expected to contain:
    1337              : 
    1338              : 
    1339              :                     Entry                   Exit
    1340              :                     =====                   ====
    1341              : 
    1342              :                                                            <- Ptr
    1343              :                                             +------------+
    1344              :                                             | 0    | 0   |
    1345              :                                             |------------|
    1346              :                                             | 0    | 0   |
    1347              :                     +-------------+         |------------|
    1348              :                     | Expr |      |         | Expr |     |
    1349              :                     |-------------|         |------------|
    1350              : */
    1351              : 
    1352              : extern "C" void M2Quads_BuildCaseStart (void);
    1353              : 
    1354              : /*
    1355              :    BuildCaseStartStatementSequence - starts the statement sequence
    1356              :                                      inside a case clause.
    1357              :                                      BackPatches the true exit to the
    1358              :                                      NextQuad.
    1359              :                                      The Stack:
    1360              : 
    1361              :                                      Entry             Exit
    1362              : 
    1363              :                               Ptr ->                                  <- Ptr
    1364              :                                      +-----------+     +------------+
    1365              :                                      | t   | f   |     | 0   | f    |
    1366              :                                      |-----------|     |------------|
    1367              : */
    1368              : 
    1369              : extern "C" void M2Quads_BuildCaseStartStatementSequence (void);
    1370              : 
    1371              : /*
    1372              :    BuildCaseEndStatementSequence - ends the statement sequence
    1373              :                                    inside a case clause.
    1374              :                                    BackPatches the false exit f1 to the
    1375              :                                    NextQuad.
    1376              :                                    Asserts that t1 and f2 is 0
    1377              :                                    Pushes t2+q and 0
    1378              : 
    1379              :                                    Quadruples:
    1380              : 
    1381              :                                    q  GotoOp  _  _  0
    1382              : 
    1383              :                                    The Stack:
    1384              : 
    1385              :                                    Entry             Exit
    1386              : 
    1387              :                             Ptr ->                                  <- Ptr
    1388              :                                    +-----------+     +------------+
    1389              :                                    | t1  | f1  |     | 0    | 0   |
    1390              :                                    |-----------|     |------------|
    1391              :                                    | t2  | f2  |     | t2+q | 0   |
    1392              :                                    |-----------|     |------------|
    1393              : */
    1394              : 
    1395              : extern "C" void M2Quads_BuildCaseEndStatementSequence (void);
    1396              : 
    1397              : /*
    1398              :    BuildCaseRange - builds the range testing quaruples for
    1399              :                     a case clause.
    1400              : 
    1401              :                     IF (e1>=ce1) AND (e1<=ce2)
    1402              :                     THEN
    1403              : 
    1404              :                     ELS..
    1405              : 
    1406              :                     The Stack:
    1407              : 
    1408              :                     Entry             Exit
    1409              : 
    1410              :              Ptr ->
    1411              :                     +-----------+
    1412              :                     | ce2       |                   <- Ptr
    1413              :                     |-----------|     +-----------+
    1414              :                     | ce1       |     | t   | f   |
    1415              :                     |-----------|     |-----------|
    1416              :                     | t1  | f1  |     | t1  | f1  |
    1417              :                     |-----------|     |-----------|
    1418              :                     | t2  | f2  |     | t2  | f2  |
    1419              :                     |-----------|     |-----------|
    1420              :                     | e1        |     | e1        |
    1421              :                     |-----------|     |-----------|
    1422              : */
    1423              : 
    1424              : extern "C" void M2Quads_BuildCaseRange (void);
    1425              : 
    1426              : /*
    1427              :    BuildCaseEquality - builds the range testing quadruples for
    1428              :                        a case clause.
    1429              : 
    1430              :                        IF e1=ce1
    1431              :                        THEN
    1432              : 
    1433              :                        ELS..
    1434              : 
    1435              :                        The Stack:
    1436              : 
    1437              :                        Entry             Exit
    1438              : 
    1439              :                 Ptr ->
    1440              :                        +-----------+     +-----------+
    1441              :                        | ce1       |     | t   | f   |
    1442              :                        |-----------|     |-----------|
    1443              :                        | t1  | f1  |     | t1  | f1  |
    1444              :                        |-----------|     |-----------|
    1445              :                        | t2  | f2  |     | t2  | f2  |
    1446              :                        |-----------|     |-----------|
    1447              :                        | e1        |     | e1        |
    1448              :                        |-----------|     |-----------|
    1449              : */
    1450              : 
    1451              : extern "C" void M2Quads_BuildCaseEquality (void);
    1452              : 
    1453              : /*
    1454              :    BuildCaseList - merges two case tests into one
    1455              : 
    1456              :                    The Stack:
    1457              : 
    1458              :                    Entry             Exit
    1459              : 
    1460              :             Ptr ->
    1461              :                    +-----------+
    1462              :                    | t2  | f2  |
    1463              :                    |-----------|     +-------------+
    1464              :                    | t1  | f1  |     | t1+t2| f1+f2|
    1465              :                    |-----------|     |-------------|
    1466              : */
    1467              : 
    1468              : extern "C" void M2Quads_BuildCaseList (void);
    1469              : 
    1470              : /*
    1471              :    BuildCaseOr - builds the , in the case clause.
    1472              : 
    1473              :                  The Stack:
    1474              : 
    1475              :                  Entry             Exit
    1476              : 
    1477              :           Ptr ->                                  <- Ptr
    1478              :                  +-----------+     +------------+
    1479              :                  | t   | f   |     | t    | 0   |
    1480              :                  |-----------|     |------------|
    1481              : */
    1482              : 
    1483              : extern "C" void M2Quads_BuildCaseOr (void);
    1484              : 
    1485              : /*
    1486              :    BuildCaseElse - builds the else of case clause.
    1487              : 
    1488              :                   The Stack:
    1489              : 
    1490              :                   Entry             Exit
    1491              : 
    1492              :            Ptr ->                                  <- Ptr
    1493              :                   +-----------+     +------------+
    1494              :                   | t   | f   |     | t    | 0   |
    1495              :                   |-----------|     |------------|
    1496              : */
    1497              : 
    1498              : extern "C" void M2Quads_BuildCaseElse (void);
    1499              : 
    1500              : /*
    1501              :    BuildCaseEnd - builds the end of case clause.
    1502              : 
    1503              :                   The Stack:
    1504              : 
    1505              :                   Entry             Exit
    1506              : 
    1507              :            Ptr ->
    1508              :                   +-----------+
    1509              :                   | t1  | f1  |
    1510              :                   |-----------|
    1511              :                   | t2  | f2  |
    1512              :                   |-----------|
    1513              :                   | e1        |
    1514              :                   |-----------|     Empty
    1515              : */
    1516              : 
    1517              : extern "C" void M2Quads_BuildCaseEnd (void);
    1518              : 
    1519              : /*
    1520              :    BuildCaseCheck - builds the case checking code to ensure that
    1521              :                     the program does not need an else clause at runtime.
    1522              :                     The stack is unaltered.
    1523              : */
    1524              : 
    1525              : extern "C" void M2Quads_BuildCaseCheck (void);
    1526              : 
    1527              : /*
    1528              :    BuildNulParam - Builds a nul parameter on the stack.
    1529              :                    The Stack:
    1530              : 
    1531              :                    Entry             Exit
    1532              : 
    1533              :                                                     <- Ptr
    1534              :                    Empty             +------------+
    1535              :                                      | 0          |
    1536              :                                      |------------|
    1537              : */
    1538              : 
    1539              : extern "C" void M2Quads_BuildNulParam (void);
    1540              : 
    1541              : /*
    1542              :    BuildProcedureCall - builds a procedure call.
    1543              :                         Although this procedure does not directly
    1544              :                         destroy the procedure parameters, it calls
    1545              :                         routine which will manipulate the stack and
    1546              :                         so the entry and exit states of the stack are shown.
    1547              : 
    1548              :                         The Stack:
    1549              : 
    1550              : 
    1551              :                         Entry                      Exit
    1552              : 
    1553              :                  Ptr ->
    1554              :                         +----------------+
    1555              :                         | NoOfParam      |
    1556              :                         |----------------|
    1557              :                         | Param 1        |
    1558              :                         |----------------|
    1559              :                         | Param 2        |
    1560              :                         |----------------|
    1561              :                         .                .
    1562              :                         .                .
    1563              :                         .                .
    1564              :                         |----------------|
    1565              :                         | Param #        |
    1566              :                         |----------------|
    1567              :                         | ProcSym | Type |         Empty
    1568              :                         |----------------|
    1569              : */
    1570              : 
    1571              : extern "C" void M2Quads_BuildProcedureCall (unsigned int tokno);
    1572              : 
    1573              : /*
    1574              :    CheckBuildFunction - checks to see whether ProcSym is a function
    1575              :                         and if so it adds a TempSym value which will
    1576              :                         hold the return value once the function finishes.
    1577              :                         This procedure also generates an error message
    1578              :                         if the user is calling a function and ignoring
    1579              :                         the return result.  The additional TempSym
    1580              :                         is not created if ProcSym is a procedure
    1581              :                         and the stack is unaltered.
    1582              : 
    1583              :                         The Stack:
    1584              : 
    1585              : 
    1586              :                        Entry                      Exit
    1587              : 
    1588              :                 Ptr ->
    1589              : 
    1590              :                                                   +----------------+
    1591              :                                                   | ProcSym | Type |
    1592              :                        +----------------+         |----------------|
    1593              :                        | ProcSym | Type |         | TempSym | Type |
    1594              :                        |----------------|         |----------------|
    1595              : */
    1596              : 
    1597              : extern "C" bool M2Quads_CheckBuildFunction (void);
    1598              : 
    1599              : /*
    1600              :    BuildFunctionCall - builds a function call.
    1601              :                        The Stack:
    1602              : 
    1603              : 
    1604              :                        Entry                      Exit
    1605              : 
    1606              :                 Ptr ->
    1607              :                        +----------------+
    1608              :                        | NoOfParam      |
    1609              :                        |----------------|
    1610              :                        | Param 1        |
    1611              :                        |----------------|
    1612              :                        | Param 2        |
    1613              :                        |----------------|
    1614              :                        .                .
    1615              :                        .                .
    1616              :                        .                .
    1617              :                        |----------------|
    1618              :                        | Param #        |                        <- Ptr
    1619              :                        |----------------|         +------------+
    1620              :                        | ProcSym | Type |         | ReturnVar  |
    1621              :                        |----------------|         |------------|
    1622              : */
    1623              : 
    1624              : extern "C" void M2Quads_BuildFunctionCall (bool ConstExpr);
    1625              : 
    1626              : /*
    1627              :    BuildConstFunctionCall - builds a function call and checks that this function can be
    1628              :                             called inside a ConstExpression.
    1629              : 
    1630              :                             The Stack:
    1631              : 
    1632              : 
    1633              :                             Entry                      Exit
    1634              : 
    1635              :                      Ptr ->
    1636              :                             +----------------+
    1637              :                             | NoOfParam      |
    1638              :                             |----------------|
    1639              :                             | Param 1        |
    1640              :                             |----------------|
    1641              :                             | Param 2        |
    1642              :                             |----------------|
    1643              :                             .                .
    1644              :                             .                .
    1645              :                             .                .
    1646              :                             |----------------|
    1647              :                             | Param #        |                        <- Ptr
    1648              :                             |----------------|         +------------+
    1649              :                             | ProcSym | Type |         | ReturnVar  |
    1650              :                             |----------------|         |------------|
    1651              : 
    1652              : */
    1653              : 
    1654              : extern "C" void M2Quads_BuildConstFunctionCall (void);
    1655              : 
    1656              : /*
    1657              :    BuildBooleanVariable - tests to see whether top of stack is a boolean
    1658              :                           conditional and if so it converts it into a boolean
    1659              :                           variable.
    1660              : */
    1661              : 
    1662              : extern "C" void M2Quads_BuildBooleanVariable (void);
    1663              : 
    1664              : /*
    1665              :    BuildModuleStart - starts current module scope.
    1666              : */
    1667              : 
    1668              : extern "C" void M2Quads_BuildModuleStart (unsigned int tok);
    1669              : 
    1670              : /*
    1671              :    BuildProcedureStart - Builds start of the procedure. Generates a
    1672              :                          quadruple which indicated the start of
    1673              :                          this procedure declarations scope.
    1674              :                          The Stack is expected to contain:
    1675              : 
    1676              : 
    1677              :                          Entry                   Exit
    1678              :                          =====                   ====
    1679              : 
    1680              :                  Ptr ->                                       <- Ptr
    1681              :                         +------------+          +-----------+
    1682              :                         | ProcSym    |          | ProcSym   |
    1683              :                         |------------|          |-----------|
    1684              :                         | Name       |          | Name      |
    1685              :                         |------------|          |-----------|
    1686              : 
    1687              : 
    1688              :                         Quadruples:
    1689              : 
    1690              :                         q   ProcedureScopeOp  Line#  Scope  ProcSym
    1691              : */
    1692              : 
    1693              : extern "C" void M2Quads_BuildProcedureStart (void);
    1694              : 
    1695              : /*
    1696              :    BuildProcedureBegin - determines the start of the BEGIN END block of
    1697              :                          the procedure.
    1698              :                          The Stack is expected to contain:
    1699              : 
    1700              : 
    1701              :                          Entry                   Exit
    1702              :                          =====                   ====
    1703              : 
    1704              :                  Ptr ->                                       <- Ptr
    1705              :                         +------------+          +-----------+
    1706              :                         | ProcSym    |          | ProcSym   |
    1707              :                         |------------|          |-----------|
    1708              :                         | Name       |          | Name      |
    1709              :                         |------------|          |-----------|
    1710              : 
    1711              : 
    1712              :                         Quadruples:
    1713              : 
    1714              :                         q   NewLocalVarOp  TokenNo(BEGIN)  _  ProcSym
    1715              : */
    1716              : 
    1717              : extern "C" void M2Quads_BuildProcedureBegin (void);
    1718              : 
    1719              : /*
    1720              :    BuildProcedureEnd - Builds end of the procedure. Destroys space for
    1721              :                        the local variables.
    1722              :                        The Stack is expected to contain:
    1723              : 
    1724              : 
    1725              :                        Entry                   Exit
    1726              :                        =====                   ====
    1727              : 
    1728              :                 Ptr ->                                       <- Ptr
    1729              :                        +------------+          +-----------+
    1730              :                        | ProcSym    |          | ProcSym   |
    1731              :                        |------------|          |-----------|
    1732              :                        | Name       |          | Name      |
    1733              :                        |------------|          |-----------|
    1734              : 
    1735              : 
    1736              :                        Quadruples:
    1737              : 
    1738              :                        q   KillLocalVarOp  TokenNo(END)  _  ProcSym
    1739              : */
    1740              : 
    1741              : extern "C" void M2Quads_BuildProcedureEnd (void);
    1742              : 
    1743              : /*
    1744              :    BuildReturn - Builds the Return part of the procedure.
    1745              :                  tokreturn is the location of the RETURN keyword.
    1746              :                  The Stack is expected to contain:
    1747              : 
    1748              : 
    1749              :                  Entry                   Exit
    1750              :                  =====                   ====
    1751              : 
    1752              :          Ptr ->
    1753              :                  +------------+
    1754              :                  | e1         |          Empty
    1755              :                  |------------|
    1756              : */
    1757              : 
    1758              : extern "C" void M2Quads_BuildReturn (unsigned int tokreturn);
    1759              : 
    1760              : /*
    1761              :    BuildModulePriority - assigns the current module with a priority
    1762              :                          from the top of stack.
    1763              : 
    1764              :                          Entry                   Exit
    1765              :                          =====                   ====
    1766              : 
    1767              : 
    1768              :                   Ptr ->                         Empty
    1769              :                          +------------+
    1770              :                          | Priority   |
    1771              :                          |------------|
    1772              : */
    1773              : 
    1774              : extern "C" void M2Quads_BuildModulePriority (void);
    1775              : 
    1776              : /*
    1777              :    StartBuildWith - performs the with statement.
    1778              :                     The Stack:
    1779              : 
    1780              :                     Entry                    Exit
    1781              : 
    1782              :                     +------------+
    1783              :                     | Sym | Type |           Empty
    1784              :                     |------------|
    1785              : */
    1786              : 
    1787              : extern "C" void M2Quads_StartBuildWith (unsigned int withTok);
    1788              : 
    1789              : /*
    1790              :    EndBuildWith - terminates the innermost with scope.
    1791              : */
    1792              : 
    1793              : extern "C" void M2Quads_EndBuildWith (void);
    1794              : 
    1795              : /*
    1796              :    CheckWithReference - performs the with statement.
    1797              :                         The Stack:
    1798              : 
    1799              :                         Entry                    Exit
    1800              : 
    1801              :                         +------------+           +------------+
    1802              :                         | Sym | Type |           | Sym | Type |
    1803              :                         |------------|           |------------|
    1804              : */
    1805              : 
    1806              : extern "C" void M2Quads_CheckWithReference (void);
    1807              : 
    1808              : /*
    1809              :    BuildDesignatorRecord - Builds the record referencing.
    1810              :                            The Stack is expected to contain:
    1811              : 
    1812              : 
    1813              :                            Entry                   Exit
    1814              :                            =====                   ====
    1815              : 
    1816              :                    Ptr ->
    1817              :                            +--------------+
    1818              :                            | n            |
    1819              :                            |--------------|
    1820              :                            | fld1 | type1 |
    1821              :                            |--------------|
    1822              :                            .              .
    1823              :                            .              .
    1824              :                            .              .
    1825              :                            |--------------|
    1826              :                            | fldn | typen |                        <- Ptr
    1827              :                            |--------------|        +-------------+
    1828              :                            | Sym  | Type  |        | S    | type1|
    1829              :                            |--------------|        |-------------|
    1830              : */
    1831              : 
    1832              : extern "C" void M2Quads_BuildDesignatorRecord (unsigned int dottok);
    1833              : 
    1834              : /*
    1835              :    BuildDesignatorArray - Builds the array referencing.
    1836              :                           The purpose of this procedure is to work out
    1837              :                           whether the DesignatorArray is a constant string or
    1838              :                           dynamic array/static array and to call the appropriate
    1839              :                           BuildRoutine.
    1840              : 
    1841              :                           The Stack is expected to contain:
    1842              : 
    1843              :                           Entry                   Exit
    1844              :                           =====                   ====
    1845              : 
    1846              :                   Ptr ->
    1847              :                           +--------------+
    1848              :                           | e            |                        <- Ptr
    1849              :                           |--------------|        +------------+
    1850              :                           | Sym  | Type  |        | S    | T   |
    1851              :                           |--------------|        |------------|
    1852              : */
    1853              : 
    1854              : extern "C" void M2Quads_BuildDesignatorArray (void);
    1855              : 
    1856              : /*
    1857              :    BuildDesignatorPointer - Builds a pointer reference.
    1858              :                             The Stack is expected to contain:
    1859              : 
    1860              : 
    1861              :                             Entry                   Exit
    1862              :                             =====                   ====
    1863              : 
    1864              :                     Ptr ->                                           <- Ptr
    1865              :                             +--------------+        +--------------+
    1866              :                             | Sym1  | Type1|        | Sym2  | Type2|
    1867              :                             |--------------|        |--------------|
    1868              : */
    1869              : 
    1870              : extern "C" void M2Quads_BuildDesignatorPointer (unsigned int ptrtok);
    1871              : 
    1872              : /*
    1873              :    BuildNulExpression - Builds a nul expression on the stack.
    1874              :                         The Stack:
    1875              : 
    1876              :                         Entry             Exit
    1877              : 
    1878              :                                                          <- Ptr
    1879              :                         Empty             +------------+
    1880              :                                           | NulSym     |
    1881              :                                           |------------|
    1882              :    tokpos is the position of the RETURN token.
    1883              : */
    1884              : 
    1885              : extern "C" void M2Quads_BuildNulExpression (unsigned int tokpos);
    1886              : 
    1887              : /*
    1888              :    BuildSetStart - Pushes a Bitset type on the stack.
    1889              : 
    1890              :                       The Stack:
    1891              : 
    1892              :                       Entry             Exit
    1893              : 
    1894              :                Ptr ->                                        <- Ptr
    1895              : 
    1896              :                       Empty             +--------------+
    1897              :                                         | Bitset       |
    1898              :                                         |--------------|
    1899              : */
    1900              : 
    1901              : extern "C" void M2Quads_BuildSetStart (unsigned int tokpos);
    1902              : 
    1903              : /*
    1904              :    BuildSetEnd - pops the set value and type from the stack
    1905              :                  and pushes the value,type pair.
    1906              : 
    1907              :                     Entry                   Exit
    1908              : 
    1909              :              Ptr ->
    1910              :                     +--------------+
    1911              :                     | Set Value    |                         <- Ptr
    1912              :                     |--------------|        +--------------+
    1913              :                     | Set Type     |        | Value | Type |
    1914              :                     |--------------|        |--------------|
    1915              : */
    1916              : 
    1917              : extern "C" void M2Quads_BuildSetEnd (void);
    1918              : 
    1919              : /*
    1920              :    BuildEmptySet - Builds an empty set on the stack.
    1921              :                    The Stack:
    1922              : 
    1923              :                    Entry             Exit
    1924              : 
    1925              :                                                      <- Ptr
    1926              :                                      +-------------+
    1927              :             Ptr ->                   | Value       |
    1928              :                    +-----------+     |-------------|
    1929              :                    | SetType   |     | SetType     |
    1930              :                    |-----------|     |-------------|
    1931              : 
    1932              :    tokpos points to the opening '{'.
    1933              : */
    1934              : 
    1935              : extern "C" void M2Quads_BuildEmptySet (unsigned int tokpos);
    1936              : 
    1937              : /*
    1938              :    BuildInclRange - includes a set range with a set.
    1939              : 
    1940              : 
    1941              :                           Entry                   Exit
    1942              :                           =====                   ====
    1943              : 
    1944              : 
    1945              :                    Ptr ->
    1946              :                           +------------+
    1947              :                           | El2        |
    1948              :                           |------------|
    1949              :                           | El1        |                                 <- Ptr
    1950              :                           |------------|           +-------------------+
    1951              :                           | Set Value  |           | Value + {El1..El2}|
    1952              :                           |------------|           |-------------------|
    1953              : 
    1954              :                    No quadruples produced as the range info is contained within
    1955              :                    the set value.
    1956              : */
    1957              : 
    1958              : extern "C" void M2Quads_BuildInclRange (void);
    1959              : 
    1960              : /*
    1961              :    BuildInclBit - includes a bit into the set.
    1962              : 
    1963              :                          Entry                   Exit
    1964              :                          =====                   ====
    1965              : 
    1966              : 
    1967              :                   Ptr ->
    1968              :                          +------------+
    1969              :                          | Element    |                         <- Ptr
    1970              :                          |------------|          +------------+
    1971              :                          | Value      |          | Value      |
    1972              :                          |------------|          |------------|
    1973              : 
    1974              : */
    1975              : 
    1976              : extern "C" void M2Quads_BuildInclBit (void);
    1977              : 
    1978              : /*
    1979              :    SilentBuildConstructor - places NulSym into the constructor fifo queue.
    1980              : */
    1981              : 
    1982              : extern "C" void M2Quads_SilentBuildConstructor (void);
    1983              : 
    1984              : /*
    1985              :    SilentBuildConstructorStart - removes an entry from the constructor fifo queue.
    1986              : */
    1987              : 
    1988              : extern "C" void M2Quads_SilentBuildConstructorStart (void);
    1989              : 
    1990              : /*
    1991              :    BuildConstructor - builds a constructor.
    1992              :                       Stack
    1993              : 
    1994              :                       Entry                 Exit
    1995              : 
    1996              :                Ptr ->
    1997              :                       +------------+
    1998              :                       | Type       |                <- Ptr
    1999              :                       |------------+
    2000              : */
    2001              : 
    2002              : extern "C" void M2Quads_BuildConstructor (unsigned int tokcbrpos);
    2003              : 
    2004              : /*
    2005              :    BuildConstructorStart - builds a constructor.
    2006              :                            Stack
    2007              : 
    2008              :                            Entry                 Exit
    2009              : 
    2010              :                     Ptr ->                                          <- Ptr
    2011              :                            +------------+        +----------------+
    2012              :                            | Type       |        | ConstructorSym |
    2013              :                            |------------+        |----------------|
    2014              : */
    2015              : 
    2016              : extern "C" void M2Quads_BuildConstructorStart (unsigned int cbratokpos);
    2017              : 
    2018              : /*
    2019              :    BuildConstructorEnd - removes the current constructor frame from the
    2020              :                          constructor stack (it does not effect the quad
    2021              :                          stack)
    2022              : 
    2023              :                          Entry                 Exit
    2024              : 
    2025              :                   Ptr ->                                      <- Ptr
    2026              :                          +------------+        +------------+
    2027              :                          | const      |        | const      |
    2028              :                          |------------|        |------------|
    2029              : 
    2030              :    startpos is the start of the constructor, either the typename or '{'
    2031              :    cbratokpos is the '}'.
    2032              : */
    2033              : 
    2034              : extern "C" void M2Quads_BuildConstructorEnd (unsigned int startpos, unsigned int cbratokpos);
    2035              : 
    2036              : /*
    2037              :    NextConstructorField - increments the top of constructor stacks index by one.
    2038              : */
    2039              : 
    2040              : extern "C" void M2Quads_NextConstructorField (void);
    2041              : 
    2042              : /*
    2043              :    BuildTypeForConstructor - pushes the type implied by the current constructor.
    2044              :                              If no constructor is currently being built then
    2045              :                              it Pushes a Bitset type.
    2046              : */
    2047              : 
    2048              : extern "C" void M2Quads_BuildTypeForConstructor (unsigned int tokpos);
    2049              : 
    2050              : /*
    2051              :    BuildComponentValue -  builds a component value.
    2052              : 
    2053              :                           Entry                 Exit
    2054              : 
    2055              :                    Ptr ->                                      <- Ptr
    2056              : 
    2057              : 
    2058              :                           +------------+        +------------+
    2059              :                           | const      |        | const      |
    2060              :                           |------------|        |------------|
    2061              : */
    2062              : 
    2063              : extern "C" void M2Quads_BuildComponentValue (void);
    2064              : 
    2065              : /*
    2066              :    PopConstructor - removes the top constructor from the top of stack.
    2067              : */
    2068              : 
    2069              : extern "C" void M2Quads_PopConstructor (void);
    2070              : 
    2071              : /*
    2072              :    BuildNot   - Builds a NOT operation from the quad stack.
    2073              :                 The Stack is expected to contain:
    2074              : 
    2075              : 
    2076              :                   Entry                   Exit
    2077              :                   =====                   ====
    2078              : 
    2079              :            Ptr ->                                        <- Ptr
    2080              :                   +------------+          +------------+
    2081              :                   | t    | f   |          | f    | t   |
    2082              :                   |------------|          |------------|
    2083              : */
    2084              : 
    2085              : extern "C" void M2Quads_BuildNot (unsigned int notTokPos);
    2086              : 
    2087              : /*
    2088              :    RecordOp - Records the operator passed on the stack.
    2089              :               This is called when a boolean operator is found in an
    2090              :               expression.  It is called just after the lhs has been built
    2091              :               and pushed to the quad stack and prior to the rhs build.
    2092              :               It checks to see if AND OR or equality tests are required.
    2093              :               It will short circuit AND and OR expressions.  It also
    2094              :               converts a lhs to a boolean variable if an xor comparison
    2095              :               is about to be performed.
    2096              : 
    2097              :               Checks for AND operator or OR operator
    2098              :               if either of these operators are found then BackPatching
    2099              :               takes place.
    2100              :               The Expected Stack:
    2101              : 
    2102              :               Entry                        Exit
    2103              : 
    2104              :        Ptr ->                                               <- Ptr
    2105              :               +-------------+               +-------------+
    2106              :               | OperatorTok |               | OperatorTok |
    2107              :               |-------------|               |-------------|
    2108              :               | t    | f    |               | t    | f    |
    2109              :               |-------------|               |-------------|
    2110              : 
    2111              : 
    2112              :               If OperatorTok=AndTok
    2113              :               Then
    2114              :                  BackPatch(f, NextQuad)
    2115              :               Elsif OperatorTok=OrTok
    2116              :               Then
    2117              :                  BackPatch(t, NextQuad)
    2118              :               End
    2119              : */
    2120              : 
    2121              : extern "C" void M2Quads_RecordOp (void);
    2122              : 
    2123              : /*
    2124              :    BuildRelOp   - Builds a relative operation from the quad stack.
    2125              :                   The Stack is expected to contain:
    2126              : 
    2127              : 
    2128              :                   Entry                   Exit
    2129              :                   =====                   ====
    2130              : 
    2131              :            Ptr ->
    2132              :                   +------------+
    2133              :                   | e1         |
    2134              :                   |------------|                          <- Ptr
    2135              :                   | Operator   |
    2136              :                   |------------|          +------------+
    2137              :                   | e2         |          | t    | f   |
    2138              :                   |------------|          |------------|
    2139              : 
    2140              : 
    2141              :                     Quadruples Produced
    2142              : 
    2143              :                     q     IFOperator  e2  e1  TrueExit    ; e2  e1 since
    2144              :                     q+1   GotoOp              FalseExit   ; relation > etc
    2145              :                                                           ; requires order.
    2146              : */
    2147              : 
    2148              : extern "C" void M2Quads_BuildRelOp (unsigned int optokpos);
    2149              : 
    2150              : /*
    2151              :    BuildBinaryOp   - Builds a binary operation from the quad stack.
    2152              :                      Be aware that this procedure will check for
    2153              :                      the overloading of the bitset operators + - \ *.
    2154              :                      So do NOT call this procedure if you are building
    2155              :                      a reference to an array which has a bitset type or
    2156              :                      the address arithmetic will be wrongly coersed into
    2157              :                      logical ORs.
    2158              : 
    2159              :                      The Stack is expected to contain:
    2160              : 
    2161              : 
    2162              :                      Entry                   Exit
    2163              :                      =====                   ====
    2164              : 
    2165              :               Ptr ->
    2166              :                      +------------+
    2167              :                      | Sym1       |
    2168              :                      |------------|
    2169              :                      | Operator   |                          <- Ptr
    2170              :                      |------------|          +------------+
    2171              :                      | Sym2       |          | Temporary  |
    2172              :                      |------------|          |------------|
    2173              : 
    2174              : 
    2175              :                      Quadruples Produced
    2176              : 
    2177              :                      q     Operator  Temporary  Sym1  Sym2
    2178              : 
    2179              : 
    2180              :                 OR
    2181              : 
    2182              : 
    2183              :                      Entry                   Exit
    2184              :                      =====                   ====
    2185              : 
    2186              :               Ptr ->
    2187              :                      +------------+
    2188              :                      | T1   | F1  |
    2189              :                      |------------|
    2190              :                      | OrTok      |                          <- Ptr
    2191              :                      |------------|          +------------+
    2192              :                      | T2   | F2  |          | T1+T2| F1  |
    2193              :                      |------------|          |------------|
    2194              : 
    2195              : 
    2196              :                      Quadruples Produced
    2197              : 
    2198              : */
    2199              : 
    2200              : extern "C" void M2Quads_BuildBinaryOp (void);
    2201              : 
    2202              : /*
    2203              :    BuildUnaryOp   - Builds a unary operation from the quad stack.
    2204              :                     The Stack is expected to contain:
    2205              : 
    2206              : 
    2207              :                     Entry                   Exit
    2208              :                     =====                   ====
    2209              : 
    2210              :              Ptr ->
    2211              :                     +------------+
    2212              :                     | Sym        |
    2213              :                     |------------|          +------------+
    2214              :                     | Operator   |          | Temporary  | <- Ptr
    2215              :                     |------------|          |------------|
    2216              : 
    2217              : 
    2218              :                     Quadruples Produced
    2219              : 
    2220              :                     q     Operator  Temporary  _ Sym
    2221              : 
    2222              : */
    2223              : 
    2224              : extern "C" void M2Quads_BuildUnaryOp (void);
    2225              : 
    2226              : /*
    2227              :    OperandT - returns the ident operand stored in the true position on the boolean stack.
    2228              : */
    2229              : 
    2230              : extern "C" unsigned int M2Quads_OperandT (unsigned int pos);
    2231              : 
    2232              : /*
    2233              :    OperandF - returns the ident operand stored in the false position on the boolean stack.
    2234              : */
    2235              : 
    2236              : extern "C" unsigned int M2Quads_OperandF (unsigned int pos);
    2237              : 
    2238              : /*
    2239              :    PushTF - Push a True and False numbers onto the True/False stack.
    2240              :             True and False are assumed to contain Symbols or Ident etc.
    2241              : */
    2242              : 
    2243              : extern "C" void M2Quads_PushTF (unsigned int True, unsigned int False);
    2244              : 
    2245              : /*
    2246              :    PopTF - Pop a True and False number from the True/False stack.
    2247              :            True and False are assumed to contain Symbols or Ident etc.
    2248              : */
    2249              : 
    2250              : extern "C" void M2Quads_PopTF (unsigned int *True, unsigned int *False);
    2251              : 
    2252              : /*
    2253              :    PushT - Push an item onto the stack in the T (true) position.
    2254              : */
    2255              : 
    2256              : extern "C" void M2Quads_PushT (unsigned int True);
    2257              : 
    2258              : /*
    2259              :    PopT - Pops the T value from the stack.
    2260              : */
    2261              : 
    2262              : extern "C" void M2Quads_PopT (unsigned int *True);
    2263              : 
    2264              : /*
    2265              :    PushTtok - Push an item onto the stack in the T (true) position,
    2266              :               it is assummed to be a token and its token location is recorded.
    2267              : */
    2268              : 
    2269              : extern "C" void M2Quads_PushTtok (unsigned int True, unsigned int tokno);
    2270              : 
    2271              : /*
    2272              :    PushTFtok - Push an item onto the stack in the T (true) position,
    2273              :                it is assummed to be a token and its token location is recorded.
    2274              : */
    2275              : 
    2276              : extern "C" void M2Quads_PushTFtok (unsigned int True, unsigned int False, unsigned int tokno);
    2277              : 
    2278              : /*
    2279              :    PopTFtok - Pop T/F/tok from the stack.
    2280              : */
    2281              : 
    2282              : extern "C" void M2Quads_PopTFtok (unsigned int *True, unsigned int *False, unsigned int *tokno);
    2283              : 
    2284              : /*
    2285              :    PushTFAtok - Push T/F/A/tok to the stack.
    2286              : */
    2287              : 
    2288              : extern "C" void M2Quads_PushTFAtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int tokno);
    2289              : 
    2290              : /*
    2291              :    PopTtok - Pops the T value from the stack and token position.
    2292              : */
    2293              : 
    2294              : extern "C" void M2Quads_PopTtok (unsigned int *True, unsigned int *tok);
    2295              : 
    2296              : /*
    2297              :    PushTFn - Push a True and False numbers onto the True/False stack.
    2298              :              True and False are assumed to contain Symbols or Ident etc.
    2299              : */
    2300              : 
    2301              : extern "C" void M2Quads_PushTFn (unsigned int True, unsigned int False, unsigned int n);
    2302              : 
    2303              : /*
    2304              :    PushTFntok - Push a True and False numbers onto the True/False stack.
    2305              :                 True and False are assumed to contain Symbols or Ident etc.
    2306              : */
    2307              : 
    2308              : extern "C" void M2Quads_PushTFntok (unsigned int True, unsigned int False, unsigned int n, unsigned int tokno);
    2309              : 
    2310              : /*
    2311              :    PopTFn - Pop a True and False number from the True/False stack.
    2312              :             True and False are assumed to contain Symbols or Ident etc.
    2313              : */
    2314              : 
    2315              : extern "C" void M2Quads_PopTFn (unsigned int *True, unsigned int *False, unsigned int *n);
    2316              : 
    2317              : /*
    2318              :    PopNothing - pops the top element on the boolean stack.
    2319              : */
    2320              : 
    2321              : extern "C" void M2Quads_PopNothing (void);
    2322              : 
    2323              : /*
    2324              :    PopN - pops multiple elements from the BoolStack.
    2325              : */
    2326              : 
    2327              : extern "C" void M2Quads_PopN (unsigned int n);
    2328              : 
    2329              : /*
    2330              :    PushTFA - Push True, False, Array, numbers onto the
    2331              :              True/False stack.  True and False are assumed to
    2332              :              contain Symbols or Ident etc.
    2333              : */
    2334              : 
    2335              : extern "C" void M2Quads_PushTFA (unsigned int True, unsigned int False, unsigned int Array);
    2336              : 
    2337              : /*
    2338              :    OperandTok - returns the token associated with pos, on the stack.
    2339              : */
    2340              : 
    2341              : extern "C" unsigned int M2Quads_OperandTok (unsigned int pos);
    2342              : 
    2343              : /*
    2344              :    OperandA - returns possible array symbol associated with the ident
    2345              :               operand stored on the boolean stack.
    2346              : */
    2347              : 
    2348              : extern "C" unsigned int M2Quads_OperandA (unsigned int pos);
    2349              : 
    2350              : /*
    2351              :    OperandAnno - returns the annotation string associated with the
    2352              :                  position, n, on the stack.
    2353              : */
    2354              : 
    2355              : extern "C" DynamicStrings_String M2Quads_OperandAnno (unsigned int n);
    2356              : 
    2357              : /*
    2358              :    Annotate - annotate the top of stack.
    2359              : */
    2360              : 
    2361              : extern "C" void M2Quads_Annotate (const char *a_, unsigned int _a_high);
    2362              : 
    2363              : /*
    2364              :    DisplayStack - displays the compile time symbol stack.
    2365              : */
    2366              : 
    2367              : extern "C" void M2Quads_DisplayStack (void);
    2368              : 
    2369              : /*
    2370              :    Top - returns the no of items held in the stack.
    2371              : */
    2372              : 
    2373              : extern "C" unsigned int M2Quads_Top (void);
    2374              : 
    2375              : /*
    2376              :    DupFrame - duplicate the top of stack and push the new frame.
    2377              : */
    2378              : 
    2379              : extern "C" void M2Quads_DupFrame (void);
    2380              : 
    2381              : /*
    2382              :    WriteOperand - displays the operands name, symbol id and mode of addressing.
    2383              : */
    2384              : 
    2385              : extern "C" void M2Quads_WriteOperand (unsigned int Sym);
    2386              : 
    2387              : /*
    2388              :    BeginVarient - begin a varient record.
    2389              : */
    2390              : 
    2391              : extern "C" void M2Quads_BeginVarient (void);
    2392              : 
    2393              : /*
    2394              :    EndVarient - end a varient record.
    2395              : */
    2396              : 
    2397              : extern "C" void M2Quads_EndVarient (void);
    2398              : 
    2399              : /*
    2400              :    ElseVarient - associate an ELSE clause with a varient record.
    2401              : */
    2402              : 
    2403              : extern "C" void M2Quads_ElseVarient (void);
    2404              : 
    2405              : /*
    2406              :    BeginVarientList - begin an ident list containing ranges belonging to a
    2407              :                       varient list.
    2408              : */
    2409              : 
    2410              : extern "C" void M2Quads_BeginVarientList (void);
    2411              : 
    2412              : /*
    2413              :    EndVarientList - end a range list for a varient field.
    2414              : */
    2415              : 
    2416              : extern "C" void M2Quads_EndVarientList (void);
    2417              : 
    2418              : /*
    2419              :    AddRecordToList - adds the record held on the top of stack to the
    2420              :                      list of records and varient fields.
    2421              : */
    2422              : 
    2423              : extern "C" void M2Quads_AddRecordToList (void);
    2424              : 
    2425              : /*
    2426              :    AddVarientToList - adds varient held on the top of stack to the list.
    2427              : */
    2428              : 
    2429              : extern "C" void M2Quads_AddVarientToList (void);
    2430              : 
    2431              : /*
    2432              :    AddVarientFieldToList - adds varient field, f, to the list of all varient
    2433              :                            fields created.
    2434              : */
    2435              : 
    2436              : extern "C" void M2Quads_AddVarientFieldToList (unsigned int f);
    2437              : 
    2438              : /*
    2439              :    AddVarientRange - creates a range from the top two contant expressions
    2440              :                      on the stack which are recorded with the current
    2441              :                      varient field.  The stack is unaltered.
    2442              : */
    2443              : 
    2444              : extern "C" void M2Quads_AddVarientRange (void);
    2445              : 
    2446              : /*
    2447              :    AddVarientEquality - adds the contant expression on the top of the stack
    2448              :                         to the current varient field being recorded.
    2449              :                         The stack is unaltered.
    2450              : */
    2451              : 
    2452              : extern "C" void M2Quads_AddVarientEquality (void);
    2453              : 
    2454              : /*
    2455              :    BuildCodeOn - generates a quadruple declaring that code should be
    2456              :                  emmitted from henceforth.
    2457              : 
    2458              :                  The Stack is unnaffected.
    2459              : */
    2460              : 
    2461              : extern "C" void M2Quads_BuildCodeOn (void);
    2462              : 
    2463              : /*
    2464              :    BuildCodeOff - generates a quadruple declaring that code should not be
    2465              :                   emmitted from henceforth.
    2466              : 
    2467              :                   The Stack is unnaffected.
    2468              : */
    2469              : 
    2470              : extern "C" void M2Quads_BuildCodeOff (void);
    2471              : 
    2472              : /*
    2473              :    BuildProfileOn - generates a quadruple declaring that profile timings
    2474              :                     should be emmitted from henceforth.
    2475              : 
    2476              :                     The Stack is unnaffected.
    2477              : */
    2478              : 
    2479              : extern "C" void M2Quads_BuildProfileOn (void);
    2480              : extern "C" void M2Quads_BuildProfileOff (void);
    2481              : 
    2482              : /*
    2483              :    BuildOptimizeOn - generates a quadruple declaring that optimization
    2484              :                      should occur from henceforth.
    2485              : 
    2486              :                      The Stack is unnaffected.
    2487              : */
    2488              : 
    2489              : extern "C" void M2Quads_BuildOptimizeOn (void);
    2490              : 
    2491              : /*
    2492              :    BuildOptimizeOff - generates a quadruple declaring that optimization
    2493              :                       should not occur from henceforth.
    2494              : 
    2495              :                       The Stack is unnaffected.
    2496              : */
    2497              : 
    2498              : extern "C" void M2Quads_BuildOptimizeOff (void);
    2499              : 
    2500              : /*
    2501              :    BuildAsm - builds an Inline pseudo quadruple operator.
    2502              :               The inline interface, Sym, is stored as the operand
    2503              :               to the operator InlineOp.
    2504              : 
    2505              :               The stack is expected to contain:
    2506              : 
    2507              : 
    2508              :                         Entry                   Exit
    2509              :                         =====                   ====
    2510              : 
    2511              :               Ptr ->
    2512              :                      +--------------+
    2513              :                      | Sym          |        Empty
    2514              :                      |--------------|
    2515              : */
    2516              : 
    2517              : extern "C" void M2Quads_BuildAsm (unsigned int tok);
    2518              : 
    2519              : /*
    2520              :    BuildLineNo - builds a LineNumberOp pseudo quadruple operator.
    2521              :                  This quadruple indicates which source line has been
    2522              :                  processed, these quadruples are only generated if we
    2523              :                  are producing runtime debugging information.
    2524              : 
    2525              :                  The stack is not affected, read or altered in any way.
    2526              : 
    2527              : 
    2528              :                         Entry                   Exit
    2529              :                         =====                   ====
    2530              : 
    2531              :                  Ptr ->                              <- Ptr
    2532              : */
    2533              : 
    2534              : extern "C" void M2Quads_BuildLineNo (void);
    2535              : 
    2536              : /*
    2537              :    PushLineNo - pushes the current file and line number to the stack.
    2538              : */
    2539              : 
    2540              : extern "C" void M2Quads_PushLineNo (void);
    2541              : 
    2542              : /*
    2543              :    BuildStmtNote - builds a StatementNoteOp pseudo quadruple operator.
    2544              :                    This quadruple indicates which source line has been
    2545              :                    processed and it represents the start of a statement
    2546              :                    sequence.
    2547              :                    It differs from LineNumberOp in that multiple successive
    2548              :                    LineNumberOps will be removed and the final one is attached to
    2549              :                    the next real GCC tree.  Whereas a StatementNoteOp is always left
    2550              :                    alone.  Depending upon the debugging level it will issue a nop
    2551              :                    instruction to ensure that the gdb single step will step into
    2552              :                    this line.  Practically it allows pedalogical debugging to
    2553              :                    occur when there is syntax sugar such as:
    2554              : 
    2555              : 
    2556              :                          END   step 
    2557              :                       END   step 
    2558              :                    END ;  step 
    2559              :                    a := 1 ;  step 
    2560              : 
    2561              :                    REPEAT  step 
    2562              :                       i := 1   step 
    2563              : 
    2564              :                    The stack is not affected, read or altered in any way.
    2565              : 
    2566              : 
    2567              :                         Entry                   Exit
    2568              :                         =====                   ====
    2569              : 
    2570              :                  Ptr ->                              <- Ptr
    2571              : */
    2572              : 
    2573              : extern "C" void M2Quads_BuildStmtNote (int offset);
    2574              : 
    2575              : /*
    2576              :    LoopAnalysis - checks whether an infinite loop exists.
    2577              : */
    2578              : 
    2579              : extern "C" void M2Quads_LoopAnalysis (unsigned int Scope, unsigned int Current, unsigned int End);
    2580              : 
    2581              : /*
    2582              :    ForLoopAnalysis - checks all the FOR loops for index variable manipulation
    2583              :                      and dangerous usage outside the loop.
    2584              : */
    2585              : 
    2586              : extern "C" void M2Quads_ForLoopAnalysis (void);
    2587              : 
    2588              : /*
    2589              :    BuildSizeCheckStart - switches off all quadruple generation if the function SIZE or HIGH
    2590              :                          is being "called".  This should be done as SIZE only requires the
    2591              :                          actual type of the expression, not its value.  Consider the problem of
    2592              :                          SIZE(UninitializedPointer^) which is quite legal and it must
    2593              :                          also be safe!
    2594              :                          ISO Modula-2 also allows HIGH(a[0]) for a two dimensional array
    2595              :                          and there is no need to compute a[0], we just need to follow the
    2596              :                          type and count dimensions.  However if SIZE(a) or HIGH(a) occurs
    2597              :                          and, a, is an unbounded array then we turn on quadruple generation.
    2598              : 
    2599              :                          The Stack is expected to contain:
    2600              : 
    2601              : 
    2602              :                          Entry                       Exit
    2603              :                          =====                       ====
    2604              : 
    2605              :                  Ptr ->                                                       <- Ptr
    2606              :                         +----------------------+     +----------------------+
    2607              :                         | ProcSym | Type | tok |     | ProcSym | Type | tok |
    2608              :                         |----------------------|     |----------------------|
    2609              : */
    2610              : 
    2611              : extern "C" void M2Quads_BuildSizeCheckStart (void);
    2612              : 
    2613              : /*
    2614              :    BackPatchSubrangesAndOptParam - runs through all the quadruples and finds SubrangeLow or SubrangeHigh
    2615              :                                    quadruples and replaces it by an assignment to the Low or High component
    2616              :                                    of the subrange type.
    2617              : 
    2618              :                                    Input:
    2619              :                                    SubrangeLow    op1     op3          op3 is a subrange 
    2620              : 
    2621              :                                    Output:
    2622              :                                    Becomes        op1     low
    2623              : 
    2624              :                                    Input:
    2625              :                                    SubrangeHigh   op1     op3          op3 is a subrange 
    2626              : 
    2627              :                                    Output:
    2628              :                                    Becomes        op1     high
    2629              : 
    2630              :                                    Input:
    2631              :                                    OptParam       op1     op2    op3
    2632              : 
    2633              :                                    Output:
    2634              :                                    Param          op1     op2    GetOptArgInit(op3)
    2635              : */
    2636              : 
    2637              : extern "C" void M2Quads_BackPatchSubrangesAndOptParam (void);
    2638              : 
    2639              : /*
    2640              :    WriteOperator - writes the name of the quadruple operator.
    2641              : */
    2642              : 
    2643              : extern "C" void M2Quads_WriteOperator (M2Quads_QuadOperator Operator);
    2644              : 
    2645              : /*
    2646              :    PushAutoOn - push the auto flag and then set it to TRUE.
    2647              :                 Any call to ident in the parser will result in the token being pushed.
    2648              : */
    2649              : 
    2650              : extern "C" void M2Quads_PushAutoOn (void);
    2651              : 
    2652              : /*
    2653              :    PushAutoOff - push the auto flag and then set it to FALSE.
    2654              : */
    2655              : 
    2656              : extern "C" void M2Quads_PushAutoOff (void);
    2657              : 
    2658              : /*
    2659              :    IsAutoPushOn - returns the value of the current Auto ident push flag.
    2660              : */
    2661              : 
    2662              : extern "C" bool M2Quads_IsAutoPushOn (void);
    2663              : 
    2664              : /*
    2665              :    PopAuto - restores the previous value of the Auto flag.
    2666              : */
    2667              : 
    2668              : extern "C" void M2Quads_PopAuto (void);
    2669              : 
    2670              : /*
    2671              :    MustCheckOverflow - returns TRUE if the quadruple should test for overflow.
    2672              : */
    2673              : 
    2674              : extern "C" bool M2Quads_MustCheckOverflow (unsigned int q);
    2675              : 
    2676              : /*
    2677              :    PushInConstExpression - push the InConstExpression flag and then set it to TRUE.
    2678              : */
    2679              : 
    2680              : extern "C" void M2Quads_PushInConstExpression (void);
    2681              : 
    2682              : /*
    2683              :    PopInConstExpression - restores the previous value of the InConstExpression.
    2684              : */
    2685              : 
    2686              : extern "C" void M2Quads_PopInConstExpression (void);
    2687              : 
    2688              : /*
    2689              :    IsInConstExpression - returns the value of the InConstExpression.
    2690              : */
    2691              : 
    2692              : extern "C" bool M2Quads_IsInConstExpression (void);
    2693              : 
    2694              : /*
    2695              :    PushInConstParameters - push the InConstParameters flag and then set it to TRUE.
    2696              : */
    2697              : 
    2698              : extern "C" void M2Quads_PushInConstParameters (void);
    2699              : 
    2700              : /*
    2701              :    PopInConstParameters - restores the previous value of the InConstParameters.
    2702              : */
    2703              : 
    2704              : extern "C" void M2Quads_PopInConstParameters (void);
    2705              : 
    2706              : /*
    2707              :    IsInConstParameters - returns the value of the InConstParameters.
    2708              : */
    2709              : 
    2710              : extern "C" bool M2Quads_IsInConstParameters (void);
    2711              : 
    2712              : /*
    2713              :    BuildAsmElement - the stack is expected to contain:
    2714              : 
    2715              : 
    2716              :                         Entry                      Exit
    2717              :                         =====                      ====
    2718              : 
    2719              :                  Ptr ->
    2720              :                         +------------------+
    2721              :                         | expr | tokpos    |
    2722              :                         |------------------|
    2723              :                         | str              |
    2724              :                         |------------------|
    2725              :                         | name             |
    2726              :                         |------------------|       +------------------+
    2727              :                         | CurrentInterface |       | CurrentInterface |
    2728              :                         |------------------|       |------------------|
    2729              :                         | CurrentAsm       |       | CurrentAsm       |
    2730              :                         |------------------|       |------------------|
    2731              :                         | n                |       | n                |
    2732              :                         |------------------|       |------------------|
    2733              : */
    2734              : 
    2735              : extern "C" void M2Quads_BuildAsmElement (bool input, bool output);
    2736              : 
    2737              : /*
    2738              :    BuildAsmTrash - the stack is expected to contain:
    2739              : 
    2740              : 
    2741              :                         Entry                      Exit
    2742              :                         =====                      ====
    2743              : 
    2744              :                  Ptr ->
    2745              :                         +------------------+
    2746              :                         | expr | tokpos    |
    2747              :                         |------------------|       +------------------+
    2748              :                         | CurrentInterface |       | CurrentInterface |
    2749              :                         |------------------|       |------------------|
    2750              :                         | CurrentAsm       |       | CurrentAsm       |
    2751              :                         |------------------|       |------------------|
    2752              :                         | n                |       | n                |
    2753              :                         |------------------|       |------------------|
    2754              : */
    2755              : 
    2756              : extern "C" void M2Quads_BuildAsmTrash (void);
    2757              : 
    2758              : /*
    2759              :    GetQuadTrash - return the symbol associated with the trashed operand.
    2760              : */
    2761              : 
    2762              : extern "C" unsigned int M2Quads_GetQuadTrash (unsigned int quad);
    2763              : 
    2764              : /*
    2765              :    DSdbEnter -
    2766              : */
    2767              : 
    2768              : static void DSdbEnter (void);
    2769              : 
    2770              : /*
    2771              :    DSdbExit -
    2772              : */
    2773              : 
    2774              : static void DSdbExit (void);
    2775              : 
    2776              : /*
    2777              :    GetQF - returns the QuadFrame associated with, q.
    2778              : */
    2779              : 
    2780              : static M2Quads_QuadFrame GetQF (unsigned int q);
    2781              : 
    2782              : /*
    2783              :    IsQuadA - returns true if QuadNo is a op.
    2784              : */
    2785              : 
    2786              : static bool IsQuadA (unsigned int QuadNo, M2Quads_QuadOperator op);
    2787              : 
    2788              : /*
    2789              :    OpUsesOp1 - return TRUE if op allows op1.
    2790              : */
    2791              : 
    2792              : static bool OpUsesOp1 (M2Quads_QuadOperator op);
    2793              : 
    2794              : /*
    2795              :    AddQuadInformation - adds variable analysis and jump analysis to the new quadruple.
    2796              : */
    2797              : 
    2798              : static void AddQuadInformation (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3);
    2799              : 
    2800              : /*
    2801              :    PutQuadO - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
    2802              :               sets a boolean to determinine whether overflow should be checked.
    2803              : */
    2804              : 
    2805              : static void PutQuadO (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow);
    2806              : 
    2807              : /*
    2808              :    PutQuadOType -
    2809              : */
    2810              : 
    2811              : static void PutQuadOType (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow, bool checktype);
    2812              : 
    2813              : /*
    2814              :    UndoReadWriteInfo -
    2815              : */
    2816              : 
    2817              : static void UndoReadWriteInfo (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3);
    2818              : 
    2819              : /*
    2820              :    CheckAddTuple2Read - checks to see whether symbol tuple contains variables or
    2821              :                         parameters and if so it then adds them to the quadruple
    2822              :                         variable list.
    2823              : */
    2824              : 
    2825              : static void CheckAddTuple2Read (unsigned int tuple, bool canDereference, unsigned int Quad);
    2826              : 
    2827              : /*
    2828              :    CheckAddVariableRead - checks to see whether symbol, Sym, is a variable or
    2829              :                           a parameter and if so it then adds this quadruple
    2830              :                           to the variable list.
    2831              : */
    2832              : 
    2833              : static void CheckAddVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad);
    2834              : 
    2835              : /*
    2836              :    CheckRemoveVariableRead - checks to see whether, Sym, is a variable or
    2837              :                              a parameter and if so then it removes the
    2838              :                              quadruple from the variable list.
    2839              : */
    2840              : 
    2841              : static void CheckRemoveVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad);
    2842              : 
    2843              : /*
    2844              :    CheckAddVariableWrite - checks to see whether symbol, Sym, is a variable and
    2845              :                            if so it then adds this quadruple to the variable list.
    2846              : */
    2847              : 
    2848              : static void CheckAddVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad);
    2849              : 
    2850              : /*
    2851              :    CheckRemoveVariableWrite - checks to see whether, Sym, is a variable and
    2852              :                               if so then it removes the quadruple from the
    2853              :                               variable list.
    2854              : */
    2855              : 
    2856              : static void CheckRemoveVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad);
    2857              : 
    2858              : /*
    2859              :    CheckConst -
    2860              : */
    2861              : 
    2862              : static void CheckConst (unsigned int sym);
    2863              : 
    2864              : /*
    2865              :    AlterReference - alters all references from OldQuad, to NewQuad in a
    2866              :                     quadruple list Head.
    2867              : */
    2868              : 
    2869              : static void AlterReference (unsigned int Head, unsigned int OldQuad, unsigned int NewQuad);
    2870              : 
    2871              : /*
    2872              :    GrowQuads - grows the list of quadruples to the quadruple, to.
    2873              : */
    2874              : 
    2875              : static void GrowQuads (unsigned int to);
    2876              : 
    2877              : /*
    2878              :    ManipulateReference - manipulates the quadruple, q, so that it now points to quad, to.
    2879              : */
    2880              : 
    2881              : static void ManipulateReference (unsigned int q, unsigned int to);
    2882              : 
    2883              : /*
    2884              :    RemoveReference - remove the reference by quadruple q to wherever
    2885              :                      it was pointing.
    2886              : */
    2887              : 
    2888              : static void RemoveReference (unsigned int q);
    2889              : 
    2890              : /*
    2891              :    NewQuad - sets QuadNo to a new quadruple.
    2892              : */
    2893              : 
    2894              : static void NewQuad (unsigned int *QuadNo);
    2895              : 
    2896              : /*
    2897              :    CheckVariableAt - checks to see whether, sym, was declared at a particular address.
    2898              : */
    2899              : 
    2900              : static void CheckVariableAt (unsigned int sym);
    2901              : 
    2902              : /*
    2903              :    CheckVariablesAt - checks to see whether we need to initialize any pointers
    2904              :                       which point to variable declared at addresses.
    2905              : */
    2906              : 
    2907              : static void CheckVariablesAt (unsigned int scope);
    2908              : 
    2909              : /*
    2910              :    GetTurnInterrupts - returns the TurnInterrupts procedure function.
    2911              : */
    2912              : 
    2913              : static unsigned int GetTurnInterrupts (unsigned int tok);
    2914              : 
    2915              : /*
    2916              :    GetProtection - returns the PROTECTION data type.
    2917              : */
    2918              : 
    2919              : static unsigned int GetProtection (unsigned int tok);
    2920              : 
    2921              : /*
    2922              :    CheckNeedPriorityBegin - checks to see whether we need to save the old
    2923              :                             module priority and change to another module
    2924              :                             priority.
    2925              :                             The current module initialization or procedure
    2926              :                             being built is defined by, scope. The module whose
    2927              :                             priority will be used is defined by, module.
    2928              : */
    2929              : 
    2930              : static void CheckNeedPriorityBegin (unsigned int tok, unsigned int scope, unsigned int module);
    2931              : 
    2932              : /*
    2933              :    CheckNeedPriorityEnd - checks to see whether we need to restore the old
    2934              :                           module priority.
    2935              :                           The current module initialization or procedure
    2936              :                           being built is defined by, scope.
    2937              : */
    2938              : 
    2939              : static void CheckNeedPriorityEnd (unsigned int tok, unsigned int scope, unsigned int module);
    2940              : 
    2941              : /*
    2942              :    BuildRTExceptEnter - informs RTExceptions that we are about to enter the except state.
    2943              : */
    2944              : 
    2945              : static void BuildRTExceptEnter (unsigned int tok);
    2946              : 
    2947              : /*
    2948              :    BuildRTExceptLeave - informs RTExceptions that we are about to leave the except state.
    2949              :                         If, destroy, is TRUE then pop the ExceptStack.
    2950              : */
    2951              : 
    2952              : static void BuildRTExceptLeave (unsigned int tok, bool destroy);
    2953              : 
    2954              : /*
    2955              :    SafeRequestSym - only used during scaffold to get argc, argv, envp.
    2956              :                     It attempts to get symbol name from the current scope(s) and if
    2957              :                     it fails then it falls back onto default constants.
    2958              : */
    2959              : 
    2960              : static unsigned int SafeRequestSym (unsigned int tok, NameKey_Name name);
    2961              : 
    2962              : /*
    2963              :    callRequestDependant - create a call:
    2964              :                           RequestDependant (GetSymName (modulesym), GetLibName (modulesym),
    2965              :                                             GetSymName (depModuleSym), GetLibName (depModuleSym));
    2966              : */
    2967              : 
    2968              : static void callRequestDependant (unsigned int tokno, unsigned int moduleSym, unsigned int depModuleSym, unsigned int requestDep);
    2969              : 
    2970              : /*
    2971              :    ForeachImportInDepDo -
    2972              : */
    2973              : 
    2974              : static void ForeachImportInDepDo (Lists_List importStatements, unsigned int moduleSym, unsigned int requestDep);
    2975              : 
    2976              : /*
    2977              :    ForeachImportedModuleDo -
    2978              : */
    2979              : 
    2980              : static void ForeachImportedModuleDo (unsigned int moduleSym, unsigned int requestDep);
    2981              : 
    2982              : /*
    2983              :    BuildM2DepFunction - creates the dependency graph procedure using IR:
    2984              :                         static void
    2985              :                         dependencies (void)
    2986              :                         {
    2987              :                            M2RTS_RequestDependant (module_name, libname, "b", "b libname");
    2988              :                            M2RTS_RequestDependant (module_name, libname, NULL, NULL);
    2989              :                         }
    2990              : */
    2991              : 
    2992              : static void BuildM2DepFunction (unsigned int tokno, unsigned int moduleSym);
    2993              : 
    2994              : /*
    2995              :    BuildM2LinkFunction - creates the _M2_link procedure which will
    2996              :                          cause the linker to pull in all the module ctors.
    2997              : */
    2998              : 
    2999              : static void BuildM2LinkFunction (unsigned int tokno);
    3000              : 
    3001              : /*
    3002              :    BuildTry - build the try statement for main.
    3003              : */
    3004              : 
    3005              : static void BuildTry (unsigned int tokno);
    3006              : 
    3007              : /*
    3008              :    BuildExcept - build the except block for main.
    3009              : */
    3010              : 
    3011              : static void BuildExcept (unsigned int tokno);
    3012              : 
    3013              : /*
    3014              :    BuildM2MainFunction - creates the main function with appropriate calls to the scaffold.
    3015              : */
    3016              : 
    3017              : static void BuildM2MainFunction (unsigned int tokno);
    3018              : 
    3019              : /*
    3020              :    DeferMakeConstStringCnul - return a C const string which will be nul terminated.
    3021              : */
    3022              : 
    3023              : static unsigned int DeferMakeConstStringCnul (unsigned int tok, unsigned int sym);
    3024              : 
    3025              : /*
    3026              :    DeferMakeConstStringM2nul - return a const string which will be nul terminated.
    3027              : */
    3028              : 
    3029              : static unsigned int DeferMakeConstStringM2nul (unsigned int tok, unsigned int sym);
    3030              : 
    3031              : /*
    3032              :    BuildStringAdrParam - push the address of a nul terminated string onto the quad stack.
    3033              : */
    3034              : 
    3035              : static void BuildStringAdrParam (unsigned int tok, NameKey_Name name);
    3036              : 
    3037              : /*
    3038              :    BuildM2InitFunction -
    3039              : */
    3040              : 
    3041              : static void BuildM2InitFunction (unsigned int tok, unsigned int moduleSym);
    3042              : 
    3043              : /*
    3044              :    BuildM2FiniFunction -
    3045              : */
    3046              : 
    3047              : static void BuildM2FiniFunction (unsigned int tok, unsigned int moduleSym);
    3048              : 
    3049              : /*
    3050              :    BuildM2CtorFunction - create a constructor function associated with moduleSym.
    3051              : 
    3052              :                          void
    3053              :                          ctorFunction ()
    3054              :                          {
    3055              :                            M2RTS_RegisterModule (GetSymName (moduleSym), GetLibName (moduleSym),
    3056              :                                                  init, fini, dependencies);
    3057              :                          }
    3058              : */
    3059              : 
    3060              : static void BuildM2CtorFunction (unsigned int tok, unsigned int moduleSym);
    3061              : 
    3062              : /*
    3063              :    AddForInfo - adds the description of the FOR loop into the record list.
    3064              :                 This is used if -pedantic is turned on to check index variable
    3065              :                 usage.
    3066              : */
    3067              : 
    3068              : static void AddForInfo (unsigned int Start, unsigned int End, unsigned int IncQuad, unsigned int Sym, unsigned int idtok);
    3069              : 
    3070              : /*
    3071              :    CheckForIndex - checks the quadruples: Start..End to see whether a
    3072              :                    for loop index is manipulated by the programmer.
    3073              :                    It generates a warning if this is the case.
    3074              :                    It also checks to see whether the IndexSym is read
    3075              :                    immediately outside the loop in which case a warning
    3076              :                    is issued.
    3077              : */
    3078              : 
    3079              : static void CheckForIndex (M2Quads_ForLoopInfo forDesc);
    3080              : 
    3081              : /*
    3082              :    BuildRange - generates a RangeCheckOp quad with, r, as its operand.
    3083              : */
    3084              : 
    3085              : static void BuildRange (unsigned int r);
    3086              : 
    3087              : /*
    3088              :    BuildError - generates a ErrorOp quad, indicating that if this
    3089              :                 quadruple is reachable, then a runtime error would
    3090              :                 occur.
    3091              : */
    3092              : 
    3093              : static void BuildError (unsigned int r);
    3094              : 
    3095              : /*
    3096              :    CheckPointerThroughNil - builds a range quadruple, providing, sym, is
    3097              :                             a candidate for checking against NIL.
    3098              :                             This range quadruple is only expanded into
    3099              :                             code during the code generation phase
    3100              :                             thus allowing limited compile time checking.
    3101              : */
    3102              : 
    3103              : static void CheckPointerThroughNil (unsigned int tokpos, unsigned int sym);
    3104              : 
    3105              : /*
    3106              :    CollectLow - returns the low of the subrange value.
    3107              : */
    3108              : 
    3109              : static unsigned int CollectLow (unsigned int sym);
    3110              : 
    3111              : /*
    3112              :    CollectHigh - returns the high of the subrange value, sym.
    3113              : */
    3114              : 
    3115              : static unsigned int CollectHigh (unsigned int sym);
    3116              : 
    3117              : /*
    3118              :    CheckCompatibleWithBecomes - checks to see that symbol, sym, is
    3119              :                                 compatible with the := operator.
    3120              : */
    3121              : 
    3122              : static void CheckCompatibleWithBecomes (unsigned int des, unsigned int expr, unsigned int destok, unsigned int exprtok);
    3123              : 
    3124              : /*
    3125              :    BuildAssignmentWithoutBounds - calls BuildAssignment but makes sure we do not
    3126              :                                   check bounds.
    3127              : */
    3128              : 
    3129              : static void BuildAssignmentWithoutBounds (unsigned int tok, bool checkTypes, bool checkOverflow);
    3130              : 
    3131              : /*
    3132              :    MarkArrayWritten - marks, Array, as being written.
    3133              : */
    3134              : 
    3135              : static void MarkArrayWritten (unsigned int Array);
    3136              : 
    3137              : /*
    3138              :    MarkAsReadWrite - marks the variable or parameter as being
    3139              :                      read/write.
    3140              : */
    3141              : 
    3142              : static void MarkAsReadWrite (unsigned int sym);
    3143              : 
    3144              : /*
    3145              :    MarkAsRead - marks the variable or parameter as being read.
    3146              : */
    3147              : 
    3148              : static void MarkAsRead (unsigned int sym);
    3149              : 
    3150              : /*
    3151              :    MarkAsWrite - marks the variable or parameter as being written.
    3152              : */
    3153              : 
    3154              : static void MarkAsWrite (unsigned int sym);
    3155              : 
    3156              : /*
    3157              :    doVal - return an expression which is VAL(type, expr).  If
    3158              :            expr is a constant then return expr.
    3159              : */
    3160              : 
    3161              : static unsigned int doVal (unsigned int type, unsigned int expr);
    3162              : 
    3163              : /*
    3164              :    MoveWithMode -
    3165              : */
    3166              : 
    3167              : static void MoveWithMode (unsigned int tokno, unsigned int Des, unsigned int Exp, unsigned int Array, unsigned int destok, unsigned int exptok, bool checkOverflow);
    3168              : 
    3169              : /*
    3170              :    CheckBecomesMeta - checks to make sure that we are not
    3171              :                       assigning a variable to a constant.
    3172              :                       Also check we are not assigning to an
    3173              :                       unbounded array.
    3174              : */
    3175              : 
    3176              : static void CheckBecomesMeta (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok);
    3177              : 
    3178              : /*
    3179              :    BuildAssignmentBoolean - build the quadruples for a boolean variable or constant
    3180              :                             which will be assigned to the result of a boolean expression.
    3181              :                             For example:
    3182              : 
    3183              :                             foo := a = b ;
    3184              :                             foo := a IN b ;
    3185              : 
    3186              :                             The boolean result is contained in the control flow
    3187              :                             the true value will emerge from the quad path t.
    3188              :                             The false value will emerge from the quad path f.
    3189              :                             This procedure terminates both paths by backpatching
    3190              :                             and assigns TRUE or FALSE to the variable/constant.
    3191              :                             A variable maybe an L value so it will require dereferencing.
    3192              : */
    3193              : 
    3194              : static void BuildAssignmentBoolean (unsigned int becomesTokNo, bool checkOverflow, unsigned int t, unsigned int f, unsigned int Des, unsigned int destok);
    3195              : 
    3196              : /*
    3197              :    doBuildAssignment - subsiduary procedure of BuildAssignment.
    3198              :                        It builds the assignment and optionally
    3199              :                        checks the types are compatible.
    3200              : */
    3201              : 
    3202              : static void doBuildAssignment (unsigned int becomesTokNo, bool checkTypes, bool checkOverflow);
    3203              : 
    3204              : /*
    3205              :    CheckAssignCompatible - checks to see that an assignment is compatible.
    3206              :                            It performs limited checking - thorough checking
    3207              :                            is done in pass 3.  But we do what we can here
    3208              :                            given knowledge so far.
    3209              : */
    3210              : 
    3211              : static void CheckAssignCompatible (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok);
    3212              : 
    3213              : /*
    3214              :    CheckBooleanId - Checks to see if the top operand is a boolean.
    3215              :                     If the operand is not a boolean then it is tested
    3216              :                     with true and a boolean is generated.
    3217              :                     The Stack:
    3218              : 
    3219              : 
    3220              :                     Entry                     Exit
    3221              :              Ptr ->                                          <- Ptr
    3222              :                     +------------+            +------------+
    3223              :                     | Sym        |            | t   | f    |
    3224              :                     |------------|            |------------|
    3225              : 
    3226              :                      Quadruples
    3227              : 
    3228              :                      q   If=      Sym   True   _
    3229              :                      q+1 GotoOp   _     _      _
    3230              : */
    3231              : 
    3232              : static void CheckBooleanId (void);
    3233              : 
    3234              : /*
    3235              :    PushOne - pushes the value one to the stack.
    3236              :              The Stack is changed:
    3237              : 
    3238              : 
    3239              :                     Entry                   Exit
    3240              :                     =====                   ====
    3241              : 
    3242              :                                                             <- Ptr
    3243              :                                             +------------+
    3244              :              Ptr ->                         | 1 | type   |
    3245              :                                             |------------|
    3246              : */
    3247              : 
    3248              : static void PushOne (unsigned int tok, unsigned int type, const char *message_, unsigned int _message_high);
    3249              : 
    3250              : /*
    3251              :    PushZero - pushes the value zero to the stack.
    3252              :               The Stack is changed:
    3253              : 
    3254              : 
    3255              :                     Entry                   Exit
    3256              :                     =====                   ====
    3257              : 
    3258              :                                                             <- Ptr
    3259              :                                             +------------+
    3260              :              Ptr ->                         | 0 | type   |
    3261              :                                             |------------|
    3262              : */
    3263              : 
    3264              : static void PushZero (unsigned int tok, unsigned int type);
    3265              : 
    3266              : /*
    3267              :    ForLoopLastIterator - calculate the last iterator value but avoid setting
    3268              :                          LastIterator twice if it is a constant (in the quads).
    3269              :                          In the ForLoopLastIteratorVariable case only one
    3270              :                          path will be chosen but at the time of quadruple
    3271              :                          generation we do not know the value of BySym.
    3272              : */
    3273              : 
    3274              : static void ForLoopLastIterator (unsigned int LastIterator, unsigned int e1, unsigned int e2, unsigned int BySym, unsigned int e1tok, unsigned int e2tok, unsigned int bytok);
    3275              : 
    3276              : /*
    3277              :    BuildSizeCheckEnd - checks to see whether the function "called" was in fact SIZE.
    3278              :                        If so then we restore quadruple generation.
    3279              : */
    3280              : 
    3281              : static void BuildSizeCheckEnd (unsigned int ProcSym);
    3282              : 
    3283              : /*
    3284              :    BuildRealProcedureCall - builds a real procedure call.
    3285              :                             The Stack:
    3286              : 
    3287              : 
    3288              :                             Entry                      Exit
    3289              : 
    3290              :                      Ptr ->
    3291              :                             +----------------+
    3292              :                             | NoOfParam      |
    3293              :                             |----------------|
    3294              :                             | Param 1        |
    3295              :                             |----------------|
    3296              :                             | Param 2        |
    3297              :                             |----------------|
    3298              :                             .                .
    3299              :                             .                .
    3300              :                             .                .
    3301              :                             |----------------|
    3302              :                             | Param #        |
    3303              :                             |----------------|
    3304              :                             | ProcSym | Type |         Empty
    3305              :                             |----------------|
    3306              : */
    3307              : 
    3308              : static void BuildRealProcedureCall (unsigned int tokno);
    3309              : 
    3310              : /*
    3311              :    BuildRealFuncProcCall - builds a real procedure or function call.
    3312              :                            The Stack:
    3313              : 
    3314              : 
    3315              :                             Entry                      Exit
    3316              : 
    3317              :                      Ptr ->
    3318              :                             +----------------+
    3319              :                             | NoOfParam      |
    3320              :                             |----------------|
    3321              :                             | Param 1        |
    3322              :                             |----------------|
    3323              :                             | Param 2        |
    3324              :                             |----------------|
    3325              :                             .                .
    3326              :                             .                .
    3327              :                             .                .
    3328              :                             |----------------|
    3329              :                             | Param #        |
    3330              :                             |----------------|
    3331              :                             | ProcSym | Type |         Empty
    3332              :                             |----------------|
    3333              : */
    3334              : 
    3335              : static void BuildRealFuncProcCall (unsigned int tokno, bool IsFunc, bool IsForC, bool ConstExpr);
    3336              : 
    3337              : /*
    3338              :    CheckProcedureParameters - Checks the parameters which are being passed to
    3339              :                               procedure ProcSym.
    3340              : 
    3341              :                               The Stack:
    3342              : 
    3343              : 
    3344              :                               Entry                      Exit
    3345              : 
    3346              :                        Ptr ->                                               <- Ptr
    3347              :                               +----------------+         +----------------+
    3348              :                               | NoOfParam      |         | NoOfParam      |
    3349              :                               |----------------|         |----------------|
    3350              :                               | Param 1        |         | Param 1        |
    3351              :                               |----------------|         |----------------|
    3352              :                               | Param 2        |         | Param 2        |
    3353              :                               |----------------|         |----------------|
    3354              :                               .                .         .                .
    3355              :                               .                .         .                .
    3356              :                               .                .         .                .
    3357              :                               |----------------|         |----------------|
    3358              :                               | Param #        |         | Param #        |
    3359              :                               |----------------|         |----------------|
    3360              :                               | ProcSym | Type |         | ProcSym | Type |
    3361              :                               |----------------|         |----------------|
    3362              : 
    3363              : */
    3364              : 
    3365              : static void CheckProcedureParameters (bool IsForC);
    3366              : 
    3367              : /*
    3368              :    CheckProcTypeAndProcedure - checks the ProcType with the call.
    3369              : */
    3370              : 
    3371              : static void CheckProcTypeAndProcedure (unsigned int tokno, unsigned int ProcType, unsigned int call, unsigned int ParamCheckId);
    3372              : 
    3373              : /*
    3374              :    IsReallyPointer - returns TRUE is sym is a pointer, address or a type declared
    3375              :                      as a pointer or address.
    3376              : */
    3377              : 
    3378              : static bool IsReallyPointer (unsigned int Sym);
    3379              : 
    3380              : /*
    3381              :    LegalUnboundedParam - returns TRUE if the parameter, Actual, can legitimately be
    3382              :                          passed to ProcSym, i, the, Formal, parameter.
    3383              : */
    3384              : 
    3385              : static bool LegalUnboundedParam (unsigned int tokpos, unsigned int ProcSym, unsigned int i, unsigned int ActualType, unsigned int Actual, unsigned int Dimension, unsigned int Formal);
    3386              : 
    3387              : /*
    3388              :    CheckParameter - checks that types ActualType and FormalType are compatible for parameter
    3389              :                     passing. ProcSym is the procedure and i is the parameter number.
    3390              : 
    3391              :                     We obey the following rules:
    3392              : 
    3393              :                     (1)  we allow WORD, BYTE, LOC to be compitable with any like sized
    3394              :                          type.
    3395              :                     (2)  we allow ADDRESS to be compatible with any pointer type.
    3396              :                     (3)  we relax INTEGER and CARDINAL checking for Temporary variables.
    3397              : 
    3398              :                     Note that type sizes are checked during the code generation pass.
    3399              : */
    3400              : 
    3401              : static void CheckParameter (unsigned int tokpos, unsigned int Actual, unsigned int Dimension, unsigned int Formal, unsigned int ProcSym, unsigned int i, Lists_List TypeList, unsigned int ParamCheckId);
    3402              : 
    3403              : /*
    3404              :    DescribeType - returns a String describing a symbol, Sym, name and its type.
    3405              : */
    3406              : 
    3407              : static DynamicStrings_String DescribeType (unsigned int Sym);
    3408              : 
    3409              : /*
    3410              :    FailParameter - generates an error message indicating that a parameter
    3411              :                    declaration has failed.
    3412              : 
    3413              :                    The parameters are:
    3414              : 
    3415              :                    CurrentState  - string describing the current failing state.
    3416              :                    Actual        - actual parameter.
    3417              :                    ParameterNo   - parameter number that has failed.
    3418              :                    ProcedureSym  - procedure symbol where parameter has failed.
    3419              : 
    3420              :                    If any parameter is Nul then it is ignored.
    3421              : */
    3422              : 
    3423              : static void FailParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo);
    3424              : 
    3425              : /*
    3426              :    WarnParameter - generates a warning message indicating that a parameter
    3427              :                    use might cause problems on another target.
    3428              : 
    3429              :                    CurrentState  - string describing the current failing state.
    3430              :                    Actual        - actual parameter.
    3431              :                    ParameterNo   - parameter number that has failed.
    3432              :                    ProcedureSym  - procedure symbol where parameter has failed.
    3433              : 
    3434              :                    If any parameter is Nul then it is ignored.
    3435              : */
    3436              : 
    3437              : static void WarnParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo);
    3438              : 
    3439              : /*
    3440              :    doIndrX - perform des = *exp with a conversion if necessary.
    3441              : */
    3442              : 
    3443              : static void doIndrX (unsigned int tok, unsigned int des, unsigned int exp);
    3444              : 
    3445              : /*
    3446              :    MakeRightValue - returns a temporary which will have the RightValue of symbol, Sym.
    3447              :                     If Sym is a right value and has type, type, then no quadruples are
    3448              :                     generated and Sym is returned. Otherwise a new temporary is created
    3449              :                     and an IndrX quadruple is generated.
    3450              : */
    3451              : 
    3452              : static unsigned int MakeRightValue (unsigned int tok, unsigned int Sym, unsigned int type);
    3453              : 
    3454              : /*
    3455              :    MakeLeftValue - returns a temporary coresponding to the LeftValue of
    3456              :                    symbol, Sym. No quadruple is generated if Sym is already
    3457              :                    a LeftValue and has the same type.
    3458              : */
    3459              : 
    3460              : static unsigned int MakeLeftValue (unsigned int tok, unsigned int Sym, SymbolTable_ModeOfAddr with, unsigned int type);
    3461              : 
    3462              : /*
    3463              :    ManipulatePseudoCallParameters - manipulates the parameters to a pseudo function or
    3464              :                                     procedure. It dereferences all LeftValue parameters
    3465              :                                     and Boolean parameters.
    3466              :                                     The Stack:
    3467              : 
    3468              : 
    3469              :                                     Entry                      Exit
    3470              : 
    3471              :                              Ptr ->                            exactly the same
    3472              :                                     +----------------+
    3473              :                                     | NoOfParameters |
    3474              :                                     |----------------|
    3475              :                                     | Param 1        |
    3476              :                                     |----------------|
    3477              :                                     | Param 2        |
    3478              :                                     |----------------|
    3479              :                                     .                .
    3480              :                                     .                .
    3481              :                                     .                .
    3482              :                                     |----------------|
    3483              :                                     | Param #        |
    3484              :                                     |----------------|
    3485              :                                     | ProcSym | Type |
    3486              :                                     |----------------|
    3487              : 
    3488              : */
    3489              : 
    3490              : static void ManipulatePseudoCallParameters (void);
    3491              : 
    3492              : /*
    3493              :    ManipulateParameters - manipulates the procedure parameters in
    3494              :                           preparation for a procedure call.
    3495              :                           Prepares Boolean, Unbounded and VAR parameters.
    3496              :                           The Stack:
    3497              : 
    3498              : 
    3499              :                           Entry                      Exit
    3500              : 
    3501              :                    Ptr ->                            exactly the same
    3502              :                           +----------------+
    3503              :                           | NoOfParameters |
    3504              :                           |----------------|
    3505              :                           | Param 1        |
    3506              :                           |----------------|
    3507              :                           | Param 2        |
    3508              :                           |----------------|
    3509              :                           .                .
    3510              :                           .                .
    3511              :                           .                .
    3512              :                           |----------------|
    3513              :                           | Param #        |
    3514              :                           |----------------|
    3515              :                           | ProcSym | Type |
    3516              :                           |----------------|
    3517              : */
    3518              : 
    3519              : static void ManipulateParameters (bool IsForC);
    3520              : 
    3521              : /*
    3522              :    CheckParameterOrdinals - check that ordinal values are within type range.
    3523              : */
    3524              : 
    3525              : static void CheckParameterOrdinals (void);
    3526              : 
    3527              : /*
    3528              :    IsSameUnbounded - returns TRUE if unbounded types, t1, and, t2,
    3529              :                      are compatible.
    3530              : */
    3531              : 
    3532              : static bool IsSameUnbounded (unsigned int t1, unsigned int t2);
    3533              : 
    3534              : /*
    3535              :    AssignUnboundedVar - assigns an Unbounded symbol fields,
    3536              :                         ArrayAddress and ArrayHigh, from an array symbol.
    3537              :                         UnboundedSym is not a VAR parameter and therefore
    3538              :                         this procedure can complete both of the fields.
    3539              :                         Sym can be a Variable with type Unbounded.
    3540              :                         Sym can be a Variable with type Array.
    3541              :                         Sym can be a String Constant.
    3542              : 
    3543              :                         ParamType is the TYPE of the parameter
    3544              : */
    3545              : 
    3546              : static void AssignUnboundedVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
    3547              : 
    3548              : /*
    3549              :    AssignUnboundedNonVar - assigns an Unbounded symbol fields,
    3550              :                            The difference between this procedure and
    3551              :                            AssignUnboundedVar is that this procedure cannot
    3552              :                            set the Unbounded.Address since the data from
    3553              :                            Sym will be copied because parameter is NOT a VAR
    3554              :                            parameter.
    3555              :                            UnboundedSym is not a VAR parameter and therefore
    3556              :                            this procedure can only complete the HIGH field
    3557              :                            and not the ADDRESS field.
    3558              :                            Sym can be a Variable with type Unbounded.
    3559              :                            Sym can be a Variable with type Array.
    3560              :                            Sym can be a String Constant.
    3561              : 
    3562              :                            ParamType is the TYPE of the paramater
    3563              : */
    3564              : 
    3565              : static void AssignUnboundedNonVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
    3566              : 
    3567              : /*
    3568              :    GenHigh - generates a HighOp but it checks if op3 is a
    3569              :              L value and if so it dereferences it.  This
    3570              :              is inefficient, however it is clean and we let the gcc
    3571              :              backend detect these as common subexpressions.
    3572              :              It will also detect that a R value -> L value -> R value
    3573              :              via indirection and eleminate these.
    3574              : */
    3575              : 
    3576              : static void GenHigh (unsigned int tok, unsigned int op1, unsigned int op2, unsigned int op3);
    3577              : 
    3578              : /*
    3579              :    AssignHighField -
    3580              : */
    3581              : 
    3582              : static void AssignHighField (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int actuali, unsigned int formali);
    3583              : 
    3584              : /*
    3585              :    AssignHighFields -
    3586              : */
    3587              : 
    3588              : static void AssignHighFields (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
    3589              : 
    3590              : /*
    3591              :    UnboundedNonVarLinkToArray - links an array, ArraySym, to an unbounded
    3592              :                                 array, UnboundedSym. The parameter is a
    3593              :                                 NON VAR variety.
    3594              : */
    3595              : 
    3596              : static void UnboundedNonVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
    3597              : 
    3598              : /*
    3599              :    UnboundedVarLinkToArray - links an array, ArraySym, to an unbounded array,
    3600              :                              UnboundedSym. The parameter is a VAR variety.
    3601              : */
    3602              : 
    3603              : static void UnboundedVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
    3604              : 
    3605              : /*
    3606              :    BuildPseudoProcedureCall - builds a pseudo procedure call.
    3607              :                               This procedure does not directly alter the
    3608              :                               stack, but by calling routines the stack
    3609              :                               will change in the following way when this
    3610              :                               procedure returns.
    3611              : 
    3612              :                               The Stack:
    3613              : 
    3614              : 
    3615              :                               Entry                      Exit
    3616              : 
    3617              :                        Ptr ->
    3618              :                               +----------------+
    3619              :                               | NoOfParam      |
    3620              :                               |----------------|
    3621              :                               | Param 1        |
    3622              :                               |----------------|
    3623              :                               | Param 2        |
    3624              :                               |----------------|
    3625              :                               .                .
    3626              :                               .                .
    3627              :                               .                .
    3628              :                               |----------------|
    3629              :                               | Param #        |
    3630              :                               |----------------|
    3631              :                               | ProcSym | Type |         Empty
    3632              :                               |----------------|
    3633              : */
    3634              : 
    3635              : static void BuildPseudoProcedureCall (unsigned int tokno);
    3636              : 
    3637              : /*
    3638              :    GetItemPointedTo - returns the symbol type that is being pointed to
    3639              :                       by Sym.
    3640              : */
    3641              : 
    3642              : static unsigned int GetItemPointedTo (unsigned int Sym);
    3643              : 
    3644              : /*
    3645              :    BuildThrowProcedure - builds the pseudo procedure call M2RTS.Throw.
    3646              :                          The Stack:
    3647              : 
    3648              : 
    3649              :                          Entry                      Exit
    3650              : 
    3651              :                 Ptr ->
    3652              :                          +----------------+
    3653              :                          | NoOfParam      |
    3654              :                          |----------------|
    3655              :                          | Param 1        |
    3656              :                          |----------------|
    3657              :                          | Param 2        |
    3658              :                          |----------------|
    3659              :                          .                .
    3660              :                          .                .
    3661              :                          .                .
    3662              :                          |----------------|
    3663              :                          | Param #        |
    3664              :                          |----------------|
    3665              :                          | ProcSym | Type |         Empty
    3666              :                          |----------------|
    3667              : */
    3668              : 
    3669              : static void BuildThrowProcedure (unsigned int functok);
    3670              : 
    3671              : /*
    3672              :    BuildNewProcedure - builds the pseudo procedure call NEW.
    3673              :                        This procedure is traditionally a "macro" for
    3674              :                        NEW(x, ...) --> ALLOCATE(x, TSIZE(x^, ...))
    3675              :                        One method of implementation is to emulate a "macro"
    3676              :                        processor by pushing the relevant input tokens
    3677              :                        back onto the input stack.
    3678              :                        However this causes two problems:
    3679              : 
    3680              :                        (i)  Unnecessary code is produced for x^
    3681              :                        (ii) SIZE must be imported from SYSTEM
    3682              :                        Therefore we chose an alternative method of
    3683              :                        implementation;
    3684              :                        generate quadruples for ALLOCATE(x, TSIZE(x^, ...))
    3685              :                        this, although slightly more efficient,
    3686              :                        is more complex and circumvents problems (i) and (ii).
    3687              : 
    3688              :                        The Stack:
    3689              : 
    3690              : 
    3691              :                        Entry                      Exit
    3692              : 
    3693              :                 Ptr ->
    3694              :                        +----------------+
    3695              :                        | NoOfParam      |
    3696              :                        |----------------|
    3697              :                        | Param 1        |
    3698              :                        |----------------|
    3699              :                        | Param 2        |
    3700              :                        |----------------|
    3701              :                        .                .
    3702              :                        .                .
    3703              :                        .                .
    3704              :                        |----------------|
    3705              :                        | Param #        |
    3706              :                        |----------------|
    3707              :                        | ProcSym | Type |         Empty
    3708              :                        |----------------|
    3709              : */
    3710              : 
    3711              : static void BuildNewProcedure (unsigned int functok);
    3712              : 
    3713              : /*
    3714              :    BuildDisposeProcedure - builds the pseudo procedure call DISPOSE.
    3715              :                            This procedure is traditionally a "macro" for
    3716              :                            DISPOSE(x) --> DEALLOCATE(x, TSIZE(x^))
    3717              :                            One method of implementation is to emulate a "macro"
    3718              :                            processor by pushing the relevant input tokens
    3719              :                            back onto the input stack.
    3720              :                            However this causes two problems:
    3721              : 
    3722              :                            (i)  Unnecessary code is produced for x^
    3723              :                            (ii) TSIZE must be imported from SYSTEM
    3724              :                            Therefore we chose an alternative method of
    3725              :                            implementation;
    3726              :                            generate quadruples for DEALLOCATE(x, TSIZE(x^))
    3727              :                            this, although slightly more efficient,
    3728              :                            is more complex and circumvents problems (i)
    3729              :                            and (ii).
    3730              : 
    3731              :                            The Stack:
    3732              : 
    3733              : 
    3734              :                            Entry                      Exit
    3735              : 
    3736              :                     Ptr ->
    3737              :                            +----------------+
    3738              :                            | NoOfParam      |
    3739              :                            |----------------|
    3740              :                            | Param 1        |
    3741              :                            |----------------|
    3742              :                            | Param 2        |
    3743              :                            |----------------|
    3744              :                            .                .
    3745              :                            .                .
    3746              :                            .                .
    3747              :                            |----------------|
    3748              :                            | Param #        |
    3749              :                            |----------------|
    3750              :                            | ProcSym | Type |         Empty
    3751              :                            |----------------|
    3752              : */
    3753              : 
    3754              : static void BuildDisposeProcedure (unsigned int functok);
    3755              : 
    3756              : /*
    3757              :    CheckRangeIncDec - performs des := des <tok> expr
    3758              :                       with range checking (if enabled).
    3759              : 
    3760              :                                Stack
    3761              :                       Entry              Exit
    3762              : 
    3763              :                                      +------------+
    3764              :                       empty          | des + expr |
    3765              :                                      |------------|
    3766              : */
    3767              : 
    3768              : static void CheckRangeIncDec (unsigned int tokenpos, unsigned int des, unsigned int expr, NameKey_Name tok);
    3769              : 
    3770              : /*
    3771              :    BuildIncProcedure - builds the pseudo procedure call INC.
    3772              :                        INC is a procedure which increments a variable.
    3773              :                        It takes one or two parameters:
    3774              :                        INC(a, b)  or  INC(a)
    3775              :                        a := a+b   or  a := a+1
    3776              : 
    3777              :                        The Stack:
    3778              : 
    3779              : 
    3780              :                        Entry                      Exit
    3781              : 
    3782              :                 Ptr ->
    3783              :                        +----------------+
    3784              :                        | NoOfParam      |
    3785              :                        |----------------|
    3786              :                        | Param 1        |
    3787              :                        |----------------|
    3788              :                        | Param 2        |
    3789              :                        |----------------|
    3790              :                        .                .
    3791              :                        .                .
    3792              :                        .                .
    3793              :                        |----------------|
    3794              :                        | Param #        |
    3795              :                        |----------------|
    3796              :                        | ProcSym | Type |         Empty
    3797              :                        |----------------|
    3798              : */
    3799              : 
    3800              : static void BuildIncProcedure (unsigned int proctok);
    3801              : 
    3802              : /*
    3803              :    BuildDecProcedure - builds the pseudo procedure call DEC.
    3804              :                        DEC is a procedure which decrements a variable.
    3805              :                        It takes one or two parameters:
    3806              :                        DEC(a, b)  or  DEC(a)
    3807              :                        a := a-b   or  a := a-1
    3808              : 
    3809              :                        The Stack:
    3810              : 
    3811              : 
    3812              :                        Entry                      Exit
    3813              : 
    3814              :                 Ptr ->
    3815              :                        +----------------+
    3816              :                        | NoOfParam      |
    3817              :                        |----------------|
    3818              :                        | Param 1        |
    3819              :                        |----------------|
    3820              :                        | Param 2        |
    3821              :                        |----------------|
    3822              :                        .                .
    3823              :                        .                .
    3824              :                        .                .
    3825              :                        |----------------|
    3826              :                        | Param #        |
    3827              :                        |----------------|
    3828              :                        | ProcSym | Type |         Empty
    3829              :                        |----------------|
    3830              : */
    3831              : 
    3832              : static void BuildDecProcedure (unsigned int proctok);
    3833              : 
    3834              : /*
    3835              :    DereferenceLValue - checks to see whether, operand, is declare as an LValue
    3836              :                        and if so it dereferences it.
    3837              : */
    3838              : 
    3839              : static unsigned int DereferenceLValue (unsigned int tok, unsigned int operand);
    3840              : 
    3841              : /*
    3842              :    BuildInclProcedure - builds the pseudo procedure call INCL.
    3843              :                         INCL is a procedure which adds bit b into a BITSET a.
    3844              :                         It takes two parameters:
    3845              :                         INCL(a, b)
    3846              : 
    3847              :                         a := a + {b}
    3848              : 
    3849              :                         The Stack:
    3850              : 
    3851              : 
    3852              :                         Entry                      Exit
    3853              : 
    3854              :                  Ptr ->
    3855              :                         +----------------+
    3856              :                         | NoOfParam      |
    3857              :                         |----------------|
    3858              :                         | Param 1        |
    3859              :                         |----------------|
    3860              :                         | Param 2        |
    3861              :                         |----------------|
    3862              :                         | ProcSym | Type |         Empty
    3863              :                         |----------------|
    3864              : */
    3865              : 
    3866              : static void BuildInclProcedure (unsigned int proctok);
    3867              : 
    3868              : /*
    3869              :    BuildExclProcedure - builds the pseudo procedure call EXCL.
    3870              :                         INCL is a procedure which removes bit b from SET a.
    3871              :                         It takes two parameters:
    3872              :                         EXCL(a, b)
    3873              : 
    3874              :                         a := a - {b}
    3875              : 
    3876              :                         The Stack:
    3877              : 
    3878              : 
    3879              :                         Entry                      Exit
    3880              : 
    3881              :                  Ptr ->
    3882              :                         +----------------+
    3883              :                         | NoOfParam      |
    3884              :                         |----------------|
    3885              :                         | Param 1        |
    3886              :                         |----------------|
    3887              :                         | Param 2        |
    3888              :                         |----------------|
    3889              :                         | ProcSym | Type |         Empty
    3890              :                         |----------------|
    3891              : */
    3892              : 
    3893              : static void BuildExclProcedure (unsigned int proctok);
    3894              : 
    3895              : /*
    3896              :    BuildTypeCoercion - builds the type coersion.
    3897              :                        Modula-2 allows types to be coersed with no runtime
    3898              :                        penility.
    3899              :                        It insists that the TSIZE(t1)=TSIZE(t2) where
    3900              :                        t2 variable := t2(variable of type t1).
    3901              :                        The ReturnVar on the stack is of type t2.
    3902              : 
    3903              :                        The Stack:
    3904              : 
    3905              : 
    3906              :                        Entry                      Exit
    3907              : 
    3908              :                 Ptr ->
    3909              :                        +----------------+
    3910              :                        | NoOfParam      |
    3911              :                        |----------------|
    3912              :                        | Param 1        |
    3913              :                        |----------------|
    3914              :                        | Param 2        |
    3915              :                        |----------------|
    3916              :                        .                .
    3917              :                        .                .
    3918              :                        .                .
    3919              :                        |----------------|
    3920              :                        | Param #        |                        <- Ptr
    3921              :                        |----------------|         +------------+
    3922              :                        | ProcSym | Type |         | ReturnVar  |
    3923              :                        |----------------|         |------------|
    3924              : 
    3925              :                        Quadruples:
    3926              : 
    3927              :                        CoerceOp  ReturnVar  Type  Param1
    3928              : 
    3929              :                        A type coercion will only be legal if the different
    3930              :                        types have exactly the same size.
    3931              :                        Since we can only decide this after M2Eval has processed
    3932              :                        the symbol table then we create a quadruple explaining
    3933              :                        the coercion taking place, the code generator can test
    3934              :                        this assertion and report an error if the type sizes
    3935              :                        differ.
    3936              : */
    3937              : 
    3938              : static void BuildTypeCoercion (bool ConstExpr);
    3939              : 
    3940              : /*
    3941              :    BuildRealFunctionCall - builds a function call.
    3942              :                            The Stack:
    3943              : 
    3944              : 
    3945              :                            Entry                      Exit
    3946              : 
    3947              :                     Ptr ->
    3948              :                            +----------------+
    3949              :                            | NoOfParam      |
    3950              :                            |----------------|
    3951              :                            | Param 1        |
    3952              :                            |----------------|
    3953              :                            | Param 2        |
    3954              :                            |----------------|
    3955              :                            .                .
    3956              :                            .                .
    3957              :                            .                .
    3958              :                            |----------------|
    3959              :                            | Param #        |                        <- Ptr
    3960              :                            |----------------|         +------------+
    3961              :                            | ProcSym | Type |         | ReturnVar  |
    3962              :                            |----------------|         |------------|
    3963              : */
    3964              : 
    3965              : static void BuildRealFunctionCall (unsigned int tokno, bool ConstExpr);
    3966              : 
    3967              : /*
    3968              :    BuildPseudoFunctionCall - builds the pseudo function
    3969              :                              The Stack:
    3970              : 
    3971              : 
    3972              :                              Entry                      Exit
    3973              : 
    3974              :                       Ptr ->
    3975              :                              +----------------+
    3976              :                              | NoOfParam      |
    3977              :                              |----------------|
    3978              :                              | Param 1        |
    3979              :                              |----------------|
    3980              :                              | Param 2        |
    3981              :                              |----------------|
    3982              :                              .                .
    3983              :                              .                .
    3984              :                              .                .
    3985              :                              |----------------|
    3986              :                              | Param #        |                        <- Ptr
    3987              :                              |----------------|         +------------+
    3988              :                              | ProcSym | Type |         | ReturnVar  |
    3989              :                              |----------------|         |------------|
    3990              : 
    3991              : */
    3992              : 
    3993              : static void BuildPseudoFunctionCall (bool ConstExpr);
    3994              : 
    3995              : /*
    3996              :    BuildAddAdrFunction - builds the pseudo procedure call ADDADR.
    3997              : 
    3998              :                          PROCEDURE ADDADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
    3999              : 
    4000              :                          Which returns address given by (addr + offset),
    4001              :                          [ the standard says that it _may_
    4002              :                            "raise an exception if this address is not valid."
    4003              :                            currently we do not generate any exception code ]
    4004              : 
    4005              :                          The Stack:
    4006              : 
    4007              :                          Entry                      Exit
    4008              : 
    4009              :                   Ptr ->
    4010              :                          +----------------+
    4011              :                          | NoOfParam      |
    4012              :                          |----------------|
    4013              :                          | Param 1        |
    4014              :                          |----------------|
    4015              :                          | Param 2        |                        <- Ptr
    4016              :                          |----------------|         +------------+
    4017              :                          | ProcSym | Type |         | ReturnVar  |
    4018              :                          |----------------|         |------------|
    4019              : */
    4020              : 
    4021              : static void BuildAddAdrFunction (unsigned int ProcSym, bool ConstExpr);
    4022              : 
    4023              : /*
    4024              :    BuildSubAdrFunction - builds the pseudo procedure call ADDADR.
    4025              : 
    4026              :                          PROCEDURE SUBADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
    4027              : 
    4028              :                          Which returns address given by (addr - offset),
    4029              :                          [ the standard says that it _may_
    4030              :                            "raise an exception if this address is not valid."
    4031              :                            currently we do not generate any exception code ]
    4032              : 
    4033              :                          The Stack:
    4034              : 
    4035              :                          Entry                      Exit
    4036              : 
    4037              :                   Ptr ->
    4038              :                          +----------------+
    4039              :                          | NoOfParam      |
    4040              :                          |----------------|
    4041              :                          | Param 1        |
    4042              :                          |----------------|
    4043              :                          | Param 2        |                        <- Ptr
    4044              :                          |----------------|         +------------+
    4045              :                          | ProcSym | Type |         | ReturnVar  |
    4046              :                          |----------------|         |------------|
    4047              : */
    4048              : 
    4049              : static void BuildSubAdrFunction (unsigned int ProcSym, bool ConstExpr);
    4050              : 
    4051              : /*
    4052              :    BuildDifAdrFunction - builds the pseudo procedure call DIFADR.
    4053              : 
    4054              :                          PROCEDURE DIFADR (addr1, addr2: ADDRESS): INTEGER ;
    4055              : 
    4056              :                          Which returns address given by (addr1 - addr2),
    4057              :                          [ the standard says that it _may_
    4058              :                            "raise an exception if this address is invalid or
    4059              :                             address space is non-contiguous."
    4060              :                            currently we do not generate any exception code ]
    4061              : 
    4062              :                          The Stack:
    4063              : 
    4064              :                          Entry                      Exit
    4065              : 
    4066              :                   Ptr ->
    4067              :                          +----------------+
    4068              :                          | NoOfParam      |
    4069              :                          |----------------|
    4070              :                          | Param 1        |
    4071              :                          |----------------|
    4072              :                          | Param 2        |                        <- Ptr
    4073              :                          |----------------|         +------------+
    4074              :                          | ProcSym | Type |         | ReturnVar  |
    4075              :                          |----------------|         |------------|
    4076              : */
    4077              : 
    4078              : static void BuildDifAdrFunction (unsigned int ProcSym, bool ConstExpr);
    4079              : 
    4080              : /*
    4081              :    BuildHighFunction - checks the stack in preparation for generating
    4082              :                        quadruples which perform HIGH.
    4083              :                        This procedure does not alter the stack but
    4084              :                        determines whether, a, in HIGH(a) is an ArraySym
    4085              :                        or UnboundedSym.
    4086              :                        Both cases are different and appropriate quadruple
    4087              :                        generating routines are called.
    4088              : 
    4089              :                        The Stack:
    4090              : 
    4091              : 
    4092              :                        Entry                      Exit
    4093              : 
    4094              :                 Ptr ->
    4095              :                        +----------------+
    4096              :                        | NoOfParam      |
    4097              :                        |----------------|
    4098              :                        | Param 1        |
    4099              :                        |----------------|
    4100              :                        | Param 2        |
    4101              :                        |----------------|
    4102              :                        .                .
    4103              :                        .                .
    4104              :                        .                .
    4105              :                        |----------------|
    4106              :                        | Param #        |                        <- Ptr
    4107              :                        |----------------|         +------------+
    4108              :                        | ProcSym | Type |         | ReturnVar  |
    4109              :                        |----------------|         |------------|
    4110              : 
    4111              : */
    4112              : 
    4113              : static void BuildHighFunction (void);
    4114              : 
    4115              : /*
    4116              :    BuildConstHighFromSym - builds the pseudo function HIGH from an Sym.
    4117              :                            Sym is a constant or an array which has constant bounds
    4118              :                            and therefore it can be calculated at compile time.
    4119              : 
    4120              :                            The Stack:
    4121              : 
    4122              : 
    4123              :                            Entry                      Exit
    4124              : 
    4125              :                    Ptr ->
    4126              :                            +----------------+
    4127              :                            | NoOfParam      |
    4128              :                            |----------------|
    4129              :                            | Param 1        |
    4130              :                            |----------------|
    4131              :                            | Param 2        |
    4132              :                            |----------------|
    4133              :                            .                .
    4134              :                            .                .
    4135              :                            .                .
    4136              :                            |----------------|
    4137              :                            | Param #        |                        <- Ptr
    4138              :                            |----------------|         +------------+
    4139              :                            | ProcSym | Type |         | ReturnVar  |
    4140              :                            |----------------|         |------------|
    4141              : */
    4142              : 
    4143              : static void BuildConstHighFromSym (unsigned int tok);
    4144              : 
    4145              : /*
    4146              :    BuildHighFromUnbounded - builds the pseudo function HIGH from an
    4147              :                             UnboundedSym.
    4148              : 
    4149              :                             The Stack:
    4150              : 
    4151              : 
    4152              :                             Entry                      Exit
    4153              : 
    4154              :                      Ptr ->
    4155              :                             +----------------+
    4156              :                             | NoOfParam      |
    4157              :                             |----------------|
    4158              :                             | Param #        |                        <- Ptr
    4159              :                             |----------------|         +------------+
    4160              :                             | ProcSym | Type |         | ReturnVar  |
    4161              :                             |----------------|         |------------|
    4162              : 
    4163              : */
    4164              : 
    4165              : static void BuildHighFromUnbounded (unsigned int tok);
    4166              : 
    4167              : /*
    4168              :    GetQualidentImport - returns the symbol as if it were qualified from, module.n.
    4169              :                         This is used to reference runtime support procedures and an
    4170              :                         error is generated if the symbol cannot be obtained.
    4171              : */
    4172              : 
    4173              : static unsigned int GetQualidentImport (unsigned int tokno, NameKey_Name n, NameKey_Name module);
    4174              : 
    4175              : /*
    4176              :    ConstExprError - return TRUE if a constant expression is being built and Var is a variable.
    4177              : */
    4178              : 
    4179              : static bool ConstExprError (unsigned int Func, unsigned int Var, unsigned int optok, bool ConstExpr);
    4180              : 
    4181              : /*
    4182              :    DeferMakeLengthConst - creates a constant which contains the length of string, sym.
    4183              : */
    4184              : 
    4185              : static unsigned int DeferMakeLengthConst (unsigned int tok, unsigned int sym);
    4186              : 
    4187              : /*
    4188              :    BuildLengthFunction - builds the inline standard function LENGTH.
    4189              : 
    4190              :                          The Stack:
    4191              : 
    4192              : 
    4193              :                          Entry                      Exit
    4194              : 
    4195              :                   Ptr ->
    4196              :                          +----------------+
    4197              :                          | NoOfParam      |
    4198              :                          |----------------|
    4199              :                          | Param 1        |                        <- Ptr
    4200              :                          |----------------|         +------------+
    4201              :                          | ProcSym | Type |         | ReturnVar  |
    4202              :                          |----------------|         |------------|
    4203              : 
    4204              : */
    4205              : 
    4206              : static void BuildLengthFunction (unsigned int Function, bool ConstExpr);
    4207              : 
    4208              : /*
    4209              :    BuildOddFunction - builds the pseudo procedure call ODD.
    4210              :                       This procedure is actually a "macro" for
    4211              :                       ORD(x) --> VAL(BOOLEAN, x MOD 2)
    4212              :                       However we cannot push tokens back onto the input stack
    4213              :                       because the compiler is currently building a function
    4214              :                       call and expecting a ReturnVar on the stack.
    4215              :                       Hence we manipulate the stack and call
    4216              :                       BuildConvertFunction.
    4217              : 
    4218              :                       The Stack:
    4219              : 
    4220              : 
    4221              :                       Entry                      Exit
    4222              : 
    4223              :                Ptr ->
    4224              :                       +----------------+
    4225              :                       | NoOfParam      |
    4226              :                       |----------------|
    4227              :                       | Param 1        |
    4228              :                       |----------------|
    4229              :                       | Param 2        |
    4230              :                       |----------------|
    4231              :                       .                .
    4232              :                       .                .
    4233              :                       .                .
    4234              :                       |----------------|
    4235              :                       | Param #        |
    4236              :                       |----------------|
    4237              :                       | ProcSym | Type |         Empty
    4238              :                       |----------------|
    4239              : */
    4240              : 
    4241              : static void BuildOddFunction (unsigned int ProcSym, bool ConstExpr);
    4242              : 
    4243              : /*
    4244              :    BuildAbsFunction - builds a call to the standard function ABS.
    4245              : 
    4246              :                       We cannot implement it as a macro or inline an
    4247              :                       IF THEN statement as the IF THEN ELSE requires
    4248              :                       we write the value to the same variable (or constant)
    4249              :                       twice. The macro implementation will fail as
    4250              :                       the compiler maybe building a function
    4251              :                       call and expecting a ReturnVar on the stack.
    4252              :                       The only method to implement this is to pass it to the
    4253              :                       gcc backend.
    4254              : 
    4255              :                       The Stack:
    4256              : 
    4257              : 
    4258              :                       Entry                      Exit
    4259              : 
    4260              :                Ptr ->
    4261              :                       +----------------+
    4262              :                       | NoOfParam      |
    4263              :                       |----------------|
    4264              :                       | Param 1        |
    4265              :                       |----------------|
    4266              :                       | Param 2        |
    4267              :                       |----------------|
    4268              :                       .                .
    4269              :                       .                .
    4270              :                       .                .
    4271              :                       |----------------|
    4272              :                       | Param #        |
    4273              :                       |----------------|
    4274              :                       | ProcSym | Type |         Empty
    4275              :                       |----------------|
    4276              : */
    4277              : 
    4278              : static void BuildAbsFunction (unsigned int ProcSym, bool ConstExpr);
    4279              : 
    4280              : /*
    4281              :    BuildCapFunction - builds the pseudo procedure call CAP.
    4282              :                       We generate a the following quad:
    4283              : 
    4284              : 
    4285              :                       StandardFunctionOp  ReturnVal  Cap  Param1
    4286              : 
    4287              :                       The Stack:
    4288              : 
    4289              : 
    4290              :                       Entry                      Exit
    4291              : 
    4292              :                Ptr ->
    4293              :                       +----------------+
    4294              :                       | NoOfParam = 1  |
    4295              :                       |----------------|
    4296              :                       | Param 1        |
    4297              :                       |----------------|         +-------------+
    4298              :                       | ProcSym | Type |         | ReturnVal   |
    4299              :                       |----------------|         |-------------|
    4300              : */
    4301              : 
    4302              : static void BuildCapFunction (unsigned int ProcSym, bool ConstExpr);
    4303              : 
    4304              : /*
    4305              :    BuildChrFunction - builds the pseudo procedure call CHR.
    4306              :                       This procedure is actually a "macro" for
    4307              :                       CHR(x) --> CONVERT(CHAR, x)
    4308              :                       However we cannot push tokens back onto the input stack
    4309              :                       because the compiler is currently building a function
    4310              :                       call and expecting a ReturnVar on the stack.
    4311              :                       Hence we manipulate the stack and call
    4312              :                       BuildConvertFunction.
    4313              : 
    4314              :                       The Stack:
    4315              : 
    4316              : 
    4317              :                       Entry                      Exit
    4318              : 
    4319              :                Ptr ->
    4320              :                       +----------------+
    4321              :                       | NoOfParam      |
    4322              :                       |----------------|
    4323              :                       | Param 1        |
    4324              :                       |----------------|
    4325              :                       | Param 2        |
    4326              :                       |----------------|
    4327              :                       .                .
    4328              :                       .                .
    4329              :                       .                .
    4330              :                       |----------------|
    4331              :                       | Param #        |
    4332              :                       |----------------|
    4333              :                       | ProcSym | Type |         Empty
    4334              :                       |----------------|
    4335              : */
    4336              : 
    4337              : static void BuildChrFunction (unsigned int ProcSym, bool ConstExpr);
    4338              : 
    4339              : /*
    4340              :    BuildOrdFunction - builds the pseudo procedure call ORD.
    4341              :                       This procedure is actually a "macro" for
    4342              :                       ORD(x) --> CONVERT(GetSType(sym), x)
    4343              :                       However we cannot push tokens back onto the input stack
    4344              :                       because the compiler is currently building a function
    4345              :                       call and expecting a ReturnVar on the stack.
    4346              :                       Hence we manipulate the stack and call
    4347              :                       BuildConvertFunction.
    4348              : 
    4349              :                       The Stack:
    4350              : 
    4351              : 
    4352              :                       Entry                      Exit
    4353              : 
    4354              :                Ptr ->
    4355              :                       +----------------+
    4356              :                       | NoOfParam      |
    4357              :                       |----------------|
    4358              :                       | Param 1        |
    4359              :                       |----------------|
    4360              :                       | Param 2        |
    4361              :                       |----------------|
    4362              :                       .                .
    4363              :                       .                .
    4364              :                       .                .
    4365              :                       |----------------|
    4366              :                       | Param #        |
    4367              :                       |----------------|
    4368              :                       | ProcSym | Type |         Empty
    4369              :                       |----------------|
    4370              : */
    4371              : 
    4372              : static void BuildOrdFunction (unsigned int Sym, bool ConstExpr);
    4373              : 
    4374              : /*
    4375              :    BuildIntFunction - builds the pseudo procedure call INT.
    4376              :                       This procedure is actually a "macro" for
    4377              :                       INT(x) --> CONVERT(INTEGER, x)
    4378              :                       However we cannot push tokens back onto the input stack
    4379              :                       because the compiler is currently building a function
    4380              :                       call and expecting a ReturnVar on the stack.
    4381              :                       Hence we manipulate the stack and call
    4382              :                       BuildConvertFunction.
    4383              : 
    4384              :                       The Stack:
    4385              : 
    4386              : 
    4387              :                       Entry                      Exit
    4388              : 
    4389              :                Ptr ->
    4390              :                       +----------------+
    4391              :                       | NoOfParam      |
    4392              :                       |----------------|
    4393              :                       | Param 1        |
    4394              :                       |----------------|
    4395              :                       | Param 2        |
    4396              :                       |----------------|
    4397              :                       .                .
    4398              :                       .                .
    4399              :                       .                .
    4400              :                       |----------------|
    4401              :                       | Param #        |
    4402              :                       |----------------|
    4403              :                       | ProcSym | Type |         Empty
    4404              :                       |----------------|
    4405              : */
    4406              : 
    4407              : static void BuildIntFunction (unsigned int Sym, bool ConstExpr);
    4408              : 
    4409              : /*
    4410              :    BuildMakeAdrFunction - builds the pseudo procedure call MAKEADR.
    4411              : 
    4412              :                           The Stack:
    4413              : 
    4414              : 
    4415              :                           Entry                      Exit
    4416              : 
    4417              :                    Ptr ->
    4418              :                           +----------------+
    4419              :                           | NoOfParam      |
    4420              :                           |----------------|
    4421              :                           | Param 1        |
    4422              :                           |----------------|
    4423              :                           | Param 2        |
    4424              :                           |----------------|
    4425              :                           .                .
    4426              :                           .                .
    4427              :                           .                .
    4428              :                           |----------------|
    4429              :                           | Param #        |
    4430              :                           |----------------|
    4431              :                           | ProcSym | Type |         Empty
    4432              :                           |----------------|
    4433              : */
    4434              : 
    4435              : static void BuildMakeAdrFunction (void);
    4436              : 
    4437              : /*
    4438              :    BuildShiftFunction - builds the pseudo procedure call SHIFT.
    4439              : 
    4440              :                         PROCEDURE SHIFT (val: <any type>;
    4441              :                                          num: INTEGER): <any type> ;
    4442              : 
    4443              :                        "Returns a bit sequence obtained from val by
    4444              :                         shifting up or down (left or right) by the
    4445              :                         absolute value of num, introducing
    4446              :                         zeros as necessary.  The direction is down if
    4447              :                         the sign of num is negative, otherwise the
    4448              :                         direction is up."
    4449              : 
    4450              :                         The Stack:
    4451              : 
    4452              :                         Entry                      Exit
    4453              : 
    4454              :                  Ptr ->
    4455              :                         +----------------+
    4456              :                         | NoOfParam      |
    4457              :                         |----------------|
    4458              :                         | Param 1        |
    4459              :                         |----------------|
    4460              :                         | Param 2        |                        <- Ptr
    4461              :                         |----------------|         +------------+
    4462              :                         | ProcSym | Type |         | ReturnVar  |
    4463              :                         |----------------|         |------------|
    4464              : */
    4465              : 
    4466              : static void BuildShiftFunction (void);
    4467              : 
    4468              : /*
    4469              :    BuildRotateFunction - builds the pseudo procedure call ROTATE.
    4470              : 
    4471              :                          PROCEDURE ROTATE (val: <any type>;
    4472              :                                            num: INTEGER): <any type> ;
    4473              : 
    4474              :                         "Returns a bit sequence obtained from val
    4475              :                          by rotating up or down (left or right) by
    4476              :                          the absolute value of num.  The direction is
    4477              :                          down if the sign of num is negative, otherwise
    4478              :                          the direction is up."
    4479              : 
    4480              :                          The Stack:
    4481              : 
    4482              :                          Entry                      Exit
    4483              : 
    4484              :                   Ptr ->
    4485              :                          +----------------+
    4486              :                          | NoOfParam      |
    4487              :                          |----------------|
    4488              :                          | Param 1        |
    4489              :                          |----------------|
    4490              :                          | Param 2        |                        <- Ptr
    4491              :                          |----------------|         +------------+
    4492              :                          | ProcSym | Type |         | ReturnVar  |
    4493              :                          |----------------|         |------------|
    4494              : */
    4495              : 
    4496              : static void BuildRotateFunction (void);
    4497              : 
    4498              : /*
    4499              :    BuildValFunction - builds the pseudo procedure call VAL.
    4500              :                       This procedure is actually a "macro" for
    4501              :                       VAL(Type, x) --> CONVERT(Type, x)
    4502              :                       However we cannot push tokens back onto the input stack
    4503              :                       because the compiler is currently building a function
    4504              :                       call and expecting a ReturnVar on the stack.
    4505              :                       Hence we manipulate the stack and call
    4506              :                       BuildConvertFunction.
    4507              : 
    4508              :                       The Stack:
    4509              : 
    4510              : 
    4511              :                       Entry                      Exit
    4512              : 
    4513              :                Ptr ->
    4514              :                       +----------------+
    4515              :                       | NoOfParam      |
    4516              :                       |----------------|
    4517              :                       | Param 1        |
    4518              :                       |----------------|
    4519              :                       | Param 2        |
    4520              :                       |----------------|
    4521              :                       .                .
    4522              :                       .                .
    4523              :                       .                .
    4524              :                       |----------------|
    4525              :                       | Param #        |
    4526              :                       |----------------|
    4527              :                       | ProcSym | Type |         Empty
    4528              :                       |----------------|
    4529              : */
    4530              : 
    4531              : static void BuildValFunction (unsigned int ProcSym, bool ConstExpr);
    4532              : 
    4533              : /*
    4534              :    BuildCastFunction - builds the pseudo procedure call CAST.
    4535              :                        This procedure is actually a "macro" for
    4536              :                        CAST(Type, x) --> Type(x)
    4537              :                        However we cannot push tokens back onto the input stack
    4538              :                        because the compiler is currently building a function
    4539              :                        call and expecting a ReturnVar on the stack.
    4540              :                        Hence we manipulate the stack and call
    4541              :                        BuildConvertFunction.
    4542              : 
    4543              :                        The Stack:
    4544              : 
    4545              : 
    4546              :                        Entry                      Exit
    4547              : 
    4548              :                 Ptr ->
    4549              :                        +----------------+
    4550              :                        | NoOfParam      |
    4551              :                        |----------------|
    4552              :                        | Param 1        |
    4553              :                        |----------------|
    4554              :                        | Param 2        |
    4555              :                        |----------------|
    4556              :                        .                .
    4557              :                        .                .
    4558              :                        .                .
    4559              :                        |----------------|
    4560              :                        | Param #        |
    4561              :                        |----------------|
    4562              :                        | ProcSym | Type |         Empty
    4563              :                        |----------------|
    4564              : */
    4565              : 
    4566              : static void BuildCastFunction (unsigned int ProcSym, bool ConstExpr);
    4567              : 
    4568              : /*
    4569              :    BuildConvertFunction - builds the pseudo function CONVERT.
    4570              :                           CONVERT( Type, Variable ) ;
    4571              : 
    4572              :                           The Stack:
    4573              : 
    4574              : 
    4575              :                           Entry                      Exit
    4576              : 
    4577              :                    Ptr ->
    4578              :                           +----------------+
    4579              :                           | NoOfParam      |
    4580              :                           |----------------|
    4581              :                           | Param 1        |
    4582              :                           |----------------|
    4583              :                           | Param 2        |
    4584              :                           |----------------|
    4585              :                           .                .
    4586              :                           .                .
    4587              :                           .                .
    4588              :                           |----------------|
    4589              :                           | Param #        |                                 <- Ptr
    4590              :                           |----------------|         +---------------------+
    4591              :                           | ProcSym | Type |         | ReturnVar | Param1  |
    4592              :                           |----------------|         |---------------------|
    4593              : 
    4594              :                           Quadruples:
    4595              : 
    4596              :                           ConvertOp  ReturnVar  Param1  Param2
    4597              : 
    4598              :                           Converts variable Param2 into a variable Param1
    4599              :                           with a type Param1.
    4600              : */
    4601              : 
    4602              : static void BuildConvertFunction (unsigned int ProcSym, bool ConstExpr);
    4603              : 
    4604              : /*
    4605              :    CheckBaseTypeValue - checks to see whether the value, min, really exists.
    4606              : */
    4607              : 
    4608              : static unsigned int CheckBaseTypeValue (unsigned int tok, unsigned int type, unsigned int min, unsigned int func);
    4609              : 
    4610              : /*
    4611              :    GetTypeMin - returns the minimium value of type and generate an error
    4612              :                 if this is unavailable.
    4613              : */
    4614              : 
    4615              : static unsigned int GetTypeMin (unsigned int tok, unsigned int func, unsigned int type);
    4616              : 
    4617              : /*
    4618              :    GetTypeMinLower - obtain the maximum value for type.
    4619              : */
    4620              : 
    4621              : static unsigned int GetTypeMinLower (unsigned int tok, unsigned int func, unsigned int type);
    4622              : 
    4623              : /*
    4624              :    GetTypeMax - returns the maximum value of type and generate an error
    4625              :                 if this is unavailable.
    4626              : */
    4627              : 
    4628              : static unsigned int GetTypeMax (unsigned int tok, unsigned int func, unsigned int type);
    4629              : 
    4630              : /*
    4631              :    GetTypeMaxLower - obtain the maximum value for type.
    4632              : */
    4633              : 
    4634              : static unsigned int GetTypeMaxLower (unsigned int tok, unsigned int func, unsigned int type);
    4635              : 
    4636              : /*
    4637              :    BuildMinFunction - builds the pseudo function call Min.
    4638              : 
    4639              :                       The Stack:
    4640              : 
    4641              :                       Entry                      Exit
    4642              : 
    4643              :                Ptr ->
    4644              :                       +----------------+
    4645              :                       | NoOfParam=1    |
    4646              :                       |----------------|
    4647              :                       | Param 1        |
    4648              :                       |----------------|
    4649              :                       | ProcSym | Type |         Empty
    4650              :                       |----------------|
    4651              : */
    4652              : 
    4653              : static void BuildMinFunction (void);
    4654              : 
    4655              : /*
    4656              :    BuildMaxFunction - builds the pseudo function call Max.
    4657              : 
    4658              :                       The Stack:
    4659              : 
    4660              :                       Entry                      Exit
    4661              : 
    4662              :                Ptr ->
    4663              :                       +----------------+
    4664              :                       | NoOfParam=1    |
    4665              :                       |----------------|
    4666              :                       | Param 1        |
    4667              :                       |----------------|
    4668              :                       | ProcSym | Type |         Empty
    4669              :                       |----------------|
    4670              : */
    4671              : 
    4672              : static void BuildMaxFunction (void);
    4673              : 
    4674              : /*
    4675              :    BuildTruncFunction - builds the pseudo procedure call TRUNC.
    4676              :                         This procedure is actually a "macro" for
    4677              :                         TRUNC(x) --> CONVERT(INTEGER, x)
    4678              :                         However we cannot push tokens back onto the input stack
    4679              :                         because the compiler is currently building a function
    4680              :                         call and expecting a ReturnVar on the stack.
    4681              :                         Hence we manipulate the stack and call
    4682              :                         BuildConvertFunction.
    4683              : 
    4684              :                         The Stack:
    4685              : 
    4686              : 
    4687              :                         Entry                      Exit
    4688              : 
    4689              :                  Ptr ->
    4690              :                         +----------------+
    4691              :                         | NoOfParam      |
    4692              :                         |----------------|
    4693              :                         | Param 1        |
    4694              :                         |----------------|
    4695              :                         | Param 2        |
    4696              :                         |----------------|
    4697              :                         .                .
    4698              :                         .                .
    4699              :                         .                .
    4700              :                         |----------------|
    4701              :                         | Param #        |
    4702              :                         |----------------|
    4703              :                         | ProcSym | Type |         Empty
    4704              :                         |----------------|
    4705              : */
    4706              : 
    4707              : static void BuildTruncFunction (unsigned int Sym, bool ConstExpr);
    4708              : 
    4709              : /*
    4710              :    BuildFloatFunction - builds the pseudo procedure call FLOAT.
    4711              :                         This procedure is actually a "macro" for
    4712              :                         FLOAT(x) --> CONVERT(REAL, x)
    4713              :                         However we cannot push tokens back onto the input stack
    4714              :                         because the compiler is currently building a function
    4715              :                         call and expecting a ReturnVar on the stack.
    4716              :                         Hence we manipulate the stack and call
    4717              :                         BuildConvertFunction.
    4718              : 
    4719              :                         The Stack:
    4720              : 
    4721              : 
    4722              :                         Entry                      Exit
    4723              : 
    4724              :                  Ptr ->
    4725              :                         +----------------+
    4726              :                         | NoOfParam      |
    4727              :                         |----------------|
    4728              :                         | Param 1        |
    4729              :                         |----------------|
    4730              :                         | Param 2        |
    4731              :                         |----------------|
    4732              :                         .                .
    4733              :                         .                .
    4734              :                         .                .
    4735              :                         |----------------|
    4736              :                         | Param #        |
    4737              :                         |----------------|
    4738              :                         | ProcSym | Type |         Empty
    4739              :                         |----------------|
    4740              : */
    4741              : 
    4742              : static void BuildFloatFunction (unsigned int Sym, bool ConstExpr);
    4743              : 
    4744              : /*
    4745              :    BuildReFunction - builds the pseudo procedure call RE.
    4746              : 
    4747              :                      The Stack:
    4748              : 
    4749              : 
    4750              :                          Entry                      Exit
    4751              : 
    4752              :                  Ptr ->
    4753              :                         +----------------+
    4754              :                         | NoOfParam      |
    4755              :                         |----------------|
    4756              :                         | Param 1        |
    4757              :                         |----------------|
    4758              :                         | Param 2        |
    4759              :                         |----------------|
    4760              :                         .                .
    4761              :                         .                .
    4762              :                         .                .
    4763              :                         |----------------|
    4764              :                         | Param #        |
    4765              :                         |----------------|
    4766              :                         | ProcSym | Type |         Empty
    4767              :                         |----------------|
    4768              : */
    4769              : 
    4770              : static void BuildReFunction (unsigned int Sym, bool ConstExpr);
    4771              : 
    4772              : /*
    4773              :    BuildImFunction - builds the pseudo procedure call IM.
    4774              : 
    4775              :                      The Stack:
    4776              : 
    4777              : 
    4778              :                          Entry                      Exit
    4779              : 
    4780              :                  Ptr ->
    4781              :                         +----------------+
    4782              :                         | NoOfParam      |
    4783              :                         |----------------|
    4784              :                         | Param 1        |
    4785              :                         |----------------|
    4786              :                         | Param 2        |
    4787              :                         |----------------|
    4788              :                         .                .
    4789              :                         .                .
    4790              :                         .                .
    4791              :                         |----------------|
    4792              :                         | Param #        |
    4793              :                         |----------------|
    4794              :                         | ProcSym | Type |         Empty
    4795              :                         |----------------|
    4796              : */
    4797              : 
    4798              : static void BuildImFunction (unsigned int Sym, bool ConstExpr);
    4799              : 
    4800              : /*
    4801              :    BuildCmplxFunction - builds the pseudo procedure call CMPLX.
    4802              : 
    4803              :                         The Stack:
    4804              : 
    4805              : 
    4806              :                         Entry                      Exit
    4807              : 
    4808              :                  Ptr ->
    4809              :                         +----------------+
    4810              :                         | NoOfParam      |
    4811              :                         |----------------|
    4812              :                         | Param 1        |
    4813              :                         |----------------|
    4814              :                         | Param 2        |
    4815              :                         |----------------|
    4816              :                         .                .
    4817              :                         .                .
    4818              :                         .                .
    4819              :                         |----------------|
    4820              :                         | Param #        |
    4821              :                         |----------------|
    4822              :                         | ProcSym | Type |         Empty
    4823              :                         |----------------|
    4824              : */
    4825              : 
    4826              : static void BuildCmplxFunction (unsigned int func, bool ConstExpr);
    4827              : 
    4828              : /*
    4829              :    BuildAdrFunction - builds the pseudo function ADR
    4830              :                       The Stack:
    4831              : 
    4832              : 
    4833              :                       Entry                      Exit
    4834              : 
    4835              :                Ptr ->
    4836              :                       +----------------+
    4837              :                       | NoOfParam      |
    4838              :                       |----------------|
    4839              :                       | Param 1        |
    4840              :                       |----------------|
    4841              :                       | Param 2        |
    4842              :                       |----------------|
    4843              :                       .                .
    4844              :                       .                .
    4845              :                       .                .
    4846              :                       |----------------|
    4847              :                       | Param #        |                        <- Ptr
    4848              :                       |----------------|         +------------+
    4849              :                       | ProcSym | Type |         | ReturnVar  |
    4850              :                       |----------------|         |------------|
    4851              : 
    4852              : */
    4853              : 
    4854              : static void BuildAdrFunction (void);
    4855              : 
    4856              : /*
    4857              :    BuildSizeFunction - builds the pseudo function SIZE
    4858              :                        The Stack:
    4859              : 
    4860              : 
    4861              :                        Entry                      Exit
    4862              : 
    4863              :                 Ptr ->
    4864              :                        +----------------+
    4865              :                        | NoOfParam      |
    4866              :                        |----------------|
    4867              :                        | Param 1        |
    4868              :                        |----------------|
    4869              :                        | Param 2        |
    4870              :                        |----------------|
    4871              :                        .                .
    4872              :                        .                .
    4873              :                        .                .
    4874              :                        |----------------|
    4875              :                        | Param #        |                        <- Ptr
    4876              :                        |----------------|         +------------+
    4877              :                        | ProcSym | Type |         | ReturnVar  |
    4878              :                        |----------------|         |------------|
    4879              : */
    4880              : 
    4881              : static void BuildSizeFunction (void);
    4882              : 
    4883              : /*
    4884              :    BuildTSizeFunction - builds the pseudo function TSIZE
    4885              :                         The Stack:
    4886              : 
    4887              : 
    4888              :                         Entry                      Exit
    4889              : 
    4890              :                  Ptr ->
    4891              :                         +----------------+
    4892              :                         | NoOfParam      |
    4893              :                         |----------------|
    4894              :                         | Param 1        |
    4895              :                         |----------------|
    4896              :                         | Param 2        |
    4897              :                         |----------------|
    4898              :                         .                .
    4899              :                         .                .
    4900              :                         .                .
    4901              :                         |----------------|
    4902              :                         | Param #        |                        <- Ptr
    4903              :                         |----------------|         +------------+
    4904              :                         | ProcSym | Type |         | ReturnVar  |
    4905              :                         |----------------|         |------------|
    4906              : 
    4907              : */
    4908              : 
    4909              : static void BuildTSizeFunction (void);
    4910              : 
    4911              : /*
    4912              :    BuildTBitSizeFunction - builds the pseudo function TBITSIZE
    4913              :                            The Stack:
    4914              : 
    4915              : 
    4916              :                            Entry                      Exit
    4917              : 
    4918              :                    Ptr ->
    4919              :                            +----------------+
    4920              :                            | NoOfParam      |
    4921              :                            |----------------|
    4922              :                            | Param 1        |
    4923              :                            |----------------|
    4924              :                            | Param 2        |
    4925              :                            |----------------|
    4926              :                            .                .
    4927              :                            .                .
    4928              :                            .                .
    4929              :                            |----------------|
    4930              :                            | Param #        |                        <- Ptr
    4931              :                            |----------------|         +------------+
    4932              :                            | ProcSym | Type |         | ReturnVar  |
    4933              :                            |----------------|         |------------|
    4934              : 
    4935              : */
    4936              : 
    4937              : static void BuildTBitSizeFunction (void);
    4938              : 
    4939              : /*
    4940              :    ExpectingParameterType -
    4941              : */
    4942              : 
    4943              : static void ExpectingParameterType (unsigned int BlockSym, unsigned int Type);
    4944              : 
    4945              : /*
    4946              :    ExpectingVariableType -
    4947              : */
    4948              : 
    4949              : static void ExpectingVariableType (unsigned int BlockSym, unsigned int Type);
    4950              : 
    4951              : /*
    4952              :    CheckVariablesAndParameterTypesInBlock - checks to make sure that block, BlockSym, has
    4953              :                                             parameters types and variable types which are legal.
    4954              : */
    4955              : 
    4956              : static void CheckVariablesAndParameterTypesInBlock (unsigned int BlockSym);
    4957              : 
    4958              : /*
    4959              :    IsNeverAltered - returns TRUE if variable, sym, is never altered
    4960              :                     between quadruples: Start..End
    4961              : */
    4962              : 
    4963              : static bool IsNeverAltered (unsigned int sym, unsigned int Start, unsigned int End);
    4964              : 
    4965              : /*
    4966              :    IsConditionVariable - returns TRUE if the condition at quadruple, q, is variable.
    4967              : */
    4968              : 
    4969              : static bool IsConditionVariable (unsigned int q, unsigned int Start, unsigned int End);
    4970              : 
    4971              : /*
    4972              :    IsInfiniteLoop - returns TRUE if an infinite loop is found.
    4973              :                     Given a backwards jump at, End, it returns a BOOLEAN which depends on
    4974              :                     whether a jump is found to jump beyond, End. If a conditonal jump is found
    4975              :                     to pass over, End, the condition is tested for global variables, procedure variables and
    4976              :                     constants.
    4977              : 
    4978              :                          constant        - ignored
    4979              :                          variables       - tested to see whether they are altered inside the loop
    4980              :                          global variable - the procedure tests to see whether it is altered as above
    4981              :                                            but will also test to see whether this loop calls a procedure
    4982              :                                            in which case it believes the loop NOT to be infinite
    4983              :                                            (as this procedure call might alter the global variable)
    4984              : 
    4985              :                     Note that this procedure can easily be fooled by the user altering variables
    4986              :                     with pointers.
    4987              : */
    4988              : 
    4989              : static bool IsInfiniteLoop (unsigned int End);
    4990              : 
    4991              : /*
    4992              :    CheckVariablesInBlock - given a block, BlockSym, check whether all variables are used.
    4993              : */
    4994              : 
    4995              : static void CheckVariablesInBlock (unsigned int BlockSym);
    4996              : 
    4997              : /*
    4998              :    CheckFunctionReturn - checks to see that a RETURN statement was present in a function.
    4999              : */
    5000              : 
    5001              : static void CheckFunctionReturn (unsigned int ProcSym);
    5002              : 
    5003              : /*
    5004              :    CheckReturnType - checks to see that the return type from currentProc is
    5005              :                      assignment compatible with actualType.
    5006              : */
    5007              : 
    5008              : static void CheckReturnType (unsigned int tokno, unsigned int currentProc, unsigned int actualVal, unsigned int actualType);
    5009              : 
    5010              : /*
    5011              :    BuildReturnLower - check the return type and value to ensure type
    5012              :                       compatibility and no range overflow will occur.
    5013              : */
    5014              : 
    5015              : static void BuildReturnLower (unsigned int tokcombined, unsigned int tokexpr, unsigned int e1, unsigned int t1);
    5016              : 
    5017              : /*
    5018              :    IsReadOnly - a helper procedure function to detect constants.
    5019              : */
    5020              : 
    5021              : static bool IsReadOnly (unsigned int sym);
    5022              : 
    5023              : /*
    5024              :    BuildDesignatorError - removes the designator from the stack and replaces
    5025              :                           it with an error symbol.
    5026              : */
    5027              : 
    5028              : static void BuildDesignatorError (const char *message_, unsigned int _message_high);
    5029              : 
    5030              : /*
    5031              :    BuildDesignatorPointerError - removes the designator from the stack and replaces
    5032              :                                  it with an error symbol.
    5033              : */
    5034              : 
    5035              : static void BuildDesignatorPointerError (unsigned int type, unsigned int rw, unsigned int tokpos, const char *message_, unsigned int _message_high);
    5036              : 
    5037              : /*
    5038              :    BuildDesignatorArrayStaticDynamic - Builds the array referencing.
    5039              :                                        The purpose of this procedure is to work out
    5040              :                                        whether the DesignatorArray is a static or
    5041              :                                        dynamic array and to call the appropriate
    5042              :                                        BuildRoutine.
    5043              : 
    5044              :                                        The Stack is expected to contain:
    5045              : 
    5046              : 
    5047              :                                        Entry                   Exit
    5048              :                                        =====                   ====
    5049              : 
    5050              :                                 Ptr ->
    5051              :                                        +--------------+
    5052              :                                        | e            |                        <- Ptr
    5053              :                                        |--------------|        +------------+
    5054              :                                        | Sym  | Type  |        | S    | T   |
    5055              :                                        |--------------|        |------------|
    5056              : */
    5057              : 
    5058              : static void BuildDesignatorArrayStaticDynamic (void);
    5059              : 
    5060              : /*
    5061              :    BuildStaticArray - Builds the array referencing for static arrays.
    5062              :                       The Stack is expected to contain:
    5063              : 
    5064              : 
    5065              :                       Entry                   Exit
    5066              :                       =====                   ====
    5067              : 
    5068              :               Ptr ->
    5069              :                       +--------------+
    5070              :                       | e            |                       <- Ptr
    5071              :                       |--------------|        +------------+
    5072              :                       | Sym  | Type  |        | S    | T   |
    5073              :                       |--------------|        |------------|
    5074              : */
    5075              : 
    5076              : static void BuildStaticArray (void);
    5077              : 
    5078              : /*
    5079              :    calculateMultipicand - generates quadruples which calculate the
    5080              :                           multiplicand for the array at dimension, dim.
    5081              : */
    5082              : 
    5083              : static unsigned int calculateMultipicand (unsigned int tok, unsigned int arraySym, unsigned int arrayType, unsigned int dim);
    5084              : 
    5085              : /*
    5086              :    ConvertToAddress - convert sym to an address.
    5087              : */
    5088              : 
    5089              : static unsigned int ConvertToAddress (unsigned int tokpos, unsigned int sym);
    5090              : 
    5091              : /*
    5092              :    BuildDynamicArray - Builds the array referencing for dynamic arrays.
    5093              :                        The Stack is expected to contain:
    5094              : 
    5095              : 
    5096              :                        Entry                          Exit
    5097              :                        =====                          ====
    5098              : 
    5099              :                Ptr ->
    5100              :                        +-----------------------+
    5101              :                        | Index                 |                                    <- Ptr
    5102              :                        |-----------------------|      +---------------------------+
    5103              :                        | ArraySym | Type | Dim |      | S  | T | ArraySym | Dim+1 |
    5104              :                        |-----------------------|      |---------------------------|
    5105              : 
    5106              : 
    5107              :    if Dim=1
    5108              :    then
    5109              :       S := base of ArraySym + TSIZE(Type)*Index
    5110              :    else
    5111              :       S := S + TSIZE(Type)*Index
    5112              :    fi
    5113              : */
    5114              : 
    5115              : static void BuildDynamicArray (void);
    5116              : 
    5117              : /*
    5118              :    DebugLocation -
    5119              : */
    5120              : 
    5121              : static void DebugLocation (unsigned int tok, const char *message_, unsigned int _message_high);
    5122              : 
    5123              : /*
    5124              :    PushWith - pushes sym and type onto the with stack. It checks for
    5125              :               previous declaration of this record type.
    5126              : */
    5127              : 
    5128              : static void PushWith (unsigned int Sym, unsigned int Type, unsigned int Ref, unsigned int Tok);
    5129              : static void PopWith (void);
    5130              : 
    5131              : /*
    5132              :    BuildAccessWithField - similar to BuildDesignatorRecord except it
    5133              :                           does not perform the address operation.
    5134              :                           The address will have been computed at the
    5135              :                           beginning of the WITH statement.
    5136              :                           It also stops the GenQuad procedure from examining the
    5137              :                           with stack.
    5138              : 
    5139              :                           The Stack
    5140              : 
    5141              :                           Entry
    5142              : 
    5143              :                    Ptr ->
    5144              :                           +--------------+
    5145              :                           | Field | Type1|                          <- Ptr
    5146              :                           |-------|------|          +-------------+
    5147              :                           | Adr   | Type2|          | Sym  | Type1|
    5148              :                           |--------------|          |-------------|
    5149              : */
    5150              : 
    5151              : static void BuildAccessWithField (void);
    5152              : 
    5153              : /*
    5154              :    SafeCheckWithField - only call CheckWithReference if the top of stack
    5155              :                         contains a record field.
    5156              : */
    5157              : 
    5158              : static void SafeCheckWithField (void);
    5159              : 
    5160              : /*
    5161              :    PushConstructor -
    5162              : */
    5163              : 
    5164              : static void PushConstructor (unsigned int sym);
    5165              : 
    5166              : /*
    5167              :    AddFieldTo - adds field to value.
    5168              : */
    5169              : 
    5170              : static unsigned int AddFieldTo (unsigned int value, unsigned int field, unsigned int valuetok, unsigned int fieldtok);
    5171              : 
    5172              : /*
    5173              :    CheckLogicalOperator - returns a logical operator if the operands imply
    5174              :                           a logical operation should be performed.
    5175              : */
    5176              : 
    5177              : static NameKey_Name CheckLogicalOperator (NameKey_Name Tok, unsigned int left, unsigned int lefttype);
    5178              : 
    5179              : /*
    5180              :    CheckDivModRem - initiates calls to check the divisor for DIV, MOD, REM
    5181              :                     expressions.
    5182              : */
    5183              : 
    5184              : static void CheckDivModRem (unsigned int TokPos, NameKey_Name tok, unsigned int d, unsigned int e);
    5185              : 
    5186              : /*
    5187              :    doConvert - convert, sym, to a new symbol with, type.
    5188              :                Return the new symbol.
    5189              : */
    5190              : 
    5191              : static unsigned int doConvert (unsigned int type, unsigned int sym);
    5192              : 
    5193              : /*
    5194              :    doBuildBinaryOp - build the binary op, with or without type
    5195              :                      checking.
    5196              : */
    5197              : 
    5198              : static void doBuildBinaryOp (bool checkTypes, bool checkOverflow);
    5199              : 
    5200              : /*
    5201              :    AreConstant - returns immediate addressing mode if b is true else
    5202              :                  offset mode is returned. b determines whether the
    5203              :                  operands are all constant - in which case we can use
    5204              :                  a constant temporary variable.
    5205              : */
    5206              : 
    5207              : static SymbolTable_ModeOfAddr AreConstant (bool b);
    5208              : 
    5209              : /*
    5210              :    ConvertBooleanToVariable - converts a BoolStack(i) from a Boolean True|False
    5211              :                               exit pair into a variable containing the value TRUE or
    5212              :                               FALSE.  The parameter i is relative to the top
    5213              :                               of the stack.
    5214              : */
    5215              : 
    5216              : static void ConvertBooleanToVariable (unsigned int tok, unsigned int i);
    5217              : 
    5218              : /*
    5219              :    DumpQuadSummary -
    5220              : */
    5221              : 
    5222              : static void DumpQuadSummary (unsigned int quad);
    5223              : 
    5224              : /*
    5225              :    BuildRelOpFromBoolean - builds a relational operator sequence of quadruples
    5226              :                            instead of using a temporary boolean variable.
    5227              :                            This function can only be used when we perform
    5228              :                            the following translation:
    5229              : 
    5230              :                            (a=b) # (c=d)  alternatively   (a=b) = (c=d)
    5231              :                                  ^                              ^
    5232              : 
    5233              :                            it only allows # = to be used as >= <= > < all
    5234              :                            assume a particular value for TRUE and FALSE.
    5235              :                            (In which case the user should specify ORD)
    5236              : 
    5237              : 
    5238              :                            before
    5239              : 
    5240              :                            q      if r1      op1     op2     t2
    5241              :                            q+1    Goto                       f2
    5242              :                            ...
    5243              :                            q+n    if r2      op3     op4     t1
    5244              :                            q+n+1  Goto                       f1
    5245              : 
    5246              :                            after (in case of =)
    5247              : 
    5248              :                            q    if r1      op1     op2     q+2
    5249              :                            q+1  Goto                       q+4
    5250              :                            q+2  if r2      op3     op4     t
    5251              :                            q+3  Goto                       f
    5252              :                            q+4  if r2      op3     op4     f
    5253              :                            q+5  Goto                       t
    5254              : 
    5255              :                            after (in case of #)
    5256              : 
    5257              :                            q      if r1      op1     op2     q+2
    5258              :                            q+1    Goto                       q+n+2
    5259              :                            q+2    ...
    5260              :                            ...    ...
    5261              :                            q+n    if r2      op3     op4     f
    5262              :                            q+n+1  Goto                       t
    5263              :                            q+n+2  if r2      op3     op4     t
    5264              :                            q+n+3  Goto                       f
    5265              : 
    5266              :                            The Stack is expected to contain:
    5267              : 
    5268              : 
    5269              :                            Entry                   Exit
    5270              :                            =====                   ====
    5271              : 
    5272              :                     Ptr ->
    5273              :                            +------------+
    5274              :                            | t1 | f1    |
    5275              :                            |------------|
    5276              :                            | Operator   |                          <- Ptr
    5277              :                            |------------|          +------------+
    5278              :                            | t2 | f2    |          | t    | f   |
    5279              :                            |------------|          |------------|
    5280              : 
    5281              : 
    5282              : */
    5283              : 
    5284              : static void BuildRelOpFromBoolean (unsigned int tokpos);
    5285              : 
    5286              : /*
    5287              :    CheckVariableOrConstantOrProcedure - checks to make sure sym is a variable, constant or procedure.
    5288              : */
    5289              : 
    5290              : static void CheckVariableOrConstantOrProcedure (unsigned int tokpos, unsigned int sym);
    5291              : 
    5292              : /*
    5293              :    MakeOp - returns the equalent quadruple operator to a token, t.
    5294              : */
    5295              : 
    5296              : static M2Quads_QuadOperator MakeOp (NameKey_Name t);
    5297              : 
    5298              : /*
    5299              :    GenQuadO - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
    5300              : */
    5301              : 
    5302              : static void GenQuadO (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow);
    5303              : 
    5304              : /*
    5305              :    GenQuadOTrash - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
    5306              : */
    5307              : 
    5308              : static void GenQuadOTrash (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow, unsigned int trash);
    5309              : 
    5310              : /*
    5311              :    GenQuad - Generate a quadruple with Operation, Op1, Op2, Op3.
    5312              : */
    5313              : 
    5314              : static void GenQuad (M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3);
    5315              : 
    5316              : /*
    5317              :    GenQuadOtok - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
    5318              : */
    5319              : 
    5320              : static void GenQuadOtok (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow, unsigned int Op1Pos, unsigned int Op2Pos, unsigned int Op3Pos);
    5321              : 
    5322              : /*
    5323              :    GenQuadOTypetok - assigns the fields of the quadruple with
    5324              :                      the parameters.
    5325              : */
    5326              : 
    5327              : static void GenQuadOTypetok (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow, bool typecheck, unsigned int Op1Pos, unsigned int Op2Pos, unsigned int Op3Pos);
    5328              : 
    5329              : /*
    5330              :    DumpUntil - dump all quadruples until we seen the ending quadruple
    5331              :                with procsym in the third operand.
    5332              :                Return the quad number containing the match.
    5333              : */
    5334              : 
    5335              : static unsigned int DumpUntil (M2Quads_QuadOperator ending, unsigned int procsym, unsigned int quad);
    5336              : 
    5337              : /*
    5338              :    GetCtorInit - return the init procedure for the module.
    5339              : */
    5340              : 
    5341              : static unsigned int GetCtorInit (unsigned int sym);
    5342              : 
    5343              : /*
    5344              :    GetCtorFini - return the fini procedure for the module.
    5345              : */
    5346              : 
    5347              : static unsigned int GetCtorFini (unsigned int sym);
    5348              : 
    5349              : /*
    5350              :    DumpQuadrupleFilter -
    5351              : */
    5352              : 
    5353              : static void DumpQuadrupleFilter (void);
    5354              : 
    5355              : /*
    5356              :    DumpQuadrupleAll - dump all quadruples.
    5357              : */
    5358              : 
    5359              : static void DumpQuadrupleAll (void);
    5360              : 
    5361              : /*
    5362              :    BackPatch - Makes each of the quadruples on the list pointed to by
    5363              :                QuadNo take quadruple Value as a target.
    5364              : */
    5365              : 
    5366              : static void BackPatch (unsigned int QuadNo, unsigned int Value);
    5367              : 
    5368              : /*
    5369              :    Merge - joins two quad lists, QuadList2 to the end of QuadList1.
    5370              :            A QuadList of value zero is a nul list.
    5371              : */
    5372              : 
    5373              : static unsigned int Merge (unsigned int QuadList1, unsigned int QuadList2);
    5374              : 
    5375              : /*
    5376              :    DisplayProcedureAttributes -
    5377              : */
    5378              : 
    5379              : static void DisplayProcedureAttributes (unsigned int proc);
    5380              : 
    5381              : /*
    5382              :    WriteQuad - Writes out the Quad BufferQuad.
    5383              : */
    5384              : 
    5385              : static void WriteQuad (unsigned int BufferQuad);
    5386              : 
    5387              : /*
    5388              :    WriteOperand - displays the operands name, symbol id and mode of addressing.
    5389              : */
    5390              : 
    5391              : static void WriteMode (SymbolTable_ModeOfAddr Mode);
    5392              : 
    5393              : /*
    5394              :    PushExit - pushes the exit value onto the EXIT stack.
    5395              : */
    5396              : 
    5397              : static void PushExit (unsigned int Exit);
    5398              : 
    5399              : /*
    5400              :    PopExit - pops the exit value from the EXIT stack.
    5401              : */
    5402              : 
    5403              : static unsigned int PopExit (void);
    5404              : 
    5405              : /*
    5406              :    PushFor - pushes the exit value onto the FOR stack.
    5407              : */
    5408              : 
    5409              : static void PushFor (unsigned int Exit);
    5410              : 
    5411              : /*
    5412              :    PopFor - pops the exit value from the FOR stack.
    5413              : */
    5414              : 
    5415              : static unsigned int PopFor (void);
    5416              : 
    5417              : /*
    5418              :    OperandTno - returns the ident operand stored in the true position
    5419              :                 on the boolean stack.  This is exactly the same as
    5420              :                 OperandT but it has no IsBoolean checking.
    5421              : */
    5422              : 
    5423              : static unsigned int OperandTno (unsigned int pos);
    5424              : 
    5425              : /*
    5426              :    OperandFno - returns the ident operand stored in the false position
    5427              :                 on the boolean stack.  This is exactly the same as
    5428              :                 OperandF but it has no IsBoolean checking.
    5429              : */
    5430              : 
    5431              : static unsigned int OperandFno (unsigned int pos);
    5432              : 
    5433              : /*
    5434              :    OperandTtok - returns the token associated with the position, pos
    5435              :                  on the boolean stack.
    5436              : */
    5437              : 
    5438              : static unsigned int OperandTtok (unsigned int pos);
    5439              : 
    5440              : /*
    5441              :    PopBooltok - Pops a True and a False exit quad number from the True/False
    5442              :                 stack.
    5443              : */
    5444              : 
    5445              : static void PopBooltok (unsigned int *True, unsigned int *False, unsigned int *tokno);
    5446              : 
    5447              : /*
    5448              :    PushBooltok - Push a True and a False exit quad numbers onto the
    5449              :                  True/False stack.
    5450              : */
    5451              : 
    5452              : static void PushBooltok (unsigned int True, unsigned int False, unsigned int tokno);
    5453              : 
    5454              : /*
    5455              :    PopBool - Pops a True and a False exit quad number from the True/False
    5456              :              stack.
    5457              : */
    5458              : 
    5459              : static void PopBool (unsigned int *True, unsigned int *False);
    5460              : 
    5461              : /*
    5462              :    PushBool - Push a True and a False exit quad numbers onto the
    5463              :               True/False stack.
    5464              : */
    5465              : 
    5466              : static void PushBool (unsigned int True, unsigned int False);
    5467              : 
    5468              : /*
    5469              :    IsBoolean - returns true is the Stack position pos contains a Boolean
    5470              :                Exit. False is returned if an Ident is stored.
    5471              : */
    5472              : 
    5473              : static bool IsBoolean (unsigned int pos);
    5474              : 
    5475              : /*
    5476              :    OperandD - returns possible array dimension associated with the ident
    5477              :               operand stored on the boolean stack.
    5478              : */
    5479              : 
    5480              : static unsigned int OperandD (unsigned int pos);
    5481              : 
    5482              : /*
    5483              :    OperandRW - returns the rw operand stored on the boolean stack.
    5484              : */
    5485              : 
    5486              : static unsigned int OperandRW (unsigned int pos);
    5487              : 
    5488              : /*
    5489              :    OperandMergeRW - returns the rw operand if not NulSym else it
    5490              :                     returns True.
    5491              : */
    5492              : 
    5493              : static unsigned int OperandMergeRW (unsigned int pos);
    5494              : 
    5495              : /*
    5496              :    OperandRangeDep - return the range dependant associated with the quad stack.
    5497              : */
    5498              : 
    5499              : static unsigned int OperandRangeDep (unsigned int pos);
    5500              : 
    5501              : /*
    5502              :    PutRangeDep - assigns the quad stack pos RangeDep to dep.
    5503              : */
    5504              : 
    5505              : static void PutRangeDep (unsigned int pos, unsigned int dep);
    5506              : 
    5507              : /*
    5508              :    UseLineNote - uses the line note and returns it to the free list.
    5509              : */
    5510              : 
    5511              : static void UseLineNote (M2Quads_LineNote l);
    5512              : 
    5513              : /*
    5514              :    PopLineNo - pops a line note from the line stack.
    5515              : */
    5516              : 
    5517              : static M2Quads_LineNote PopLineNo (void);
    5518              : 
    5519              : /*
    5520              :    InitLineNote - creates a line note and initializes it to
    5521              :                   contain, file, line.
    5522              : */
    5523              : 
    5524              : static M2Quads_LineNote InitLineNote (NameKey_Name file, unsigned int line);
    5525              : 
    5526              : /*
    5527              :    PushLineNote -
    5528              : */
    5529              : 
    5530              : static void PushLineNote (M2Quads_LineNote l);
    5531              : 
    5532              : /*
    5533              :    BuildStmtNoteTok - adds a nop (with an assigned tokenno location) to the code.
    5534              : */
    5535              : 
    5536              : static void BuildStmtNoteTok (unsigned int tokenno);
    5537              : 
    5538              : /*
    5539              :    GetRecordOrField -
    5540              : */
    5541              : 
    5542              : static unsigned int GetRecordOrField (void);
    5543              : 
    5544              : /*
    5545              :    PushTFAD - Push True, False, Array, Dim, numbers onto the
    5546              :               True/False stack.  True and False are assumed to
    5547              :               contain Symbols or Ident etc.
    5548              : */
    5549              : 
    5550              : static void PushTFAD (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim);
    5551              : 
    5552              : /*
    5553              :    PushTFADtok - Push True, False, Array, Dim, numbers onto the
    5554              :                  True/False stack.  True and False are assumed to
    5555              :                  contain Symbols or Ident etc.
    5556              : */
    5557              : 
    5558              : static void PushTFADtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int tokno);
    5559              : 
    5560              : /*
    5561              :    PushTFADrwtok - Push True, False, Array, Dim, rw, numbers onto the
    5562              :                    True/False stack.  True and False are assumed to
    5563              :                    contain Symbols or Ident etc.
    5564              : */
    5565              : 
    5566              : static void PushTFADrwtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int rw, unsigned int Tok);
    5567              : 
    5568              : /*
    5569              :    PopTFrwtok - Pop a True and False number from the True/False stack.
    5570              :                 True and False are assumed to contain Symbols or Ident etc.
    5571              : */
    5572              : 
    5573              : static void PopTFrwtok (unsigned int *True, unsigned int *False, unsigned int *rw, unsigned int *tokno);
    5574              : 
    5575              : /*
    5576              :    PushTFrwtok - Push an item onto the stack in the T (true) position,
    5577              :                  it is assummed to be a token and its token location is recorded.
    5578              : */
    5579              : 
    5580              : static void PushTFrwtok (unsigned int True, unsigned int False, unsigned int rw, unsigned int tokno);
    5581              : 
    5582              : /*
    5583              :    PushTFDtok - Push True, False, Dim, numbers onto the
    5584              :                 True/False stack.  True and False are assumed to
    5585              :                 contain Symbols or Ident etc.
    5586              : */
    5587              : 
    5588              : static void PushTFDtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int Tok);
    5589              : 
    5590              : /*
    5591              :    PopTFDtok - Pop a True, False, Dim number from the True/False stack.
    5592              :                True and False are assumed to contain Symbols or Ident etc.
    5593              : */
    5594              : 
    5595              : static void PopTFDtok (unsigned int *True, unsigned int *False, unsigned int *Dim, unsigned int *Tok);
    5596              : 
    5597              : /*
    5598              :    PushTFDrwtok - Push True, False, Dim, numbers onto the
    5599              :                   True/False stack.  True and False are assumed to
    5600              :                   contain Symbols or Ident etc.
    5601              : */
    5602              : 
    5603              : static void PushTFDrwtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int rw, unsigned int Tok);
    5604              : 
    5605              : /*
    5606              :    PushTFrw - Push a True and False numbers onto the True/False stack.
    5607              :               True and False are assumed to contain Symbols or Ident etc.
    5608              :               It also pushes the higher level symbol which is associated
    5609              :               with the True symbol.  Eg record variable or array variable.
    5610              : */
    5611              : 
    5612              : static void PushTFrw (unsigned int True, unsigned int False, unsigned int rw);
    5613              : 
    5614              : /*
    5615              :    PopTFrw - Pop a True and False number from the True/False stack.
    5616              :              True and False are assumed to contain Symbols or Ident etc.
    5617              : */
    5618              : 
    5619              : static void PopTFrw (unsigned int *True, unsigned int *False, unsigned int *rw);
    5620              : 
    5621              : /*
    5622              :    newBoolFrame - creates a new BoolFrame with all fields initialised to their defaults.
    5623              : */
    5624              : 
    5625              : static M2Quads_BoolFrame newBoolFrame (void);
    5626              : 
    5627              : /*
    5628              :    PushTrwtok - Push an item onto the True/False stack. The False value will be zero.
    5629              : */
    5630              : 
    5631              : static void PushTrwtok (unsigned int True, unsigned int rw, unsigned int tok);
    5632              : 
    5633              : /*
    5634              :    PopTrw - Pop a True field and rw symbol from the stack.
    5635              : */
    5636              : 
    5637              : static void PopTrw (unsigned int *True, unsigned int *rw);
    5638              : 
    5639              : /*
    5640              :    PopTrwtok - Pop a True field and rw symbol from the stack.
    5641              : */
    5642              : 
    5643              : static void PopTrwtok (unsigned int *True, unsigned int *rw, unsigned int *tok);
    5644              : 
    5645              : /*
    5646              :    gdbhook - a debugger convenience hook.
    5647              : */
    5648              : 
    5649              : static void gdbhook (void);
    5650              : 
    5651              : /*
    5652              :    BreakWhenQuadCreated - to be called interactively by gdb.
    5653              : */
    5654              : 
    5655              : static void BreakWhenQuadCreated (unsigned int quad);
    5656              : 
    5657              : /*
    5658              :    CheckBreak - if quad = BreakQuad then call gdbhook.
    5659              : */
    5660              : 
    5661              : static void CheckBreak (unsigned int quad);
    5662              : 
    5663              : /*
    5664              :    Init - initialize the M2Quads module, all the stacks, all the lists
    5665              :           and the quads list.
    5666              : */
    5667              : 
    5668              : static void Init (void);
    5669              : 
    5670              : 
    5671              : /*
    5672              :    DSdbEnter -
    5673              : */
    5674              : 
    5675            0 : static void DSdbEnter (void)
    5676              : {
    5677            0 : }
    5678              : 
    5679              : 
    5680              : /*
    5681              :    DSdbExit -
    5682              : */
    5683              : 
    5684            0 : static void DSdbExit (void)
    5685              : {
    5686            0 : }
    5687              : 
    5688              : 
    5689              : /*
    5690              :    GetQF - returns the QuadFrame associated with, q.
    5691              : */
    5692              : 
    5693  14295715828 : static M2Quads_QuadFrame GetQF (unsigned int q)
    5694              : {
    5695            0 :   return (M2Quads_QuadFrame) (Indexing_GetIndice (QuadArray, q));
    5696              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5697              :   __builtin_unreachable ();
    5698              : }
    5699              : 
    5700              : 
    5701              : /*
    5702              :    IsQuadA - returns true if QuadNo is a op.
    5703              : */
    5704              : 
    5705   1057897666 : static bool IsQuadA (unsigned int QuadNo, M2Quads_QuadOperator op)
    5706              : {
    5707   1057897666 :   M2Quads_QuadFrame f;
    5708              : 
    5709            0 :   f = GetQF (QuadNo);
    5710   1057897666 :   return f->Operator == op;
    5711              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5712              :   __builtin_unreachable ();
    5713              : }
    5714              : 
    5715              : 
    5716              : /*
    5717              :    OpUsesOp1 - return TRUE if op allows op1.
    5718              : */
    5719              : 
    5720       425884 : static bool OpUsesOp1 (M2Quads_QuadOperator op)
    5721              : {
    5722       425884 :   switch (op)
    5723              :     {
    5724              :       case M2Quads_StringConvertCnulOp:
    5725              :       case M2Quads_StringConvertM2nulOp:
    5726              :       case M2Quads_StringLengthOp:
    5727              :       case M2Quads_InclOp:
    5728              :       case M2Quads_ExclOp:
    5729              :       case M2Quads_UnboundedOp:
    5730              :       case M2Quads_FunctValueOp:
    5731              :       case M2Quads_NegateOp:
    5732              :       case M2Quads_BecomesOp:
    5733              :       case M2Quads_HighOp:
    5734              :       case M2Quads_SizeOp:
    5735              :       case M2Quads_AddrOp:
    5736              :       case M2Quads_RecordFieldOp:
    5737              :       case M2Quads_ArrayOp:
    5738              :       case M2Quads_LogicalShiftOp:
    5739              :       case M2Quads_LogicalRotateOp:
    5740              :       case M2Quads_LogicalOrOp:
    5741              :       case M2Quads_LogicalAndOp:
    5742              :       case M2Quads_LogicalXorOp:
    5743              :       case M2Quads_CoerceOp:
    5744              :       case M2Quads_ConvertOp:
    5745              :       case M2Quads_CastOp:
    5746              :       case M2Quads_AddOp:
    5747              :       case M2Quads_SubOp:
    5748              :       case M2Quads_MultOp:
    5749              :       case M2Quads_ModFloorOp:
    5750              :       case M2Quads_DivCeilOp:
    5751              :       case M2Quads_ModCeilOp:
    5752              :       case M2Quads_DivFloorOp:
    5753              :       case M2Quads_ModTruncOp:
    5754              :       case M2Quads_DivTruncOp:
    5755              :       case M2Quads_DivM2Op:
    5756              :       case M2Quads_ModM2Op:
    5757              :       case M2Quads_XIndrOp:
    5758              :       case M2Quads_IndrXOp:
    5759              :       case M2Quads_SaveExceptionOp:
    5760              :       case M2Quads_RestoreExceptionOp:
    5761              :         return true;
    5762       100788 :         break;
    5763              : 
    5764              : 
    5765       100788 :       default:
    5766       100788 :         return false;
    5767              :         break;
    5768              :     }
    5769              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5770              :   __builtin_unreachable ();
    5771              : }
    5772              : 
    5773              : 
    5774              : /*
    5775              :    AddQuadInformation - adds variable analysis and jump analysis to the new quadruple.
    5776              : */
    5777              : 
    5778      6411484 : static void AddQuadInformation (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
    5779              : {
    5780      6411484 :   switch (Op)
    5781              :     {
    5782       177961 :       case M2Quads_IfInOp:
    5783       177961 :       case M2Quads_IfNotInOp:
    5784       177961 :       case M2Quads_IfEquOp:
    5785       177961 :       case M2Quads_IfNotEquOp:
    5786       177961 :       case M2Quads_IfLessOp:
    5787       177961 :       case M2Quads_IfLessEquOp:
    5788       177961 :       case M2Quads_IfGreOp:
    5789       177961 :       case M2Quads_IfGreEquOp:
    5790       177961 :         ManipulateReference (QuadNo, Oper3);
    5791       177961 :         CheckAddVariableRead (Oper1, false, QuadNo);
    5792       177961 :         CheckAddVariableRead (Oper2, false, QuadNo);
    5793       177961 :         break;
    5794              : 
    5795         2586 :       case M2Quads_LastForIteratorOp:
    5796         2586 :         CheckAddVariableWrite (Oper1, false, QuadNo);
    5797         2586 :         CheckAddTuple2Read (Oper2, false, QuadNo);
    5798         2586 :         CheckAddVariableRead (Oper3, false, QuadNo);
    5799         2586 :         break;
    5800              : 
    5801       187188 :       case M2Quads_TryOp:
    5802       187188 :       case M2Quads_RetryOp:
    5803       187188 :       case M2Quads_GotoOp:
    5804       187188 :         ManipulateReference (QuadNo, Oper3);
    5805       187188 :         break;
    5806              : 
    5807         2020 :       case M2Quads_InclOp:
    5808         2020 :       case M2Quads_ExclOp:
    5809              :         /* variable references  */
    5810         2020 :         CheckConst (Oper1);
    5811         2020 :         CheckAddVariableRead (Oper3, false, QuadNo);
    5812         2020 :         CheckAddVariableWrite (Oper1, true, QuadNo);
    5813         2020 :         break;
    5814              : 
    5815       679458 :       case M2Quads_UnboundedOp:
    5816       679458 :       case M2Quads_FunctValueOp:
    5817       679458 :       case M2Quads_NegateOp:
    5818       679458 :       case M2Quads_BecomesOp:
    5819       679458 :       case M2Quads_HighOp:
    5820       679458 :       case M2Quads_SizeOp:
    5821       679458 :         CheckConst (Oper1);
    5822       679458 :         CheckAddVariableWrite (Oper1, false, QuadNo);
    5823       679458 :         CheckAddVariableRead (Oper3, false, QuadNo);
    5824       679458 :         break;
    5825              : 
    5826       198458 :       case M2Quads_AddrOp:
    5827       198458 :         CheckConst (Oper1);
    5828       198458 :         CheckAddVariableWrite (Oper1, false, QuadNo);
    5829              :         /* the next line is a kludge and assumes we _will_
    5830              :                           write to the variable as we have taken its address  */
    5831       198458 :         CheckRemoveVariableWrite (Oper1, true, QuadNo);
    5832       198458 :         break;
    5833              : 
    5834        28111 :       case M2Quads_ReturnValueOp:
    5835        28111 :         CheckAddVariableRead (Oper1, false, QuadNo);
    5836        28111 :         break;
    5837              : 
    5838              :       case M2Quads_ReturnOp:
    5839              :       case M2Quads_NewLocalVarOp:
    5840              :       case M2Quads_KillLocalVarOp:
    5841              :         break;
    5842              : 
    5843       220622 :       case M2Quads_CallOp:
    5844       220622 :         CheckAddVariableRead (Oper3, true, QuadNo);
    5845       220622 :         break;
    5846              : 
    5847       618640 :       case M2Quads_ParamOp:
    5848       618640 :         CheckAddVariableRead (Oper2, false, QuadNo);
    5849       618640 :         CheckAddVariableRead (Oper3, false, QuadNo);
    5850       618640 :         if (((Oper1 > 0) && (Oper1 <= (SymbolTable_NoOfParamAny (Oper2)))) && (SymbolTable_IsVarParamAny (Oper2, Oper1)))
    5851              :           {
    5852              :             /* _may_ also write to a var parameter, although we dont know  */
    5853        20486 :             CheckAddVariableWrite (Oper3, true, QuadNo);
    5854              :           }
    5855              :         break;
    5856              : 
    5857       361043 :       case M2Quads_RecordFieldOp:
    5858       361043 :       case M2Quads_ArrayOp:
    5859       361043 :       case M2Quads_LogicalShiftOp:
    5860       361043 :       case M2Quads_LogicalRotateOp:
    5861       361043 :       case M2Quads_LogicalOrOp:
    5862       361043 :       case M2Quads_LogicalAndOp:
    5863       361043 :       case M2Quads_LogicalXorOp:
    5864       361043 :       case M2Quads_CoerceOp:
    5865       361043 :       case M2Quads_ConvertOp:
    5866       361043 :       case M2Quads_CastOp:
    5867       361043 :       case M2Quads_AddOp:
    5868       361043 :       case M2Quads_SubOp:
    5869       361043 :       case M2Quads_MultOp:
    5870       361043 :       case M2Quads_DivM2Op:
    5871       361043 :       case M2Quads_ModM2Op:
    5872       361043 :       case M2Quads_ModFloorOp:
    5873       361043 :       case M2Quads_DivCeilOp:
    5874       361043 :       case M2Quads_ModCeilOp:
    5875       361043 :       case M2Quads_DivFloorOp:
    5876       361043 :       case M2Quads_ModTruncOp:
    5877       361043 :       case M2Quads_DivTruncOp:
    5878       361043 :         CheckConst (Oper1);
    5879       361043 :         CheckAddVariableWrite (Oper1, false, QuadNo);
    5880       361043 :         CheckAddVariableRead (Oper2, false, QuadNo);
    5881       361043 :         CheckAddVariableRead (Oper3, false, QuadNo);
    5882       361043 :         break;
    5883              : 
    5884        43640 :       case M2Quads_XIndrOp:
    5885        43640 :         CheckConst (Oper1);
    5886        43640 :         CheckAddVariableWrite (Oper1, true, QuadNo);
    5887        43640 :         CheckAddVariableRead (Oper3, false, QuadNo);
    5888        43640 :         break;
    5889              : 
    5890        17449 :       case M2Quads_IndrXOp:
    5891        17449 :         CheckConst (Oper1);
    5892        17449 :         CheckAddVariableWrite (Oper1, false, QuadNo);
    5893        17449 :         CheckAddVariableRead (Oper3, true, QuadNo);
    5894        17449 :         break;
    5895              : 
    5896         2969 :       case M2Quads_SaveExceptionOp:
    5897              :         /* RangeCheckOp      : CheckRangeAddVariableRead(Oper3, QuadNo) |  */
    5898         2969 :         CheckConst (Oper1);
    5899         2969 :         CheckAddVariableWrite (Oper1, false, QuadNo);
    5900         2969 :         break;
    5901              : 
    5902         3131 :       case M2Quads_RestoreExceptionOp:
    5903         3131 :         CheckAddVariableRead (Oper1, false, QuadNo);
    5904         3131 :         break;
    5905              : 
    5906              : 
    5907              :       default:
    5908              :         break;
    5909              :     }
    5910      6411484 : }
    5911              : 
    5912              : 
    5913              : /*
    5914              :    PutQuadO - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
    5915              :               sets a boolean to determinine whether overflow should be checked.
    5916              : */
    5917              : 
    5918      5447607 : static void PutQuadO (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow)
    5919              : {
    5920            0 :   PutQuadOType (QuadNo, Op, Oper1, Oper2, Oper3, overflow, true);
    5921            0 : }
    5922              : 
    5923              : 
    5924              : /*
    5925              :    PutQuadOType -
    5926              : */
    5927              : 
    5928      6329303 : static void PutQuadOType (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow, bool checktype)
    5929              : {
    5930      6329303 :   M2Quads_QuadFrame f;
    5931              : 
    5932      6329303 :   if (QuadrupleGeneration)
    5933              :     {
    5934      6329303 :       M2Quads_EraseQuad (QuadNo);
    5935      6329303 :       AddQuadInformation (QuadNo, Op, Oper1, Oper2, Oper3);
    5936      6329303 :       f = GetQF (QuadNo);
    5937      6329303 :       f->Operator = Op;
    5938      6329303 :       f->Operand1 = Oper1;
    5939      6329303 :       f->Operand2 = Oper2;
    5940      6329303 :       f->Operand3 = Oper3;
    5941      6329303 :       f->CheckOverflow = overflow;
    5942      6329303 :       f->CheckType = checktype;
    5943      6329303 :       f->ConstExpr = false;  /* IsInConstExpression ()  */
    5944              :     }
    5945              :    /* IsInConstExpression ()  */
    5946      6329303 : }
    5947              : 
    5948              : 
    5949              : /*
    5950              :    UndoReadWriteInfo -
    5951              : */
    5952              : 
    5953      8340045 : static void UndoReadWriteInfo (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
    5954              : {
    5955      8340045 :   switch (Op)
    5956              :     {
    5957        98046 :       case M2Quads_IfInOp:
    5958        98046 :       case M2Quads_IfNotInOp:
    5959        98046 :       case M2Quads_IfEquOp:
    5960        98046 :       case M2Quads_IfNotEquOp:
    5961        98046 :       case M2Quads_IfLessOp:
    5962        98046 :       case M2Quads_IfLessEquOp:
    5963        98046 :       case M2Quads_IfGreOp:
    5964        98046 :       case M2Quads_IfGreEquOp:
    5965              :         /* jumps, calls and branches  */
    5966        98046 :         RemoveReference (QuadNo);
    5967        98046 :         CheckRemoveVariableRead (Oper1, false, QuadNo);
    5968        98046 :         CheckRemoveVariableRead (Oper2, false, QuadNo);
    5969        98046 :         break;
    5970              : 
    5971       137259 :       case M2Quads_TryOp:
    5972       137259 :       case M2Quads_RetryOp:
    5973       137259 :       case M2Quads_GotoOp:
    5974       137259 :         RemoveReference (QuadNo);
    5975       137259 :         break;
    5976              : 
    5977            0 :       case M2Quads_InclOp:
    5978            0 :       case M2Quads_ExclOp:
    5979              :         /* variable references  */
    5980            0 :         CheckRemoveVariableRead (Oper1, false, QuadNo);
    5981            0 :         CheckRemoveVariableWrite (Oper1, true, QuadNo);
    5982            0 :         break;
    5983              : 
    5984       336945 :       case M2Quads_UnboundedOp:
    5985       336945 :       case M2Quads_FunctValueOp:
    5986       336945 :       case M2Quads_NegateOp:
    5987       336945 :       case M2Quads_BecomesOp:
    5988       336945 :       case M2Quads_HighOp:
    5989       336945 :       case M2Quads_SizeOp:
    5990       336945 :         CheckRemoveVariableWrite (Oper1, false, QuadNo);
    5991       336945 :         CheckRemoveVariableRead (Oper3, false, QuadNo);
    5992       336945 :         break;
    5993              : 
    5994         1630 :       case M2Quads_AddrOp:
    5995         1630 :         CheckRemoveVariableWrite (Oper1, false, QuadNo);
    5996              :         /* the next line is a kludge and assumes we _will_
    5997              :                           write to the variable as we have taken its address  */
    5998         1630 :         CheckRemoveVariableWrite (Oper1, true, QuadNo);
    5999         1630 :         break;
    6000              : 
    6001          184 :       case M2Quads_ReturnValueOp:
    6002          184 :         CheckRemoveVariableRead (Oper1, false, QuadNo);
    6003          184 :         break;
    6004              : 
    6005              :       case M2Quads_ReturnOp:
    6006              :       case M2Quads_CallOp:
    6007              :       case M2Quads_NewLocalVarOp:
    6008              :       case M2Quads_KillLocalVarOp:
    6009              :         break;
    6010              : 
    6011        11254 :       case M2Quads_ParamOp:
    6012        11254 :         CheckRemoveVariableRead (Oper2, false, QuadNo);
    6013        11254 :         CheckRemoveVariableRead (Oper3, false, QuadNo);
    6014        11254 :         if (((Oper1 > 0) && (Oper1 <= (SymbolTable_NoOfParamAny (Oper2)))) && (SymbolTable_IsVarParamAny (Oper2, Oper1)))
    6015              :           {
    6016              :             /* _may_ also write to a var parameter, although we dont know  */
    6017          112 :             CheckRemoveVariableWrite (Oper3, true, QuadNo);
    6018              :           }
    6019              :         break;
    6020              : 
    6021        50688 :       case M2Quads_RecordFieldOp:
    6022        50688 :       case M2Quads_ArrayOp:
    6023        50688 :       case M2Quads_LogicalShiftOp:
    6024        50688 :       case M2Quads_LogicalRotateOp:
    6025        50688 :       case M2Quads_LogicalOrOp:
    6026        50688 :       case M2Quads_LogicalAndOp:
    6027        50688 :       case M2Quads_LogicalXorOp:
    6028        50688 :       case M2Quads_CoerceOp:
    6029        50688 :       case M2Quads_ConvertOp:
    6030        50688 :       case M2Quads_CastOp:
    6031        50688 :       case M2Quads_AddOp:
    6032        50688 :       case M2Quads_SubOp:
    6033        50688 :       case M2Quads_MultOp:
    6034        50688 :       case M2Quads_DivM2Op:
    6035        50688 :       case M2Quads_ModM2Op:
    6036        50688 :       case M2Quads_ModFloorOp:
    6037        50688 :       case M2Quads_DivCeilOp:
    6038        50688 :       case M2Quads_ModCeilOp:
    6039        50688 :       case M2Quads_DivFloorOp:
    6040        50688 :       case M2Quads_ModTruncOp:
    6041        50688 :       case M2Quads_DivTruncOp:
    6042        50688 :         CheckRemoveVariableWrite (Oper1, false, QuadNo);
    6043        50688 :         CheckRemoveVariableRead (Oper2, false, QuadNo);
    6044        50688 :         CheckRemoveVariableRead (Oper3, false, QuadNo);
    6045        50688 :         break;
    6046              : 
    6047            4 :       case M2Quads_XIndrOp:
    6048            4 :         CheckRemoveVariableWrite (Oper1, true, QuadNo);
    6049            4 :         CheckRemoveVariableRead (Oper3, false, QuadNo);
    6050            4 :         break;
    6051              : 
    6052          450 :       case M2Quads_IndrXOp:
    6053          450 :         CheckRemoveVariableWrite (Oper1, false, QuadNo);
    6054          450 :         CheckRemoveVariableRead (Oper3, true, QuadNo);
    6055          450 :         break;
    6056              : 
    6057            0 :       case M2Quads_SaveExceptionOp:
    6058              :         /* RangeCheckOp      : CheckRangeRemoveVariableRead(Oper3, QuadNo) |  */
    6059            0 :         CheckRemoveVariableWrite (Oper1, false, QuadNo);
    6060            0 :         break;
    6061              : 
    6062          216 :       case M2Quads_RestoreExceptionOp:
    6063          216 :         CheckRemoveVariableRead (Oper1, false, QuadNo);
    6064          216 :         break;
    6065              : 
    6066              : 
    6067              :       default:
    6068              :         break;
    6069              :     }
    6070      8340045 : }
    6071              : 
    6072              : 
    6073              : /*
    6074              :    CheckAddTuple2Read - checks to see whether symbol tuple contains variables or
    6075              :                         parameters and if so it then adds them to the quadruple
    6076              :                         variable list.
    6077              : */
    6078              : 
    6079         2586 : static void CheckAddTuple2Read (unsigned int tuple, bool canDereference, unsigned int Quad)
    6080              : {
    6081         2586 :   if (SymbolTable_IsTuple (tuple))
    6082              :     {
    6083         2586 :       CheckAddVariableRead (SymbolTable_GetNth (tuple, 1), canDereference, Quad);
    6084         2586 :       CheckAddVariableRead (SymbolTable_GetNth (tuple, 2), canDereference, Quad);
    6085              :     }
    6086         2586 : }
    6087              : 
    6088              : 
    6089              : /*
    6090              :    CheckAddVariableRead - checks to see whether symbol, Sym, is a variable or
    6091              :                           a parameter and if so it then adds this quadruple
    6092              :                           to the variable list.
    6093              : */
    6094              : 
    6095      3317477 : static void CheckAddVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad)
    6096              : {
    6097      3317477 :   if (SymbolTable_IsVar (Sym))
    6098              :     {
    6099      1181619 :       SymbolTable_PutReadQuad (Sym, SymbolTable_GetMode (Sym), Quad);
    6100      1181619 :       if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
    6101              :         {
    6102        17517 :           SymbolTable_PutReadQuad (Sym, SymbolTable_RightValue, Quad);
    6103              :         }
    6104              :     }
    6105      3317477 : }
    6106              : 
    6107              : 
    6108              : /*
    6109              :    CheckRemoveVariableRead - checks to see whether, Sym, is a variable or
    6110              :                              a parameter and if so then it removes the
    6111              :                              quadruple from the variable list.
    6112              : */
    6113              : 
    6114       657775 : static void CheckRemoveVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad)
    6115              : {
    6116       657775 :   if (SymbolTable_IsVar (Sym))
    6117              :     {
    6118       124100 :       SymbolTable_RemoveReadQuad (Sym, SymbolTable_GetMode (Sym), Quad);
    6119       124100 :       if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
    6120              :         {
    6121          450 :           SymbolTable_RemoveReadQuad (Sym, SymbolTable_RightValue, Quad);
    6122              :         }
    6123              :     }
    6124       657775 : }
    6125              : 
    6126              : 
    6127              : /*
    6128              :    CheckAddVariableWrite - checks to see whether symbol, Sym, is a variable and
    6129              :                            if so it then adds this quadruple to the variable list.
    6130              : */
    6131              : 
    6132      1328109 : static void CheckAddVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad)
    6133              : {
    6134      1328109 :   if (SymbolTable_IsVar (Sym))
    6135              :     {
    6136              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6137       953879 :       if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
    6138              :         {
    6139        60022 :           SymbolTable_PutReadQuad (Sym, SymbolTable_LeftValue, Quad);
    6140        60022 :           SymbolTable_PutWriteQuad (Sym, SymbolTable_RightValue, Quad);
    6141              :         }
    6142              :       else
    6143              :         {
    6144       893857 :           SymbolTable_PutWriteQuad (Sym, SymbolTable_GetMode (Sym), Quad);
    6145              :         }
    6146              :     }
    6147      1328109 : }
    6148              : 
    6149              : 
    6150              : /*
    6151              :    CheckRemoveVariableWrite - checks to see whether, Sym, is a variable and
    6152              :                               if so then it removes the quadruple from the
    6153              :                               variable list.
    6154              : */
    6155              : 
    6156       589917 : static void CheckRemoveVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad)
    6157              : {
    6158       589917 :   if (SymbolTable_IsVar (Sym))
    6159              :     {
    6160              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6161       219836 :       if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
    6162              :         {
    6163        11374 :           SymbolTable_RemoveReadQuad (Sym, SymbolTable_LeftValue, Quad);
    6164        11374 :           SymbolTable_RemoveWriteQuad (Sym, SymbolTable_RightValue, Quad);
    6165              :         }
    6166              :       else
    6167              :         {
    6168       208462 :           SymbolTable_RemoveWriteQuad (Sym, SymbolTable_GetMode (Sym), Quad);
    6169              :         }
    6170              :     }
    6171       589917 : }
    6172              : 
    6173              : 
    6174              : /*
    6175              :    CheckConst -
    6176              : */
    6177              : 
    6178      1305037 : static void CheckConst (unsigned int sym)
    6179              : {
    6180      1305037 :   if (SymbolTable_IsConst (sym))
    6181              :     {
    6182       372448 :       M2GCCDeclare_PutToBeSolvedByQuads (sym);
    6183              :     }
    6184      1305037 : }
    6185              : 
    6186              : 
    6187              : /*
    6188              :    AlterReference - alters all references from OldQuad, to NewQuad in a
    6189              :                     quadruple list Head.
    6190              : */
    6191              : 
    6192      1928561 : static void AlterReference (unsigned int Head, unsigned int OldQuad, unsigned int NewQuad)
    6193              : {
    6194      1928561 :   M2Quads_QuadFrame f;
    6195      1928561 :   M2Quads_QuadFrame g;
    6196      1928561 :   unsigned int i;
    6197              : 
    6198      1928561 :   f = GetQF (OldQuad);
    6199     12895292 :   while ((f->NoOfTimesReferenced > 0) && (Head != 0))
    6200              :     {
    6201      9038170 :       g = GetQF (Head);
    6202      9038170 :       switch (g->Operator)
    6203              :         {
    6204       399714 :           case M2Quads_IfInOp:
    6205       399714 :           case M2Quads_IfNotInOp:
    6206       399714 :           case M2Quads_IfEquOp:
    6207       399714 :           case M2Quads_IfNotEquOp:
    6208       399714 :           case M2Quads_IfLessOp:
    6209       399714 :           case M2Quads_IfLessEquOp:
    6210       399714 :           case M2Quads_IfGreOp:
    6211       399714 :           case M2Quads_IfGreEquOp:
    6212       399714 :           case M2Quads_TryOp:
    6213       399714 :           case M2Quads_RetryOp:
    6214       399714 :           case M2Quads_GotoOp:
    6215       399714 :             if (g->Operand3 == OldQuad)
    6216              :               {
    6217         8982 :                 ManipulateReference (Head, NewQuad);
    6218              :               }
    6219              :             break;
    6220              : 
    6221              : 
    6222              :           default:
    6223              :             break;
    6224              :         }
    6225      9038170 :       i = g->Next;
    6226      9038170 :       Head = i;
    6227              :     }
    6228      1928561 : }
    6229              : 
    6230              : 
    6231              : /*
    6232              :    GrowQuads - grows the list of quadruples to the quadruple, to.
    6233              : */
    6234              : 
    6235       645034 : static void GrowQuads (unsigned int to)
    6236              : {
    6237       645034 :   unsigned int i;
    6238       645034 :   M2Quads_QuadFrame f;
    6239              : 
    6240       645034 :   if ((to != 0) && (to > GrowInitialization))
    6241              :     {
    6242        10044 :       i = GrowInitialization+1;
    6243        20088 :       while (i <= to)
    6244              :         {
    6245        10044 :           if (Indexing_InBounds (QuadArray, i))
    6246              :             {
    6247            0 :               M2Debug_Assert ((Indexing_GetIndice (QuadArray, i)) != NULL);
    6248              :             }
    6249              :           else
    6250              :             {
    6251        10044 :               Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T3));
    6252        10044 :               if (f == NULL)
    6253              :                 {
    6254            0 :                   M2Error_InternalError ((const char *) "out of memory error when trying to allocate a quadruple", 55);
    6255              :                 }
    6256        10044 :               Indexing_PutIndice (QuadArray, i, reinterpret_cast <void *> (f));
    6257        10044 :               f->NoOfTimesReferenced = 0;
    6258              :             }
    6259        10044 :           i += 1;
    6260              :         }
    6261        10044 :       GrowInitialization = to;
    6262              :     }
    6263       645034 : }
    6264              : 
    6265              : 
    6266              : /*
    6267              :    ManipulateReference - manipulates the quadruple, q, so that it now points to quad, to.
    6268              : */
    6269              : 
    6270       645034 : static void ManipulateReference (unsigned int q, unsigned int to)
    6271              : {
    6272       645034 :   M2Quads_QuadFrame f;
    6273              : 
    6274      1290068 :   M2Debug_Assert ((GrowInitialization >= q) || (to == 0));
    6275       645034 :   GrowQuads (to);
    6276       645034 :   RemoveReference (q);
    6277       645034 :   f = GetQF (q);
    6278       645034 :   f->Operand3 = to;
    6279       645034 :   if (to != 0)
    6280              :     {
    6281       409823 :       f = GetQF (to);
    6282       409823 :       f->NoOfTimesReferenced += 1;
    6283              :     }
    6284       645034 : }
    6285              : 
    6286              : 
    6287              : /*
    6288              :    RemoveReference - remove the reference by quadruple q to wherever
    6289              :                      it was pointing.
    6290              : */
    6291              : 
    6292       880339 : static void RemoveReference (unsigned int q)
    6293              : {
    6294       880339 :   M2Quads_QuadFrame f;
    6295       880339 :   M2Quads_QuadFrame g;
    6296              : 
    6297       880339 :   f = GetQF (q);
    6298       880339 :   if ((f->Operand3 != 0) && (f->Operand3 < NextQuad))
    6299              :     {
    6300       279979 :       CheckBreak (f->Operand3);
    6301       279979 :       g = GetQF (f->Operand3);
    6302       279979 :       M2Debug_Assert (g->NoOfTimesReferenced != 0);
    6303       279979 :       g->NoOfTimesReferenced -= 1;
    6304              :     }
    6305       880339 : }
    6306              : 
    6307              : 
    6308              : /*
    6309              :    NewQuad - sets QuadNo to a new quadruple.
    6310              : */
    6311              : 
    6312      6330256 : static void NewQuad (unsigned int *QuadNo)
    6313              : {
    6314      6330256 :   M2Quads_QuadFrame f;
    6315              : 
    6316      6330256 :   (*QuadNo) = FreeList;
    6317      6330256 :   if ((Indexing_InBounds (QuadArray, (*QuadNo))) && ((Indexing_GetIndice (QuadArray, (*QuadNo))) != NULL))
    6318              :     {
    6319        10044 :       f = static_cast<M2Quads_QuadFrame> (Indexing_GetIndice (QuadArray, (*QuadNo)));
    6320              :     }
    6321              :   else
    6322              :     {
    6323      6320212 :       Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T3));
    6324      6320212 :       if (f == NULL)
    6325              :         {
    6326            0 :           M2Error_InternalError ((const char *) "out of memory error trying to allocate a quadruple", 50);
    6327              :         }
    6328              :       else
    6329              :         {
    6330      6320212 :           NoOfQuads += 1;
    6331      6320212 :           Indexing_PutIndice (QuadArray, (*QuadNo), reinterpret_cast <void *> (f));
    6332      6320212 :           f->NoOfTimesReferenced = 0;
    6333      6320212 :           M2Diagnostic_MemSet (QuadMemDiag, 1, NoOfQuads);
    6334      6320212 :           M2Diagnostic_MemIncr (QuadMemDiag, 2, sizeof ((*f)));
    6335              :         }
    6336              :     }
    6337      6330256 :   f->Operator = M2Quads_DummyOp;
    6338      6330256 :   f->Operand3 = 0;
    6339      6330256 :   f->Next = 0;
    6340      6330256 :   FreeList += 1;
    6341      6330256 :   if (GrowInitialization < FreeList)
    6342              :     {
    6343      6320212 :       GrowInitialization = FreeList;
    6344              :     }
    6345      6330256 : }
    6346              : 
    6347              : 
    6348              : /*
    6349              :    CheckVariableAt - checks to see whether, sym, was declared at a particular address.
    6350              : */
    6351              : 
    6352      4141015 : static void CheckVariableAt (unsigned int sym)
    6353              : {
    6354      4141015 :   if ((SymbolTable_IsVar (sym)) && (SymbolTable_IsVariableAtAddress (sym)))
    6355              :     {
    6356              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6357           54 :       if ((SymbolTable_GetMode (sym)) == SymbolTable_LeftValue)
    6358              :         {
    6359           54 :           GenQuad (M2Quads_InitAddressOp, sym, SymbolTable_NulSym, SymbolTable_GetVariableAtAddress (sym));
    6360              :         }
    6361              :       else
    6362              :         {
    6363            0 :           M2Error_InternalError ((const char *) "expecting lvalue for this variable which is declared at an explicit address", 75);
    6364              :         }
    6365              :     }
    6366      4141015 : }
    6367              : 
    6368              : 
    6369              : /*
    6370              :    CheckVariablesAt - checks to see whether we need to initialize any pointers
    6371              :                       which point to variable declared at addresses.
    6372              : */
    6373              : 
    6374       166631 : static void CheckVariablesAt (unsigned int scope)
    6375              : {
    6376            0 :   SymbolTable_ForeachLocalSymDo (scope, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) CheckVariableAt});
    6377            0 : }
    6378              : 
    6379              : 
    6380              : /*
    6381              :    GetTurnInterrupts - returns the TurnInterrupts procedure function.
    6382              : */
    6383              : 
    6384          840 : static unsigned int GetTurnInterrupts (unsigned int tok)
    6385              : {
    6386          840 :   if (M2Options_Iso)
    6387              :     {
    6388            0 :       return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "TurnInterrupts", 14), NameKey_MakeKey ((const char *) "COROUTINES", 10));
    6389              :     }
    6390              :   else
    6391              :     {
    6392          840 :       return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "TurnInterrupts", 14), NameKey_MakeKey ((const char *) "SYSTEM", 6));
    6393              :     }
    6394              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6395              :   __builtin_unreachable ();
    6396              : }
    6397              : 
    6398              : 
    6399              : /*
    6400              :    GetProtection - returns the PROTECTION data type.
    6401              : */
    6402              : 
    6403          420 : static unsigned int GetProtection (unsigned int tok)
    6404              : {
    6405          420 :   if (M2Options_Iso)
    6406              :     {
    6407            0 :       return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "PROTECTION", 10), NameKey_MakeKey ((const char *) "COROUTINES", 10));
    6408              :     }
    6409              :   else
    6410              :     {
    6411          420 :       return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "PROTECTION", 10), NameKey_MakeKey ((const char *) "SYSTEM", 6));
    6412              :     }
    6413              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6414              :   __builtin_unreachable ();
    6415              : }
    6416              : 
    6417              : 
    6418              : /*
    6419              :    CheckNeedPriorityBegin - checks to see whether we need to save the old
    6420              :                             module priority and change to another module
    6421              :                             priority.
    6422              :                             The current module initialization or procedure
    6423              :                             being built is defined by, scope. The module whose
    6424              :                             priority will be used is defined by, module.
    6425              : */
    6426              : 
    6427       182664 : static void CheckNeedPriorityBegin (unsigned int tok, unsigned int scope, unsigned int module)
    6428              : {
    6429       182664 :   unsigned int ProcSym;
    6430       182664 :   unsigned int old;
    6431              : 
    6432       182664 :   if ((SymbolTable_GetPriority (module)) != SymbolTable_NulSym)
    6433              :     {
    6434              :       /* module has been given a priority  */
    6435          420 :       ProcSym = GetTurnInterrupts (tok);
    6436          420 :       if (ProcSym != SymbolTable_NulSym)
    6437              :         {
    6438          420 :           old = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
    6439          420 :           SymbolTable_PutVar (old, GetProtection (tok));
    6440          840 :           GenQuadO (tok, M2Quads_SavePriorityOp, old, scope, ProcSym, false);
    6441          420 :           M2StackWord_PushWord (PriorityStack, old);
    6442              :         }
    6443              :     }
    6444       182664 : }
    6445              : 
    6446              : 
    6447              : /*
    6448              :    CheckNeedPriorityEnd - checks to see whether we need to restore the old
    6449              :                           module priority.
    6450              :                           The current module initialization or procedure
    6451              :                           being built is defined by, scope.
    6452              : */
    6453              : 
    6454       182486 : static void CheckNeedPriorityEnd (unsigned int tok, unsigned int scope, unsigned int module)
    6455              : {
    6456       182486 :   unsigned int ProcSym;
    6457       182486 :   unsigned int old;
    6458              : 
    6459       182486 :   if ((SymbolTable_GetPriority (module)) != SymbolTable_NulSym)
    6460              :     {
    6461              :       /* module has been given a priority  */
    6462          420 :       ProcSym = GetTurnInterrupts (tok);
    6463          420 :       if (ProcSym != SymbolTable_NulSym)
    6464              :         {
    6465          420 :           old = static_cast<unsigned int> (M2StackWord_PopWord (PriorityStack));
    6466          420 :           GenQuad (M2Quads_RestorePriorityOp, old, scope, ProcSym);
    6467              :         }
    6468              :     }
    6469       182486 : }
    6470              : 
    6471              : 
    6472              : /*
    6473              :    BuildRTExceptEnter - informs RTExceptions that we are about to enter the except state.
    6474              : */
    6475              : 
    6476         2969 : static void BuildRTExceptEnter (unsigned int tok)
    6477              : {
    6478         2969 :   unsigned int old;
    6479         2969 :   unsigned int ProcSym;
    6480              : 
    6481         2969 :   if (M2Options_Exceptions)
    6482              :     {
    6483              :       /* now inform the Modula-2 runtime we are in the exception state  */
    6484         2969 :       ProcSym = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "SetExceptionState", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
    6485         2969 :       if (ProcSym == SymbolTable_NulSym)
    6486              :         {
    6487            0 :           M2MetaError_MetaErrorT0 (tok, (const char *) "{%W}no procedure SetExceptionState found in RTExceptions which is needed to implement exception handling", 104);
    6488              :         }
    6489              :       else
    6490              :         {
    6491         2969 :           old = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
    6492         2969 :           SymbolTable_PutVar (old, M2Base_Boolean);
    6493         5938 :           GenQuadO (tok, M2Quads_SaveExceptionOp, old, SymbolTable_NulSym, ProcSym, false);
    6494         2969 :           M2StackWord_PushWord (ExceptStack, old);
    6495              :         }
    6496              :     }
    6497              :   else
    6498              :     {
    6499            0 :       M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}cannot use {%kEXCEPT} blocks with the -fno-exceptions flag", 62);
    6500              :     }
    6501         2969 : }
    6502              : 
    6503              : 
    6504              : /*
    6505              :    BuildRTExceptLeave - informs RTExceptions that we are about to leave the except state.
    6506              :                         If, destroy, is TRUE then pop the ExceptStack.
    6507              : */
    6508              : 
    6509         3131 : static void BuildRTExceptLeave (unsigned int tok, bool destroy)
    6510              : {
    6511         3131 :   unsigned int old;
    6512         3131 :   unsigned int ProcSym;
    6513              : 
    6514         3131 :   if (M2Options_Exceptions)
    6515              :     {
    6516              :       /* avoid dangling else.  */
    6517              :       /* now inform the Modula-2 runtime we are in the exception state  */
    6518         3131 :       ProcSym = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "SetExceptionState", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
    6519         3131 :       if (ProcSym != SymbolTable_NulSym)
    6520              :         {
    6521         3131 :           if (destroy)
    6522              :             {
    6523         2969 :               old = static_cast<unsigned int> (M2StackWord_PopWord (ExceptStack));
    6524              :             }
    6525              :           else
    6526              :             {
    6527          162 :               old = static_cast<unsigned int> (M2StackWord_PeepWord (ExceptStack, 1));
    6528              :             }
    6529         3131 :           GenQuadO (tok, M2Quads_RestoreExceptionOp, old, SymbolTable_NulSym, ProcSym, false);
    6530              :         }
    6531              :     }
    6532              :   /* no need for an error message here as it will be generated in the Enter procedure above  */
    6533         3131 : }
    6534              : 
    6535              : 
    6536              : /*
    6537              :    SafeRequestSym - only used during scaffold to get argc, argv, envp.
    6538              :                     It attempts to get symbol name from the current scope(s) and if
    6539              :                     it fails then it falls back onto default constants.
    6540              : */
    6541              : 
    6542        16482 : static unsigned int SafeRequestSym (unsigned int tok, NameKey_Name name)
    6543              : {
    6544        16482 :   unsigned int sym;
    6545              : 
    6546        16482 :   sym = SymbolTable_GetSym (name);
    6547        16482 :   if (sym == SymbolTable_NulSym)
    6548              :     {
    6549              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6550            0 :       if (name == (NameKey_MakeKey ((const char *) "argc", 4)))
    6551              :         {
    6552            0 :           return SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType);
    6553              :         }
    6554            0 :       else if ((name == (NameKey_MakeKey ((const char *) "argv", 4))) || (name == (NameKey_MakeKey ((const char *) "envp", 4))))
    6555              :         {
    6556              :           /* avoid dangling else.  */
    6557            0 :           return M2Base_Nil;
    6558              :         }
    6559              :       else
    6560              :         {
    6561              :           /* avoid dangling else.  */
    6562            0 :           M2Error_InternalError ((const char *) "not expecting this parameter name", 33);
    6563              :           return M2Base_Nil;
    6564              :         }
    6565              :     }
    6566              :   return sym;
    6567              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6568              :   __builtin_unreachable ();
    6569              : }
    6570              : 
    6571              : 
    6572              : /*
    6573              :    callRequestDependant - create a call:
    6574              :                           RequestDependant (GetSymName (modulesym), GetLibName (modulesym),
    6575              :                                             GetSymName (depModuleSym), GetLibName (depModuleSym));
    6576              : */
    6577              : 
    6578        39080 : static void callRequestDependant (unsigned int tokno, unsigned int moduleSym, unsigned int depModuleSym, unsigned int requestDep)
    6579              : {
    6580        39080 :   M2Debug_Assert (requestDep != SymbolTable_NulSym);
    6581        39080 :   M2Quads_PushTtok (requestDep, tokno);
    6582        39080 :   M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
    6583        39080 :   M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetSymName (moduleSym)), tokno);
    6584        39080 :   M2Quads_PushT (static_cast<unsigned int> (1));
    6585        39080 :   BuildAdrFunction ();
    6586        39080 :   M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
    6587        39080 :   M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetLibName (moduleSym)), tokno);
    6588        39080 :   M2Quads_PushT (static_cast<unsigned int> (1));
    6589        39080 :   BuildAdrFunction ();
    6590        39080 :   if (depModuleSym == SymbolTable_NulSym)
    6591              :     {
    6592        15783 :       M2Quads_PushTF (M2Base_Nil, M2System_Address);
    6593        15783 :       M2Quads_PushTF (M2Base_Nil, M2System_Address);
    6594              :     }
    6595              :   else
    6596              :     {
    6597        23297 :       M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
    6598        23297 :       M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetSymName (depModuleSym)), tokno);
    6599        23297 :       M2Quads_PushT (static_cast<unsigned int> (1));
    6600        23297 :       BuildAdrFunction ();
    6601        23297 :       M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
    6602        23297 :       M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetLibName (depModuleSym)), tokno);
    6603        23297 :       M2Quads_PushT (static_cast<unsigned int> (1));
    6604        23297 :       BuildAdrFunction ();
    6605              :     }
    6606        39080 :   M2Quads_PushT (static_cast<unsigned int> (4));
    6607        39080 :   M2Quads_BuildProcedureCall (tokno);
    6608        39080 : }
    6609              : 
    6610              : 
    6611              : /*
    6612              :    ForeachImportInDepDo -
    6613              : */
    6614              : 
    6615        31566 : static void ForeachImportInDepDo (Lists_List importStatements, unsigned int moduleSym, unsigned int requestDep)
    6616              : {
    6617        31566 :   unsigned int i;
    6618        31566 :   unsigned int j;
    6619        31566 :   unsigned int m;
    6620        31566 :   unsigned int n;
    6621        31566 :   unsigned int imported;
    6622        31566 :   unsigned int stmt;
    6623        31566 :   Lists_List l;
    6624              : 
    6625        31566 :   if (importStatements != NULL)
    6626              :     {
    6627        19868 :       i = 1;
    6628        19868 :       n = Lists_NoOfItemsInList (importStatements);
    6629        62283 :       while (i <= n)
    6630              :         {
    6631        22547 :           stmt = static_cast<unsigned int> (Lists_GetItemFromList (importStatements, i));
    6632        22547 :           M2Debug_Assert (SymbolTable_IsImportStatement (stmt));
    6633        22547 :           l = SymbolTable_GetImportStatementList (stmt);
    6634        22547 :           j = 1;
    6635        22547 :           m = Lists_NoOfItemsInList (l);
    6636        68391 :           while (j <= m)
    6637              :             {
    6638        23297 :               imported = static_cast<unsigned int> (Lists_GetItemFromList (l, j));
    6639        23297 :               M2Debug_Assert (SymbolTable_IsImport (imported));
    6640        23297 :               callRequestDependant (SymbolTable_GetImportDeclared (imported), moduleSym, SymbolTable_GetImportModule (imported), requestDep);
    6641        23297 :               j += 1;
    6642              :             }
    6643        22547 :           i += 1;
    6644              :         }
    6645              :     }
    6646        31566 : }
    6647              : 
    6648              : 
    6649              : /*
    6650              :    ForeachImportedModuleDo -
    6651              : */
    6652              : 
    6653        15783 : static void ForeachImportedModuleDo (unsigned int moduleSym, unsigned int requestDep)
    6654              : {
    6655        15783 :   Lists_List importStatements;
    6656              : 
    6657        15783 :   importStatements = SymbolTable_GetModuleModImportStatementList (moduleSym);
    6658        15783 :   ForeachImportInDepDo (importStatements, moduleSym, requestDep);
    6659        15783 :   importStatements = SymbolTable_GetModuleDefImportStatementList (moduleSym);
    6660        15783 :   ForeachImportInDepDo (importStatements, moduleSym, requestDep);
    6661        15783 : }
    6662              : 
    6663              : 
    6664              : /*
    6665              :    BuildM2DepFunction - creates the dependency graph procedure using IR:
    6666              :                         static void
    6667              :                         dependencies (void)
    6668              :                         {
    6669              :                            M2RTS_RequestDependant (module_name, libname, "b", "b libname");
    6670              :                            M2RTS_RequestDependant (module_name, libname, NULL, NULL);
    6671              :                         }
    6672              : */
    6673              : 
    6674        15827 : static void BuildM2DepFunction (unsigned int tokno, unsigned int moduleSym)
    6675              : {
    6676        15827 :   unsigned int requestDep;
    6677        15827 :   unsigned int ctor;
    6678        15827 :   unsigned int init;
    6679        15827 :   unsigned int fini;
    6680        15827 :   unsigned int dep;
    6681              : 
    6682        15827 :   if (M2Options_ScaffoldDynamic)
    6683              :     {
    6684              :       /* Scaffold required and dynamic dependency graph should be produced.  */
    6685        15783 :       SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
    6686        15783 :       M2Quads_PushT (dep);
    6687        15783 :       M2Quads_BuildProcedureStart ();
    6688        15783 :       M2Quads_BuildProcedureBegin ();
    6689        15783 :       SymbolTable_StartScope (dep);
    6690        15783 :       requestDep = GetQualidentImport (tokno, NameKey_MakeKey ((const char *) "RequestDependant", 16), NameKey_MakeKey ((const char *) "M2RTS", 5));
    6691        15783 :       if (requestDep != SymbolTable_NulSym)
    6692              :         {
    6693        15783 :           ForeachImportedModuleDo (moduleSym, requestDep);
    6694        15783 :           callRequestDependant (tokno, moduleSym, SymbolTable_NulSym, requestDep);
    6695              :         }
    6696        15783 :       SymbolTable_EndScope ();
    6697        15783 :       M2Quads_BuildProcedureEnd ();
    6698        15783 :       M2Quads_PopN (1);
    6699              :     }
    6700        15827 : }
    6701              : 
    6702              : 
    6703              : /*
    6704              :    BuildM2LinkFunction - creates the _M2_link procedure which will
    6705              :                          cause the linker to pull in all the module ctors.
    6706              : */
    6707              : 
    6708         2783 : static void BuildM2LinkFunction (unsigned int tokno)
    6709              : {
    6710         2783 :   if (M2Options_ScaffoldDynamic)
    6711              :     {
    6712         2747 :       if (M2Scaffold_linkFunction != SymbolTable_NulSym)
    6713              :         {
    6714              :           /* void
    6715              :            _M2_link (void)
    6716              :            {
    6717              :               for each module in uselist do
    6718              :                  PROC foo_%d = _M2_module_ctor
    6719              :               done
    6720              :            }.  */
    6721         2732 :           M2Quads_PushT (M2Scaffold_linkFunction);
    6722         2732 :           M2Quads_BuildProcedureStart ();
    6723         2732 :           M2Quads_BuildProcedureBegin ();
    6724         2732 :           SymbolTable_StartScope (M2Scaffold_linkFunction);
    6725         2732 :           M2Scaffold_PopulateCtorArray (tokno);
    6726         2732 :           SymbolTable_EndScope ();
    6727         2732 :           M2Quads_BuildProcedureEnd ();
    6728         2732 :           M2Quads_PopN (1);
    6729              :         }
    6730              :     }
    6731         2783 : }
    6732              : 
    6733              : 
    6734              : /*
    6735              :    BuildTry - build the try statement for main.
    6736              : */
    6737              : 
    6738         2747 : static void BuildTry (unsigned int tokno)
    6739              : {
    6740         2747 :   if (M2Options_Exceptions)
    6741              :     {
    6742         2747 :       M2StackWord_PushWord (TryStack, NextQuad);
    6743         2747 :       M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
    6744         2747 :       GenQuadO (tokno, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
    6745              :     }
    6746         2747 : }
    6747              : 
    6748              : 
    6749              : /*
    6750              :    BuildExcept - build the except block for main.
    6751              : */
    6752              : 
    6753         2747 : static void BuildExcept (unsigned int tokno)
    6754              : {
    6755         2747 :   unsigned int catchProcedure;
    6756              : 
    6757         2747 :   if (M2Options_Exceptions)
    6758              :     {
    6759         2747 :       M2Quads_BuildExceptInitial (tokno);
    6760         2747 :       catchProcedure = GetQualidentImport (tokno, NameKey_MakeKey ((const char *) "DefaultErrorCatch", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
    6761         2747 :       if (catchProcedure != SymbolTable_NulSym)
    6762              :         {
    6763         2747 :           M2Quads_PushTtok (catchProcedure, tokno);
    6764         2747 :           M2Quads_PushT (static_cast<unsigned int> (0));
    6765         2747 :           M2Quads_BuildProcedureCall (tokno);
    6766              :         }
    6767         2747 :       BuildRTExceptLeave (tokno, true);
    6768         2747 :       GenQuadO (tokno, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
    6769              :     }
    6770         2747 : }
    6771              : 
    6772              : 
    6773              : /*
    6774              :    BuildM2MainFunction - creates the main function with appropriate calls to the scaffold.
    6775              : */
    6776              : 
    6777         2783 : static void BuildM2MainFunction (unsigned int tokno)
    6778              : {
    6779         2783 :   if ((M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic) && ! M2Options_SharedFlag)
    6780              :     {
    6781              :       /* 
    6782              :          int
    6783              :          main (int argc, char *argv[], char *envp[])
    6784              :          {
    6785              :             try {
    6786              :                _M2_init (argc, argv, envp);
    6787              :                _M2_fini (argc, argv, envp);
    6788              :                return 0;
    6789              :             }
    6790              :             catch (...) {
    6791              :                RTExceptions_DefaultErrorCatch ();
    6792              :                return 0;
    6793              :             }
    6794              :          }
    6795              :   */
    6796         2747 :       M2Quads_PushT (M2Scaffold_mainFunction);
    6797         2747 :       M2Quads_BuildProcedureStart ();
    6798         2747 :       M2Quads_BuildProcedureBegin ();
    6799         2747 :       SymbolTable_StartScope (M2Scaffold_mainFunction);
    6800         2747 :       BuildTry (tokno);
    6801              :       /* _M2_init (argc, argv, envp);  */
    6802         2747 :       M2Quads_PushTtok (M2Scaffold_initFunction, tokno);
    6803         2747 :       M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argc", 4)), tokno);
    6804         2747 :       M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argv", 4)), tokno);
    6805         2747 :       M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "envp", 4)), tokno);
    6806         2747 :       M2Quads_PushT (static_cast<unsigned int> (3));
    6807         2747 :       M2Quads_BuildProcedureCall (tokno);
    6808              :       /* _M2_fini (argc, argv, envp);  */
    6809         2747 :       M2Quads_PushTtok (M2Scaffold_finiFunction, tokno);
    6810         2747 :       M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argc", 4)), tokno);
    6811         2747 :       M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argv", 4)), tokno);
    6812         2747 :       M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "envp", 4)), tokno);
    6813         2747 :       M2Quads_PushT (static_cast<unsigned int> (3));
    6814         2747 :       M2Quads_BuildProcedureCall (tokno);
    6815         2747 :       PushZero (tokno, M2Base_Integer);
    6816         2747 :       M2Quads_BuildReturn (tokno);
    6817         2747 :       BuildExcept (tokno);
    6818         2747 :       PushZero (tokno, M2Base_Integer);
    6819         2747 :       M2Quads_BuildReturn (tokno);
    6820         2747 :       SymbolTable_EndScope ();
    6821         2747 :       M2Quads_BuildProcedureEnd ();
    6822         2747 :       M2Quads_PopN (1);
    6823              :     }
    6824         2783 : }
    6825              : 
    6826              : 
    6827              : /*
    6828              :    DeferMakeConstStringCnul - return a C const string which will be nul terminated.
    6829              : */
    6830              : 
    6831         9733 : static unsigned int DeferMakeConstStringCnul (unsigned int tok, unsigned int sym)
    6832              : {
    6833         9733 :   unsigned int const_;
    6834              : 
    6835         9733 :   const_ = SymbolTable_MakeConstStringCnul (tok, NameKey_NulName, false);
    6836        19466 :   GenQuadO (tok, M2Quads_StringConvertCnulOp, const_, 0, sym, false);
    6837         9733 :   return const_;
    6838              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6839              :   __builtin_unreachable ();
    6840              : }
    6841              : 
    6842              : 
    6843              : /*
    6844              :    DeferMakeConstStringM2nul - return a const string which will be nul terminated.
    6845              : */
    6846              : 
    6847        34964 : static unsigned int DeferMakeConstStringM2nul (unsigned int tok, unsigned int sym)
    6848              : {
    6849        34964 :   unsigned int const_;
    6850              : 
    6851        34964 :   const_ = SymbolTable_MakeConstStringM2nul (tok, NameKey_NulName, false);
    6852        69928 :   GenQuadO (tok, M2Quads_StringConvertM2nulOp, const_, 0, sym, false);
    6853        34964 :   return const_;
    6854              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6855              :   __builtin_unreachable ();
    6856              : }
    6857              : 
    6858              : 
    6859              : /*
    6860              :    BuildStringAdrParam - push the address of a nul terminated string onto the quad stack.
    6861              : */
    6862              : 
    6863         8241 : static void BuildStringAdrParam (unsigned int tok, NameKey_Name name)
    6864              : {
    6865         8241 :   unsigned int str;
    6866         8241 :   unsigned int m2strnul;
    6867              : 
    6868         8241 :   M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
    6869         8241 :   str = SymbolTable_MakeConstString (tok, name);
    6870         8241 :   SymbolTable_PutConstStringKnown (tok, str, name, false, true);
    6871         8241 :   m2strnul = DeferMakeConstStringM2nul (tok, str);
    6872         8241 :   M2Quads_PushTtok (m2strnul, tok);
    6873         8241 :   M2Quads_PushT (static_cast<unsigned int> (1));
    6874         8241 :   BuildAdrFunction ();
    6875         8241 : }
    6876              : 
    6877              : 
    6878              : /*
    6879              :    BuildM2InitFunction -
    6880              : */
    6881              : 
    6882         2783 : static void BuildM2InitFunction (unsigned int tok, unsigned int moduleSym)
    6883              : {
    6884         2783 :   unsigned int constructModules;
    6885              : 
    6886         2783 :   if (M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic)
    6887              :     {
    6888              :       /* int
    6889              :          _M2_init (int argc, char *argv[], char *envp[])
    6890              :          {
    6891              :             M2RTS_ConstructModules (module_name, libname,
    6892              :                                     overrideliborder, argc, argv, envp);
    6893              :          }  */
    6894         2747 :       M2Quads_PushT (M2Scaffold_initFunction);
    6895         2747 :       M2Quads_BuildProcedureStart ();
    6896         2747 :       M2Quads_BuildProcedureBegin ();
    6897         2747 :       SymbolTable_StartScope (M2Scaffold_initFunction);
    6898         2747 :       if (M2Options_ScaffoldDynamic)
    6899              :         {
    6900              :           /* avoid dangling else.  */
    6901         2747 :           if (M2Scaffold_linkFunction != SymbolTable_NulSym)
    6902              :             {
    6903              :               /* _M2_link ();  */
    6904         2732 :               M2Quads_PushTtok (M2Scaffold_linkFunction, tok);
    6905         2732 :               M2Quads_PushT (static_cast<unsigned int> (0));
    6906         2732 :               M2Quads_BuildProcedureCall (tok);
    6907              :             }
    6908              :           /* Lookup ConstructModules and call it.  */
    6909         2747 :           constructModules = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "ConstructModules", 16), NameKey_MakeKey ((const char *) "M2RTS", 5));
    6910         2747 :           if (constructModules != SymbolTable_NulSym)
    6911              :             {
    6912              :               /* ConstructModules (module_name, argc, argv, envp);  */
    6913         2747 :               M2Quads_PushTtok (constructModules, tok);
    6914         2747 :               BuildStringAdrParam (tok, SymbolTable_GetSymName (moduleSym));
    6915         2747 :               BuildStringAdrParam (tok, SymbolTable_GetLibName (moduleSym));
    6916         2747 :               BuildStringAdrParam (tok, NameKey_makekey (M2Options_GetRuntimeModuleOverride ()));
    6917         2747 :               M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argc", 4)), tok);
    6918         2747 :               M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argv", 4)), tok);
    6919         2747 :               M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "envp", 4)), tok);
    6920         2747 :               M2Quads_PushT (static_cast<unsigned int> (6));
    6921         2747 :               M2Quads_BuildProcedureCall (tok);
    6922              :             }
    6923              :         }
    6924            0 :       else if (M2Options_ScaffoldStatic)
    6925              :         {
    6926              :           /* avoid dangling else.  */
    6927            0 :           M2Scaffold_ForeachModuleCallInit (tok, SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argc", 4)), SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argv", 4)), SafeRequestSym (tok, NameKey_MakeKey ((const char *) "envp", 4)));
    6928              :         }
    6929         2747 :       SymbolTable_EndScope ();
    6930         2747 :       M2Quads_BuildProcedureEnd ();
    6931         2747 :       M2Quads_PopN (1);
    6932              :     }
    6933         2783 : }
    6934              : 
    6935              : 
    6936              : /*
    6937              :    BuildM2FiniFunction -
    6938              : */
    6939              : 
    6940         2783 : static void BuildM2FiniFunction (unsigned int tok, unsigned int moduleSym)
    6941              : {
    6942         2783 :   unsigned int deconstructModules;
    6943              : 
    6944         2783 :   if (M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic)
    6945              :     {
    6946              :       /* Scaffold required and main should be produced.  */
    6947         2747 :       M2Quads_PushT (M2Scaffold_finiFunction);
    6948         2747 :       M2Quads_BuildProcedureStart ();
    6949         2747 :       M2Quads_BuildProcedureBegin ();
    6950         2747 :       SymbolTable_StartScope (M2Scaffold_finiFunction);
    6951         2747 :       if (M2Options_ScaffoldDynamic)
    6952              :         {
    6953              :           /* avoid dangling else.  */
    6954              :           /* static void
    6955              :             _M2_finish (int argc, char *argv[], char *envp[])
    6956              :             {
    6957              :               M2RTS_DeconstructModules (module_name, argc, argv, envp);
    6958              :             }  */
    6959         2747 :           deconstructModules = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "DeconstructModules", 18), NameKey_MakeKey ((const char *) "M2RTS", 5));
    6960         2747 :           if (deconstructModules != SymbolTable_NulSym)
    6961              :             {
    6962              :               /* DeconstructModules (module_name, argc, argv, envp);  */
    6963         2747 :               M2Quads_PushTtok (deconstructModules, tok);
    6964         2747 :               M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
    6965         2747 :               M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetSymName (moduleSym)), tok);
    6966         2747 :               M2Quads_PushT (static_cast<unsigned int> (1));
    6967         2747 :               BuildAdrFunction ();
    6968         2747 :               M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
    6969         2747 :               M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetLibName (moduleSym)), tok);
    6970         2747 :               M2Quads_PushT (static_cast<unsigned int> (1));
    6971         2747 :               BuildAdrFunction ();
    6972         2747 :               M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argc", 4)), tok);
    6973         2747 :               M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argv", 4)), tok);
    6974         2747 :               M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "envp", 4)), tok);
    6975         2747 :               M2Quads_PushT (static_cast<unsigned int> (5));
    6976         2747 :               M2Quads_BuildProcedureCall (tok);
    6977              :             }
    6978              :         }
    6979            0 :       else if (M2Options_ScaffoldStatic)
    6980              :         {
    6981              :           /* avoid dangling else.  */
    6982            0 :           M2Scaffold_ForeachModuleCallFinish (tok, SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argc", 4)), SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argv", 4)), SafeRequestSym (tok, NameKey_MakeKey ((const char *) "envp", 4)));
    6983              :         }
    6984         2747 :       SymbolTable_EndScope ();
    6985         2747 :       M2Quads_BuildProcedureEnd ();
    6986         2747 :       M2Quads_PopN (1);
    6987              :     }
    6988         2783 : }
    6989              : 
    6990              : 
    6991              : /*
    6992              :    BuildM2CtorFunction - create a constructor function associated with moduleSym.
    6993              : 
    6994              :                          void
    6995              :                          ctorFunction ()
    6996              :                          {
    6997              :                            M2RTS_RegisterModule (GetSymName (moduleSym), GetLibName (moduleSym),
    6998              :                                                  init, fini, dependencies);
    6999              :                          }
    7000              : */
    7001              : 
    7002        15827 : static void BuildM2CtorFunction (unsigned int tok, unsigned int moduleSym)
    7003              : {
    7004        15827 :   unsigned int RegisterModule;
    7005        15827 :   unsigned int ctor;
    7006        15827 :   unsigned int init;
    7007        15827 :   unsigned int fini;
    7008        15827 :   unsigned int dep;
    7009              : 
    7010        15827 :   if (M2Options_ScaffoldDynamic)
    7011              :     {
    7012        15783 :       SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
    7013        15783 :       if (ctor != SymbolTable_NulSym)
    7014              :         {
    7015        15783 :           M2Debug_Assert (SymbolTable_IsProcedure (ctor));
    7016        15783 :           M2Quads_PushT (ctor);
    7017        15783 :           M2Quads_BuildProcedureStart ();
    7018        15783 :           M2Quads_BuildProcedureBegin ();
    7019        15783 :           SymbolTable_StartScope (ctor);
    7020        15783 :           RegisterModule = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "RegisterModule", 14), NameKey_MakeKey ((const char *) "M2RTS", 5));
    7021        15783 :           if (RegisterModule != SymbolTable_NulSym)
    7022              :             {
    7023              :               /* RegisterModule (module_name, init, fini, dependencies);  */
    7024        15783 :               M2Quads_PushTtok (RegisterModule, tok);
    7025        15783 :               M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
    7026        15783 :               M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetSymName (moduleSym)), tok);
    7027        15783 :               M2Quads_PushT (static_cast<unsigned int> (1));
    7028        15783 :               BuildAdrFunction ();
    7029        15783 :               M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
    7030        15783 :               M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetLibName (moduleSym)), tok);
    7031        15783 :               M2Quads_PushT (static_cast<unsigned int> (1));
    7032        15783 :               BuildAdrFunction ();
    7033        15783 :               M2Quads_PushTtok (init, tok);
    7034        15783 :               M2Quads_PushTtok (fini, tok);
    7035        15783 :               M2Quads_PushTtok (dep, tok);
    7036        15783 :               M2Quads_PushT (static_cast<unsigned int> (5));
    7037        15783 :               M2Quads_BuildProcedureCall (tok);
    7038              :             }
    7039        15783 :           SymbolTable_EndScope ();
    7040        15783 :           M2Quads_BuildProcedureEnd ();
    7041        15783 :           M2Quads_PopN (1);
    7042              :         }
    7043              :     }
    7044        15827 : }
    7045              : 
    7046              : 
    7047              : /*
    7048              :    AddForInfo - adds the description of the FOR loop into the record list.
    7049              :                 This is used if -pedantic is turned on to check index variable
    7050              :                 usage.
    7051              : */
    7052              : 
    7053         2604 : static void AddForInfo (unsigned int Start, unsigned int End, unsigned int IncQuad, unsigned int Sym, unsigned int idtok)
    7054              : {
    7055         2604 :   M2Quads_ForLoopInfo forDesc;
    7056              : 
    7057         2604 :   if (M2Options_Pedantic)
    7058              :     {
    7059            0 :       Storage_ALLOCATE ((void **) &forDesc, sizeof (M2Quads__T5));
    7060            0 :       forDesc->IncrementQuad = IncQuad;
    7061            0 :       forDesc->StartOfForLoop = Start;
    7062            0 :       forDesc->EndOfForLoop = End;
    7063            0 :       forDesc->ForLoopIndex = Sym;
    7064            0 :       forDesc->IndexTok = idtok;
    7065            0 :       Indexing_IncludeIndiceIntoIndex (ForInfo, reinterpret_cast <void *> (forDesc));
    7066              :     }
    7067         2604 : }
    7068              : 
    7069              : 
    7070              : /*
    7071              :    CheckForIndex - checks the quadruples: Start..End to see whether a
    7072              :                    for loop index is manipulated by the programmer.
    7073              :                    It generates a warning if this is the case.
    7074              :                    It also checks to see whether the IndexSym is read
    7075              :                    immediately outside the loop in which case a warning
    7076              :                    is issued.
    7077              : */
    7078              : 
    7079            0 : static void CheckForIndex (M2Quads_ForLoopInfo forDesc)
    7080              : {
    7081            0 :   unsigned int ReadStart;
    7082            0 :   unsigned int ReadEnd;
    7083            0 :   unsigned int WriteStart;
    7084            0 :   unsigned int WriteEnd;
    7085              : 
    7086            0 :   SymbolTable_GetWriteLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->StartOfForLoop, forDesc->EndOfForLoop, &WriteStart, &WriteEnd);
    7087            0 :   if ((WriteStart < forDesc->IncrementQuad) && (WriteStart > forDesc->StartOfForLoop))
    7088              :     {
    7089            0 :       M2MetaError_MetaErrorT1 (forDesc->IndexTok, (const char *) "{%kFOR} loop index variable {%1Wad} is being manipulated inside the loop", 72, forDesc->ForLoopIndex);
    7090            0 :       M2MetaError_MetaErrorT1 (M2Quads_QuadToTokenNo (WriteStart), (const char *) "{%kFOR} loop index variable {%1Wad} is being manipulated, this is considered bad practice and may cause unknown program behaviour", 129, forDesc->ForLoopIndex);
    7091              :     }
    7092            0 :   SymbolTable_GetWriteLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->EndOfForLoop, 0, &WriteStart, &WriteEnd);
    7093            0 :   SymbolTable_GetReadLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->EndOfForLoop, 0, &ReadStart, &ReadEnd);
    7094            0 :   if ((ReadStart != 0) && ((ReadStart < WriteStart) || (WriteStart == 0)))
    7095              :     {
    7096            0 :       M2MetaError_MetaErrorT1 (forDesc->IndexTok, (const char *) "{%kFOR} loop index variable {%1Wad} is being read outside the FOR loop (without being reset)", 92, forDesc->ForLoopIndex);
    7097            0 :       M2MetaError_MetaErrorT1 (M2Quads_QuadToTokenNo (ReadStart), (const char *) "{%kFOR} loop index variable {%1Wad} is being read outside the FOR loop (without being reset), this is considered extremely bad practice and may cause unknown program behaviour", 175, forDesc->ForLoopIndex);
    7098              :     }
    7099            0 : }
    7100              : 
    7101              : 
    7102              : /*
    7103              :    BuildRange - generates a RangeCheckOp quad with, r, as its operand.
    7104              : */
    7105              : 
    7106      2086369 : static void BuildRange (unsigned int r)
    7107              : {
    7108      2086369 :   GenQuad (M2Quads_RangeCheckOp, (unsigned int ) (M2LexBuf_GetLineNo ()), SymbolTable_NulSym, r);
    7109      2086369 : }
    7110              : 
    7111              : 
    7112              : /*
    7113              :    BuildError - generates a ErrorOp quad, indicating that if this
    7114              :                 quadruple is reachable, then a runtime error would
    7115              :                 occur.
    7116              : */
    7117              : 
    7118        19660 : static void BuildError (unsigned int r)
    7119              : {
    7120        19660 :   GenQuad (M2Quads_ErrorOp, (unsigned int ) (M2LexBuf_GetLineNo ()), SymbolTable_NulSym, r);
    7121        19660 : }
    7122              : 
    7123              : 
    7124              : /*
    7125              :    CheckPointerThroughNil - builds a range quadruple, providing, sym, is
    7126              :                             a candidate for checking against NIL.
    7127              :                             This range quadruple is only expanded into
    7128              :                             code during the code generation phase
    7129              :                             thus allowing limited compile time checking.
    7130              : */
    7131              : 
    7132        80695 : static void CheckPointerThroughNil (unsigned int tokpos, unsigned int sym)
    7133              : {
    7134        80695 :   if ((SymbolTable_IsVar (sym)) && (SymbolTable_GetVarPointerCheck (sym)))
    7135              :     {
    7136              :       /* PutVarPointerCheck(sym, FALSE) ;   so we do not detect this again  */
    7137        23714 :       BuildRange (M2Range_InitPointerRangeCheck (tokpos, sym, (SymbolTable_GetMode (sym)) == SymbolTable_LeftValue));
    7138              :     }
    7139        80695 : }
    7140              : 
    7141              : 
    7142              : /*
    7143              :    CollectLow - returns the low of the subrange value.
    7144              : */
    7145              : 
    7146          306 : static unsigned int CollectLow (unsigned int sym)
    7147              : {
    7148          306 :   unsigned int low;
    7149          306 :   unsigned int high;
    7150              : 
    7151          306 :   if (SymbolTable_IsSubrange (sym))
    7152              :     {
    7153          306 :       SymbolTable_GetSubrange (sym, &high, &low);
    7154          306 :       return low;
    7155              :     }
    7156              :   else
    7157              :     {
    7158            0 :       M2Error_InternalError ((const char *) "expecting Subrange symbol", 25);
    7159              :     }
    7160              :   ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
    7161              :   __builtin_unreachable ();
    7162              : }
    7163              : 
    7164              : 
    7165              : /*
    7166              :    CollectHigh - returns the high of the subrange value, sym.
    7167              : */
    7168              : 
    7169          562 : static unsigned int CollectHigh (unsigned int sym)
    7170              : {
    7171          562 :   unsigned int low;
    7172          562 :   unsigned int high;
    7173              : 
    7174          562 :   if (SymbolTable_IsSubrange (sym))
    7175              :     {
    7176          562 :       SymbolTable_GetSubrange (sym, &high, &low);
    7177          562 :       return high;
    7178              :     }
    7179              :   else
    7180              :     {
    7181            0 :       M2Error_InternalError ((const char *) "expecting Subrange symbol", 25);
    7182              :     }
    7183              :   ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
    7184              :   __builtin_unreachable ();
    7185              : }
    7186              : 
    7187              : 
    7188              : /*
    7189              :    CheckCompatibleWithBecomes - checks to see that symbol, sym, is
    7190              :                                 compatible with the := operator.
    7191              : */
    7192              : 
    7193       502381 : static void CheckCompatibleWithBecomes (unsigned int des, unsigned int expr, unsigned int destok, unsigned int exprtok)
    7194              : {
    7195       502381 :   if (SymbolTable_IsType (des))
    7196              :     {
    7197            0 :       M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to a type {%1a}", 51, des);
    7198              :     }
    7199       502381 :   else if (SymbolTable_IsProcedure (des))
    7200              :     {
    7201              :       /* avoid dangling else.  */
    7202            6 :       M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to a procedure {%1a}", 56, des);
    7203              :     }
    7204       502375 :   else if (SymbolTable_IsFieldEnumeration (des))
    7205              :     {
    7206              :       /* avoid dangling else.  */
    7207            0 :       M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to an enumeration field {%1a}", 65, des);
    7208              :     }
    7209       502381 :   if ((M2Base_IsPseudoBaseProcedure (expr)) || (M2Base_IsPseudoBaseFunction (expr)))
    7210              :     {
    7211            6 :       M2MetaError_MetaErrorT1 (exprtok, (const char *) "an assignment cannot assign a {%1dv} {%1a}", 42, expr);
    7212              :     }
    7213       502381 : }
    7214              : 
    7215              : 
    7216              : /*
    7217              :    BuildAssignmentWithoutBounds - calls BuildAssignment but makes sure we do not
    7218              :                                   check bounds.
    7219              : */
    7220              : 
    7221        83855 : static void BuildAssignmentWithoutBounds (unsigned int tok, bool checkTypes, bool checkOverflow)
    7222              : {
    7223        83855 :   bool old;
    7224              : 
    7225        83855 :   old = MustNotCheckBounds;
    7226        83855 :   MustNotCheckBounds = true;
    7227            0 :   doBuildAssignment (tok, checkTypes, checkOverflow);
    7228        83855 :   MustNotCheckBounds = old;
    7229        19748 : }
    7230              : 
    7231              : 
    7232              : /*
    7233              :    MarkArrayWritten - marks, Array, as being written.
    7234              : */
    7235              : 
    7236       101950 : static void MarkArrayWritten (unsigned int Array)
    7237              : {
    7238       101950 :   if ((Array != SymbolTable_NulSym) && (SymbolTable_IsVarAParam (Array)))
    7239              :     {
    7240        12630 :       SymbolTable_PutVarWritten (Array, true);
    7241              :     }
    7242       101950 : }
    7243              : 
    7244              : 
    7245              : /*
    7246              :    MarkAsReadWrite - marks the variable or parameter as being
    7247              :                      read/write.
    7248              : */
    7249              : 
    7250        31247 : static void MarkAsReadWrite (unsigned int sym)
    7251              : {
    7252        31247 :   if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
    7253              :     {
    7254        21514 :       SymbolTable_PutReadQuad (sym, SymbolTable_RightValue, NextQuad);
    7255        21514 :       SymbolTable_PutWriteQuad (sym, SymbolTable_RightValue, NextQuad);
    7256              :     }
    7257        31247 : }
    7258              : 
    7259              : 
    7260              : /*
    7261              :    MarkAsRead - marks the variable or parameter as being read.
    7262              : */
    7263              : 
    7264      1275988 : static void MarkAsRead (unsigned int sym)
    7265              : {
    7266      1275988 :   if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
    7267              :     {
    7268       361363 :       SymbolTable_PutReadQuad (sym, SymbolTable_RightValue, NextQuad);
    7269              :     }
    7270      1275988 : }
    7271              : 
    7272              : 
    7273              : /*
    7274              :    MarkAsWrite - marks the variable or parameter as being written.
    7275              : */
    7276              : 
    7277       502381 : static void MarkAsWrite (unsigned int sym)
    7278              : {
    7279       502381 :   if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
    7280              :     {
    7281        86131 :       SymbolTable_PutWriteQuad (sym, SymbolTable_RightValue, NextQuad);
    7282              :     }
    7283       502381 : }
    7284              : 
    7285              : 
    7286              : /*
    7287              :    doVal - return an expression which is VAL(type, expr).  If
    7288              :            expr is a constant then return expr.
    7289              : */
    7290              : 
    7291        44030 : static unsigned int doVal (unsigned int type, unsigned int expr)
    7292              : {
    7293        44030 :   if ((! (SymbolTable_IsConst (expr))) && ((SymbolTable_SkipType (type)) != (SymbolTable_GetDType (expr))))
    7294              :     {
    7295        33286 :       M2Quads_PushTF (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym));
    7296        33286 :       M2Quads_PushT (SymbolTable_SkipType (type));
    7297        33286 :       M2Quads_PushT (expr);
    7298        33286 :       M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
    7299        33286 :       BuildConvertFunction (M2Base_Convert, false);  /* Two parameters  */
    7300        33286 :       M2Quads_PopT (&expr);
    7301              :     }
    7302        44030 :   return expr;
    7303              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    7304              :   __builtin_unreachable ();
    7305              : }
    7306              : 
    7307              : 
    7308              : /*
    7309              :    MoveWithMode -
    7310              : */
    7311              : 
    7312       502375 : static void MoveWithMode (unsigned int tokno, unsigned int Des, unsigned int Exp, unsigned int Array, unsigned int destok, unsigned int exptok, bool checkOverflow)
    7313              : {
    7314       502375 :   unsigned int t;
    7315              : 
    7316       502375 :   if ((SymbolTable_IsConstString (Exp)) && (SymbolTable_IsConst (Des)))
    7317              :     {
    7318         1426 :       GenQuadOtok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, destok, M2LexBuf_UnknownTokenNo, exptok);
    7319              :     }
    7320              :   else
    7321              :     {
    7322       500949 :       if ((SymbolTable_GetMode (Des)) == SymbolTable_RightValue)
    7323              :         {
    7324       158152 :           if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
    7325              :             {
    7326         2688 :               CheckPointerThroughNil (tokno, Exp);  /* Des = *Exp  */
    7327         2688 :               doIndrX (tokno, Des, Exp);  /* Des = *Exp  */
    7328              :             }
    7329              :           else
    7330              :             {
    7331       155464 :               GenQuadOtok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, destok, M2LexBuf_UnknownTokenNo, exptok);
    7332              :             }
    7333              :         }
    7334       342797 :       else if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
    7335              :         {
    7336              :           /* avoid dangling else.  */
    7337        43512 :           MarkArrayWritten (Array);
    7338        43512 :           if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
    7339              :             {
    7340         1106 :               t = SymbolTable_MakeTemporary (tokno, SymbolTable_RightValue);
    7341         1106 :               SymbolTable_PutVar (t, SymbolTable_GetSType (Exp));
    7342         1106 :               CheckPointerThroughNil (tokno, Exp);
    7343         1106 :               doIndrX (tokno, t, Exp);
    7344         1106 :               CheckPointerThroughNil (tokno, Des);  /* *Des = Exp  */
    7345         1106 :               GenQuadO (tokno, M2Quads_XIndrOp, Des, SymbolTable_GetSType (Des), doVal (SymbolTable_GetSType (Des), t), checkOverflow);  /* *Des = Exp  */
    7346              :             }
    7347              :           else
    7348              :             {
    7349        42406 :               CheckPointerThroughNil (tokno, Des);  /* *Des = Exp  */
    7350        42406 :               GenQuadO (tokno, M2Quads_XIndrOp, Des, SymbolTable_GetSType (Des), doVal (SymbolTable_GetSType (Des), Exp), checkOverflow);  /* *Des = Exp  */
    7351              :             }
    7352              :         }
    7353              :       else
    7354              :         {
    7355              :           /* avoid dangling else.  */
    7356              :           /* This might be inside a const expression.  */
    7357       299285 :           GenQuadOTypetok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, true, destok, M2LexBuf_UnknownTokenNo, exptok);
    7358              :         }
    7359              :     }
    7360       502375 : }
    7361              : 
    7362              : 
    7363              : /*
    7364              :    CheckBecomesMeta - checks to make sure that we are not
    7365              :                       assigning a variable to a constant.
    7366              :                       Also check we are not assigning to an
    7367              :                       unbounded array.
    7368              : */
    7369              : 
    7370       430324 : static void CheckBecomesMeta (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok)
    7371              : {
    7372       430324 :   if ((SymbolTable_IsConst (Des)) && (SymbolTable_IsVar (Exp)))
    7373              :     {
    7374           84 :       M2MetaError_MetaErrorsT2 (combinedtok, (const char *) "in assignment, cannot assign a variable {%2a} to a constant {%1a}", 65, (const char *) "designator {%1Da} is declared as a {%kCONST}", 44, Des, Exp);
    7375              :     }
    7376       430324 :   if ((((SymbolTable_GetDType (Des)) != SymbolTable_NulSym) && (SymbolTable_IsVar (Des))) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (Des))))
    7377              :     {
    7378            0 :       M2MetaError_MetaErrorT1 (destok, (const char *) "in assignment, cannot assign to an unbounded array {%1ad}", 57, Des);
    7379              :     }
    7380       430324 :   if ((((SymbolTable_GetDType (Exp)) != SymbolTable_NulSym) && (SymbolTable_IsVar (Exp))) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (Exp))))
    7381              :     {
    7382            0 :       M2MetaError_MetaErrorT1 (exprtok, (const char *) "in assignment, cannot assign from an unbounded array {%1ad}", 59, Exp);
    7383              :     }
    7384       430324 : }
    7385              : 
    7386              : 
    7387              : /*
    7388              :    BuildAssignmentBoolean - build the quadruples for a boolean variable or constant
    7389              :                             which will be assigned to the result of a boolean expression.
    7390              :                             For example:
    7391              : 
    7392              :                             foo := a = b ;
    7393              :                             foo := a IN b ;
    7394              : 
    7395              :                             The boolean result is contained in the control flow
    7396              :                             the true value will emerge from the quad path t.
    7397              :                             The false value will emerge from the quad path f.
    7398              :                             This procedure terminates both paths by backpatching
    7399              :                             and assigns TRUE or FALSE to the variable/constant.
    7400              :                             A variable maybe an L value so it will require dereferencing.
    7401              : */
    7402              : 
    7403        10044 : static void BuildAssignmentBoolean (unsigned int becomesTokNo, bool checkOverflow, unsigned int t, unsigned int f, unsigned int Des, unsigned int destok)
    7404              : {
    7405        10044 :   SymbolTable_PutVarConditional (Des, true);  /* Des will contain the result of a boolean relop.  */
    7406              :   /* Conditional Boolean Assignment.  */
    7407        10044 :   BackPatch (t, NextQuad);
    7408        10044 :   if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
    7409              :     {
    7410           64 :       CheckPointerThroughNil (destok, Des);
    7411          128 :       GenQuadO (destok, M2Quads_XIndrOp, Des, M2Base_Boolean, M2Base_True, checkOverflow);
    7412           64 :       GenQuadO (destok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, NextQuad+2, false);
    7413              :     }
    7414              :   else
    7415              :     {
    7416              :       /* This might be inside a const expression.  */
    7417        19960 :       GenQuadO (becomesTokNo, M2Quads_BecomesOp, Des, SymbolTable_NulSym, M2Base_True, checkOverflow);
    7418         9980 :       GenQuadO (destok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, NextQuad+2, false);
    7419              :     }
    7420        10044 :   BackPatch (f, NextQuad);
    7421        10044 :   if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
    7422              :     {
    7423           64 :       CheckPointerThroughNil (destok, Des);
    7424           64 :       GenQuadO (destok, M2Quads_XIndrOp, Des, M2Base_Boolean, M2Base_False, checkOverflow);
    7425              :     }
    7426              :   else
    7427              :     {
    7428         9980 :       GenQuadO (becomesTokNo, M2Quads_BecomesOp, Des, SymbolTable_NulSym, M2Base_False, checkOverflow);
    7429              :     }
    7430        10044 : }
    7431              : 
    7432              : 
    7433              : /*
    7434              :    doBuildAssignment - subsiduary procedure of BuildAssignment.
    7435              :                        It builds the assignment and optionally
    7436              :                        checks the types are compatible.
    7437              : */
    7438              : 
    7439       512425 : static void doBuildAssignment (unsigned int becomesTokNo, bool checkTypes, bool checkOverflow)
    7440              : {
    7441       512425 :   unsigned int r;
    7442       512425 :   unsigned int w;
    7443       512425 :   unsigned int t;
    7444       512425 :   unsigned int f;
    7445       512425 :   unsigned int Array;
    7446       512425 :   unsigned int Des;
    7447       512425 :   unsigned int Exp;
    7448       512425 :   unsigned int combinedtok;
    7449       512425 :   unsigned int destok;
    7450       512425 :   unsigned int exptok;
    7451              : 
    7452       512425 :   M2Quads_DisplayStack ();
    7453       512425 :   if (IsBoolean (1))
    7454              :     {
    7455        20088 :       PopBool (&t, &f);
    7456        10044 :       M2Quads_PopTtok (&Des, &destok);
    7457        10044 :       if ((SymbolTable_IsVar (Des)) || (SymbolTable_IsConstVar (Des)))
    7458              :         {
    7459        10044 :           BuildAssignmentBoolean (becomesTokNo, checkOverflow, t, f, Des, destok);
    7460              :         }
    7461              :       else
    7462              :         {
    7463            0 :           M2MetaError_MetaErrorT1 (destok, (const char *) "expecting the designator {%1Ead} to be a constant or a variable and not a {%1dv}", 80, Des);
    7464              :         }
    7465              :     }
    7466              :   else
    7467              :     {
    7468       502381 :       PopTrwtok (&Exp, &r, &exptok);
    7469       502381 :       MarkAsRead (r);
    7470       502381 :       if (Exp == SymbolTable_NulSym)
    7471              :         {
    7472            0 :           M2MetaError_MetaError0 ((const char *) "{%E}unknown expression found during assignment", 46);
    7473            0 :           M2Error_FlushErrors ();
    7474              :         }
    7475       502381 :       Array = static_cast<unsigned int> (M2Quads_OperandA (1));
    7476       502381 :       PopTrwtok (&Des, &w, &destok);
    7477       502381 :       MarkAsWrite (w);
    7478       502381 :       CheckCompatibleWithBecomes (Des, Exp, destok, exptok);
    7479       502381 :       if (DebugTokPos)
    7480              :         {
    7481              :           M2MetaError_MetaErrorT1 (becomesTokNo, (const char *) "becomestok {%1Oad}", 18, Des);
    7482              :           M2MetaError_MetaErrorT1 (destok, (const char *) "destok {%1Oad}", 14, Des);
    7483              :           M2MetaError_MetaErrorT1 (exptok, (const char *) "exptok {%1Oad}", 14, Exp);
    7484              :         }
    7485       502381 :       combinedtok = M2LexBuf_MakeVirtualTok (becomesTokNo, destok, exptok);
    7486       502381 :       if (DebugTokPos)
    7487              :         {
    7488              :           M2MetaError_MetaErrorT1 (combinedtok, (const char *) "combined {%1Oad}", 16, Des);
    7489              :         }
    7490       502381 :       if (M2Options_StrictTypeAssignment)
    7491              :         {
    7492       502381 :           BuildRange (M2Range_InitTypesAssignmentCheck (combinedtok, Des, Exp));
    7493              :         }
    7494       502381 :       if (((SymbolTable_GetSType (Des)) != SymbolTable_NulSym) && (! (SymbolTable_IsSet (SymbolTable_GetDType (Des)))))
    7495              :         {
    7496              :           /* Tell code generator to test runtime values of assignment so ensure we
    7497              :             catch overflow and underflow.  */
    7498       492723 :           BuildRange (M2Range_InitAssignmentRangeCheck (combinedtok, Des, Exp, destok, exptok));
    7499              :         }
    7500       502375 :       if (checkTypes)
    7501              :         {
    7502       430324 :           CheckBecomesMeta (Des, Exp, combinedtok, destok, exptok);
    7503              :         }
    7504              :       /* Simple assignment.  */
    7505       502375 :       MoveWithMode (combinedtok, Des, Exp, Array, destok, exptok, checkOverflow);
    7506       502375 :       if (checkTypes)
    7507              :         {
    7508       430324 :           CheckAssignCompatible (Des, Exp, combinedtok, destok, exptok);
    7509              :         }
    7510              :     }
    7511       512419 :   M2Quads_DisplayStack ();
    7512       512419 : }
    7513              : 
    7514              : 
    7515              : /*
    7516              :    CheckAssignCompatible - checks to see that an assignment is compatible.
    7517              :                            It performs limited checking - thorough checking
    7518              :                            is done in pass 3.  But we do what we can here
    7519              :                            given knowledge so far.
    7520              : */
    7521              : 
    7522       430324 : static void CheckAssignCompatible (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok)
    7523              : {
    7524       430324 :   unsigned int DesT;
    7525       430324 :   unsigned int ExpT;
    7526       430324 :   unsigned int DesL;
    7527              : 
    7528       430324 :   DesT = SymbolTable_GetSType (Des);
    7529       430324 :   ExpT = SymbolTable_GetSType (Exp);
    7530       430324 :   DesL = SymbolTable_GetLType (Des);
    7531       430324 :   if (((SymbolTable_IsProcedure (Exp)) && ((DesT != SymbolTable_NulSym) && (! (SymbolTable_IsProcType (DesT))))) && ((DesL != SymbolTable_NulSym) && (! (SymbolTable_IsProcType (DesL)))))
    7532              :     {
    7533            0 :       M2MetaError_MetaErrorT1 (destok, (const char *) "incorrectly assigning a procedure to a designator {%1Ead} (designator is not a procedure type, {%1ast})", 103, Des);
    7534              :     }
    7535              :   /* We ignore checking of these types in pass 3 - but we do check them thoroughly post pass 3  */
    7536       430324 :   else if ((SymbolTable_IsProcedure (Exp)) && (SymbolTable_IsProcedureNested (Exp)))
    7537              :     {
    7538              :       /* avoid dangling else.  */
    7539            6 :       M2MetaError_MetaErrorT1 (exprtok, (const char *) "cannot call nested procedure {%1Ead} indirectly as the outer scope will not be known", 84, Exp);
    7540              :     }
    7541       430318 :   else if (SymbolTable_IsConstString (Exp))
    7542              :     {
    7543              :       /* avoid dangling else.  */
    7544              :     }
    7545       427226 :   else if ((DesT != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (DesT)))
    7546              :     {
    7547              :       /* avoid dangling else.  */
    7548              :     }
    7549       427226 :   else if ((ExpT != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (ExpT)))
    7550              :     {
    7551              :       /* avoid dangling else.  */
    7552              :     }
    7553       427226 :   else if ((DesL != SymbolTable_NulSym) && (SymbolTable_IsArray (DesL)))
    7554              :     {
    7555              :       /* avoid dangling else.  */
    7556              :     }
    7557       426378 :   else if (SymbolTable_IsConstructor (Exp))
    7558              :     {
    7559              :       /* avoid dangling else.  */
    7560         6426 :       if (ExpT == SymbolTable_NulSym)
    7561              :         {}  /* empty.  */
    7562         6386 :       else if (((DesT == SymbolTable_NulSym) && (SymbolTable_IsConst (Des))) && ((SymbolTable_IsConstructor (Des)) || (SymbolTable_IsConstSet (Des))))
    7563              :         {
    7564              :           /* avoid dangling else.  */
    7565            0 :           SymbolTable_PutConst (Des, ExpT);
    7566              :         }
    7567         6386 :       else if (! (M2Base_IsAssignmentCompatible (DesT, ExpT)))
    7568              :         {
    7569              :           /* avoid dangling else.  */
    7570            0 :           M2MetaError_MetaErrorT1 (combinedtok, (const char *) "constructor expression is not compatible during assignment to {%1Ead}", 69, Des);
    7571              :         }
    7572              :     }
    7573       419952 :   else if (((DesT != SymbolTable_NulSym) && (SymbolTable_IsSet (DesT))) && (SymbolTable_IsConst (Exp)))
    7574              :     {
    7575              :       /* avoid dangling else.  */
    7576              :     }
    7577       419822 :   else if ((((((SymbolTable_IsConst (Exp)) && (ExpT != M2System_Address)) && (! (SymbolTable_IsConst (Des)))) && (DesL != SymbolTable_NulSym)) && ((DesL == M2Base_Cardinal) || (! (SymbolTable_IsSubrange (DesL))))) && (! (SymbolTable_IsEnumeration (DesL))))
    7578              :     {
    7579              :       /* avoid dangling else.  */
    7580        25001 :       if ((M2Base_IsBaseType (DesL)) || (M2System_IsSystemType (DesL)))
    7581              :         {
    7582        25001 :           M2Base_CheckAssignmentCompatible (combinedtok, ExpT, DesT);
    7583              :         }
    7584              :       else
    7585              :         {
    7586            0 :           M2MetaError_MetaErrorT2 (combinedtok, (const char *) "assignment of a constant {%1Ead} can only be made to a variable whose type is equivalent to a Modula-2 base type {%2tsa}", 120, Exp, Des);
    7587              :         }
    7588              :     }
    7589              :   else
    7590              :     {
    7591              :       /* avoid dangling else.  */
    7592       394821 :       if (((DesT != SymbolTable_NulSym) && (SymbolTable_IsProcType (DesT))) && (SymbolTable_IsProcedure (Exp)))
    7593              :         {
    7594        32562 :           DesT = SymbolTable_GetSType (DesT);  /* we can at least check RETURN values of procedure variables  */
    7595              :           /* remember that thorough assignment checking is done post pass 3  */
    7596        32562 :           M2Base_CheckAssignmentCompatible (combinedtok, ExpT, DesT);
    7597              :         }
    7598              :     }
    7599       430324 : }
    7600              : 
    7601              : 
    7602              : /*
    7603              :    CheckBooleanId - Checks to see if the top operand is a boolean.
    7604              :                     If the operand is not a boolean then it is tested
    7605              :                     with true and a boolean is generated.
    7606              :                     The Stack:
    7607              : 
    7608              : 
    7609              :                     Entry                     Exit
    7610              :              Ptr ->                                          <- Ptr
    7611              :                     +------------+            +------------+
    7612              :                     | Sym        |            | t   | f    |
    7613              :                     |------------|            |------------|
    7614              : 
    7615              :                      Quadruples
    7616              : 
    7617              :                      q   If=      Sym   True   _
    7618              :                      q+1 GotoOp   _     _      _
    7619              : */
    7620              : 
    7621        86312 : static void CheckBooleanId (void)
    7622              : {
    7623        86312 :   unsigned int tok;
    7624              : 
    7625        86312 :   if (! (IsBoolean (1)))
    7626              :     {
    7627        18063 :       tok = static_cast<unsigned int> (M2Quads_OperandTok (1));
    7628        18063 :       if (SymbolTable_IsVar (M2Quads_OperandT (1)))
    7629              :         {
    7630        14439 :           if ((SymbolTable_GetSType (M2Quads_OperandT (1))) != M2Base_Boolean)
    7631              :             {
    7632            0 :               M2MetaError_MetaError1 ((const char *) "{%1Ua:is not a boolean expression}{!%1Ua:boolean expression expected}", 69, M2Quads_OperandT (1));
    7633              :             }
    7634              :         }
    7635        18063 :       M2Quads_PushT (M2Reserved_EqualTok);
    7636        18063 :       M2Quads_PushT (M2Base_True);
    7637        18063 :       M2Quads_BuildRelOp (tok);
    7638              :     }
    7639        86312 : }
    7640              : 
    7641              : 
    7642              : /*
    7643              :    PushOne - pushes the value one to the stack.
    7644              :              The Stack is changed:
    7645              : 
    7646              : 
    7647              :                     Entry                   Exit
    7648              :                     =====                   ====
    7649              : 
    7650              :                                                             <- Ptr
    7651              :                                             +------------+
    7652              :              Ptr ->                         | 1 | type   |
    7653              :                                             |------------|
    7654              : */
    7655              : 
    7656        16432 : static void PushOne (unsigned int tok, unsigned int type, const char *message_, unsigned int _message_high)
    7657              : {
    7658        16432 :   unsigned int const_;
    7659        16432 :   char message[_message_high+1];
    7660              : 
    7661              :   /* make a local copy of each unbounded array.  */
    7662        16432 :   memcpy (message, message_, _message_high+1);
    7663              : 
    7664        16432 :   if (type == SymbolTable_NulSym)
    7665              :     {
    7666          220 :       const_ = SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), SymbolTable_NulSym);
    7667          220 :       SymbolTable_PutConstLitInternal (const_, true);
    7668          220 :       M2Quads_PushTFtok (const_, static_cast<unsigned int> (SymbolTable_NulSym), tok);
    7669              :     }
    7670        16212 :   else if (SymbolTable_IsEnumeration (type))
    7671              :     {
    7672              :       /* avoid dangling else.  */
    7673          238 :       if ((SymbolTable_NoOfElements (type)) == 0)
    7674              :         {
    7675            0 :           M2MetaError_MetaErrorString1 (DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "enumeration type only has one element {%1Dad} and therefore ", 60), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) message, _message_high))), type);
    7676            0 :           PushZero (tok, type);
    7677              :         }
    7678              :       else
    7679              :         {
    7680          238 :           M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
    7681          238 :           M2Quads_PushT (type);
    7682          238 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_ZType), M2Base_ZType, tok);
    7683          238 :           M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
    7684          238 :           BuildConvertFunction (M2Base_Convert, true);  /* Two parameters  */
    7685              :         }
    7686              :     }
    7687              :   else
    7688              :     {
    7689              :       /* avoid dangling else.  */
    7690        15974 :       const_ = SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), type);
    7691        15974 :       SymbolTable_PutConstLitInternal (const_, true);
    7692        15974 :       M2Quads_PushTFtok (const_, type, tok);
    7693              :     }
    7694        16432 : }
    7695              : 
    7696              : 
    7697              : /*
    7698              :    PushZero - pushes the value zero to the stack.
    7699              :               The Stack is changed:
    7700              : 
    7701              : 
    7702              :                     Entry                   Exit
    7703              :                     =====                   ====
    7704              : 
    7705              :                                                             <- Ptr
    7706              :                                             +------------+
    7707              :              Ptr ->                         | 0 | type   |
    7708              :                                             |------------|
    7709              : */
    7710              : 
    7711         8098 : static void PushZero (unsigned int tok, unsigned int type)
    7712              : {
    7713         8098 :   if (type == SymbolTable_NulSym)
    7714              :     {
    7715          424 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym), static_cast<unsigned int> (SymbolTable_NulSym), tok);
    7716              :     }
    7717         7674 :   else if (SymbolTable_IsEnumeration (type))
    7718              :     {
    7719              :       /* avoid dangling else.  */
    7720          196 :       M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
    7721          196 :       M2Quads_PushTtok (type, tok);
    7722          196 :       M2Quads_PushTtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType), tok);
    7723          196 :       M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
    7724          196 :       BuildConvertFunction (M2Base_Convert, true);  /* Two parameters  */
    7725              :     }
    7726              :   else
    7727              :     {
    7728              :       /* avoid dangling else.  */
    7729         7478 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), type), type, tok);
    7730              :     }
    7731         8098 : }
    7732              : 
    7733              : 
    7734              : /*
    7735              :    ForLoopLastIterator - calculate the last iterator value but avoid setting
    7736              :                          LastIterator twice if it is a constant (in the quads).
    7737              :                          In the ForLoopLastIteratorVariable case only one
    7738              :                          path will be chosen but at the time of quadruple
    7739              :                          generation we do not know the value of BySym.
    7740              : */
    7741              : 
    7742         2604 : static void ForLoopLastIterator (unsigned int LastIterator, unsigned int e1, unsigned int e2, unsigned int BySym, unsigned int e1tok, unsigned int e2tok, unsigned int bytok)
    7743              : {
    7744         2604 :   if (! (SymbolTable_IsConst (BySym)))
    7745              :     {
    7746           18 :       M2MetaError_MetaErrorT1 (bytok, (const char *) "{%E}the {%kFOR} loop {%kBY} expression must be constant, the expression {%1a} is variable", 89, BySym);
    7747           18 :       M2MetaError_MetaErrorDecl (BySym, true);
    7748              :     }
    7749              :   else
    7750              :     {
    7751         2586 :       e1 = DereferenceLValue (e1tok, e1);
    7752         2586 :       e2 = DereferenceLValue (e2tok, e2);
    7753         2586 :       GenQuadOTypetok (bytok, M2Quads_LastForIteratorOp, LastIterator, SymbolTable_Make2Tuple (e1, e2), BySym, false, false, bytok, M2LexBuf_MakeVirtual2Tok (e1tok, e2tok), bytok);
    7754              :     }
    7755         2604 : }
    7756              : 
    7757              : 
    7758              : /*
    7759              :    BuildSizeCheckEnd - checks to see whether the function "called" was in fact SIZE.
    7760              :                        If so then we restore quadruple generation.
    7761              : */
    7762              : 
    7763        16340 : static void BuildSizeCheckEnd (unsigned int ProcSym)
    7764              : {
    7765        16340 :   if (((ProcSym == M2Size_Size) || (ProcSym == M2System_TSize)) || (ProcSym == M2System_TBitSize))
    7766              :     {
    7767        13362 :       QuadrupleGeneration = true;
    7768        13362 :       BuildingSize = false;
    7769              :     }
    7770         2978 :   else if (ProcSym == M2Base_High)
    7771              :     {
    7772              :       /* avoid dangling else.  */
    7773         2978 :       QuadrupleGeneration = true;
    7774         2978 :       BuildingHigh = false;
    7775              :     }
    7776        16340 : }
    7777              : 
    7778              : 
    7779              : /*
    7780              :    BuildRealProcedureCall - builds a real procedure call.
    7781              :                             The Stack:
    7782              : 
    7783              : 
    7784              :                             Entry                      Exit
    7785              : 
    7786              :                      Ptr ->
    7787              :                             +----------------+
    7788              :                             | NoOfParam      |
    7789              :                             |----------------|
    7790              :                             | Param 1        |
    7791              :                             |----------------|
    7792              :                             | Param 2        |
    7793              :                             |----------------|
    7794              :                             .                .
    7795              :                             .                .
    7796              :                             .                .
    7797              :                             |----------------|
    7798              :                             | Param #        |
    7799              :                             |----------------|
    7800              :                             | ProcSym | Type |         Empty
    7801              :                             |----------------|
    7802              : */
    7803              : 
    7804       158692 : static void BuildRealProcedureCall (unsigned int tokno)
    7805              : {
    7806       158692 :   unsigned int NoOfParam;
    7807       158692 :   unsigned int ProcSym;
    7808              : 
    7809       158692 :   M2Quads_PopT (&NoOfParam);
    7810       158692 :   M2Quads_PushT (NoOfParam);
    7811       158692 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+2));
    7812       158692 :   ProcSym = PCSymBuild_SkipConst (ProcSym);
    7813              :   /* --checkme--  */
    7814       158692 :   if (SymbolTable_IsVar (ProcSym))
    7815              :     {
    7816              :       /* Procedure Variable ?  */
    7817          684 :       ProcSym = SymbolTable_SkipType (M2Quads_OperandF (NoOfParam+2));
    7818              :     }
    7819       158692 :   if ((SymbolTable_IsDefImp (SymbolTable_GetScope (ProcSym))) && (SymbolTable_IsDefinitionForC (SymbolTable_GetScope (ProcSym))))
    7820              :     {
    7821        14726 :       BuildRealFuncProcCall (tokno, false, true, false);
    7822              :     }
    7823              :   else
    7824              :     {
    7825       143966 :       BuildRealFuncProcCall (tokno, false, false, false);
    7826              :     }
    7827       158686 : }
    7828              : 
    7829              : 
    7830              : /*
    7831              :    BuildRealFuncProcCall - builds a real procedure or function call.
    7832              :                            The Stack:
    7833              : 
    7834              : 
    7835              :                             Entry                      Exit
    7836              : 
    7837              :                      Ptr ->
    7838              :                             +----------------+
    7839              :                             | NoOfParam      |
    7840              :                             |----------------|
    7841              :                             | Param 1        |
    7842              :                             |----------------|
    7843              :                             | Param 2        |
    7844              :                             |----------------|
    7845              :                             .                .
    7846              :                             .                .
    7847              :                             .                .
    7848              :                             |----------------|
    7849              :                             | Param #        |
    7850              :                             |----------------|
    7851              :                             | ProcSym | Type |         Empty
    7852              :                             |----------------|
    7853              : */
    7854              : 
    7855       220640 : static void BuildRealFuncProcCall (unsigned int tokno, bool IsFunc, bool IsForC, bool ConstExpr)
    7856              : {
    7857       220640 :   bool AllocateProc;
    7858       220640 :   bool DeallocateProc;
    7859       220640 :   bool ForcedFunc;
    7860       220640 :   bool ParamConstant;
    7861       220640 :   unsigned int trash;
    7862       220640 :   unsigned int resulttok;
    7863       220640 :   unsigned int paramtok;
    7864       220640 :   unsigned int proctok;
    7865       220640 :   unsigned int NoOfParameters;
    7866       220640 :   unsigned int i;
    7867       220640 :   unsigned int pi;
    7868       220640 :   unsigned int ParamType;
    7869       220640 :   unsigned int Param1;
    7870       220640 :   unsigned int ReturnVar;
    7871       220640 :   unsigned int ProcSym;
    7872       220640 :   unsigned int Proc;
    7873              : 
    7874       220640 :   Param1 = SymbolTable_NulSym;  /* Used to remember first param for allocate/deallocate.  */
    7875       220640 :   ParamType = SymbolTable_NulSym;
    7876       220640 :   CheckProcedureParameters (IsForC);
    7877       220622 :   M2Quads_PopT (&NoOfParameters);
    7878       220622 :   M2Quads_PushT (NoOfParameters);  /* Restore stack to original state.  */
    7879       220622 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+2));  /* Restore stack to original state.  */
    7880       220622 :   proctok = tokno;  /* OperandTtok (NoOfParameters+2) ;  */
    7881       220622 :   if (proctok == M2LexBuf_UnknownTokenNo)  /* OperandTtok (NoOfParameters+2) ;  */
    7882              :     {
    7883            0 :       proctok = M2LexBuf_GetTokenNo ();
    7884              :     }
    7885       220622 :   paramtok = proctok;
    7886       220622 :   ProcSym = PCSymBuild_SkipConst (ProcSym);
    7887       220622 :   ForcedFunc = false;
    7888       220622 :   AllocateProc = false;
    7889       220622 :   DeallocateProc = false;
    7890       220622 :   if (SymbolTable_IsVar (ProcSym))
    7891              :     {
    7892              :       /* Procedure Variable ?  */
    7893          772 :       Proc = SymbolTable_SkipType (M2Quads_OperandF (NoOfParameters+2));
    7894          772 :       ParamConstant = false;
    7895              :     }
    7896              :   else
    7897              :     {
    7898       219850 :       Proc = ProcSym;
    7899       219850 :       ParamConstant = true;
    7900       219850 :       AllocateProc = (SymbolTable_GetSymName (Proc)) == (NameKey_MakeKey ((const char *) "ALLOCATE", 8));
    7901       219850 :       DeallocateProc = (SymbolTable_GetSymName (Proc)) == (NameKey_MakeKey ((const char *) "DEALLOCATE", 10));
    7902              :     }
    7903       220622 :   if (IsFunc)
    7904              :     {
    7905              :       /* avoid dangling else.  */
    7906        61936 :       if ((SymbolTable_GetSType (Proc)) == SymbolTable_NulSym)
    7907              :         {
    7908            0 :           M2MetaError_MetaErrors1 ((const char *) "procedure {%1a} cannot be used as a function", 44, (const char *) "procedure {%1Da} does not have a return type", 44, Proc);
    7909              :         }
    7910              :     }
    7911              :   else
    7912              :     {
    7913              :       /* is being called as a procedure  */
    7914       158686 :       if ((SymbolTable_GetSType (Proc)) != SymbolTable_NulSym)
    7915              :         {
    7916              :           /* however it was declared as a procedure function  */
    7917         9069 :           if (! (SymbolTable_IsReturnOptionalAny (Proc)))
    7918              :             {
    7919            6 :               M2MetaError_MetaErrors1 ((const char *) "function {%1a} is being called but its return value is ignored", 62, (const char *) "function {%1Da} return a type {%1ta:of {%1ta}}", 46, Proc);
    7920              :             }
    7921              :           IsFunc = true;
    7922              :           ForcedFunc = true;
    7923              :         }
    7924              :     }
    7925       220622 :   if (AllocateProc || DeallocateProc)
    7926              :     {
    7927         1830 :       Param1 = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+1));  /* Remember this before manipulating.  */
    7928              :     }
    7929       220622 :   ManipulateParameters (IsForC);
    7930       220622 :   CheckParameterOrdinals ();
    7931       220622 :   M2Quads_PopT (&NoOfParameters);
    7932       220622 :   if (IsFunc)
    7933              :     {
    7934        71005 :       GenQuad (M2Quads_ParamOp, 0, Proc, ProcSym);  /* Space for return value  */
    7935              :     }
    7936       220622 :   if (((NoOfParameters+1) == (SymbolTable_NoOfParamAny (Proc))) && (SymbolTable_UsesOptArgAny (Proc)))
    7937              :     {
    7938         3626 :       GenQuad (M2Quads_OptParamOp, SymbolTable_NoOfParamAny (Proc), Proc, Proc);
    7939              :     }
    7940       220622 :   i = NoOfParameters;
    7941       220622 :   pi = 1;  /* stack index referencing stacked parameter, i  */
    7942       768233 :   while (i > 0)  /* stack index referencing stacked parameter, i  */
    7943              :     {
    7944       547611 :       paramtok = OperandTtok (pi);
    7945       547611 :       if (((AllocateProc || DeallocateProc) && (i == 1)) && (Param1 != SymbolTable_NulSym))
    7946              :         {
    7947         1830 :           ParamType = GetItemPointedTo (Param1);
    7948         1830 :           if (ParamType == SymbolTable_NulSym)
    7949              :             {
    7950            0 :               GenQuadO (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true);
    7951              :             }
    7952              :           else
    7953              :             {
    7954         1830 :               if (AllocateProc)
    7955              :                 {
    7956         1282 :                   trash = SymbolTable_MakeTemporary (paramtok, SymbolTable_RightValue);
    7957         1282 :                   SymbolTable_PutVar (trash, ParamType);
    7958         1282 :                   SymbolTable_PutVarHeap (trash, true);
    7959              :                 }
    7960              :               else
    7961              :                 {
    7962          548 :                   M2Debug_Assert (DeallocateProc);
    7963          548 :                   trash = M2Base_Nil;
    7964              :                 }
    7965         1830 :               GenQuadOTrash (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true, trash);
    7966              :             }
    7967              :         }
    7968              :       else
    7969              :         {
    7970       545781 :           GenQuadO (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true);
    7971              :         }
    7972       547611 :       if (! (SymbolTable_IsConst (M2Quads_OperandT (pi))))
    7973              :         {
    7974       462280 :           ParamConstant = false;
    7975              :         }
    7976       547611 :       i -= 1;
    7977       547611 :       pi += 1;
    7978              :     }
    7979       441244 :   GenQuadO (proctok, M2Quads_CallOp, SymbolTable_NulSym, SymbolTable_NulSym, ProcSym, true);
    7980       220622 :   M2Quads_PopN (NoOfParameters+1);  /* Destroy arguments and procedure call  */
    7981       220622 :   if (IsFunc)
    7982              :     {
    7983              :       /* ReturnVar has the type of the procedure.  */
    7984        71005 :       resulttok = M2LexBuf_MakeVirtualTok (proctok, proctok, paramtok);
    7985        71005 :       if (ConstExpr && (! (SymbolTable_IsProcedureBuiltinAvailable (Proc))))
    7986              :         {
    7987            0 :           M2MetaError_MetaError1 ((const char *) "{%1d} {%1ad} cannot be used in a constant expression", 52, Proc);
    7988            0 :           ParamConstant = false;
    7989              :         }
    7990        71005 :       ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (ParamConstant && ConstExpr));
    7991        71005 :       SymbolTable_PutVar (ReturnVar, SymbolTable_GetSType (Proc));
    7992       142010 :       GenQuadO (resulttok, M2Quads_FunctValueOp, ReturnVar, SymbolTable_NulSym, Proc, true);
    7993        71005 :       if (! ForcedFunc)
    7994              :         {
    7995        61936 :           M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (Proc), resulttok);
    7996              :         }
    7997              :     }
    7998       220622 : }
    7999              : 
    8000              : 
    8001              : /*
    8002              :    CheckProcedureParameters - Checks the parameters which are being passed to
    8003              :                               procedure ProcSym.
    8004              : 
    8005              :                               The Stack:
    8006              : 
    8007              : 
    8008              :                               Entry                      Exit
    8009              : 
    8010              :                        Ptr ->                                               <- Ptr
    8011              :                               +----------------+         +----------------+
    8012              :                               | NoOfParam      |         | NoOfParam      |
    8013              :                               |----------------|         |----------------|
    8014              :                               | Param 1        |         | Param 1        |
    8015              :                               |----------------|         |----------------|
    8016              :                               | Param 2        |         | Param 2        |
    8017              :                               |----------------|         |----------------|
    8018              :                               .                .         .                .
    8019              :                               .                .         .                .
    8020              :                               .                .         .                .
    8021              :                               |----------------|         |----------------|
    8022              :                               | Param #        |         | Param #        |
    8023              :                               |----------------|         |----------------|
    8024              :                               | ProcSym | Type |         | ProcSym | Type |
    8025              :                               |----------------|         |----------------|
    8026              : 
    8027              : */
    8028              : 
    8029       220640 : static void CheckProcedureParameters (bool IsForC)
    8030              : {
    8031       220640 :   unsigned int proctok;
    8032       220640 :   unsigned int paramtok;
    8033       220640 :   NameKey_Name n1;
    8034       220640 :   NameKey_Name n2;
    8035       220640 :   unsigned int ParamCheckId;
    8036       220640 :   unsigned int Dim;
    8037       220640 :   unsigned int Actual;
    8038       220640 :   unsigned int FormalI;
    8039       220640 :   unsigned int ParamTotal;
    8040       220640 :   unsigned int pi;
    8041       220640 :   unsigned int Proc;
    8042       220640 :   unsigned int ProcSym;
    8043       220640 :   unsigned int i;
    8044       220640 :   DynamicStrings_String s;
    8045              : 
    8046       220640 :   M2Quads_PopT (&ParamTotal);
    8047       220640 :   M2Quads_PushT (ParamTotal);  /* Restore stack to origional state  */
    8048       220640 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((ParamTotal+1)+1));  /* Restore stack to origional state  */
    8049       220640 :   proctok = OperandTtok ((ParamTotal+1)+1);
    8050       220640 :   if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (SymbolTable_GetDType (ProcSym))))
    8051              :     {
    8052              :       /* Procedure Variable ?  */
    8053          772 :       Proc = SymbolTable_SkipType (M2Quads_OperandF ((ParamTotal+1)+1));
    8054              :     }
    8055              :   else
    8056              :     {
    8057       219868 :       Proc = PCSymBuild_SkipConst (ProcSym);
    8058              :     }
    8059       220640 :   if (! ((SymbolTable_IsProcedure (Proc)) || (SymbolTable_IsProcType (Proc))))
    8060              :     {
    8061              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    8062           12 :       if (SymbolTable_IsUnknown (Proc))
    8063              :         {
    8064              :           /* Spellcheck.  */
    8065            0 :           M2MetaError_MetaError1 ((const char *) "{%1Ua} is not recognised as a procedure, check declaration or import {%1&s}", 75, Proc);
    8066            0 :           SymbolTable_UnknownReported (Proc);
    8067              :         }
    8068              :       else
    8069              :         {
    8070              :           /* --fixme-- filter on Var, Const, Procedure.  */
    8071           12 :           M2MetaError_MetaErrors1 ((const char *) "{%1a} is not recognised as a procedure, check declaration or import {%1&s}", 74, (const char *) "{%1Ua} is not recognised as a procedure, check declaration or import", 68, Proc);
    8072              :         }
    8073              :     }
    8074       220640 :   if (M2Options_CompilerDebugging)
    8075              :     {
    8076            0 :       n1 = SymbolTable_GetSymName (Proc);
    8077            0 :       M2Printf_printf1 ((const char *) "  %a ( ", 7, (const unsigned char *) &n1, (sizeof (n1)-1));
    8078              :     }
    8079       220640 :   if (DebugTokPos)
    8080              :     {
    8081              :       s = DynamicStrings_InitString ((const char *) "procedure", 9);
    8082              :       M2Error_WarnStringAt (s, proctok);
    8083              :     }
    8084       220640 :   i = 1;
    8085       220640 :   pi = ParamTotal+1;  /* stack index referencing stacked parameter, i  */
    8086       765117 :   while (i <= ParamTotal)  /* stack index referencing stacked parameter, i  */
    8087              :     {
    8088       544495 :       if (i <= (SymbolTable_NoOfParamAny (Proc)))
    8089              :         {
    8090              :           /* FormalI := GetParam(Proc, i) ;  */
    8091       539229 :           FormalI = SymbolTable_GetNthParamAnyClosest (Proc, i, SymbolTable_GetCurrentModule ());
    8092       539229 :           if (M2Options_CompilerDebugging)
    8093              :             {
    8094            0 :               n1 = SymbolTable_GetSymName (FormalI);
    8095            0 :               n2 = SymbolTable_GetSymName (SymbolTable_GetSType (FormalI));
    8096            0 :               M2Printf_printf2 ((const char *) "%a: %a", 6, (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
    8097              :             }
    8098       539229 :           Actual = static_cast<unsigned int> (M2Quads_OperandT (pi));
    8099       539229 :           Dim = static_cast<unsigned int> (OperandD (pi));
    8100       539229 :           paramtok = OperandTtok (pi);
    8101       539229 :           if (DebugTokPos)
    8102              :             {
    8103              :               s = DynamicStrings_InitString ((const char *) "actual", 6);
    8104              :               M2Error_WarnStringAt (s, paramtok);
    8105              :             }
    8106       539229 :           ParamCheckId = M2Range_InitTypesParameterCheck (paramtok, Proc, i, FormalI, Actual, 0);
    8107       539229 :           BuildRange (ParamCheckId);
    8108              :           /* Store the ParamCheckId on the quad stack so that any dependant checks
    8109              :             can be cancelled if the type check above detects an error.  */
    8110       539229 :           PutRangeDep (pi, ParamCheckId);
    8111       539229 :           if (SymbolTable_IsConst (Actual))
    8112              :             {
    8113              :               /* avoid dangling else.  */
    8114       120815 :               if (SymbolTable_IsVarParamAny (Proc, i))
    8115              :                 {
    8116            0 :                   FailParameter (paramtok, (const char *) "trying to pass a constant to a VAR parameter", 44, Actual, Proc, i);
    8117              :                 }
    8118       120815 :               else if (SymbolTable_IsConstString (Actual))
    8119              :                 {
    8120              :                   /* avoid dangling else.  */
    8121        39548 :                   if (! (SymbolTable_IsConstStringKnown (Actual)))
    8122              :                     {}  /* empty.  */
    8123        39314 :                   else if ((SymbolTable_IsArray (SymbolTable_GetDType (FormalI))) && ((SymbolTable_GetSType (SymbolTable_GetDType (FormalI))) == M2Base_Char))
    8124              :                     {
    8125              :                       /* avoid dangling else.  */
    8126              :                     }
    8127        39290 :                   else if ((SymbolTable_GetStringLength (paramtok, Actual)) == 1)
    8128              :                     {
    8129              :                       /* avoid dangling else.  */
    8130         5408 :                       CheckParameter (paramtok, Actual, Dim, FormalI, Proc, i, static_cast<Lists_List> (NULL), ParamCheckId);
    8131              :                     }
    8132        33882 :                   else if (! (SymbolTable_IsUnboundedParamAny (Proc, i)))
    8133              :                     {
    8134              :                       /* avoid dangling else.  */
    8135            0 :                       if (IsForC && ((SymbolTable_GetSType (FormalI)) == M2System_Address))
    8136              :                         {
    8137            0 :                           FailParameter (paramtok, (const char *) "a string constant can either be passed to an ADDRESS parameter or an ARRAY OF CHAR", 82, Actual, Proc, i);
    8138              :                         }
    8139              :                       else
    8140              :                         {
    8141            0 :                           FailParameter (paramtok, (const char *) "cannot pass a string constant to a non unbounded array parameter", 64, Actual, Proc, i);
    8142              :                         }
    8143              :                     }
    8144              :                 }
    8145              :             }
    8146              :           else
    8147              :             {
    8148       418414 :               CheckParameter (paramtok, Actual, Dim, FormalI, Proc, i, static_cast<Lists_List> (NULL), ParamCheckId);
    8149              :             }
    8150              :         }
    8151              :       else
    8152              :         {
    8153         5254 :           if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
    8154              :             {
    8155              :               /* these are varargs, therefore we don't check them  */
    8156         5254 :               i = ParamTotal;
    8157              :             }
    8158              :           else
    8159              :             {
    8160            0 :               M2MetaError_MetaErrorT2 (proctok, (const char *) "too many parameters, {%2n} passed to {%1a} ", 43, Proc, i);
    8161              :             }
    8162              :         }
    8163       544477 :       i += 1;
    8164       544477 :       pi -= 1;
    8165       544477 :       if (M2Options_CompilerDebugging)
    8166              :         {
    8167              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    8168            0 :           if (i <= ParamTotal)
    8169              :             {
    8170            0 :               M2Printf_printf0 ((const char *) "; ", 2);
    8171              :             }
    8172              :           else
    8173              :             {
    8174            0 :               M2Printf_printf0 ((const char *) " ) ; \\n", 7);
    8175              :             }
    8176              :         }
    8177              :     }
    8178       220622 : }
    8179              : 
    8180              : 
    8181              : /*
    8182              :    CheckProcTypeAndProcedure - checks the ProcType with the call.
    8183              : */
    8184              : 
    8185        49261 : static void CheckProcTypeAndProcedure (unsigned int tokno, unsigned int ProcType, unsigned int call, unsigned int ParamCheckId)
    8186              : {
    8187        49261 :   NameKey_Name n1;
    8188        49261 :   NameKey_Name n2;
    8189        49261 :   unsigned int i;
    8190        49261 :   unsigned int n;
    8191        49261 :   unsigned int t;
    8192        49261 :   unsigned int CheckedProcedure;
    8193        49261 :   M2Error_Error e;
    8194              : 
    8195        49261 :   if (((SymbolTable_IsVar (call)) || (SymbolTable_IsTemporary (call))) || (SymbolTable_IsParameter (call)))
    8196              :     {
    8197          592 :       CheckedProcedure = SymbolTable_GetDType (call);
    8198              :     }
    8199              :   else
    8200              :     {
    8201              :       CheckedProcedure = call;
    8202              :     }
    8203        49261 :   if (ProcType != CheckedProcedure)
    8204              :     {
    8205        48739 :       n = SymbolTable_NoOfParamAny (ProcType);
    8206              :       /* We need to check the formal parameters between the procedure and proc type.  */
    8207        48739 :       if (n != (SymbolTable_NoOfParamAny (CheckedProcedure)))
    8208              :         {
    8209            0 :           e = M2Error_NewError (SymbolTable_GetDeclaredMod (ProcType));
    8210            0 :           n1 = SymbolTable_GetSymName (call);
    8211            0 :           n2 = SymbolTable_GetSymName (ProcType);
    8212            0 :           M2Error_ErrorFormat2 (e, (const char *) "procedure (%a) is a parameter being passed as variable (%a) but they are declared with different number of parameters", 117, (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
    8213            0 :           e = M2Error_ChainError (SymbolTable_GetDeclaredMod (call), e);
    8214            0 :           t = SymbolTable_NoOfParamAny (CheckedProcedure);
    8215            0 :           if (n < 2)
    8216              :             {
    8217            0 :               M2Error_ErrorFormat3 (e, (const char *) "procedure (%a) is being called incorrectly with (%d) parameter, declared with (%d)", 82, (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n, (sizeof (n)-1), (const unsigned char *) &t, (sizeof (t)-1));
    8218              :             }
    8219              :           else
    8220              :             {
    8221            0 :               M2Error_ErrorFormat3 (e, (const char *) "procedure (%a) is being called incorrectly with (%d) parameters, declared with (%d)", 83, (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n, (sizeof (n)-1), (const unsigned char *) &t, (sizeof (t)-1));
    8222              :             }
    8223              :         }
    8224              :       else
    8225              :         {
    8226              :           i = 1;
    8227       145247 :           while (i <= n)
    8228              :             {
    8229        96508 :               if ((SymbolTable_IsVarParamAny (ProcType, i)) != (SymbolTable_IsVarParamAny (CheckedProcedure, i)))
    8230              :                 {
    8231            0 :                   M2MetaError_MetaError3 ((const char *) "parameter {%3n} in {%1dD} causes a mismatch it was declared as a {%2dv}", 71, ProcType, SymbolTable_GetNth (ProcType, i), i);
    8232            0 :                   M2MetaError_MetaError3 ((const char *) "parameter {%3n} in {%1dD} causes a mismatch it was declared as a {%2dv}", 71, call, SymbolTable_GetNth (call, i), i);
    8233              :                 }
    8234        96508 :               BuildRange (M2Range_InitTypesParameterCheck (tokno, CheckedProcedure, i, SymbolTable_GetNthParamAnyClosest (CheckedProcedure, i, SymbolTable_GetCurrentModule ()), SymbolTable_GetParam (ProcType, i), ParamCheckId));
    8235        96508 :               i += 1;
    8236              :             }
    8237              :         }
    8238              :     }
    8239        49261 : }
    8240              : 
    8241              : 
    8242              : /*
    8243              :    IsReallyPointer - returns TRUE is sym is a pointer, address or a type declared
    8244              :                      as a pointer or address.
    8245              : */
    8246              : 
    8247         1277 : static bool IsReallyPointer (unsigned int Sym)
    8248              : {
    8249         1277 :   if (SymbolTable_IsVar (Sym))
    8250              :     {
    8251         1276 :       Sym = SymbolTable_GetSType (Sym);
    8252              :     }
    8253         1277 :   Sym = SymbolTable_SkipType (Sym);
    8254         1277 :   return (SymbolTable_IsPointer (Sym)) || (Sym == M2System_Address);
    8255              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8256              :   __builtin_unreachable ();
    8257              : }
    8258              : 
    8259              : 
    8260              : /*
    8261              :    LegalUnboundedParam - returns TRUE if the parameter, Actual, can legitimately be
    8262              :                          passed to ProcSym, i, the, Formal, parameter.
    8263              : */
    8264              : 
    8265         9930 : static bool LegalUnboundedParam (unsigned int tokpos, unsigned int ProcSym, unsigned int i, unsigned int ActualType, unsigned int Actual, unsigned int Dimension, unsigned int Formal)
    8266              : {
    8267         9930 :   unsigned int FormalType;
    8268         9930 :   unsigned int n;
    8269         9930 :   unsigned int m;
    8270              : 
    8271         9930 :   ActualType = SymbolTable_SkipType (ActualType);
    8272         9930 :   FormalType = SymbolTable_GetDType (Formal);
    8273         9930 :   FormalType = SymbolTable_GetSType (FormalType);  /* type of the unbounded ARRAY  */
    8274         9930 :   if (SymbolTable_IsArray (ActualType))  /* type of the unbounded ARRAY  */
    8275              :     {
    8276         6900 :       m = SymbolTable_GetDimension (Formal);
    8277         6900 :       n = 0;
    8278        14046 :       while (SymbolTable_IsArray (ActualType))
    8279              :         {
    8280         7068 :           n += 1;
    8281         7068 :           ActualType = SymbolTable_GetDType (ActualType);
    8282         7068 :           if ((m == n) && (ActualType == FormalType))
    8283              :             {
    8284              :               return true;
    8285              :             }
    8286              :         }
    8287           78 :       if (n == m)
    8288              :         {}  /* empty.  */
    8289              :       else
    8290              :         {
    8291              :           /* now we fall though and test ActualType against FormalType  */
    8292           24 :           if (M2System_IsGenericSystemType (FormalType))
    8293              :             {
    8294              :               return true;
    8295              :             }
    8296              :           else
    8297              :             {
    8298           12 :               FailParameter (tokpos, (const char *) "attempting to pass an array with the incorrect number dimenisons to an unbounded formal parameter of different dimensions", 121, Actual, ProcSym, i);
    8299           12 :               return false;
    8300              :             }
    8301              :         }
    8302              :     }
    8303         3030 :   else if (SymbolTable_IsUnbounded (ActualType))
    8304              :     {
    8305              :       /* avoid dangling else.  */
    8306           36 :       if ((Dimension == 0) && ((SymbolTable_GetDimension (Formal)) == (SymbolTable_GetDimension (Actual))))
    8307              :         {
    8308              :           /* now we fall though and test ActualType against FormalType  */
    8309            0 :           ActualType = SymbolTable_GetSType (ActualType);
    8310              :         }
    8311              :       else
    8312              :         {
    8313           36 :           if (M2System_IsGenericSystemType (FormalType))
    8314              :             {
    8315              :               return true;
    8316              :             }
    8317              :           else
    8318              :             {
    8319           12 :               if (((SymbolTable_GetDimension (Actual))-Dimension) == (SymbolTable_GetDimension (Formal)))
    8320              :                 {
    8321           12 :                   ActualType = SymbolTable_GetSType (ActualType);
    8322              :                 }
    8323              :               else
    8324              :                 {
    8325            0 :                   FailParameter (tokpos, (const char *) "attempting to pass an unbounded array with the incorrect number dimenisons to an unbounded formal parameter of different dimensions", 131, Actual, ProcSym, i);
    8326            0 :                   return false;
    8327              :                 }
    8328              :             }
    8329              :         }
    8330              :     }
    8331         3060 :   if (((M2System_IsGenericSystemType (FormalType)) || (M2System_IsGenericSystemType (ActualType))) || (M2Base_IsAssignmentCompatible (FormalType, ActualType)))
    8332              :     {
    8333              :       /* we think it is legal, but we ask post pass 3 to check as
    8334              :          not all types are known at this point  */
    8335         3054 :       return true;
    8336              :     }
    8337              :   else
    8338              :     {
    8339            6 :       FailParameter (tokpos, (const char *) "identifier with an incompatible type is being passed to this procedure", 70, Actual, ProcSym, i);
    8340            6 :       return false;
    8341              :     }
    8342              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8343              :   __builtin_unreachable ();
    8344              : }
    8345              : 
    8346              : 
    8347              : /*
    8348              :    CheckParameter - checks that types ActualType and FormalType are compatible for parameter
    8349              :                     passing. ProcSym is the procedure and i is the parameter number.
    8350              : 
    8351              :                     We obey the following rules:
    8352              : 
    8353              :                     (1)  we allow WORD, BYTE, LOC to be compitable with any like sized
    8354              :                          type.
    8355              :                     (2)  we allow ADDRESS to be compatible with any pointer type.
    8356              :                     (3)  we relax INTEGER and CARDINAL checking for Temporary variables.
    8357              : 
    8358              :                     Note that type sizes are checked during the code generation pass.
    8359              : */
    8360              : 
    8361       423822 : static void CheckParameter (unsigned int tokpos, unsigned int Actual, unsigned int Dimension, unsigned int Formal, unsigned int ProcSym, unsigned int i, Lists_List TypeList, unsigned int ParamCheckId)
    8362              : {
    8363       423822 :   bool NewList;
    8364       423822 :   unsigned int ActualType;
    8365       423822 :   unsigned int FormalType;
    8366              : 
    8367       423822 :   if ((SymbolTable_IsConstString (Actual)) && (! (SymbolTable_IsConstStringKnown (Actual))))
    8368              :     {
    8369              :       /* Cannot check if the string content is not yet known.  */
    8370              :       return;
    8371              :     }
    8372       423822 :   FormalType = SymbolTable_GetDType (Formal);
    8373       423822 :   if ((SymbolTable_IsConstString (Actual)) && ((SymbolTable_GetStringLength (tokpos, Actual)) == 1))  /* if = 1 then it maybe treated as a char  */
    8374              :     {
    8375         5408 :       ActualType = M2Base_Char;
    8376              :     }
    8377       418414 :   else if (Actual == M2Base_Boolean)
    8378              :     {
    8379              :       /* avoid dangling else.  */
    8380              :       ActualType = Actual;
    8381              :     }
    8382              :   else
    8383              :     {
    8384              :       /* avoid dangling else.  */
    8385       418414 :       ActualType = SymbolTable_GetDType (Actual);
    8386              :     }
    8387       423816 :   if (TypeList == NULL)
    8388              :     {
    8389       423816 :       NewList = true;
    8390       423816 :       Lists_InitList (&TypeList);
    8391              :     }
    8392              :   else
    8393              :     {
    8394              :       NewList = false;
    8395              :     }
    8396       423816 :   if (Lists_IsItemInList (TypeList, ActualType))
    8397              :     {
    8398              :       /* no need to check  */
    8399              :       return;
    8400              :     }
    8401       423816 :   Lists_IncludeItemIntoList (TypeList, ActualType);
    8402       423816 :   if (SymbolTable_IsProcType (FormalType))
    8403              :     {
    8404        49261 :       if ((! (SymbolTable_IsProcedure (Actual))) && ((ActualType == SymbolTable_NulSym) || (! (SymbolTable_IsProcType (SymbolTable_SkipType (ActualType))))))
    8405              :         {
    8406            0 :           FailParameter (tokpos, (const char *) "expecting a procedure or procedure variable as a parameter", 58, Actual, ProcSym, i);
    8407            0 :           return;
    8408              :         }
    8409        49261 :       if ((SymbolTable_IsProcedure (Actual)) && (SymbolTable_IsProcedureNested (Actual)))
    8410              :         {
    8411            6 :           M2MetaError_MetaError2 ((const char *) "cannot pass a nested procedure {%1Ea} seen in the {%2N} parameter as the outer scope will be unknown at runtime", 111, Actual, i);
    8412              :         }
    8413              :       /* we can check the return type of both proc types  */
    8414        49261 :       if ((ActualType != SymbolTable_NulSym) && (SymbolTable_IsProcType (ActualType)))
    8415              :         {
    8416              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    8417          592 :           if (((SymbolTable_GetSType (ActualType)) != SymbolTable_NulSym) && ((SymbolTable_GetSType (FormalType)) == SymbolTable_NulSym))
    8418              :             {
    8419            0 :               FailParameter (tokpos, (const char *) "the item being passed is a function whereas the formal procedure parameter is a procedure", 89, Actual, ProcSym, i);
    8420            0 :               return;
    8421              :             }
    8422          592 :           else if (((SymbolTable_GetSType (ActualType)) == SymbolTable_NulSym) && ((SymbolTable_GetSType (FormalType)) != SymbolTable_NulSym))
    8423              :             {
    8424              :               /* avoid dangling else.  */
    8425            0 :               FailParameter (tokpos, (const char *) "the item being passed is a procedure whereas the formal procedure parameter is a function", 89, Actual, ProcSym, i);
    8426            0 :               return;
    8427              :             }
    8428          592 :           else if (M2Base_AssignmentRequiresWarning (SymbolTable_GetSType (ActualType), SymbolTable_GetSType (FormalType)))
    8429              :             {
    8430              :               /* avoid dangling else.  */
    8431            0 :               WarnParameter (tokpos, (const char *) "the return result of the procedure variable parameter may not be compatible on other targets with the return result of the item being passed", 140, Actual, ProcSym, i);
    8432            0 :               return;
    8433              :             }
    8434          592 :           else if (((M2System_IsGenericSystemType (SymbolTable_GetSType (FormalType))) || (M2System_IsGenericSystemType (SymbolTable_GetSType (ActualType)))) || (M2Base_IsAssignmentCompatible (SymbolTable_GetSType (ActualType), SymbolTable_GetSType (FormalType))))
    8435              :             {
    8436              :               /* avoid dangling else.  */
    8437              :             }
    8438              :           else
    8439              :             {
    8440              :               /* avoid dangling else.  */
    8441              :               /* pass  */
    8442            0 :               FailParameter (tokpos, (const char *) "the return result of the procedure variable parameter is not compatible with the return result of the item being passed", 119, Actual, ProcSym, i);
    8443            0 :               return;
    8444              :             }
    8445              :         }
    8446              :       /* now to check each parameter of the proc type  */
    8447        49261 :       CheckProcTypeAndProcedure (tokpos, FormalType, Actual, ParamCheckId);
    8448              :     }
    8449       374555 :   else if ((ActualType != FormalType) && (ActualType != SymbolTable_NulSym))
    8450              :     {
    8451              :       /* avoid dangling else.  */
    8452        17880 :       if (SymbolTable_IsUnknown (FormalType))
    8453              :         {
    8454              :           /* Spellcheck.  */
    8455            0 :           FailParameter (tokpos, (const char *) "procedure parameter type is undeclared {%1&s}", 45, Actual, ProcSym, i);
    8456            0 :           return;
    8457              :         }
    8458        17880 :       if ((SymbolTable_IsUnbounded (ActualType)) && (! (SymbolTable_IsUnboundedParamAny (ProcSym, i))))
    8459              :         {
    8460            0 :           FailParameter (tokpos, (const char *) "attempting to pass an unbounded array to a NON unbounded parameter", 66, Actual, ProcSym, i);
    8461            0 :           return;
    8462              :         }
    8463        17880 :       else if (SymbolTable_IsUnboundedParamAny (ProcSym, i))
    8464              :         {
    8465              :           /* avoid dangling else.  */
    8466         9930 :           if (! (LegalUnboundedParam (tokpos, ProcSym, i, ActualType, Actual, Dimension, Formal)))
    8467              :             {
    8468              :               return;
    8469              :             }
    8470              :         }
    8471         7950 :       else if (ActualType != FormalType)
    8472              :         {
    8473              :           /* avoid dangling else.  */
    8474         7950 :           if (M2Base_AssignmentRequiresWarning (FormalType, ActualType))
    8475              :             {
    8476            0 :               WarnParameter (tokpos, (const char *) "identifier being passed to this procedure may contain a possibly incompatible type when compiling for a different target", 120, Actual, ProcSym, i);
    8477              :             }
    8478         7950 :           else if (((M2System_IsGenericSystemType (FormalType)) || (M2System_IsGenericSystemType (ActualType))) || (M2Base_IsAssignmentCompatible (ActualType, FormalType)))
    8479              :             {
    8480              :               /* avoid dangling else.  */
    8481              :             }
    8482              :           else
    8483              :             {
    8484              :               /* avoid dangling else.  */
    8485              :               /* so far we know it is legal, but not all types have been resolved
    8486              :                and so this is checked later on in another pass.  */
    8487           24 :               FailParameter (tokpos, (const char *) "identifier with an incompatible type is being passed to this procedure", 70, Actual, ProcSym, i);
    8488              :             }
    8489              :         }
    8490              :     }
    8491       423798 :   if (NewList)
    8492              :     {
    8493       423798 :       Lists_KillList (&TypeList);
    8494              :     }
    8495              : }
    8496              : 
    8497              : 
    8498              : /*
    8499              :    DescribeType - returns a String describing a symbol, Sym, name and its type.
    8500              : */
    8501              : 
    8502            0 : static DynamicStrings_String DescribeType (unsigned int Sym)
    8503              : {
    8504            0 :   DynamicStrings_String s;
    8505            0 :   DynamicStrings_String s1;
    8506            0 :   DynamicStrings_String s2;
    8507            0 :   unsigned int Low;
    8508            0 :   unsigned int High;
    8509            0 :   unsigned int Subrange;
    8510            0 :   unsigned int Subscript;
    8511            0 :   unsigned int Type;
    8512              : 
    8513            0 :   s = static_cast<DynamicStrings_String> (NULL);
    8514            0 :   if (SymbolTable_IsConstString (Sym))
    8515              :     {
    8516              :       /* If = 1 then it maybe treated as a char.  */
    8517            0 :       if ((SymbolTable_IsConstStringKnown (Sym)) && ((SymbolTable_GetStringLength (SymbolTable_GetDeclaredMod (Sym), Sym)) == 1))
    8518              :         {
    8519            0 :           s = DynamicStrings_InitString ((const char *) "(constant string) or {%kCHAR}", 29);
    8520              :         }
    8521              :       else
    8522              :         {
    8523            0 :           s = DynamicStrings_InitString ((const char *) "(constant string)", 17);
    8524              :         }
    8525              :     }
    8526            0 :   else if (SymbolTable_IsConst (Sym))
    8527              :     {
    8528              :       /* avoid dangling else.  */
    8529            0 :       s = DynamicStrings_InitString ((const char *) "(constant)", 10);
    8530              :     }
    8531            0 :   else if (SymbolTable_IsUnknown (Sym))
    8532              :     {
    8533              :       /* avoid dangling else.  */
    8534            0 :       s = DynamicStrings_InitString ((const char *) "(unknown)", 9);
    8535              :     }
    8536              :   else
    8537              :     {
    8538              :       /* avoid dangling else.  */
    8539            0 :       Type = SymbolTable_GetSType (Sym);
    8540            0 :       if (Type == SymbolTable_NulSym)
    8541              :         {
    8542            0 :           s = DynamicStrings_InitString ((const char *) "(unknown)", 9);
    8543              :         }
    8544            0 :       else if (SymbolTable_IsUnbounded (Type))
    8545              :         {
    8546              :           /* avoid dangling else.  */
    8547            0 :           s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (SymbolTable_GetSType (Type)))));
    8548            0 :           s = FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "{%%kARRAY} {%%kOF} %s", 21)), (const unsigned char *) &s1, (sizeof (s1)-1));
    8549              :         }
    8550            0 :       else if (SymbolTable_IsArray (Type))
    8551              :         {
    8552              :           /* avoid dangling else.  */
    8553            0 :           s = DynamicStrings_InitString ((const char *) "{%kARRAY} [", 11);
    8554            0 :           Subscript = SymbolTable_GetArraySubscript (Type);
    8555            0 :           if (Subscript != SymbolTable_NulSym)
    8556              :             {
    8557            0 :               M2Debug_Assert (SymbolTable_IsSubscript (Subscript));
    8558            0 :               Subrange = SymbolTable_GetSType (Subscript);
    8559            0 :               if (! (SymbolTable_IsSubrange (Subrange)))
    8560              :                 {
    8561            0 :                   M2MetaError_MetaError3 ((const char *) "error in definition of array {%1Ead} in the {%2N} subscript which has no subrange, instead type given is {%3a}", 110, Sym, Subscript, Subrange);
    8562              :                 }
    8563            0 :               M2Debug_Assert (SymbolTable_IsSubrange (Subrange));
    8564            0 :               SymbolTable_GetSubrange (Subrange, &High, &Low);
    8565            0 :               s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Low))));
    8566            0 :               s2 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (High))));
    8567            0 :               s = DynamicStrings_ConCat (s, DynamicStrings_Mark (FormatStrings_Sprintf2 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "%s..%s", 6)), (const unsigned char *) &s1, (sizeof (s1)-1), (const unsigned char *) &s2, (sizeof (s2)-1))));
    8568              :             }
    8569            0 :           s1 = DynamicStrings_Mark (DescribeType (Type));
    8570            0 :           s = DynamicStrings_ConCat (DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "] OF ", 5))), s1);
    8571              :         }
    8572              :       else
    8573              :         {
    8574              :           /* avoid dangling else.  */
    8575            0 :           if (SymbolTable_IsUnknown (Type))
    8576              :             {
    8577              :               /* Spellcheck.  */
    8578            0 :               s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Type))));
    8579            0 :               s = FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "%s (currently unknown, check declaration or import) {%1&s}", 58)), (const unsigned char *) &s1, (sizeof (s1)-1));
    8580              :             }
    8581              :           else
    8582              :             {
    8583            0 :               s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Type)));
    8584              :             }
    8585              :         }
    8586              :     }
    8587            0 :   return s;
    8588              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8589              :   __builtin_unreachable ();
    8590              : }
    8591              : 
    8592              : 
    8593              : /*
    8594              :    FailParameter - generates an error message indicating that a parameter
    8595              :                    declaration has failed.
    8596              : 
    8597              :                    The parameters are:
    8598              : 
    8599              :                    CurrentState  - string describing the current failing state.
    8600              :                    Actual        - actual parameter.
    8601              :                    ParameterNo   - parameter number that has failed.
    8602              :                    ProcedureSym  - procedure symbol where parameter has failed.
    8603              : 
    8604              :                    If any parameter is Nul then it is ignored.
    8605              : */
    8606              : 
    8607           42 : static void FailParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo)
    8608              : {
    8609           42 :   unsigned int FormalParam;
    8610           42 :   DynamicStrings_String Msg;
    8611           42 :   char CurrentState[_CurrentState_high+1];
    8612              : 
    8613              :   /* make a local copy of each unbounded array.  */
    8614           42 :   memcpy (CurrentState, CurrentState_, _CurrentState_high+1);
    8615              : 
    8616           84 :   Msg = DynamicStrings_InitString ((const char *) "parameter mismatch between the {%2N} parameter of procedure {%1Ead}, ", 69);
    8617           42 :   Msg = DynamicStrings_ConCat (Msg, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) CurrentState, _CurrentState_high)));
    8618           42 :   M2MetaError_MetaErrorStringT2 (tokpos, Msg, ProcedureSym, ParameterNo);
    8619           42 :   if ((SymbolTable_NoOfParamAny (ProcedureSym)) >= ParameterNo)
    8620              :     {
    8621           42 :       FormalParam = SymbolTable_GetNthParamAnyClosest (ProcedureSym, ParameterNo, SymbolTable_GetCurrentModule ());
    8622           42 :       if (SymbolTable_IsUnboundedParamAny (ProcedureSym, ParameterNo))
    8623              :         {
    8624           18 :           M2MetaError_MetaErrorT2 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "formal parameter {%1ad} has an open array type {%2tad}", 54, FormalParam, SymbolTable_GetSType (SymbolTable_GetSType (FormalParam)));
    8625              :         }
    8626              :       else
    8627              :         {
    8628           24 :           M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "formal parameter {%1ad} has type {%1tad}", 40, FormalParam);
    8629              :         }
    8630              :     }
    8631              :   else
    8632              :     {
    8633            0 :       M2MetaError_MetaErrorT1 (SymbolTable_GetDeclaredMod (ProcedureSym), (const char *) "procedure declaration", 21, ProcedureSym);
    8634              :     }
    8635           42 :   if ((SymbolTable_GetLType (Actual)) == SymbolTable_NulSym)
    8636              :     {
    8637            0 :       M2MetaError_MetaError1 ((const char *) "actual parameter being passed is {%1Eda} {%1ad}", 47, Actual);
    8638              :     }
    8639              :   else
    8640              :     {
    8641           42 :       if (SymbolTable_IsVar (Actual))
    8642              :         {
    8643           36 :           M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (Actual), (const char *) "actual parameter variable being passed is {%1Eda} {%1ad} of an incompatible type {%1ts}", 87, Actual);
    8644              :         }
    8645              :       else
    8646              :         {
    8647            6 :           M2MetaError_MetaErrorT1 (tokpos, (const char *) "actual parameter being passed is {%1Eda} {%1ad} of an incompatible type {%1ts}", 78, Actual);
    8648              :         }
    8649              :     }
    8650           42 : }
    8651              : 
    8652              : 
    8653              : /*
    8654              :    WarnParameter - generates a warning message indicating that a parameter
    8655              :                    use might cause problems on another target.
    8656              : 
    8657              :                    CurrentState  - string describing the current failing state.
    8658              :                    Actual        - actual parameter.
    8659              :                    ParameterNo   - parameter number that has failed.
    8660              :                    ProcedureSym  - procedure symbol where parameter has failed.
    8661              : 
    8662              :                    If any parameter is Nul then it is ignored.
    8663              : */
    8664              : 
    8665            0 : static void WarnParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo)
    8666              : {
    8667            0 :   unsigned int FormalParam;
    8668            0 :   DynamicStrings_String Msg;
    8669            0 :   char CurrentState[_CurrentState_high+1];
    8670              : 
    8671              :   /* make a local copy of each unbounded array.  */
    8672            0 :   memcpy (CurrentState, CurrentState_, _CurrentState_high+1);
    8673              : 
    8674            0 :   Msg = DynamicStrings_InitString ((const char *) "{%W}parameter mismatch between the {%2N} parameter of procedure {%1ad}, ", 72);
    8675            0 :   Msg = DynamicStrings_ConCat (Msg, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) CurrentState, _CurrentState_high)));
    8676            0 :   M2MetaError_MetaErrorStringT2 (tokpos, Msg, ProcedureSym, ParameterNo);
    8677            0 :   if ((SymbolTable_NoOfParamAny (ProcedureSym)) >= ParameterNo)
    8678              :     {
    8679            0 :       FormalParam = SymbolTable_GetNthParamAnyClosest (ProcedureSym, ParameterNo, SymbolTable_GetCurrentModule ());
    8680            0 :       if (SymbolTable_IsUnboundedParamAny (ProcedureSym, ParameterNo))
    8681              :         {
    8682            0 :           M2MetaError_MetaErrorT2 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "{%W}formal parameter {%1ad} has an open array type {%2tad}", 58, FormalParam, SymbolTable_GetSType (SymbolTable_GetSType (FormalParam)));
    8683              :         }
    8684              :       else
    8685              :         {
    8686            0 :           M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "{%W}formal parameter {%1ad} has type {%1tad}", 44, FormalParam);
    8687              :         }
    8688              :     }
    8689              :   else
    8690              :     {
    8691            0 :       M2MetaError_MetaErrorT1 (SymbolTable_GetDeclaredMod (ProcedureSym), (const char *) "{%W}procedure declaration", 25, ProcedureSym);
    8692              :     }
    8693            0 :   if ((SymbolTable_GetLType (Actual)) == SymbolTable_NulSym)
    8694              :     {
    8695            0 :       M2MetaError_MetaError1 ((const char *) "actual parameter being passed is {%1Wda} {%1ad}", 47, Actual);
    8696              :     }
    8697              :   else
    8698              :     {
    8699            0 :       if (SymbolTable_IsVar (Actual))
    8700              :         {
    8701            0 :           M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (Actual), (const char *) "actual parameter variable being passed is {%1Wda} {%1ad} of type {%1ts}", 71, Actual);
    8702              :         }
    8703              :       else
    8704              :         {
    8705            0 :           M2MetaError_MetaErrorT1 (tokpos, (const char *) "actual parameter being passed is {%1Wda} {%1ad} of type {%1ts}", 62, Actual);
    8706              :         }
    8707              :     }
    8708            0 : }
    8709              : 
    8710              : 
    8711              : /*
    8712              :    doIndrX - perform des = *exp with a conversion if necessary.
    8713              : */
    8714              : 
    8715        16999 : static void doIndrX (unsigned int tok, unsigned int des, unsigned int exp)
    8716              : {
    8717        16999 :   unsigned int t;
    8718              : 
    8719        16999 :   if ((SymbolTable_GetDType (des)) == (SymbolTable_GetDType (exp)))
    8720              :     {
    8721        16481 :       GenQuadOtok (tok, M2Quads_IndrXOp, des, SymbolTable_GetSType (des), exp, true, tok, tok, tok);
    8722              :     }
    8723              :   else
    8724              :     {
    8725          518 :       if (M2Options_StrictTypeAssignment)
    8726              :         {
    8727          518 :           BuildRange (M2Range_InitTypesIndrXCheck (tok, des, exp));
    8728              :         }
    8729          518 :       t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
    8730          518 :       SymbolTable_PutVar (t, SymbolTable_GetSType (exp));
    8731          518 :       GenQuadOtok (tok, M2Quads_IndrXOp, t, SymbolTable_GetSType (exp), exp, true, tok, tok, tok);
    8732          518 :       GenQuadOtok (tok, M2Quads_BecomesOp, des, SymbolTable_NulSym, doVal (SymbolTable_GetSType (des), t), true, tok, M2LexBuf_UnknownTokenNo, tok);
    8733              :     }
    8734        16999 : }
    8735              : 
    8736              : 
    8737              : /*
    8738              :    MakeRightValue - returns a temporary which will have the RightValue of symbol, Sym.
    8739              :                     If Sym is a right value and has type, type, then no quadruples are
    8740              :                     generated and Sym is returned. Otherwise a new temporary is created
    8741              :                     and an IndrX quadruple is generated.
    8742              : */
    8743              : 
    8744         1520 : static unsigned int MakeRightValue (unsigned int tok, unsigned int Sym, unsigned int type)
    8745              : {
    8746         1520 :   unsigned int t;
    8747              : 
    8748         1520 :   if ((SymbolTable_GetMode (Sym)) == SymbolTable_RightValue)
    8749              :     {
    8750            0 :       if ((SymbolTable_GetSType (Sym)) == type)
    8751              :         {
    8752              :           return Sym;
    8753              :         }
    8754              :       else
    8755              :         {
    8756              :           /* 
    8757              :             type change or mode change, type changes are a pain, but I've
    8758              :             left them here as it is perhaps easier to remove them later.
    8759              :   */
    8760            0 :           t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
    8761            0 :           SymbolTable_PutVar (t, type);
    8762            0 :           GenQuadOtok (tok, M2Quads_BecomesOp, t, SymbolTable_NulSym, doVal (type, Sym), true, tok, tok, tok);
    8763            0 :           return t;
    8764              :         }
    8765              :     }
    8766              :   else
    8767              :     {
    8768         1520 :       t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
    8769         1520 :       SymbolTable_PutVar (t, type);
    8770         1520 :       CheckPointerThroughNil (tok, Sym);
    8771         1520 :       doIndrX (tok, t, Sym);
    8772         1520 :       return t;
    8773              :     }
    8774              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8775              :   __builtin_unreachable ();
    8776              : }
    8777              : 
    8778              : 
    8779              : /*
    8780              :    MakeLeftValue - returns a temporary coresponding to the LeftValue of
    8781              :                    symbol, Sym. No quadruple is generated if Sym is already
    8782              :                    a LeftValue and has the same type.
    8783              : */
    8784              : 
    8785       198312 : static unsigned int MakeLeftValue (unsigned int tok, unsigned int Sym, SymbolTable_ModeOfAddr with, unsigned int type)
    8786              : {
    8787       198312 :   unsigned int t;
    8788              : 
    8789       198312 :   if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
    8790              :     {
    8791         5142 :       if ((SymbolTable_GetSType (Sym)) == type)
    8792              :         {
    8793              :           return Sym;
    8794              :         }
    8795              :       else
    8796              :         {
    8797              :           /* 
    8798              :             type change or mode change, type changes are a pain, but I've
    8799              :             left them here as it is perhaps easier to remove them later
    8800              :   */
    8801          172 :           t = SymbolTable_MakeTemporary (tok, with);
    8802          172 :           SymbolTable_PutVar (t, type);
    8803          172 :           GenQuadOtok (tok, M2Quads_BecomesOp, t, SymbolTable_NulSym, Sym, true, tok, M2LexBuf_UnknownTokenNo, tok);
    8804          172 :           return t;
    8805              :         }
    8806              :     }
    8807              :   else
    8808              :     {
    8809       193170 :       t = SymbolTable_MakeTemporary (tok, with);
    8810       193170 :       SymbolTable_PutVar (t, type);
    8811       193170 :       GenQuadOtok (tok, M2Quads_AddrOp, t, SymbolTable_NulSym, Sym, true, tok, M2LexBuf_UnknownTokenNo, tok);
    8812       193170 :       return t;
    8813              :     }
    8814              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8815              :   __builtin_unreachable ();
    8816              : }
    8817              : 
    8818              : 
    8819              : /*
    8820              :    ManipulatePseudoCallParameters - manipulates the parameters to a pseudo function or
    8821              :                                     procedure. It dereferences all LeftValue parameters
    8822              :                                     and Boolean parameters.
    8823              :                                     The Stack:
    8824              : 
    8825              : 
    8826              :                                     Entry                      Exit
    8827              : 
    8828              :                              Ptr ->                            exactly the same
    8829              :                                     +----------------+
    8830              :                                     | NoOfParameters |
    8831              :                                     |----------------|
    8832              :                                     | Param 1        |
    8833              :                                     |----------------|
    8834              :                                     | Param 2        |
    8835              :                                     |----------------|
    8836              :                                     .                .
    8837              :                                     .                .
    8838              :                                     .                .
    8839              :                                     |----------------|
    8840              :                                     | Param #        |
    8841              :                                     |----------------|
    8842              :                                     | ProcSym | Type |
    8843              :                                     |----------------|
    8844              : 
    8845              : */
    8846              : 
    8847        66875 : static void ManipulatePseudoCallParameters (void)
    8848              : {
    8849        66875 :   unsigned int NoOfParameters;
    8850        66875 :   unsigned int ProcSym;
    8851        66875 :   unsigned int Proc;
    8852        66875 :   unsigned int i;
    8853        66875 :   unsigned int pi;
    8854        66875 :   M2Quads_BoolFrame f;
    8855              : 
    8856        66875 :   M2Quads_PopT (&NoOfParameters);
    8857        66875 :   M2Quads_PushT (NoOfParameters);  /* restored to original state  */
    8858              :   /* Ptr points to the ProcSym  */
    8859        66875 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((NoOfParameters+1)+1));
    8860        66875 :   if (SymbolTable_IsVar (ProcSym))
    8861              :     {
    8862            0 :       M2Error_InternalError ((const char *) "expecting a pseudo procedure or a type", 38);
    8863              :     }
    8864              :   else
    8865              :     {
    8866        66875 :       Proc = ProcSym;
    8867              :     }
    8868        66875 :   i = 1;
    8869        66875 :   pi = NoOfParameters+1;
    8870       146506 :   while (i <= NoOfParameters)
    8871              :     {
    8872        79631 :       if (((((((SymbolTable_GetMode (M2Quads_OperandT (pi))) == SymbolTable_LeftValue) && (Proc != M2System_Adr)) && (Proc != M2Size_Size)) && (Proc != M2System_TSize)) && (Proc != M2Base_High)) && (((((((Proc != M2Base_Inc) && (Proc != M2Base_Incl)) && (Proc != M2Base_Dec)) && (Proc != M2Base_Excl)) && (Proc != M2Base_New)) && (Proc != M2Base_Dispose)) || (i > 1)))
    8873              :         {
    8874              :           /* must dereference LeftValue  */
    8875         1344 :           f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pi));
    8876         1344 :           f->TrueExit = MakeRightValue (M2LexBuf_GetTokenNo (), M2Quads_OperandT (pi), SymbolTable_GetSType (M2Quads_OperandT (pi)));
    8877              :         }
    8878        79631 :       i += 1;
    8879        79631 :       pi -= 1;
    8880              :     }
    8881        66875 : }
    8882              : 
    8883              : 
    8884              : /*
    8885              :    ManipulateParameters - manipulates the procedure parameters in
    8886              :                           preparation for a procedure call.
    8887              :                           Prepares Boolean, Unbounded and VAR parameters.
    8888              :                           The Stack:
    8889              : 
    8890              : 
    8891              :                           Entry                      Exit
    8892              : 
    8893              :                    Ptr ->                            exactly the same
    8894              :                           +----------------+
    8895              :                           | NoOfParameters |
    8896              :                           |----------------|
    8897              :                           | Param 1        |
    8898              :                           |----------------|
    8899              :                           | Param 2        |
    8900              :                           |----------------|
    8901              :                           .                .
    8902              :                           .                .
    8903              :                           .                .
    8904              :                           |----------------|
    8905              :                           | Param #        |
    8906              :                           |----------------|
    8907              :                           | ProcSym | Type |
    8908              :                           |----------------|
    8909              : */
    8910              : 
    8911       220622 : static void ManipulateParameters (bool IsForC)
    8912              : {
    8913       220622 :   unsigned int tokpos;
    8914       220622 :   unsigned int np;
    8915       220622 :   DynamicStrings_String s;
    8916       220622 :   unsigned int ArraySym;
    8917       220622 :   unsigned int UnboundedType;
    8918       220622 :   unsigned int ParamType;
    8919       220622 :   unsigned int NoOfParameters;
    8920       220622 :   unsigned int i;
    8921       220622 :   unsigned int pi;
    8922       220622 :   unsigned int ProcSym;
    8923       220622 :   unsigned int rw;
    8924       220622 :   unsigned int Proc;
    8925       220622 :   unsigned int t;
    8926       220622 :   M2Quads_BoolFrame f;
    8927              : 
    8928       220622 :   M2Quads_PopT (&NoOfParameters);
    8929       220622 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+1));
    8930       220622 :   tokpos = OperandTtok (NoOfParameters+1);
    8931       220622 :   if (SymbolTable_IsVar (ProcSym))
    8932              :     {
    8933              :       /* Procedure Variable ?  */
    8934          772 :       Proc = SymbolTable_SkipType (M2Quads_OperandF (NoOfParameters+1));
    8935              :     }
    8936              :   else
    8937              :     {
    8938       219850 :       Proc = PCSymBuild_SkipConst (ProcSym);
    8939              :     }
    8940       220622 :   if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
    8941              :     {
    8942              :       /* avoid dangling else.  */
    8943         9761 :       if (NoOfParameters < (SymbolTable_NoOfParamAny (Proc)))
    8944              :         {
    8945            0 :           s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
    8946            0 :           np = SymbolTable_NoOfParamAny (Proc);
    8947            0 :           M2Error_ErrorStringAt2 (FormatStrings_Sprintf3 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "attempting to pass (%d) parameters to procedure (%s) which was declared with varargs but contains at least (%d) parameters", 122)), (const unsigned char *) &NoOfParameters, (sizeof (NoOfParameters)-1), (const unsigned char *) &s, (sizeof (s)-1), (const unsigned char *) &np, (sizeof (np)-1)), tokpos, SymbolTable_GetDeclaredMod (ProcSym));
    8948              :         }
    8949              :     }
    8950       210861 :   else if (SymbolTable_UsesOptArgAny (Proc))
    8951              :     {
    8952              :       /* avoid dangling else.  */
    8953         3806 :       if (! ((NoOfParameters == (SymbolTable_NoOfParamAny (Proc))) || ((NoOfParameters+1) == (SymbolTable_NoOfParamAny (Proc)))))
    8954              :         {
    8955            0 :           s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
    8956            0 :           np = SymbolTable_NoOfParamAny (Proc);
    8957            0 :           M2Error_ErrorStringAt2 (FormatStrings_Sprintf3 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "attempting to pass (%d) parameters to procedure (%s) which was declared with an optarg with a maximum of (%d) parameters", 120)), (const unsigned char *) &NoOfParameters, (sizeof (NoOfParameters)-1), (const unsigned char *) &s, (sizeof (s)-1), (const unsigned char *) &np, (sizeof (np)-1)), tokpos, SymbolTable_GetDeclaredMod (ProcSym));
    8958              :         }
    8959              :     }
    8960       207055 :   else if (NoOfParameters != (SymbolTable_NoOfParamAny (Proc)))
    8961              :     {
    8962              :       /* avoid dangling else.  */
    8963            0 :       s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
    8964            0 :       np = SymbolTable_NoOfParamAny (Proc);
    8965            0 :       M2Error_ErrorStringAt2 (FormatStrings_Sprintf3 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "attempting to pass (%d) parameters to procedure (%s) which was declared with (%d) parameters", 92)), (const unsigned char *) &NoOfParameters, (sizeof (NoOfParameters)-1), (const unsigned char *) &s, (sizeof (s)-1), (const unsigned char *) &np, (sizeof (np)-1)), tokpos, SymbolTable_GetDeclaredMod (ProcSym));
    8966              :     }
    8967       220622 :   i = 1;
    8968       220622 :   pi = NoOfParameters;
    8969       768233 :   while (i <= NoOfParameters)
    8970              :     {
    8971       547611 :       f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pi));
    8972       547611 :       rw = static_cast<unsigned int> (OperandMergeRW (pi));
    8973       547611 :       M2Debug_Assert (SymbolTable_IsLegal (rw));
    8974       547611 :       if (i > (SymbolTable_NoOfParamAny (Proc)))
    8975              :         {
    8976         8388 :           if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
    8977              :             {
    8978              :               /* avoid dangling else.  */
    8979         8388 :               if (((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym) && (SymbolTable_IsArray (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
    8980              :                 {
    8981          156 :                   f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_RightValue, M2System_Address);
    8982          156 :                   MarkAsReadWrite (rw);
    8983              :                 }
    8984         8232 :               else if (SymbolTable_IsConstString (M2Quads_OperandT (pi)))
    8985              :                 {
    8986              :                   /* avoid dangling else.  */
    8987          284 :                   f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), DeferMakeConstStringCnul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi)), SymbolTable_RightValue, M2System_Address);
    8988          284 :                   MarkAsReadWrite (rw);
    8989              :                 }
    8990         7948 :               else if (((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (M2Quads_OperandT (pi)))))
    8991              :                 {
    8992              :                   /* avoid dangling else.  */
    8993          200 :                   MarkAsReadWrite (rw);
    8994              :                   /* pass the address field of an unbounded variable  */
    8995          200 :                   M2Quads_PushTFtok (M2System_Adr, M2System_Address, M2Quads_OperandTok (pi));
    8996          200 :                   PushTFAD (f->TrueExit, f->FalseExit, f->Unbounded, f->Dimension);
    8997          200 :                   M2Quads_PushT (static_cast<unsigned int> (1));
    8998          200 :                   BuildAdrFunction ();
    8999          200 :                   M2Quads_PopT (&f->TrueExit);
    9000              :                 }
    9001         7748 :               else if ((SymbolTable_GetMode (M2Quads_OperandT (pi))) == SymbolTable_LeftValue)
    9002              :                 {
    9003              :                   /* avoid dangling else.  */
    9004          464 :                   MarkAsReadWrite (rw);
    9005              :                   /* must dereference LeftValue (even if we are passing variable as a vararg)  */
    9006          464 :                   t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
    9007          464 :                   SymbolTable_PutVar (t, SymbolTable_GetSType (M2Quads_OperandT (pi)));
    9008          464 :                   CheckPointerThroughNil (tokpos, M2Quads_OperandT (pi));
    9009          464 :                   doIndrX (M2Quads_OperandTok (pi), t, M2Quads_OperandT (pi));
    9010          464 :                   f->TrueExit = t;
    9011              :                 }
    9012              :             }
    9013              :           else
    9014              :             {
    9015            0 :               M2MetaError_MetaErrorT2 (tokpos, (const char *) "attempting to pass too many parameters to procedure {%1a}, the {%2N} parameter does not exist", 93, Proc, i);
    9016              :             }
    9017              :         }
    9018       539223 :       else if (((IsForC && (SymbolTable_IsUnboundedParamAny (Proc, i))) && ((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym)) && (SymbolTable_IsArray (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
    9019              :         {
    9020              :           /* avoid dangling else.  */
    9021           24 :           f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_RightValue, M2System_Address);
    9022           24 :           MarkAsReadWrite (rw);
    9023              :         }
    9024       539199 :       else if (((IsForC && (SymbolTable_IsUnboundedParamAny (Proc, i))) && ((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym)) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
    9025              :         {
    9026              :           /* avoid dangling else.  */
    9027          184 :           MarkAsReadWrite (rw);
    9028              :           /* pass the address field of an unbounded variable  */
    9029          184 :           M2Quads_PushTFtok (M2System_Adr, M2System_Address, M2Quads_OperandTok (pi));
    9030          184 :           PushTFAD (f->TrueExit, f->FalseExit, f->Unbounded, f->Dimension);
    9031          184 :           M2Quads_PushT (static_cast<unsigned int> (1));
    9032          184 :           BuildAdrFunction ();
    9033          184 :           M2Quads_PopT (&f->TrueExit);
    9034              :         }
    9035       539015 :       else if ((IsForC && (SymbolTable_IsConstString (M2Quads_OperandT (pi)))) && ((SymbolTable_IsUnboundedParamAny (Proc, i)) || ((SymbolTable_GetDType (SymbolTable_GetParam (Proc, i))) == M2System_Address)))
    9036              :         {
    9037              :           /* avoid dangling else.  */
    9038         9449 :           f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), DeferMakeConstStringCnul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi)), SymbolTable_RightValue, M2System_Address);
    9039         9449 :           MarkAsReadWrite (rw);
    9040              :         }
    9041       529566 :       else if (SymbolTable_IsUnboundedParamAny (Proc, i))
    9042              :         {
    9043              :           /* avoid dangling else.  */
    9044              :           /* always pass constant strings with a nul terminator, but leave the HIGH as before.  */
    9045        40821 :           if (SymbolTable_IsConstString (M2Quads_OperandT (pi)))
    9046              :             {
    9047              :               /* this is a Modula-2 string which must be nul terminated.  */
    9048        26723 :               f->TrueExit = DeferMakeConstStringM2nul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi));
    9049              :             }
    9050        40821 :           t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
    9051        40821 :           UnboundedType = SymbolTable_GetSType (SymbolTable_GetParam (Proc, i));
    9052        40821 :           SymbolTable_PutVar (t, UnboundedType);
    9053        40821 :           ParamType = SymbolTable_GetSType (UnboundedType);
    9054        40821 :           if ((OperandD (pi)) == 0)
    9055              :             {
    9056        40773 :               ArraySym = static_cast<unsigned int> (M2Quads_OperandT (pi));
    9057              :             }
    9058              :           else
    9059              :             {
    9060           48 :               ArraySym = static_cast<unsigned int> (M2Quads_OperandA (pi));
    9061              :             }
    9062        40821 :           if (SymbolTable_IsVarParamAny (Proc, i))
    9063              :             {
    9064         4450 :               MarkArrayWritten (M2Quads_OperandT (pi));
    9065         4450 :               MarkArrayWritten (M2Quads_OperandA (pi));
    9066         4450 :               MarkAsReadWrite (rw);
    9067         4450 :               AssignUnboundedVar (OperandTtok (pi), M2Quads_OperandT (pi), ArraySym, t, ParamType, OperandD (pi));
    9068              :             }
    9069              :           else
    9070              :             {
    9071        36371 :               MarkAsRead (rw);
    9072        36371 :               AssignUnboundedNonVar (OperandTtok (pi), M2Quads_OperandT (pi), ArraySym, t, ParamType, OperandD (pi));
    9073              :             }
    9074        40821 :           f->TrueExit = t;
    9075              :         }
    9076       488745 :       else if (SymbolTable_IsVarParamAny (Proc, i))
    9077              :         {
    9078              :           /* avoid dangling else.  */
    9079              :           /* must reference by address, but we contain the type of the referenced entity  */
    9080        16036 :           MarkArrayWritten (M2Quads_OperandT (pi));
    9081        16036 :           MarkArrayWritten (M2Quads_OperandA (pi));
    9082        16036 :           MarkAsReadWrite (rw);
    9083        16036 :           f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_LeftValue, SymbolTable_GetSType (SymbolTable_GetParam (Proc, i)));
    9084              :         }
    9085       472709 :       else if ((! (SymbolTable_IsVarParamAny (Proc, i))) && ((SymbolTable_GetMode (M2Quads_OperandT (pi))) == SymbolTable_LeftValue))
    9086              :         {
    9087              :           /* avoid dangling else.  */
    9088              :           /* must dereference LeftValue  */
    9089         1514 :           t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
    9090         1514 :           SymbolTable_PutVar (t, SymbolTable_GetSType (M2Quads_OperandT (pi)));
    9091         1514 :           CheckPointerThroughNil (tokpos, M2Quads_OperandT (pi));
    9092         1514 :           doIndrX (M2Quads_OperandTok (pi), t, M2Quads_OperandT (pi));
    9093         1514 :           f->TrueExit = t;
    9094         1514 :           MarkAsRead (rw);
    9095              :         }
    9096              :       else
    9097              :         {
    9098              :           /* avoid dangling else.  */
    9099       471195 :           MarkAsRead (rw);
    9100              :         }
    9101       547611 :       i += 1;
    9102       547611 :       pi -= 1;
    9103              :     }
    9104       220622 :   M2Quads_PushT (NoOfParameters);
    9105       220622 : }
    9106              : 
    9107              : 
    9108              : /*
    9109              :    CheckParameterOrdinals - check that ordinal values are within type range.
    9110              : */
    9111              : 
    9112       220622 : static void CheckParameterOrdinals (void)
    9113              : {
    9114       220622 :   unsigned int tokno;
    9115       220622 :   unsigned int Proc;
    9116       220622 :   unsigned int ProcSym;
    9117       220622 :   unsigned int Actual;
    9118       220622 :   unsigned int FormalI;
    9119       220622 :   unsigned int ParamTotal;
    9120       220622 :   unsigned int pi;
    9121       220622 :   unsigned int i;
    9122              : 
    9123       220622 :   M2Quads_PopT (&ParamTotal);
    9124       220622 :   M2Quads_PushT (ParamTotal);  /* Restore stack to origional state  */
    9125       220622 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((ParamTotal+1)+1));  /* Restore stack to origional state  */
    9126       220622 :   if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (SymbolTable_GetDType (ProcSym))))
    9127              :     {
    9128              :       /* Indirect procedure call.  */
    9129          772 :       Proc = SymbolTable_SkipType (M2Quads_OperandF ((ParamTotal+1)+1));
    9130              :     }
    9131              :   else
    9132              :     {
    9133       219850 :       Proc = PCSymBuild_SkipConst (ProcSym);
    9134              :     }
    9135       220622 :   i = 1;
    9136       220622 :   pi = ParamTotal+1;  /* stack index referencing stacked parameter, i  */
    9137       768233 :   while (i <= ParamTotal)  /* stack index referencing stacked parameter, i  */
    9138              :     {
    9139       547611 :       if (i <= (SymbolTable_NoOfParamAny (Proc)))
    9140              :         {
    9141       539223 :           FormalI = SymbolTable_GetParam (Proc, i);
    9142       539223 :           Actual = static_cast<unsigned int> (M2Quads_OperandT (pi));
    9143       539223 :           tokno = static_cast<unsigned int> (M2Quads_OperandTok (pi));
    9144       539223 :           if (M2Base_IsOrdinalType (SymbolTable_GetLType (FormalI)))
    9145              :             {
    9146       142599 :               if (! (SymbolTable_IsSet (SymbolTable_GetDType (FormalI))))
    9147              :                 {
    9148              :                   /* Tell the code generator to test the runtime values of the assignment
    9149              :                   so ensure we catch overflow and underflow.  */
    9150       142599 :                   BuildRange (M2Range_InitParameterRangeCheck (tokno, Proc, i, FormalI, Actual, OperandRangeDep (pi)));
    9151              :                 }
    9152              :             }
    9153              :         }
    9154       547611 :       i += 1;
    9155       547611 :       pi -= 1;
    9156              :     }
    9157       220622 : }
    9158              : 
    9159              : 
    9160              : /*
    9161              :    IsSameUnbounded - returns TRUE if unbounded types, t1, and, t2,
    9162              :                      are compatible.
    9163              : */
    9164              : 
    9165           36 : static bool IsSameUnbounded (unsigned int t1, unsigned int t2)
    9166              : {
    9167           36 :   M2Debug_Assert (SymbolTable_IsUnbounded (t1));
    9168           36 :   M2Debug_Assert (SymbolTable_IsUnbounded (t2));
    9169           36 :   return (SymbolTable_GetDType (t1)) == (SymbolTable_GetDType (t2));
    9170              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    9171              :   __builtin_unreachable ();
    9172              : }
    9173              : 
    9174              : 
    9175              : /*
    9176              :    AssignUnboundedVar - assigns an Unbounded symbol fields,
    9177              :                         ArrayAddress and ArrayHigh, from an array symbol.
    9178              :                         UnboundedSym is not a VAR parameter and therefore
    9179              :                         this procedure can complete both of the fields.
    9180              :                         Sym can be a Variable with type Unbounded.
    9181              :                         Sym can be a Variable with type Array.
    9182              :                         Sym can be a String Constant.
    9183              : 
    9184              :                         ParamType is the TYPE of the parameter
    9185              : */
    9186              : 
    9187         4450 : static void AssignUnboundedVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
    9188              : {
    9189         4450 :   unsigned int Type;
    9190              : 
    9191         4450 :   if (SymbolTable_IsConst (Sym))
    9192              :     {
    9193            0 :       M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
    9194              :     }
    9195         4450 :   else if (SymbolTable_IsVar (Sym))
    9196              :     {
    9197              :       /* avoid dangling else.  */
    9198         4450 :       Type = SymbolTable_GetDType (Sym);
    9199         4450 :       if (Type == SymbolTable_NulSym)
    9200              :         {
    9201            0 :           M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} has no type and cannot be passed to a VAR formal parameter", 65, Sym);
    9202              :         }
    9203         4450 :       else if (SymbolTable_IsUnbounded (Type))
    9204              :         {
    9205              :           /* avoid dangling else.  */
    9206         1462 :           if (Type == (SymbolTable_GetSType (UnboundedSym)))
    9207              :             {
    9208              :               /* Copy Unbounded Symbol ie. UnboundedSym := Sym  */
    9209         1426 :               M2Quads_PushT (UnboundedSym);
    9210         1426 :               M2Quads_PushT (Sym);
    9211         1426 :               BuildAssignmentWithoutBounds (tok, false, true);
    9212              :             }
    9213           36 :           else if ((IsSameUnbounded (Type, SymbolTable_GetSType (UnboundedSym))) || (M2System_IsGenericSystemType (ParamType)))
    9214              :             {
    9215              :               /* avoid dangling else.  */
    9216           36 :               UnboundedVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
    9217              :             }
    9218              :           else
    9219              :             {
    9220              :               /* avoid dangling else.  */
    9221            0 :               M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
    9222              :             }
    9223              :         }
    9224         2988 :       else if ((SymbolTable_IsArray (Type)) || (M2System_IsGenericSystemType (ParamType)))
    9225              :         {
    9226              :           /* avoid dangling else.  */
    9227         2988 :           UnboundedVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
    9228              :         }
    9229              :       else
    9230              :         {
    9231              :           /* avoid dangling else.  */
    9232            0 :           M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
    9233              :         }
    9234              :     }
    9235              :   else
    9236              :     {
    9237              :       /* avoid dangling else.  */
    9238            0 :       M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
    9239              :     }
    9240         4450 : }
    9241              : 
    9242              : 
    9243              : /*
    9244              :    AssignUnboundedNonVar - assigns an Unbounded symbol fields,
    9245              :                            The difference between this procedure and
    9246              :                            AssignUnboundedVar is that this procedure cannot
    9247              :                            set the Unbounded.Address since the data from
    9248              :                            Sym will be copied because parameter is NOT a VAR
    9249              :                            parameter.
    9250              :                            UnboundedSym is not a VAR parameter and therefore
    9251              :                            this procedure can only complete the HIGH field
    9252              :                            and not the ADDRESS field.
    9253              :                            Sym can be a Variable with type Unbounded.
    9254              :                            Sym can be a Variable with type Array.
    9255              :                            Sym can be a String Constant.
    9256              : 
    9257              :                            ParamType is the TYPE of the paramater
    9258              : */
    9259              : 
    9260        36371 : static void AssignUnboundedNonVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
    9261              : {
    9262        36371 :   unsigned int Type;
    9263              : 
    9264        36371 :   if (SymbolTable_IsConst (Sym))  /* was IsConstString(Sym)  */
    9265              :     {
    9266        26777 :       UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
    9267              :     }
    9268         9594 :   else if (SymbolTable_IsVar (Sym))
    9269              :     {
    9270              :       /* avoid dangling else.  */
    9271         9594 :       Type = SymbolTable_GetDType (Sym);
    9272         9594 :       if (Type == SymbolTable_NulSym)
    9273              :         {
    9274            0 :           M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} has no type and cannot be passed to a non VAR formal parameter", 69, Sym);
    9275              :         }
    9276         9594 :       else if (SymbolTable_IsUnbounded (Type))
    9277              :         {
    9278              :           /* avoid dangling else.  */
    9279         4800 :           UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
    9280              :         }
    9281         4794 :       else if ((SymbolTable_IsArray (Type)) || (M2System_IsGenericSystemType (ParamType)))
    9282              :         {
    9283              :           /* avoid dangling else.  */
    9284         4782 :           UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
    9285              :         }
    9286              :       else
    9287              :         {
    9288              :           /* avoid dangling else.  */
    9289           12 :           M2MetaError_MetaErrorT1 (tok, (const char *) "illegal type parameter {%1Ead} expecting array or dynamic array", 63, Sym);
    9290              :         }
    9291              :     }
    9292              :   else
    9293              :     {
    9294              :       /* avoid dangling else.  */
    9295            0 :       M2MetaError_MetaErrorT1 (tok, (const char *) "illegal parameter {%1Ead} which cannot be passed as {%kVAR} {%kARRAY} {%kOF} {%1tsad}", 85, Sym);
    9296              :     }
    9297        36371 : }
    9298              : 
    9299              : 
    9300              : /*
    9301              :    GenHigh - generates a HighOp but it checks if op3 is a
    9302              :              L value and if so it dereferences it.  This
    9303              :              is inefficient, however it is clean and we let the gcc
    9304              :              backend detect these as common subexpressions.
    9305              :              It will also detect that a R value -> L value -> R value
    9306              :              via indirection and eleminate these.
    9307              : */
    9308              : 
    9309        42265 : static void GenHigh (unsigned int tok, unsigned int op1, unsigned int op2, unsigned int op3)
    9310              : {
    9311        42265 :   unsigned int sym;
    9312              : 
    9313        42265 :   if (((SymbolTable_GetMode (op3)) == SymbolTable_LeftValue) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (op3))))
    9314              :     {
    9315           48 :       sym = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
    9316           48 :       SymbolTable_PutVar (sym, SymbolTable_GetSType (op3));
    9317           48 :       doIndrX (tok, sym, op3);
    9318           48 :       GenQuadO (tok, M2Quads_HighOp, op1, op2, sym, true);
    9319              :     }
    9320              :   else
    9321              :     {
    9322        42217 :       GenQuadO (tok, M2Quads_HighOp, op1, op2, op3, true);
    9323              :     }
    9324        42265 : }
    9325              : 
    9326              : 
    9327              : /*
    9328              :    AssignHighField -
    9329              : */
    9330              : 
    9331        39539 : static void AssignHighField (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int actuali, unsigned int formali)
    9332              : {
    9333        39539 :   unsigned int ReturnVar;
    9334        39539 :   unsigned int ArrayType;
    9335        39539 :   unsigned int Field;
    9336              : 
    9337              :   /* Unbounded.ArrayHigh := HIGH(ArraySym)  */
    9338        39539 :   M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
    9339        39539 :   Field = SymbolTable_GetUnboundedHighOffset (SymbolTable_GetSType (UnboundedSym), formali);
    9340        39539 :   M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
    9341        39539 :   M2Quads_PushT (static_cast<unsigned int> (1));
    9342        39539 :   M2Quads_BuildDesignatorRecord (tok);
    9343        39539 :   if (M2System_IsGenericSystemType (ParamType))
    9344              :     {
    9345         2036 :       if (SymbolTable_IsConstString (Sym))
    9346              :         {
    9347           18 :           M2Quads_PushTtok (DeferMakeLengthConst (tok, Sym), tok);
    9348              :         }
    9349              :       else
    9350              :         {
    9351         2018 :           ArrayType = SymbolTable_GetSType (Sym);
    9352         2018 :           if (SymbolTable_IsUnbounded (ArrayType))
    9353              :             {
    9354              :               /* 
    9355              :              *  SIZE(parameter) DIV TSIZE(ParamType)
    9356              :              *  however in this case parameter
    9357              :              *  is an unbounded symbol and therefore we must use
    9358              :              *  (HIGH(parameter)+1)*SIZE(unbounded type) DIV TSIZE(ParamType)
    9359              :              *
    9360              :              *  we call upon the function SIZE(ArraySym)
    9361              :              *  remember SIZE doubles as
    9362              :              *  (HIGH(a)+1) * SIZE(ArrayType) for unbounded symbols
    9363              :   */
    9364         1106 :               M2Quads_PushTFtok (calculateMultipicand (tok, ArraySym, ArrayType, actuali-1), M2Base_Cardinal, tok);
    9365         1106 :               M2Quads_PushT (M2Reserved_DivideTok);  /* Divide by  */
    9366         1106 :               M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok);  /* TSIZE(ParamType)  */
    9367         1106 :               M2Quads_PushTtok (ParamType, tok);  /* TSIZE(ParamType)  */
    9368         1106 :               M2Quads_PushT (static_cast<unsigned int> (1));  /* 1 parameter for TSIZE()  */
    9369         1106 :               M2Quads_BuildFunctionCall (false);  /* 1 parameter for TSIZE()  */
    9370         1106 :               M2Quads_BuildBinaryOp ();
    9371              :             }
    9372              :           else
    9373              :             {
    9374              :               /* SIZE(parameter) DIV TSIZE(ParamType)  */
    9375          912 :               M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok);  /* TSIZE(ArrayType)  */
    9376          912 :               M2Quads_PushTtok (ArrayType, tok);  /* TSIZE(ArrayType)  */
    9377          912 :               M2Quads_PushT (static_cast<unsigned int> (1));  /* 1 parameter for TSIZE()  */
    9378          912 :               M2Quads_BuildFunctionCall (true);  /* 1 parameter for TSIZE()  */
    9379          912 :               M2Quads_PushT (M2Reserved_DivideTok);  /* Divide by  */
    9380          912 :               M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok);  /* TSIZE(ParamType)  */
    9381          912 :               M2Quads_PushTtok (ParamType, tok);  /* TSIZE(ParamType)  */
    9382          912 :               M2Quads_PushT (static_cast<unsigned int> (1));  /* 1 parameter for TSIZE()  */
    9383          912 :               M2Quads_BuildFunctionCall (true);  /* 1 parameter for TSIZE()  */
    9384          912 :               M2Quads_BuildBinaryOp ();
    9385              :             }
    9386              :           /* now convert from no of elements into HIGH by subtracting 1  */
    9387         2018 :           M2Quads_PushT (M2Reserved_MinusTok);  /* -1  */
    9388         2018 :           M2Quads_PushTtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal), tok);  /* -1  */
    9389         2018 :           M2Quads_BuildBinaryOp ();
    9390              :         }
    9391              :     }
    9392              :   else
    9393              :     {
    9394        37503 :       ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
    9395        37503 :       SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
    9396        37503 :       if (((actuali != formali) && (ArraySym != SymbolTable_NulSym)) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (ArraySym))))
    9397              :         {
    9398           12 :           GenHigh (tok, ReturnVar, actuali, ArraySym);
    9399              :         }
    9400              :       else
    9401              :         {
    9402        37491 :           GenHigh (tok, ReturnVar, formali, Sym);
    9403              :         }
    9404        37503 :       M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), tok);
    9405              :     }
    9406        39539 :   BuildAssignmentWithoutBounds (tok, false, true);
    9407        39539 : }
    9408              : 
    9409              : 
    9410              : /*
    9411              :    AssignHighFields -
    9412              : */
    9413              : 
    9414        39383 : static void AssignHighFields (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
    9415              : {
    9416        39383 :   unsigned int type;
    9417        39383 :   unsigned int actuali;
    9418        39383 :   unsigned int formali;
    9419        39383 :   unsigned int actualn;
    9420        39383 :   unsigned int formaln;
    9421              : 
    9422        39383 :   type = SymbolTable_GetDType (Sym);
    9423        39383 :   actualn = 1;
    9424        39383 :   if ((type != SymbolTable_NulSym) && ((SymbolTable_IsUnbounded (type)) || (SymbolTable_IsArray (type))))
    9425              :     {
    9426        11724 :       actualn = SymbolTable_GetDimension (type);
    9427              :     }
    9428        39383 :   actuali = dim+1;
    9429        39383 :   formali = 1;
    9430        39383 :   formaln = SymbolTable_GetDimension (SymbolTable_GetDType (UnboundedSym));
    9431        78922 :   while ((actuali < actualn) && (formali < formaln))
    9432              :     {
    9433          156 :       AssignHighField (tok, Sym, ArraySym, UnboundedSym, SymbolTable_NulSym, actuali, formali);
    9434          156 :       actuali += 1;
    9435          156 :       formali += 1;
    9436              :     }
    9437        39383 :   AssignHighField (tok, Sym, ArraySym, UnboundedSym, ParamType, actuali, formali);
    9438        39383 : }
    9439              : 
    9440              : 
    9441              : /*
    9442              :    UnboundedNonVarLinkToArray - links an array, ArraySym, to an unbounded
    9443              :                                 array, UnboundedSym. The parameter is a
    9444              :                                 NON VAR variety.
    9445              : */
    9446              : 
    9447        36359 : static void UnboundedNonVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
    9448              : {
    9449        36359 :   unsigned int Field;
    9450        36359 :   unsigned int AddressField;
    9451              : 
    9452              :   /* Unbounded.ArrayAddress := to be assigned at runtime.  */
    9453        36359 :   M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
    9454        36359 :   Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
    9455        36359 :   M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
    9456        36359 :   M2Quads_PushT (static_cast<unsigned int> (1));
    9457        36359 :   M2Quads_BuildDesignatorRecord (tok);
    9458        36359 :   M2Quads_PopT (&AddressField);
    9459              :   /* caller saves non var unbounded array contents.  */
    9460        72718 :   GenQuadO (tok, M2Quads_UnboundedOp, AddressField, SymbolTable_NulSym, Sym, false);
    9461        36359 :   AssignHighFields (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
    9462        36359 : }
    9463              : 
    9464              : 
    9465              : /*
    9466              :    UnboundedVarLinkToArray - links an array, ArraySym, to an unbounded array,
    9467              :                              UnboundedSym. The parameter is a VAR variety.
    9468              : */
    9469              : 
    9470         3024 : static void UnboundedVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
    9471              : {
    9472         3024 :   unsigned int SymType;
    9473         3024 :   unsigned int Field;
    9474              : 
    9475         3024 :   SymType = SymbolTable_GetSType (Sym);
    9476              :   /* Unbounded.ArrayAddress := ADR(Sym)  */
    9477         3024 :   M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
    9478         3024 :   Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
    9479         3024 :   M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
    9480         3024 :   M2Quads_PushT (static_cast<unsigned int> (1));
    9481         3024 :   M2Quads_BuildDesignatorRecord (tok);
    9482         3024 :   M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);  /* ADR (Sym).  */
    9483         3024 :   if ((SymbolTable_IsUnbounded (SymType)) && (dim == 0))  /* ADR (Sym).  */
    9484              :     {
    9485           12 :       PushTFADtok (Sym, SymType, UnboundedSym, dim, tok);
    9486              :     }
    9487              :   else
    9488              :     {
    9489         3012 :       PushTFADtok (Sym, SymType, ArraySym, dim, tok);
    9490              :     }
    9491         3024 :   M2Quads_PushT (static_cast<unsigned int> (1));  /* 1 parameter for ADR().  */
    9492         3024 :   M2Quads_BuildFunctionCall (false);  /* 1 parameter for ADR().  */
    9493         3024 :   BuildAssignmentWithoutBounds (tok, false, true);
    9494         3024 :   AssignHighFields (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
    9495         3024 : }
    9496              : 
    9497              : 
    9498              : /*
    9499              :    BuildPseudoProcedureCall - builds a pseudo procedure call.
    9500              :                               This procedure does not directly alter the
    9501              :                               stack, but by calling routines the stack
    9502              :                               will change in the following way when this
    9503              :                               procedure returns.
    9504              : 
    9505              :                               The Stack:
    9506              : 
    9507              : 
    9508              :                               Entry                      Exit
    9509              : 
    9510              :                        Ptr ->
    9511              :                               +----------------+
    9512              :                               | NoOfParam      |
    9513              :                               |----------------|
    9514              :                               | Param 1        |
    9515              :                               |----------------|
    9516              :                               | Param 2        |
    9517              :                               |----------------|
    9518              :                               .                .
    9519              :                               .                .
    9520              :                               .                .
    9521              :                               |----------------|
    9522              :                               | Param #        |
    9523              :                               |----------------|
    9524              :                               | ProcSym | Type |         Empty
    9525              :                               |----------------|
    9526              : */
    9527              : 
    9528        21535 : static void BuildPseudoProcedureCall (unsigned int tokno)
    9529              : {
    9530        21535 :   unsigned int NoOfParam;
    9531        21535 :   unsigned int ProcSym;
    9532              : 
    9533        21535 :   M2Quads_PopT (&NoOfParam);
    9534        21535 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
    9535        21535 :   M2Quads_PushT (NoOfParam);
    9536              :   /* Compile time stack restored to entry state  */
    9537        21535 :   if (ProcSym == M2Base_New)
    9538              :     {
    9539          873 :       BuildNewProcedure (tokno);
    9540              :     }
    9541        20662 :   else if (ProcSym == M2Base_Dispose)
    9542              :     {
    9543              :       /* avoid dangling else.  */
    9544          332 :       BuildDisposeProcedure (tokno);
    9545              :     }
    9546        20330 :   else if (ProcSym == M2Base_Inc)
    9547              :     {
    9548              :       /* avoid dangling else.  */
    9549        14391 :       BuildIncProcedure (tokno);
    9550              :     }
    9551         5939 :   else if (ProcSym == M2Base_Dec)
    9552              :     {
    9553              :       /* avoid dangling else.  */
    9554         3933 :       BuildDecProcedure (tokno);
    9555              :     }
    9556         2006 :   else if (ProcSym == M2Base_Incl)
    9557              :     {
    9558              :       /* avoid dangling else.  */
    9559         1123 :       BuildInclProcedure (tokno);
    9560              :     }
    9561          883 :   else if (ProcSym == M2Base_Excl)
    9562              :     {
    9563              :       /* avoid dangling else.  */
    9564          771 :       BuildExclProcedure (tokno);
    9565              :     }
    9566          112 :   else if (ProcSym == M2System_Throw)
    9567              :     {
    9568              :       /* avoid dangling else.  */
    9569          112 :       BuildThrowProcedure (tokno);
    9570              :     }
    9571              :   else
    9572              :     {
    9573              :       /* avoid dangling else.  */
    9574            0 :       M2Error_InternalError ((const char *) "pseudo procedure not implemented yet", 36);
    9575              :     }
    9576        21535 : }
    9577              : 
    9578              : 
    9579              : /*
    9580              :    GetItemPointedTo - returns the symbol type that is being pointed to
    9581              :                       by Sym.
    9582              : */
    9583              : 
    9584         3034 : static unsigned int GetItemPointedTo (unsigned int Sym)
    9585              : {
    9586         6076 :   if (SymbolTable_IsPointer (Sym))
    9587              :     {
    9588         3034 :       return SymbolTable_GetSType (Sym);
    9589              :     }
    9590         3042 :   else if ((SymbolTable_IsVar (Sym)) || (SymbolTable_IsType (Sym)))
    9591              :     {
    9592              :       /* avoid dangling else.  */
    9593         3042 :       return GetItemPointedTo (SymbolTable_GetSType (Sym));
    9594              :     }
    9595              :   else
    9596              :     {
    9597              :       /* avoid dangling else.  */
    9598              :       return SymbolTable_NulSym;
    9599              :     }
    9600              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    9601              :   __builtin_unreachable ();
    9602              : }
    9603              : 
    9604              : 
    9605              : /*
    9606              :    BuildThrowProcedure - builds the pseudo procedure call M2RTS.Throw.
    9607              :                          The Stack:
    9608              : 
    9609              : 
    9610              :                          Entry                      Exit
    9611              : 
    9612              :                 Ptr ->
    9613              :                          +----------------+
    9614              :                          | NoOfParam      |
    9615              :                          |----------------|
    9616              :                          | Param 1        |
    9617              :                          |----------------|
    9618              :                          | Param 2        |
    9619              :                          |----------------|
    9620              :                          .                .
    9621              :                          .                .
    9622              :                          .                .
    9623              :                          |----------------|
    9624              :                          | Param #        |
    9625              :                          |----------------|
    9626              :                          | ProcSym | Type |         Empty
    9627              :                          |----------------|
    9628              : */
    9629              : 
    9630          112 : static void BuildThrowProcedure (unsigned int functok)
    9631              : {
    9632          112 :   unsigned int op;
    9633          112 :   unsigned int NoOfParam;
    9634              : 
    9635          112 :   M2Quads_PopT (&NoOfParam);
    9636          112 :   if (NoOfParam == 1)
    9637              :     {
    9638          112 :       op = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
    9639          112 :       GenQuadO (functok, M2Quads_ThrowOp, SymbolTable_NulSym, SymbolTable_NulSym, op, false);
    9640              :     }
    9641              :   else
    9642              :     {
    9643            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure %{1Ea} takes one INTEGER parameter", 55, M2System_Throw);
    9644              :     }
    9645          112 :   M2Quads_PopN (NoOfParam+1);
    9646          112 : }
    9647              : 
    9648              : 
    9649              : /*
    9650              :    BuildNewProcedure - builds the pseudo procedure call NEW.
    9651              :                        This procedure is traditionally a "macro" for
    9652              :                        NEW(x, ...) --> ALLOCATE(x, TSIZE(x^, ...))
    9653              :                        One method of implementation is to emulate a "macro"
    9654              :                        processor by pushing the relevant input tokens
    9655              :                        back onto the input stack.
    9656              :                        However this causes two problems:
    9657              : 
    9658              :                        (i)  Unnecessary code is produced for x^
    9659              :                        (ii) SIZE must be imported from SYSTEM
    9660              :                        Therefore we chose an alternative method of
    9661              :                        implementation;
    9662              :                        generate quadruples for ALLOCATE(x, TSIZE(x^, ...))
    9663              :                        this, although slightly more efficient,
    9664              :                        is more complex and circumvents problems (i) and (ii).
    9665              : 
    9666              :                        The Stack:
    9667              : 
    9668              : 
    9669              :                        Entry                      Exit
    9670              : 
    9671              :                 Ptr ->
    9672              :                        +----------------+
    9673              :                        | NoOfParam      |
    9674              :                        |----------------|
    9675              :                        | Param 1        |
    9676              :                        |----------------|
    9677              :                        | Param 2        |
    9678              :                        |----------------|
    9679              :                        .                .
    9680              :                        .                .
    9681              :                        .                .
    9682              :                        |----------------|
    9683              :                        | Param #        |
    9684              :                        |----------------|
    9685              :                        | ProcSym | Type |         Empty
    9686              :                        |----------------|
    9687              : */
    9688              : 
    9689          873 : static void BuildNewProcedure (unsigned int functok)
    9690              : {
    9691          873 :   unsigned int NoOfParam;
    9692          873 :   unsigned int SizeSym;
    9693          873 :   unsigned int PtrSym;
    9694          873 :   unsigned int ProcSym;
    9695          873 :   unsigned int paramtok;
    9696          873 :   unsigned int combinedtok;
    9697              : 
    9698          873 :   M2Quads_PopT (&NoOfParam);
    9699          873 :   if (NoOfParam >= 1)
    9700              :     {
    9701          873 :       ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "ALLOCATE", 8));
    9702          873 :       if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
    9703              :         {
    9704          873 :           PtrSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
    9705          873 :           paramtok = OperandTtok (1);
    9706          873 :           if (IsReallyPointer (PtrSym))
    9707              :             {
    9708          872 :               combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
    9709              :               /* 
    9710              :                Build macro: ALLOCATE( PtrSym, SIZE(PtrSym^) )
    9711              :   */
    9712          872 :               M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, paramtok);  /* Procedure  */
    9713              :               /* x^  */
    9714          872 :               M2Quads_PushTtok (GetItemPointedTo (PtrSym), paramtok);
    9715          872 :               M2Quads_PushT (static_cast<unsigned int> (1));  /* One parameter  */
    9716          872 :               M2Quads_BuildFunctionCall (false);  /* One parameter  */
    9717          872 :               M2Quads_PopT (&SizeSym);
    9718          872 :               M2Quads_PushTtok (ProcSym, combinedtok);  /* ALLOCATE  */
    9719          872 :               M2Quads_PushTtok (PtrSym, paramtok);  /* x  */
    9720          872 :               M2Quads_PushTtok (SizeSym, paramtok);  /* TSIZE(x^)  */
    9721          872 :               M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
    9722          872 :               M2Quads_BuildProcedureCall (combinedtok);  /* Two parameters  */
    9723              :             }
    9724              :           else
    9725              :             {
    9726            1 :               M2MetaError_MetaErrorT1 (paramtok, (const char *) "parameter to {%EkNEW} must be a pointer, seen {%1Ed} {%1&s}", 59, PtrSym);
    9727              :             }
    9728              :         }
    9729              :       else
    9730              :         {
    9731            0 :           M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}ALLOCATE procedure not found for NEW substitution", 53);
    9732              :         }
    9733              :     }
    9734              :   else
    9735              :     {
    9736            0 :       M2MetaError_MetaErrorT0 (functok, (const char *) "the pseudo procedure {%EkNEW} has one or more parameters", 56);
    9737              :     }
    9738          873 :   M2Quads_PopN (NoOfParam+1);
    9739          873 : }
    9740              : 
    9741              : 
    9742              : /*
    9743              :    BuildDisposeProcedure - builds the pseudo procedure call DISPOSE.
    9744              :                            This procedure is traditionally a "macro" for
    9745              :                            DISPOSE(x) --> DEALLOCATE(x, TSIZE(x^))
    9746              :                            One method of implementation is to emulate a "macro"
    9747              :                            processor by pushing the relevant input tokens
    9748              :                            back onto the input stack.
    9749              :                            However this causes two problems:
    9750              : 
    9751              :                            (i)  Unnecessary code is produced for x^
    9752              :                            (ii) TSIZE must be imported from SYSTEM
    9753              :                            Therefore we chose an alternative method of
    9754              :                            implementation;
    9755              :                            generate quadruples for DEALLOCATE(x, TSIZE(x^))
    9756              :                            this, although slightly more efficient,
    9757              :                            is more complex and circumvents problems (i)
    9758              :                            and (ii).
    9759              : 
    9760              :                            The Stack:
    9761              : 
    9762              : 
    9763              :                            Entry                      Exit
    9764              : 
    9765              :                     Ptr ->
    9766              :                            +----------------+
    9767              :                            | NoOfParam      |
    9768              :                            |----------------|
    9769              :                            | Param 1        |
    9770              :                            |----------------|
    9771              :                            | Param 2        |
    9772              :                            |----------------|
    9773              :                            .                .
    9774              :                            .                .
    9775              :                            .                .
    9776              :                            |----------------|
    9777              :                            | Param #        |
    9778              :                            |----------------|
    9779              :                            | ProcSym | Type |         Empty
    9780              :                            |----------------|
    9781              : */
    9782              : 
    9783          332 : static void BuildDisposeProcedure (unsigned int functok)
    9784              : {
    9785          332 :   unsigned int NoOfParam;
    9786          332 :   unsigned int SizeSym;
    9787          332 :   unsigned int PtrSym;
    9788          332 :   unsigned int ProcSym;
    9789          332 :   unsigned int combinedtok;
    9790          332 :   unsigned int paramtok;
    9791              : 
    9792          332 :   M2Quads_PopT (&NoOfParam);
    9793          332 :   if (NoOfParam >= 1)
    9794              :     {
    9795          332 :       ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "DEALLOCATE", 10));
    9796          332 :       if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
    9797              :         {
    9798          332 :           PtrSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
    9799          332 :           paramtok = OperandTtok (1);
    9800          332 :           if (IsReallyPointer (PtrSym))
    9801              :             {
    9802          332 :               combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
    9803              :               /* 
    9804              :                Build macro: DEALLOCATE( PtrSym, TSIZE(PtrSym^) )
    9805              :   */
    9806          332 :               M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, paramtok);  /* Procedure  */
    9807              :               /* x^  */
    9808          332 :               M2Quads_PushTtok (GetItemPointedTo (PtrSym), paramtok);
    9809          332 :               M2Quads_PushT (static_cast<unsigned int> (1));  /* One parameter  */
    9810          332 :               M2Quads_BuildFunctionCall (false);  /* One parameter  */
    9811          332 :               M2Quads_PopT (&SizeSym);
    9812          332 :               M2Quads_PushTtok (ProcSym, combinedtok);  /* DEALLOCATE  */
    9813          332 :               M2Quads_PushTtok (PtrSym, paramtok);  /* x  */
    9814          332 :               M2Quads_PushTtok (SizeSym, paramtok);  /* TSIZE(x^)  */
    9815          332 :               M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
    9816          332 :               M2Quads_BuildProcedureCall (combinedtok);  /* Two parameters  */
    9817              :             }
    9818              :           else
    9819              :             {
    9820            0 :               M2MetaError_MetaErrorT1 (paramtok, (const char *) "argument to {%EkDISPOSE} must be a pointer, seen {%1Ed} {%1&s}", 62, PtrSym);
    9821              :             }
    9822              :         }
    9823              :       else
    9824              :         {
    9825            0 :           M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}DEALLOCATE procedure not found for DISPOSE substitution", 59);
    9826              :         }
    9827              :     }
    9828              :   else
    9829              :     {
    9830            0 :       M2MetaError_MetaErrorT0 (functok, (const char *) "the pseudo procedure {%EkDISPOSE} has one or more parameters", 60);
    9831              :     }
    9832          332 :   M2Quads_PopN (NoOfParam+1);
    9833          332 : }
    9834              : 
    9835              : 
    9836              : /*
    9837              :    CheckRangeIncDec - performs des := des <tok> expr
    9838              :                       with range checking (if enabled).
    9839              : 
    9840              :                                Stack
    9841              :                       Entry              Exit
    9842              : 
    9843              :                                      +------------+
    9844              :                       empty          | des + expr |
    9845              :                                      |------------|
    9846              : */
    9847              : 
    9848        18322 : static void CheckRangeIncDec (unsigned int tokenpos, unsigned int des, unsigned int expr, NameKey_Name tok)
    9849              : {
    9850        18322 :   unsigned int dtype;
    9851        18322 :   unsigned int etype;
    9852              : 
    9853        18322 :   dtype = SymbolTable_GetDType (des);
    9854        18322 :   etype = SymbolTable_GetDType (expr);
    9855        18322 :   if ((etype == SymbolTable_NulSym) && (SymbolTable_IsPointer (SymbolTable_GetTypeMode (des))))
    9856              :     {
    9857           24 :       expr = ConvertToAddress (tokenpos, expr);
    9858           24 :       etype = M2System_Address;
    9859              :     }
    9860        18322 :   if (M2Options_WholeValueChecking && ! MustNotCheckBounds)
    9861              :     {
    9862              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    9863         1488 :       if (tok == M2Reserved_PlusTok)
    9864              :         {
    9865          804 :           BuildRange (M2Range_InitIncRangeCheck (des, expr));
    9866              :         }
    9867              :       else
    9868              :         {
    9869          684 :           BuildRange (M2Range_InitDecRangeCheck (des, expr));
    9870              :         }
    9871              :     }
    9872        18322 :   if (M2Base_IsExpressionCompatible (dtype, etype))
    9873              :     {
    9874              :       /* the easy case simulate a straightforward macro  */
    9875        16852 :       M2Quads_PushTFtok (des, dtype, tokenpos);
    9876        16852 :       M2Quads_PushT (tok);
    9877        16852 :       M2Quads_PushTFtok (expr, etype, tokenpos);
    9878        16852 :       doBuildBinaryOp (false, true);
    9879              :     }
    9880              :   else
    9881              :     {
    9882         1470 :       if ((((M2Base_IsOrdinalType (dtype)) || (dtype == M2System_Address)) || (SymbolTable_IsPointer (dtype))) && (((M2Base_IsOrdinalType (etype)) || (etype == M2System_Address)) || (SymbolTable_IsPointer (etype))))
    9883              :         {
    9884         1470 :           M2Quads_PushTFtok (des, dtype, tokenpos);
    9885         1470 :           M2Quads_PushT (tok);
    9886         1470 :           M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tokenpos);
    9887         1470 :           M2Quads_PushTtok (dtype, tokenpos);
    9888         1470 :           M2Quads_PushTtok (expr, tokenpos);
    9889         1470 :           M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
    9890         1470 :           BuildConvertFunction (M2Base_Convert, false);  /* Two parameters  */
    9891         1470 :           doBuildBinaryOp (false, true);
    9892              :         }
    9893              :       else
    9894              :         {
    9895            0 :           if (tok == M2Reserved_PlusTok)
    9896              :             {
    9897            0 :               M2MetaError_MetaError0 ((const char *) "cannot perform {%EkINC} using non ordinal types", 47);
    9898              :             }
    9899              :           else
    9900              :             {
    9901            0 :               M2MetaError_MetaError0 ((const char *) "cannot perform {%EkDEC} using non ordinal types", 47);
    9902              :             }
    9903            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (tokenpos, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym), static_cast<unsigned int> (SymbolTable_NulSym), tokenpos);
    9904              :         }
    9905              :     }
    9906        18322 : }
    9907              : 
    9908              : 
    9909              : /*
    9910              :    BuildIncProcedure - builds the pseudo procedure call INC.
    9911              :                        INC is a procedure which increments a variable.
    9912              :                        It takes one or two parameters:
    9913              :                        INC(a, b)  or  INC(a)
    9914              :                        a := a+b   or  a := a+1
    9915              : 
    9916              :                        The Stack:
    9917              : 
    9918              : 
    9919              :                        Entry                      Exit
    9920              : 
    9921              :                 Ptr ->
    9922              :                        +----------------+
    9923              :                        | NoOfParam      |
    9924              :                        |----------------|
    9925              :                        | Param 1        |
    9926              :                        |----------------|
    9927              :                        | Param 2        |
    9928              :                        |----------------|
    9929              :                        .                .
    9930              :                        .                .
    9931              :                        .                .
    9932              :                        |----------------|
    9933              :                        | Param #        |
    9934              :                        |----------------|
    9935              :                        | ProcSym | Type |         Empty
    9936              :                        |----------------|
    9937              : */
    9938              : 
    9939        14391 : static void BuildIncProcedure (unsigned int proctok)
    9940              : {
    9941        14391 :   unsigned int vartok;
    9942        14391 :   unsigned int NoOfParam;
    9943        14391 :   unsigned int dtype;
    9944        14391 :   unsigned int OperandSym;
    9945        14391 :   unsigned int VarSym;
    9946        14391 :   unsigned int TempSym;
    9947              : 
    9948        14391 :   M2Quads_PopT (&NoOfParam);
    9949        14391 :   if ((NoOfParam == 1) || (NoOfParam == 2))
    9950              :     {
    9951        14391 :       VarSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));  /* Bottom/first parameter.  */
    9952        14391 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam));  /* Bottom/first parameter.  */
    9953        14391 :       if (SymbolTable_IsVar (VarSym))
    9954              :         {
    9955        14390 :           dtype = SymbolTable_GetDType (VarSym);
    9956        14390 :           if (NoOfParam == 2)
    9957              :             {
    9958         2742 :               OperandSym = DereferenceLValue (proctok, M2Quads_OperandT (1));
    9959              :             }
    9960              :           else
    9961              :             {
    9962        11648 :               PushOne (proctok, dtype, (const char *) "the {%EkINC} will cause an overflow {%1ad}", 42);
    9963        11648 :               M2Quads_PopT (&OperandSym);
    9964              :             }
    9965        14390 :           M2Quads_PushTtok (VarSym, vartok);
    9966        14390 :           TempSym = DereferenceLValue (vartok, VarSym);
    9967        14390 :           CheckRangeIncDec (proctok, TempSym, OperandSym, M2Reserved_PlusTok);  /* TempSym + OperandSym.  */
    9968        14390 :           BuildAssignmentWithoutBounds (proctok, false, true);  /* VarSym := TempSym + OperandSym.  */
    9969              :         }
    9970              :       else
    9971              :         {
    9972            1 :           M2MetaError_MetaErrorT1 (vartok, (const char *) "base procedure {%EkINC} expects a variable as a parameter but was given {%1Ed} {%1&s}", 85, VarSym);
    9973              :         }
    9974              :     }
    9975              :   else
    9976              :     {
    9977            0 :       M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkINC} expects 1 or 2 parameters", 53);
    9978              :     }
    9979        14391 :   M2Quads_PopN (NoOfParam+1);
    9980        14391 : }
    9981              : 
    9982              : 
    9983              : /*
    9984              :    BuildDecProcedure - builds the pseudo procedure call DEC.
    9985              :                        DEC is a procedure which decrements a variable.
    9986              :                        It takes one or two parameters:
    9987              :                        DEC(a, b)  or  DEC(a)
    9988              :                        a := a-b   or  a := a-1
    9989              : 
    9990              :                        The Stack:
    9991              : 
    9992              : 
    9993              :                        Entry                      Exit
    9994              : 
    9995              :                 Ptr ->
    9996              :                        +----------------+
    9997              :                        | NoOfParam      |
    9998              :                        |----------------|
    9999              :                        | Param 1        |
   10000              :                        |----------------|
   10001              :                        | Param 2        |
   10002              :                        |----------------|
   10003              :                        .                .
   10004              :                        .                .
   10005              :                        .                .
   10006              :                        |----------------|
   10007              :                        | Param #        |
   10008              :                        |----------------|
   10009              :                        | ProcSym | Type |         Empty
   10010              :                        |----------------|
   10011              : */
   10012              : 
   10013         3933 : static void BuildDecProcedure (unsigned int proctok)
   10014              : {
   10015         3933 :   unsigned int vartok;
   10016         3933 :   unsigned int NoOfParam;
   10017         3933 :   unsigned int dtype;
   10018         3933 :   unsigned int OperandSym;
   10019         3933 :   unsigned int VarSym;
   10020         3933 :   unsigned int TempSym;
   10021              : 
   10022         3933 :   M2Quads_PopT (&NoOfParam);
   10023         3933 :   if ((NoOfParam == 1) || (NoOfParam == 2))
   10024              :     {
   10025         3933 :       VarSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));  /* Bottom/first parameter.  */
   10026         3933 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam));  /* Bottom/first parameter.  */
   10027         3933 :       if (SymbolTable_IsVar (VarSym))
   10028              :         {
   10029         3932 :           dtype = SymbolTable_GetDType (VarSym);
   10030         3932 :           if (NoOfParam == 2)
   10031              :             {
   10032         1392 :               OperandSym = DereferenceLValue (proctok, M2Quads_OperandT (1));
   10033              :             }
   10034              :           else
   10035              :             {
   10036         2540 :               PushOne (proctok, dtype, (const char *) "the {%EkDEC} will cause an overflow {%1ad}", 42);
   10037         2540 :               M2Quads_PopT (&OperandSym);
   10038              :             }
   10039         3932 :           M2Quads_PushTtok (VarSym, vartok);
   10040         3932 :           TempSym = DereferenceLValue (vartok, VarSym);
   10041         3932 :           CheckRangeIncDec (proctok, TempSym, OperandSym, M2Reserved_MinusTok);  /* TempSym - OperandSym.  */
   10042         3932 :           BuildAssignmentWithoutBounds (proctok, false, true);  /* VarSym := TempSym - OperandSym.  */
   10043              :         }
   10044              :       else
   10045              :         {
   10046            1 :           M2MetaError_MetaErrorT1 (vartok, (const char *) "base procedure {%EkDEC} expects a variable as a parameter but was given {%1Ed} {%1&s}", 85, VarSym);
   10047              :         }
   10048              :     }
   10049              :   else
   10050              :     {
   10051            0 :       M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkDEC} expects 1 or 2 parameters", 53);
   10052              :     }
   10053         3933 :   M2Quads_PopN (NoOfParam+1);
   10054         3933 : }
   10055              : 
   10056              : 
   10057              : /*
   10058              :    DereferenceLValue - checks to see whether, operand, is declare as an LValue
   10059              :                        and if so it dereferences it.
   10060              : */
   10061              : 
   10062        30662 : static unsigned int DereferenceLValue (unsigned int tok, unsigned int operand)
   10063              : {
   10064        30662 :   unsigned int sym;
   10065              : 
   10066        30662 :   if ((SymbolTable_GetMode (operand)) == SymbolTable_LeftValue)
   10067              :     {
   10068              :       /* dereference the pointer  */
   10069         1492 :       sym = SymbolTable_MakeTemporary (tok, AreConstant (SymbolTable_IsConst (operand)));
   10070          746 :       SymbolTable_PutVar (sym, SymbolTable_GetSType (operand));
   10071          746 :       M2Quads_PushTtok (sym, tok);
   10072          746 :       M2Quads_PushTtok (operand, tok);
   10073          746 :       BuildAssignmentWithoutBounds (tok, false, true);
   10074          746 :       return sym;
   10075              :     }
   10076              :   else
   10077              :     {
   10078              :       return operand;
   10079              :     }
   10080              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   10081              :   __builtin_unreachable ();
   10082              : }
   10083              : 
   10084              : 
   10085              : /*
   10086              :    BuildInclProcedure - builds the pseudo procedure call INCL.
   10087              :                         INCL is a procedure which adds bit b into a BITSET a.
   10088              :                         It takes two parameters:
   10089              :                         INCL(a, b)
   10090              : 
   10091              :                         a := a + {b}
   10092              : 
   10093              :                         The Stack:
   10094              : 
   10095              : 
   10096              :                         Entry                      Exit
   10097              : 
   10098              :                  Ptr ->
   10099              :                         +----------------+
   10100              :                         | NoOfParam      |
   10101              :                         |----------------|
   10102              :                         | Param 1        |
   10103              :                         |----------------|
   10104              :                         | Param 2        |
   10105              :                         |----------------|
   10106              :                         | ProcSym | Type |         Empty
   10107              :                         |----------------|
   10108              : */
   10109              : 
   10110         1123 : static void BuildInclProcedure (unsigned int proctok)
   10111              : {
   10112         1123 :   unsigned int vartok;
   10113         1123 :   unsigned int optok;
   10114         1123 :   unsigned int NoOfParam;
   10115         1123 :   unsigned int DerefSym;
   10116         1123 :   unsigned int OperandSym;
   10117         1123 :   unsigned int VarSym;
   10118              : 
   10119         1123 :   M2Quads_PopT (&NoOfParam);
   10120         1123 :   if (NoOfParam == 2)
   10121              :     {
   10122         1123 :       VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
   10123         1123 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
   10124         1123 :       MarkArrayWritten (M2Quads_OperandA (2));
   10125         1123 :       OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
   10126         1123 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   10127         1123 :       if (SymbolTable_IsVar (VarSym))
   10128              :         {
   10129         1116 :           if (SymbolTable_IsSet (SymbolTable_GetDType (VarSym)))
   10130              :             {
   10131         1116 :               DerefSym = DereferenceLValue (optok, OperandSym);
   10132         1116 :               BuildRange (M2Range_InitInclCheck (VarSym, DerefSym));
   10133         1116 :               GenQuadO (proctok, M2Quads_InclOp, VarSym, SymbolTable_NulSym, DerefSym, false);
   10134              :             }
   10135              :           else
   10136              :             {
   10137            0 :               M2MetaError_MetaErrorT1 (vartok, (const char *) "the first parameter to {%EkINCL} must be a set variable, seen {%1Ed} {%1&s}", 75, VarSym);
   10138              :             }
   10139              :         }
   10140              :       else
   10141              :         {
   10142            7 :           M2MetaError_MetaErrorT1 (vartok, (const char *) "base procedure {%EkINCL} expects a variable as a parameter, seen {%1Ed} {%1&s}", 78, VarSym);
   10143              :         }
   10144              :     }
   10145              :   else
   10146              :     {
   10147            0 :       M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkINCL} expects 1 or 2 parameters", 54);
   10148              :     }
   10149         1123 :   M2Quads_PopN (NoOfParam+1);
   10150         1123 : }
   10151              : 
   10152              : 
   10153              : /*
   10154              :    BuildExclProcedure - builds the pseudo procedure call EXCL.
   10155              :                         INCL is a procedure which removes bit b from SET a.
   10156              :                         It takes two parameters:
   10157              :                         EXCL(a, b)
   10158              : 
   10159              :                         a := a - {b}
   10160              : 
   10161              :                         The Stack:
   10162              : 
   10163              : 
   10164              :                         Entry                      Exit
   10165              : 
   10166              :                  Ptr ->
   10167              :                         +----------------+
   10168              :                         | NoOfParam      |
   10169              :                         |----------------|
   10170              :                         | Param 1        |
   10171              :                         |----------------|
   10172              :                         | Param 2        |
   10173              :                         |----------------|
   10174              :                         | ProcSym | Type |         Empty
   10175              :                         |----------------|
   10176              : */
   10177              : 
   10178          771 : static void BuildExclProcedure (unsigned int proctok)
   10179              : {
   10180          771 :   unsigned int vartok;
   10181          771 :   unsigned int optok;
   10182          771 :   unsigned int NoOfParam;
   10183          771 :   unsigned int DerefSym;
   10184          771 :   unsigned int OperandSym;
   10185          771 :   unsigned int VarSym;
   10186              : 
   10187          771 :   M2Quads_PopT (&NoOfParam);
   10188          771 :   if (NoOfParam == 2)
   10189              :     {
   10190          771 :       VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
   10191          771 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
   10192          771 :       MarkArrayWritten (M2Quads_OperandA (2));
   10193          771 :       OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
   10194          771 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   10195          771 :       if (SymbolTable_IsVar (VarSym))
   10196              :         {
   10197          770 :           if (SymbolTable_IsSet (SymbolTable_GetDType (VarSym)))
   10198              :             {
   10199          770 :               DerefSym = DereferenceLValue (optok, OperandSym);
   10200          770 :               BuildRange (M2Range_InitExclCheck (VarSym, DerefSym));
   10201          770 :               GenQuadO (proctok, M2Quads_ExclOp, VarSym, SymbolTable_NulSym, DerefSym, false);
   10202              :             }
   10203              :           else
   10204              :             {
   10205            0 :               M2MetaError_MetaErrorT1 (vartok, (const char *) "the first parameter to {%EkEXCL} must be a set variable, seen {%1Ed} {%1&s}", 75, VarSym);
   10206              :             }
   10207              :         }
   10208              :       else
   10209              :         {
   10210            1 :           M2MetaError_MetaErrorT1 (vartok, (const char *) "base procedure {%EkEXCL} expects a variable as a parameter, seen {%1Ed} {%1&s}", 78, VarSym);
   10211              :         }
   10212              :     }
   10213              :   else
   10214              :     {
   10215            0 :       M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkEXCL} expects 1 or 2 parameters", 54);
   10216              :     }
   10217          771 :   M2Quads_PopN (NoOfParam+1);
   10218          771 : }
   10219              : 
   10220              : 
   10221              : /*
   10222              :    BuildTypeCoercion - builds the type coersion.
   10223              :                        Modula-2 allows types to be coersed with no runtime
   10224              :                        penility.
   10225              :                        It insists that the TSIZE(t1)=TSIZE(t2) where
   10226              :                        t2 variable := t2(variable of type t1).
   10227              :                        The ReturnVar on the stack is of type t2.
   10228              : 
   10229              :                        The Stack:
   10230              : 
   10231              : 
   10232              :                        Entry                      Exit
   10233              : 
   10234              :                 Ptr ->
   10235              :                        +----------------+
   10236              :                        | NoOfParam      |
   10237              :                        |----------------|
   10238              :                        | Param 1        |
   10239              :                        |----------------|
   10240              :                        | Param 2        |
   10241              :                        |----------------|
   10242              :                        .                .
   10243              :                        .                .
   10244              :                        .                .
   10245              :                        |----------------|
   10246              :                        | Param #        |                        <- Ptr
   10247              :                        |----------------|         +------------+
   10248              :                        | ProcSym | Type |         | ReturnVar  |
   10249              :                        |----------------|         |------------|
   10250              : 
   10251              :                        Quadruples:
   10252              : 
   10253              :                        CoerceOp  ReturnVar  Type  Param1
   10254              : 
   10255              :                        A type coercion will only be legal if the different
   10256              :                        types have exactly the same size.
   10257              :                        Since we can only decide this after M2Eval has processed
   10258              :                        the symbol table then we create a quadruple explaining
   10259              :                        the coercion taking place, the code generator can test
   10260              :                        this assertion and report an error if the type sizes
   10261              :                        differ.
   10262              : */
   10263              : 
   10264         2574 : static void BuildTypeCoercion (bool ConstExpr)
   10265              : {
   10266         2574 :   unsigned int resulttok;
   10267         2574 :   unsigned int proctok;
   10268         2574 :   unsigned int exptok;
   10269         2574 :   unsigned int r;
   10270         2574 :   unsigned int exp;
   10271         2574 :   unsigned int NoOfParam;
   10272         2574 :   unsigned int ReturnVar;
   10273         2574 :   unsigned int ProcSym;
   10274              : 
   10275         2574 :   M2Quads_PopT (&NoOfParam);
   10276         2574 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   10277         2574 :   proctok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   10278         2574 :   if (! (SymbolTable_IsAModula2Type (ProcSym)))
   10279              :     {
   10280            0 :       M2MetaError_MetaError1 ((const char *) "coersion expecting a type, seen {%1Ea} which is {%1Ed} {%1&s}", 61, ProcSym);
   10281              :     }
   10282         2574 :   if (NoOfParam == 1)
   10283              :     {
   10284         2574 :       PopTrwtok (&exp, &r, &exptok);
   10285         2574 :       MarkAsRead (r);
   10286         2574 :       resulttok = M2LexBuf_MakeVirtual2Tok (proctok, exptok);
   10287         2574 :       M2Quads_PopN (1);  /* Pop procedure.  */
   10288         2574 :       if (ConstExprError (ProcSym, exp, exptok, ConstExpr))  /* Pop procedure.  */
   10289              :         {
   10290            0 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
   10291            0 :           SymbolTable_PutVar (ReturnVar, ProcSym);  /* Set ReturnVar's TYPE.  */
   10292              :         }
   10293              :        /* Set ReturnVar's TYPE.  */
   10294         2574 :       else if ((SymbolTable_IsConst (exp)) || (SymbolTable_IsVar (exp)))
   10295              :         {
   10296              :           /* avoid dangling else.  */
   10297         5148 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (SymbolTable_IsConst (exp)));
   10298         2574 :           SymbolTable_PutVar (ReturnVar, ProcSym);  /* Set ReturnVar's TYPE.  */
   10299         2574 :           GenQuad (M2Quads_CoerceOp, ReturnVar, ProcSym, exp);  /* Set ReturnVar's TYPE.  */
   10300              :         }
   10301              :       else
   10302              :         {
   10303              :           /* avoid dangling else.  */
   10304            0 :           M2MetaError_MetaError2 ((const char *) "trying to coerse {%1EMRad} which is not a variable or constant into {%2ad}", 74, exp, ProcSym);
   10305            0 :           M2MetaError_MetaError2 ((const char *) "trying to coerse {%1ECad} which is not a variable or constant into {%2ad}", 73, exp, ProcSym);
   10306            0 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_RightValue);
   10307            0 :           SymbolTable_PutVar (ReturnVar, ProcSym);  /* Set ReturnVar's TYPE.  */
   10308              :         }
   10309         2574 :       M2Quads_PushTFtok (ReturnVar, ProcSym, resulttok);
   10310              :     }
   10311              :   else
   10312              :     {
   10313            0 :       M2MetaError_MetaError0 ((const char *) "{%E}only one parameter expected in a TYPE coersion", 50);
   10314              :     }
   10315         2574 : }
   10316              : 
   10317              : 
   10318              : /*
   10319              :    BuildRealFunctionCall - builds a function call.
   10320              :                            The Stack:
   10321              : 
   10322              : 
   10323              :                            Entry                      Exit
   10324              : 
   10325              :                     Ptr ->
   10326              :                            +----------------+
   10327              :                            | NoOfParam      |
   10328              :                            |----------------|
   10329              :                            | Param 1        |
   10330              :                            |----------------|
   10331              :                            | Param 2        |
   10332              :                            |----------------|
   10333              :                            .                .
   10334              :                            .                .
   10335              :                            .                .
   10336              :                            |----------------|
   10337              :                            | Param #        |                        <- Ptr
   10338              :                            |----------------|         +------------+
   10339              :                            | ProcSym | Type |         | ReturnVar  |
   10340              :                            |----------------|         |------------|
   10341              : */
   10342              : 
   10343        61948 : static void BuildRealFunctionCall (unsigned int tokno, bool ConstExpr)
   10344              : {
   10345        61948 :   unsigned int NoOfParam;
   10346        61948 :   unsigned int ProcSym;
   10347              : 
   10348        61948 :   M2Quads_PopT (&NoOfParam);
   10349        61948 :   M2Quads_PushT (NoOfParam);
   10350        61948 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+2));
   10351        61948 :   ProcSym = PCSymBuild_SkipConst (ProcSym);
   10352        61948 :   if (SymbolTable_IsVar (ProcSym))
   10353              :     {
   10354              :       /* Procedure Variable therefore get its type to see if it is a FOR "C" call.  */
   10355           94 :       ProcSym = SymbolTable_SkipType (M2Quads_OperandF (NoOfParam+2));
   10356              :     }
   10357        61948 :   if ((SymbolTable_IsDefImp (SymbolTable_GetScope (ProcSym))) && (SymbolTable_IsDefinitionForC (SymbolTable_GetScope (ProcSym))))
   10358              :     {
   10359         7342 :       BuildRealFuncProcCall (tokno, true, true, ConstExpr);
   10360              :     }
   10361              :   else
   10362              :     {
   10363        54606 :       BuildRealFuncProcCall (tokno, true, false, ConstExpr);
   10364              :     }
   10365        61936 : }
   10366              : 
   10367              : 
   10368              : /*
   10369              :    BuildPseudoFunctionCall - builds the pseudo function
   10370              :                              The Stack:
   10371              : 
   10372              : 
   10373              :                              Entry                      Exit
   10374              : 
   10375              :                       Ptr ->
   10376              :                              +----------------+
   10377              :                              | NoOfParam      |
   10378              :                              |----------------|
   10379              :                              | Param 1        |
   10380              :                              |----------------|
   10381              :                              | Param 2        |
   10382              :                              |----------------|
   10383              :                              .                .
   10384              :                              .                .
   10385              :                              .                .
   10386              :                              |----------------|
   10387              :                              | Param #        |                        <- Ptr
   10388              :                              |----------------|         +------------+
   10389              :                              | ProcSym | Type |         | ReturnVar  |
   10390              :                              |----------------|         |------------|
   10391              : 
   10392              : */
   10393              : 
   10394        42796 : static void BuildPseudoFunctionCall (bool ConstExpr)
   10395              : {
   10396        42796 :   unsigned int NoOfParam;
   10397        42796 :   unsigned int ProcSym;
   10398              : 
   10399        42796 :   M2Quads_PopT (&NoOfParam);
   10400        42796 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   10401        42796 :   ProcSym = PCSymBuild_SkipConst (ProcSym);
   10402        42796 :   M2Quads_PushT (NoOfParam);
   10403              :   /* Compile time stack restored to entry state.  */
   10404        42796 :   if (ProcSym == M2Base_High)
   10405              :     {
   10406         2978 :       BuildHighFunction ();
   10407              :     }
   10408        39818 :   else if (ProcSym == M2Base_LengthS)
   10409              :     {
   10410              :       /* avoid dangling else.  */
   10411          346 :       BuildLengthFunction (ProcSym, ConstExpr);
   10412              :     }
   10413        39472 :   else if (ProcSym == M2System_Adr)
   10414              :     {
   10415              :       /* avoid dangling else.  */
   10416         9711 :       BuildAdrFunction ();
   10417              :     }
   10418        29761 :   else if (ProcSym == M2Size_Size)
   10419              :     {
   10420              :       /* avoid dangling else.  */
   10421         2099 :       BuildSizeFunction ();
   10422              :     }
   10423        27662 :   else if (ProcSym == M2System_TSize)
   10424              :     {
   10425              :       /* avoid dangling else.  */
   10426         4774 :       BuildTSizeFunction ();
   10427              :     }
   10428        22888 :   else if (ProcSym == M2System_TBitSize)
   10429              :     {
   10430              :       /* avoid dangling else.  */
   10431         6496 :       BuildTBitSizeFunction ();
   10432              :     }
   10433        16392 :   else if (ProcSym == M2Base_Convert)
   10434              :     {
   10435              :       /* avoid dangling else.  */
   10436           12 :       BuildConvertFunction (ProcSym, ConstExpr);
   10437              :     }
   10438        16380 :   else if (ProcSym == M2Base_Odd)
   10439              :     {
   10440              :       /* avoid dangling else.  */
   10441           46 :       BuildOddFunction (ProcSym, ConstExpr);
   10442              :     }
   10443        16334 :   else if (ProcSym == M2Base_Abs)
   10444              :     {
   10445              :       /* avoid dangling else.  */
   10446          177 :       BuildAbsFunction (ProcSym, ConstExpr);
   10447              :     }
   10448        16157 :   else if (ProcSym == M2Base_Cap)
   10449              :     {
   10450              :       /* avoid dangling else.  */
   10451          125 :       BuildCapFunction (ProcSym, ConstExpr);
   10452              :     }
   10453        16032 :   else if (ProcSym == M2Base_Val)
   10454              :     {
   10455              :       /* avoid dangling else.  */
   10456         4920 :       BuildValFunction (ProcSym, ConstExpr);
   10457              :     }
   10458        11112 :   else if (ProcSym == M2Base_Chr)
   10459              :     {
   10460              :       /* avoid dangling else.  */
   10461         1024 :       BuildChrFunction (ProcSym, ConstExpr);
   10462              :     }
   10463        10088 :   else if (M2Base_IsOrd (ProcSym))
   10464              :     {
   10465              :       /* avoid dangling else.  */
   10466         4724 :       BuildOrdFunction (ProcSym, ConstExpr);
   10467              :     }
   10468         5364 :   else if (M2Base_IsInt (ProcSym))
   10469              :     {
   10470              :       /* avoid dangling else.  */
   10471            6 :       BuildIntFunction (ProcSym, ConstExpr);
   10472              :     }
   10473         5358 :   else if (M2Base_IsTrunc (ProcSym))
   10474              :     {
   10475              :       /* avoid dangling else.  */
   10476           60 :       BuildTruncFunction (ProcSym, ConstExpr);
   10477              :     }
   10478         5298 :   else if (M2Base_IsFloat (ProcSym))
   10479              :     {
   10480              :       /* avoid dangling else.  */
   10481           88 :       BuildFloatFunction (ProcSym, ConstExpr);
   10482              :     }
   10483         5210 :   else if (ProcSym == M2Base_Min)
   10484              :     {
   10485              :       /* avoid dangling else.  */
   10486         1250 :       BuildMinFunction ();
   10487              :     }
   10488         3960 :   else if (ProcSym == M2Base_Max)
   10489              :     {
   10490              :       /* avoid dangling else.  */
   10491         2032 :       BuildMaxFunction ();
   10492              :     }
   10493         1928 :   else if (ProcSym == M2System_AddAdr)
   10494              :     {
   10495              :       /* avoid dangling else.  */
   10496           36 :       BuildAddAdrFunction (ProcSym, ConstExpr);
   10497              :     }
   10498         1892 :   else if (ProcSym == M2System_SubAdr)
   10499              :     {
   10500              :       /* avoid dangling else.  */
   10501           12 :       BuildSubAdrFunction (ProcSym, ConstExpr);
   10502              :     }
   10503         1880 :   else if (ProcSym == M2System_DifAdr)
   10504              :     {
   10505              :       /* avoid dangling else.  */
   10506           12 :       BuildDifAdrFunction (ProcSym, ConstExpr);
   10507              :     }
   10508         1868 :   else if (ProcSym == M2System_Cast)
   10509              :     {
   10510              :       /* avoid dangling else.  */
   10511          156 :       BuildCastFunction (ProcSym, ConstExpr);
   10512              :     }
   10513         1712 :   else if (ProcSym == M2System_Shift)
   10514              :     {
   10515              :       /* avoid dangling else.  */
   10516          682 :       BuildShiftFunction ();
   10517              :     }
   10518         1030 :   else if (ProcSym == M2System_Rotate)
   10519              :     {
   10520              :       /* avoid dangling else.  */
   10521          406 :       BuildRotateFunction ();
   10522              :     }
   10523          624 :   else if (ProcSym == M2System_MakeAdr)
   10524              :     {
   10525              :       /* avoid dangling else.  */
   10526           12 :       BuildMakeAdrFunction ();
   10527              :     }
   10528          612 :   else if (ProcSym == M2Base_Re)
   10529              :     {
   10530              :       /* avoid dangling else.  */
   10531           60 :       BuildReFunction (ProcSym, ConstExpr);
   10532              :     }
   10533          552 :   else if (ProcSym == M2Base_Im)
   10534              :     {
   10535              :       /* avoid dangling else.  */
   10536           60 :       BuildImFunction (ProcSym, ConstExpr);
   10537              :     }
   10538          492 :   else if (ProcSym == M2Base_Cmplx)
   10539              :     {
   10540              :       /* avoid dangling else.  */
   10541          492 :       BuildCmplxFunction (ProcSym, ConstExpr);
   10542              :     }
   10543              :   else
   10544              :     {
   10545              :       /* avoid dangling else.  */
   10546            0 :       M2Error_InternalError ((const char *) "pseudo function not implemented yet", 35);
   10547              :     }
   10548        42781 : }
   10549              : 
   10550              : 
   10551              : /*
   10552              :    BuildAddAdrFunction - builds the pseudo procedure call ADDADR.
   10553              : 
   10554              :                          PROCEDURE ADDADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
   10555              : 
   10556              :                          Which returns address given by (addr + offset),
   10557              :                          [ the standard says that it _may_
   10558              :                            "raise an exception if this address is not valid."
   10559              :                            currently we do not generate any exception code ]
   10560              : 
   10561              :                          The Stack:
   10562              : 
   10563              :                          Entry                      Exit
   10564              : 
   10565              :                   Ptr ->
   10566              :                          +----------------+
   10567              :                          | NoOfParam      |
   10568              :                          |----------------|
   10569              :                          | Param 1        |
   10570              :                          |----------------|
   10571              :                          | Param 2        |                        <- Ptr
   10572              :                          |----------------|         +------------+
   10573              :                          | ProcSym | Type |         | ReturnVar  |
   10574              :                          |----------------|         |------------|
   10575              : */
   10576              : 
   10577           36 : static void BuildAddAdrFunction (unsigned int ProcSym, bool ConstExpr)
   10578              : {
   10579           36 :   unsigned int combinedtok;
   10580           36 :   unsigned int functok;
   10581           36 :   unsigned int vartok;
   10582           36 :   unsigned int optok;
   10583           36 :   unsigned int opa;
   10584           36 :   unsigned int ReturnVar;
   10585           36 :   unsigned int NoOfParam;
   10586           36 :   unsigned int OperandSym;
   10587           36 :   unsigned int VarSym;
   10588              : 
   10589           36 :   M2Quads_PopT (&NoOfParam);
   10590           36 :   functok = OperandTtok (NoOfParam+1);
   10591           36 :   if (NoOfParam == 2)
   10592              :     {
   10593           36 :       VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
   10594           36 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
   10595           36 :       OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
   10596           36 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   10597           36 :       combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
   10598           36 :       M2Quads_PopN (NoOfParam+1);
   10599           36 :       if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
   10600              :         {
   10601              :           /* Fake return result.  */
   10602            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
   10603              :         }
   10604           36 :       else if (SymbolTable_IsVar (VarSym))
   10605              :         {
   10606              :           /* avoid dangling else.  */
   10607           36 :           if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
   10608              :             {
   10609           36 :               ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
   10610           36 :               SymbolTable_PutVar (ReturnVar, M2System_Address);
   10611           36 :               opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
   10612           72 :               GenQuadOtok (combinedtok, M2Quads_AddOp, ReturnVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
   10613           36 :               M2Quads_PushTFtok (ReturnVar, M2System_Address, combinedtok);
   10614              :             }
   10615              :           else
   10616              :             {
   10617            0 :               M2MetaError_MetaErrorT1 (functok, (const char *) "the first parameter to ADDADR {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsdv}", 114, VarSym);
   10618            0 :               M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
   10619              :             }
   10620              :         }
   10621              :       else
   10622              :         {
   10623              :           /* avoid dangling else.  */
   10624            0 :           M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure ADDADR expects a variable of type ADDRESS or POINTER as its first parameter", 96);
   10625            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
   10626              :         }
   10627              :     }
   10628              :   else
   10629              :     {
   10630            0 :       M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure {%EkADDADR} expects 2 parameters", 53);
   10631            0 :       M2Quads_PopN (NoOfParam+1);
   10632            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, functok);
   10633              :     }
   10634           36 : }
   10635              : 
   10636              : 
   10637              : /*
   10638              :    BuildSubAdrFunction - builds the pseudo procedure call ADDADR.
   10639              : 
   10640              :                          PROCEDURE SUBADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
   10641              : 
   10642              :                          Which returns address given by (addr - offset),
   10643              :                          [ the standard says that it _may_
   10644              :                            "raise an exception if this address is not valid."
   10645              :                            currently we do not generate any exception code ]
   10646              : 
   10647              :                          The Stack:
   10648              : 
   10649              :                          Entry                      Exit
   10650              : 
   10651              :                   Ptr ->
   10652              :                          +----------------+
   10653              :                          | NoOfParam      |
   10654              :                          |----------------|
   10655              :                          | Param 1        |
   10656              :                          |----------------|
   10657              :                          | Param 2        |                        <- Ptr
   10658              :                          |----------------|         +------------+
   10659              :                          | ProcSym | Type |         | ReturnVar  |
   10660              :                          |----------------|         |------------|
   10661              : */
   10662              : 
   10663           12 : static void BuildSubAdrFunction (unsigned int ProcSym, bool ConstExpr)
   10664              : {
   10665           12 :   unsigned int functok;
   10666           12 :   unsigned int combinedtok;
   10667           12 :   unsigned int optok;
   10668           12 :   unsigned int vartok;
   10669           12 :   unsigned int ReturnVar;
   10670           12 :   unsigned int NoOfParam;
   10671           12 :   unsigned int OperandSym;
   10672           12 :   unsigned int opa;
   10673           12 :   unsigned int VarSym;
   10674              : 
   10675           12 :   M2Quads_PopT (&NoOfParam);
   10676           12 :   functok = OperandTtok (NoOfParam+1);
   10677           12 :   if (NoOfParam == 2)
   10678              :     {
   10679           12 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   10680           12 :       OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
   10681           12 :       VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
   10682           12 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
   10683           12 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
   10684           12 :       M2Quads_PopN (NoOfParam+1);
   10685           12 :       if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
   10686              :         {
   10687              :           /* Fake return result.  */
   10688            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
   10689              :         }
   10690           12 :       else if (SymbolTable_IsVar (VarSym))
   10691              :         {
   10692              :           /* avoid dangling else.  */
   10693           12 :           if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
   10694              :             {
   10695           12 :               ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
   10696           12 :               SymbolTable_PutVar (ReturnVar, M2System_Address);
   10697           12 :               opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
   10698           24 :               GenQuadOtok (combinedtok, M2Quads_SubOp, ReturnVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
   10699           12 :               M2Quads_PushTFtok (ReturnVar, M2System_Address, combinedtok);
   10700              :             }
   10701              :           else
   10702              :             {
   10703            0 :               M2MetaError_MetaErrorT1 (functok, (const char *) "the first parameter to {%EkSUBADR} {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsdv}", 119, VarSym);
   10704            0 :               M2Quads_PushTFtok (SymbolTable_MakeConstLit (vartok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, vartok);
   10705              :             }
   10706              :         }
   10707              :       else
   10708              :         {
   10709              :           /* avoid dangling else.  */
   10710            0 :           combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
   10711            0 :           M2MetaError_MetaErrorT0 (combinedtok, (const char *) "{%E}SYSTEM procedure {%EkSUBADR} expects a variable of type ADDRESS or POINTER as its first parameter", 101);
   10712            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
   10713              :         }
   10714              :     }
   10715              :   else
   10716              :     {
   10717            0 :       M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure {%EkSUBADR} expects 2 parameters", 53);
   10718            0 :       M2Quads_PopN (NoOfParam+1);
   10719            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, functok);
   10720              :     }
   10721           12 : }
   10722              : 
   10723              : 
   10724              : /*
   10725              :    BuildDifAdrFunction - builds the pseudo procedure call DIFADR.
   10726              : 
   10727              :                          PROCEDURE DIFADR (addr1, addr2: ADDRESS): INTEGER ;
   10728              : 
   10729              :                          Which returns address given by (addr1 - addr2),
   10730              :                          [ the standard says that it _may_
   10731              :                            "raise an exception if this address is invalid or
   10732              :                             address space is non-contiguous."
   10733              :                            currently we do not generate any exception code ]
   10734              : 
   10735              :                          The Stack:
   10736              : 
   10737              :                          Entry                      Exit
   10738              : 
   10739              :                   Ptr ->
   10740              :                          +----------------+
   10741              :                          | NoOfParam      |
   10742              :                          |----------------|
   10743              :                          | Param 1        |
   10744              :                          |----------------|
   10745              :                          | Param 2        |                        <- Ptr
   10746              :                          |----------------|         +------------+
   10747              :                          | ProcSym | Type |         | ReturnVar  |
   10748              :                          |----------------|         |------------|
   10749              : */
   10750              : 
   10751           12 : static void BuildDifAdrFunction (unsigned int ProcSym, bool ConstExpr)
   10752              : {
   10753           12 :   unsigned int functok;
   10754           12 :   unsigned int optok;
   10755           12 :   unsigned int vartok;
   10756           12 :   unsigned int combinedtok;
   10757           12 :   unsigned int TempVar;
   10758           12 :   unsigned int NoOfParam;
   10759           12 :   unsigned int OperandSym;
   10760           12 :   unsigned int opa;
   10761           12 :   unsigned int VarSym;
   10762              : 
   10763           12 :   M2Quads_PopT (&NoOfParam);
   10764           12 :   functok = OperandTtok (NoOfParam+1);
   10765           12 :   if (NoOfParam >= 1)
   10766              :     {
   10767           12 :       OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
   10768           12 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   10769              :     }
   10770              :   else
   10771              :     {
   10772              :       optok = functok;
   10773              :     }
   10774           12 :   if (NoOfParam == 2)
   10775              :     {
   10776           12 :       VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
   10777           12 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
   10778           12 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
   10779           12 :       M2Quads_PopN (NoOfParam+1);
   10780           12 :       if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
   10781              :         {
   10782              :           /* Fake return result.  */
   10783            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
   10784              :         }
   10785           12 :       else if (SymbolTable_IsVar (VarSym))
   10786              :         {
   10787              :           /* avoid dangling else.  */
   10788           12 :           if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
   10789              :             {
   10790           12 :               if ((IsReallyPointer (OperandSym)) || ((SymbolTable_GetSType (OperandSym)) == M2System_Address))
   10791              :                 {
   10792           12 :                   TempVar = SymbolTable_MakeTemporary (vartok, SymbolTable_RightValue);
   10793           12 :                   SymbolTable_PutVar (TempVar, M2System_Address);
   10794           12 :                   opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
   10795           24 :                   GenQuadOtok (combinedtok, M2Quads_SubOp, TempVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
   10796              :                   /* 
   10797              :                   Build macro: CONVERT( INTEGER, TempVar )
   10798              :   */
   10799           12 :                   M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
   10800           12 :                   M2Quads_PushTtok (M2Base_Integer, functok);
   10801           12 :                   M2Quads_PushTtok (TempVar, vartok);
   10802           12 :                   M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
   10803           12 :                   BuildConvertFunction (M2Base_Convert, ConstExpr);  /* Two parameters  */
   10804              :                 }
   10805              :               else
   10806              :                 {
   10807            0 :                   M2MetaError_MetaError1 ((const char *) "the second parameter to {%EkDIFADR} {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsdv}", 120, OperandSym);
   10808            0 :                   M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
   10809              :                 }
   10810              :             }
   10811              :           else
   10812              :             {
   10813            0 :               M2MetaError_MetaErrorT1 (vartok, (const char *) "the first parameter to {%EkDIFADR} {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsdv}", 119, VarSym);
   10814            0 :               M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
   10815              :             }
   10816              :         }
   10817              :       else
   10818              :         {
   10819              :           /* avoid dangling else.  */
   10820            0 :           M2MetaError_MetaError0 ((const char *) "{%E}SYSTEM procedure {%EkDIFADR} expects a variable of type ADDRESS or POINTER as its first parameter", 101);
   10821            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
   10822              :         }
   10823              :     }
   10824              :   else
   10825              :     {
   10826            0 :       combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
   10827            0 :       M2MetaError_MetaErrorT0 (combinedtok, (const char *) "{%E}SYSTEM procedure {%EkDIFADR} expects 2 parameters", 53);
   10828            0 :       M2Quads_PopN (NoOfParam+1);
   10829            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
   10830              :     }
   10831           12 : }
   10832              : 
   10833              : 
   10834              : /*
   10835              :    BuildHighFunction - checks the stack in preparation for generating
   10836              :                        quadruples which perform HIGH.
   10837              :                        This procedure does not alter the stack but
   10838              :                        determines whether, a, in HIGH(a) is an ArraySym
   10839              :                        or UnboundedSym.
   10840              :                        Both cases are different and appropriate quadruple
   10841              :                        generating routines are called.
   10842              : 
   10843              :                        The Stack:
   10844              : 
   10845              : 
   10846              :                        Entry                      Exit
   10847              : 
   10848              :                 Ptr ->
   10849              :                        +----------------+
   10850              :                        | NoOfParam      |
   10851              :                        |----------------|
   10852              :                        | Param 1        |
   10853              :                        |----------------|
   10854              :                        | Param 2        |
   10855              :                        |----------------|
   10856              :                        .                .
   10857              :                        .                .
   10858              :                        .                .
   10859              :                        |----------------|
   10860              :                        | Param #        |                        <- Ptr
   10861              :                        |----------------|         +------------+
   10862              :                        | ProcSym | Type |         | ReturnVar  |
   10863              :                        |----------------|         |------------|
   10864              : 
   10865              : */
   10866              : 
   10867         2978 : static void BuildHighFunction (void)
   10868              : {
   10869         2978 :   unsigned int functok;
   10870         2978 :   unsigned int combinedtok;
   10871         2978 :   unsigned int paramtok;
   10872         2978 :   unsigned int ProcSym;
   10873         2978 :   unsigned int Type;
   10874         2978 :   unsigned int NoOfParam;
   10875         2978 :   unsigned int Param;
   10876              : 
   10877         2978 :   M2Quads_PopT (&NoOfParam);
   10878         2978 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   10879         2978 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   10880         2978 :   BuildSizeCheckEnd (ProcSym);  /* quadruple generation now on  */
   10881         2978 :   if (NoOfParam == 1)  /* quadruple generation now on  */
   10882              :     {
   10883         2978 :       Param = static_cast<unsigned int> (M2Quads_OperandT (1));
   10884         2978 :       paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   10885         2978 :       combinedtok = M2LexBuf_MakeVirtualTok (paramtok, functok, paramtok);
   10886         2978 :       Type = SymbolTable_GetDType (Param);
   10887              :       /* Restore stack to original form  */
   10888         2978 :       M2Quads_PushT (NoOfParam);
   10889         2978 :       if (((! (SymbolTable_IsVar (Param))) && (! (SymbolTable_IsConstString (Param)))) && (! (SymbolTable_IsConst (Param))))
   10890              :         {
   10891              :           /* we cannot test for IsConst(Param) AND (GetSType(Param)=Char)  as the type might not be assigned yet  */
   10892            0 :           M2MetaError_MetaError1 ((const char *) "base procedure {%EkHIGH} expects a variable or string constant as its parameter {%1d:rather than {%1d}} {%1asa}", 111, Param);
   10893              :         }
   10894         2978 :       else if ((Type != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (Type)))
   10895              :         {
   10896              :           /* avoid dangling else.  */
   10897         2744 :           BuildHighFromUnbounded (combinedtok);
   10898              :         }
   10899              :       else
   10900              :         {
   10901              :           /* avoid dangling else.  */
   10902          234 :           BuildConstHighFromSym (combinedtok);
   10903              :         }
   10904              :     }
   10905              :   else
   10906              :     {
   10907            0 :       M2MetaError_MetaError0 ((const char *) "base procedure {%EkHIGH} requires one parameter", 47);
   10908            0 :       M2Quads_PopN (2);
   10909            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
   10910              :     }
   10911         2978 : }
   10912              : 
   10913              : 
   10914              : /*
   10915              :    BuildConstHighFromSym - builds the pseudo function HIGH from an Sym.
   10916              :                            Sym is a constant or an array which has constant bounds
   10917              :                            and therefore it can be calculated at compile time.
   10918              : 
   10919              :                            The Stack:
   10920              : 
   10921              : 
   10922              :                            Entry                      Exit
   10923              : 
   10924              :                    Ptr ->
   10925              :                            +----------------+
   10926              :                            | NoOfParam      |
   10927              :                            |----------------|
   10928              :                            | Param 1        |
   10929              :                            |----------------|
   10930              :                            | Param 2        |
   10931              :                            |----------------|
   10932              :                            .                .
   10933              :                            .                .
   10934              :                            .                .
   10935              :                            |----------------|
   10936              :                            | Param #        |                        <- Ptr
   10937              :                            |----------------|         +------------+
   10938              :                            | ProcSym | Type |         | ReturnVar  |
   10939              :                            |----------------|         |------------|
   10940              : */
   10941              : 
   10942          234 : static void BuildConstHighFromSym (unsigned int tok)
   10943              : {
   10944          234 :   unsigned int NoOfParam;
   10945          234 :   unsigned int ReturnVar;
   10946              : 
   10947          234 :   M2Quads_PopT (&NoOfParam);
   10948          234 :   ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
   10949          234 :   SymbolTable_PutConst (ReturnVar, M2Base_Cardinal);
   10950          234 :   GenHigh (tok, ReturnVar, 1, M2Quads_OperandT (1));
   10951          234 :   M2Quads_PopN (NoOfParam+1);
   10952          234 :   M2Quads_PushTtok (ReturnVar, tok);
   10953          234 : }
   10954              : 
   10955              : 
   10956              : /*
   10957              :    BuildHighFromUnbounded - builds the pseudo function HIGH from an
   10958              :                             UnboundedSym.
   10959              : 
   10960              :                             The Stack:
   10961              : 
   10962              : 
   10963              :                             Entry                      Exit
   10964              : 
   10965              :                      Ptr ->
   10966              :                             +----------------+
   10967              :                             | NoOfParam      |
   10968              :                             |----------------|
   10969              :                             | Param #        |                        <- Ptr
   10970              :                             |----------------|         +------------+
   10971              :                             | ProcSym | Type |         | ReturnVar  |
   10972              :                             |----------------|         |------------|
   10973              : 
   10974              : */
   10975              : 
   10976         2744 : static void BuildHighFromUnbounded (unsigned int tok)
   10977              : {
   10978         2744 :   unsigned int Dim;
   10979         2744 :   unsigned int NoOfParam;
   10980         2744 :   unsigned int ReturnVar;
   10981              : 
   10982         2744 :   M2Quads_PopT (&NoOfParam);
   10983         2744 :   M2Debug_Assert (NoOfParam == 1);
   10984         2744 :   ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
   10985         2744 :   SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
   10986         2744 :   Dim = static_cast<unsigned int> (OperandD (1));
   10987         2744 :   Dim += 1;
   10988         2744 :   if (Dim > 1)
   10989              :     {
   10990           36 :       GenHigh (tok, ReturnVar, Dim, M2Quads_OperandA (1));
   10991              :     }
   10992              :   else
   10993              :     {
   10994         2708 :       GenHigh (tok, ReturnVar, Dim, M2Quads_OperandT (1));
   10995              :     }
   10996         2744 :   M2Quads_PopN (2);
   10997         2744 :   M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), tok);
   10998         2744 : }
   10999              : 
   11000              : 
   11001              : /*
   11002              :    GetQualidentImport - returns the symbol as if it were qualified from, module.n.
   11003              :                         This is used to reference runtime support procedures and an
   11004              :                         error is generated if the symbol cannot be obtained.
   11005              : */
   11006              : 
   11007        47459 : static unsigned int GetQualidentImport (unsigned int tokno, NameKey_Name n, NameKey_Name module)
   11008              : {
   11009        47459 :   unsigned int sym;
   11010        47459 :   unsigned int ModSym;
   11011              : 
   11012        47459 :   ModSym = M2Batch_MakeDefinitionSource (tokno, module);
   11013        47459 :   if (ModSym == SymbolTable_NulSym)
   11014              :     {
   11015            0 :       M2MetaError_MetaErrorNT2 (tokno, (const char *) "module %a cannot be found and is needed to import %a", 52, module, n);
   11016            0 :       M2Error_FlushErrors ();
   11017            0 :       return SymbolTable_NulSym;
   11018              :     }
   11019        47459 :   M2Debug_Assert (SymbolTable_IsDefImp (ModSym));
   11020        47459 :   if (((SymbolTable_GetExported (tokno, ModSym, n)) == SymbolTable_NulSym) || (SymbolTable_IsUnknown (SymbolTable_GetExported (tokno, ModSym, n))))
   11021              :     {
   11022            0 :       sym = SymbolTable_GetExported (tokno, ModSym, n);
   11023            0 :       if (SymbolTable_IsUnknown (sym))
   11024              :         {
   11025              :           /* Spellcheck.  */
   11026            0 :           M2MetaError_MetaErrorN2 ((const char *) "module %a does not export procedure %a which is a necessary component of the runtime system, hint check the path and library/language variant", 141, module, n);
   11027            0 :           M2MetaError_MetaErrorT1 (tokno, (const char *) "unknown symbol {%1&s}", 21, sym);
   11028            0 :           SymbolTable_UnknownReported (sym);
   11029              :         }
   11030              :       else
   11031              :         {
   11032            0 :           M2MetaError_MetaErrorN2 ((const char *) "module %a does not export procedure %a which is a necessary component of the runtime system, hint check the path and library/language variant", 141, module, n);
   11033              :         }
   11034            0 :       M2Error_FlushErrors ();
   11035            0 :       return SymbolTable_NulSym;
   11036              :     }
   11037        47459 :   return SymbolTable_GetExported (tokno, M2Batch_MakeDefinitionSource (tokno, module), n);
   11038              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   11039              :   __builtin_unreachable ();
   11040              : }
   11041              : 
   11042              : 
   11043              : /*
   11044              :    ConstExprError - return TRUE if a constant expression is being built and Var is a variable.
   11045              : */
   11046              : 
   11047        71945 : static bool ConstExprError (unsigned int Func, unsigned int Var, unsigned int optok, bool ConstExpr)
   11048              : {
   11049        71945 :   if (ConstExpr && (SymbolTable_IsVar (Var)))
   11050              :     {
   11051          108 :       M2MetaError_MetaErrorT2 (optok, (const char *) "the procedure function {%1Ea} is being called from within a constant expression and therefore the parameter {%2a} must be a constant, seen a {%2dav} {%2&s}", 155, Func, Var);
   11052          108 :       return true;
   11053              :     }
   11054              :   else
   11055              :     {
   11056        71837 :       return false;
   11057              :     }
   11058              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   11059              :   __builtin_unreachable ();
   11060              : }
   11061              : 
   11062              : 
   11063              : /*
   11064              :    DeferMakeLengthConst - creates a constant which contains the length of string, sym.
   11065              : */
   11066              : 
   11067           66 : static unsigned int DeferMakeLengthConst (unsigned int tok, unsigned int sym)
   11068              : {
   11069           66 :   unsigned int const_;
   11070              : 
   11071           66 :   const_ = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
   11072           66 :   SymbolTable_PutVar (const_, M2Base_ZType);
   11073          132 :   GenQuadO (tok, M2Quads_StringLengthOp, const_, 0, sym, false);
   11074           66 :   return const_;
   11075              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   11076              :   __builtin_unreachable ();
   11077              : }
   11078              : 
   11079              : 
   11080              : /*
   11081              :    BuildLengthFunction - builds the inline standard function LENGTH.
   11082              : 
   11083              :                          The Stack:
   11084              : 
   11085              : 
   11086              :                          Entry                      Exit
   11087              : 
   11088              :                   Ptr ->
   11089              :                          +----------------+
   11090              :                          | NoOfParam      |
   11091              :                          |----------------|
   11092              :                          | Param 1        |                        <- Ptr
   11093              :                          |----------------|         +------------+
   11094              :                          | ProcSym | Type |         | ReturnVar  |
   11095              :                          |----------------|         |------------|
   11096              : 
   11097              : */
   11098              : 
   11099          346 : static void BuildLengthFunction (unsigned int Function, bool ConstExpr)
   11100              : {
   11101          346 :   unsigned int combinedtok;
   11102          346 :   unsigned int paramtok;
   11103          346 :   unsigned int functok;
   11104          346 :   unsigned int ProcSym;
   11105          346 :   unsigned int Type;
   11106          346 :   unsigned int NoOfParam;
   11107          346 :   unsigned int Param;
   11108          346 :   unsigned int ReturnVar;
   11109              : 
   11110          346 :   M2Quads_PopT (&NoOfParam);
   11111          346 :   Param = static_cast<unsigned int> (M2Quads_OperandT (1));
   11112          346 :   paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   11113          346 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11114              :   /* Restore stack to origional form.  */
   11115          346 :   M2Quads_PushT (NoOfParam);
   11116          346 :   Type = SymbolTable_GetSType (Param);  /* Get the type from the symbol, not the stack.  */
   11117          346 :   if (NoOfParam != 1)  /* Get the type from the symbol, not the stack.  */
   11118              :     {
   11119            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "base procedure {%1EkLENGTH} expects 1 parameter, seen {%1n} parameters", 70, NoOfParam);
   11120              :     }
   11121          346 :   if (NoOfParam >= 1)
   11122              :     {
   11123          346 :       combinedtok = M2LexBuf_MakeVirtual2Tok (functok, paramtok);
   11124          346 :       if ((SymbolTable_IsConst (Param)) && ((SymbolTable_GetSType (Param)) == M2Base_Char))
   11125              :         {
   11126            6 :           M2Quads_PopT (&NoOfParam);
   11127            6 :           M2Quads_PopN (NoOfParam+1);
   11128            6 :           ReturnVar = SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal);
   11129            6 :           M2Quads_PushTtok (ReturnVar, combinedtok);
   11130              :         }
   11131          340 :       else if (SymbolTable_IsConstString (Param))
   11132              :         {
   11133              :           /* avoid dangling else.  */
   11134           48 :           M2Quads_PopT (&NoOfParam);
   11135           48 :           ReturnVar = DeferMakeLengthConst (combinedtok, M2Quads_OperandT (1));
   11136           48 :           M2Quads_PopN (NoOfParam+1);
   11137           48 :           M2Quads_PushTtok (ReturnVar, combinedtok);
   11138              :         }
   11139              :       else
   11140              :         {
   11141              :           /* avoid dangling else.  */
   11142          292 :           ProcSym = GetQualidentImport (functok, NameKey_MakeKey ((const char *) "Length", 6), NameKey_MakeKey ((const char *) "M2RTS", 5));
   11143          292 :           if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
   11144              :             {
   11145          292 :               M2Quads_PopT (&NoOfParam);
   11146          292 :               if (SymbolTable_IsConst (Param))
   11147              :                 {
   11148              :                   /* This can be folded in M2GenGCC.  */
   11149            0 :                   ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_ImmediateValue);
   11150            0 :                   SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
   11151            0 :                   GenQuad (M2Quads_StandardFunctionOp, ReturnVar, ProcSym, Param);
   11152            0 :                   M2Quads_PopN (NoOfParam+1);
   11153            0 :                   M2Quads_PushTtok (ReturnVar, combinedtok);
   11154              :                 }
   11155          292 :               else if (ConstExprError (Function, Param, paramtok, ConstExpr))
   11156              :                 {
   11157              :                   /* avoid dangling else.  */
   11158              :                   /* Fake a result as we have detected and reported an error.  */
   11159            6 :                   M2Quads_PopN (NoOfParam+1);
   11160            6 :                   ReturnVar = SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal);
   11161            6 :                   M2Quads_PushTtok (ReturnVar, combinedtok);
   11162              :                 }
   11163              :               else
   11164              :                 {
   11165              :                   /* avoid dangling else.  */
   11166              :                   /* We must resolve this at runtime or in the GCC optimizer.  */
   11167          286 :                   M2Quads_PopTF (&Param, &Type);
   11168          286 :                   M2Quads_PopN (NoOfParam);
   11169          286 :                   M2Quads_PushTtok (ProcSym, functok);
   11170          286 :                   M2Quads_PushTFtok (Param, Type, paramtok);
   11171          286 :                   M2Quads_PushT (NoOfParam);
   11172          286 :                   BuildRealFunctionCall (functok, false);
   11173              :                 }
   11174              :             }
   11175              :           else
   11176              :             {
   11177            0 :               M2Quads_PopT (&NoOfParam);
   11178            0 :               M2Quads_PopN (NoOfParam+1);
   11179            0 :               M2Quads_PushTtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), combinedtok);
   11180            0 :               M2MetaError_MetaErrorT0 (functok, (const char *) "no procedure Length found for substitution to the standard function {%1EkLENGTH} which is required to calculate non constant string lengths", 139);
   11181              :             }
   11182              :         }
   11183              :     }
   11184              :   else
   11185              :     {
   11186              :       /* NoOfParam is _very_ wrong, we flush all outstanding errors  */
   11187            0 :       M2Error_FlushErrors ();
   11188              :     }
   11189          346 : }
   11190              : 
   11191              : 
   11192              : /*
   11193              :    BuildOddFunction - builds the pseudo procedure call ODD.
   11194              :                       This procedure is actually a "macro" for
   11195              :                       ORD(x) --> VAL(BOOLEAN, x MOD 2)
   11196              :                       However we cannot push tokens back onto the input stack
   11197              :                       because the compiler is currently building a function
   11198              :                       call and expecting a ReturnVar on the stack.
   11199              :                       Hence we manipulate the stack and call
   11200              :                       BuildConvertFunction.
   11201              : 
   11202              :                       The Stack:
   11203              : 
   11204              : 
   11205              :                       Entry                      Exit
   11206              : 
   11207              :                Ptr ->
   11208              :                       +----------------+
   11209              :                       | NoOfParam      |
   11210              :                       |----------------|
   11211              :                       | Param 1        |
   11212              :                       |----------------|
   11213              :                       | Param 2        |
   11214              :                       |----------------|
   11215              :                       .                .
   11216              :                       .                .
   11217              :                       .                .
   11218              :                       |----------------|
   11219              :                       | Param #        |
   11220              :                       |----------------|
   11221              :                       | ProcSym | Type |         Empty
   11222              :                       |----------------|
   11223              : */
   11224              : 
   11225           46 : static void BuildOddFunction (unsigned int ProcSym, bool ConstExpr)
   11226              : {
   11227           46 :   unsigned int combinedtok;
   11228           46 :   unsigned int optok;
   11229           46 :   unsigned int functok;
   11230           46 :   unsigned int NoOfParam;
   11231           46 :   unsigned int Res;
   11232           46 :   unsigned int Var;
   11233              : 
   11234           46 :   M2Quads_PopT (&NoOfParam);
   11235           46 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11236           46 :   if (NoOfParam == 1)
   11237              :     {
   11238           46 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   11239           46 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   11240           46 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
   11241           46 :       if (ConstExprError (ProcSym, Var, optok, ConstExpr))
   11242              :         {
   11243              :           /* Nothing to do.  */
   11244            6 :           M2Quads_PushTtok (M2Base_False, combinedtok);
   11245              :         }
   11246           40 :       else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   11247              :         {
   11248              :           /* avoid dangling else.  */
   11249           40 :           M2Quads_PopN (NoOfParam+1);
   11250              :           /* compute (x MOD 2)  */
   11251           40 :           M2Quads_PushTFtok (Var, SymbolTable_GetSType (Var), optok);
   11252           40 :           M2Quads_PushT (M2Reserved_ModTok);
   11253           40 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (optok, NameKey_MakeKey ((const char *) "2", 1), M2Base_ZType), M2Base_ZType, optok);
   11254           40 :           M2Quads_BuildBinaryOp ();
   11255           40 :           M2Quads_PopT (&Res);
   11256              :           /* compute IF ...=0  */
   11257           40 :           M2Quads_PushTtok (Res, optok);
   11258           40 :           M2Quads_PushT (M2Reserved_EqualTok);
   11259           40 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (optok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType), M2Base_ZType, optok);
   11260           40 :           M2Quads_BuildRelOp (combinedtok);
   11261           40 :           M2Quads_BuildThenIf ();
   11262           40 :           Res = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
   11263           40 :           SymbolTable_PutVar (Res, M2Base_Boolean);
   11264           40 :           M2Quads_PushTtok (Res, combinedtok);
   11265           40 :           M2Quads_PushTtok (M2Base_False, combinedtok);
   11266           40 :           M2Quads_BuildAssignment (combinedtok);
   11267           40 :           M2Quads_BuildElse ();
   11268           40 :           M2Quads_PushTtok (Res, combinedtok);
   11269           40 :           M2Quads_PushTtok (M2Base_True, combinedtok);
   11270           40 :           M2Quads_BuildAssignment (combinedtok);
   11271           40 :           M2Quads_BuildEndIf ();
   11272           40 :           M2Quads_PushTtok (Res, combinedtok);
   11273              :         }
   11274              :       else
   11275              :         {
   11276              :           /* avoid dangling else.  */
   11277            0 :           M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%1EkODD} must be a variable or constant, seen {%1ad} {%1&s}", 77, Var);
   11278            0 :           M2Quads_PushTtok (M2Base_False, combinedtok);
   11279              :         }
   11280              :     }
   11281              :   else
   11282              :     {
   11283            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%E1kODD} only has one parameter, seen {%1n} parameters", 76, NoOfParam);
   11284            0 :       M2Quads_PushTtok (M2Base_False, functok);
   11285              :     }
   11286           46 : }
   11287              : 
   11288              : 
   11289              : /*
   11290              :    BuildAbsFunction - builds a call to the standard function ABS.
   11291              : 
   11292              :                       We cannot implement it as a macro or inline an
   11293              :                       IF THEN statement as the IF THEN ELSE requires
   11294              :                       we write the value to the same variable (or constant)
   11295              :                       twice. The macro implementation will fail as
   11296              :                       the compiler maybe building a function
   11297              :                       call and expecting a ReturnVar on the stack.
   11298              :                       The only method to implement this is to pass it to the
   11299              :                       gcc backend.
   11300              : 
   11301              :                       The Stack:
   11302              : 
   11303              : 
   11304              :                       Entry                      Exit
   11305              : 
   11306              :                Ptr ->
   11307              :                       +----------------+
   11308              :                       | NoOfParam      |
   11309              :                       |----------------|
   11310              :                       | Param 1        |
   11311              :                       |----------------|
   11312              :                       | Param 2        |
   11313              :                       |----------------|
   11314              :                       .                .
   11315              :                       .                .
   11316              :                       .                .
   11317              :                       |----------------|
   11318              :                       | Param #        |
   11319              :                       |----------------|
   11320              :                       | ProcSym | Type |         Empty
   11321              :                       |----------------|
   11322              : */
   11323              : 
   11324          177 : static void BuildAbsFunction (unsigned int ProcSym, bool ConstExpr)
   11325              : {
   11326          177 :   unsigned int vartok;
   11327          177 :   unsigned int functok;
   11328          177 :   unsigned int combinedtok;
   11329          177 :   unsigned int NoOfParam;
   11330          177 :   unsigned int Res;
   11331          177 :   unsigned int Var;
   11332              : 
   11333          177 :   M2Quads_PopT (&NoOfParam);
   11334          177 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11335          177 :   if (NoOfParam == 1)
   11336              :     {
   11337          177 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   11338          177 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   11339          177 :       M2Quads_PopN (NoOfParam+1);
   11340          177 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
   11341          177 :       if (ConstExprError (ProcSym, Var, vartok, ConstExpr))
   11342              :         {
   11343              :           /* Create fake result.  */
   11344           24 :           Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   11345           12 :           SymbolTable_PutVar (Res, SymbolTable_GetSType (Var));
   11346           12 :           M2Quads_PushTFtok (Res, SymbolTable_GetSType (Var), combinedtok);
   11347              :         }
   11348          165 :       else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   11349              :         {
   11350              :           /* avoid dangling else.  */
   11351          316 :           Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   11352          158 :           SymbolTable_PutVar (Res, SymbolTable_GetSType (Var));
   11353          316 :           GenQuadO (combinedtok, M2Quads_StandardFunctionOp, Res, ProcSym, Var, false);
   11354          158 :           M2Quads_PushTFtok (Res, SymbolTable_GetSType (Var), combinedtok);
   11355              :         }
   11356              :       else
   11357              :         {
   11358              :           /* avoid dangling else.  */
   11359            7 :           M2MetaError_MetaErrorT1 (vartok, (const char *) "the parameter to {%AkABS} must be a variable or constant, seen {%1ad} {%1&s}", 76, Var);
   11360              :         }
   11361              :     }
   11362              :   else
   11363              :     {
   11364            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkABS} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
   11365              :     }
   11366          170 : }
   11367              : 
   11368              : 
   11369              : /*
   11370              :    BuildCapFunction - builds the pseudo procedure call CAP.
   11371              :                       We generate a the following quad:
   11372              : 
   11373              : 
   11374              :                       StandardFunctionOp  ReturnVal  Cap  Param1
   11375              : 
   11376              :                       The Stack:
   11377              : 
   11378              : 
   11379              :                       Entry                      Exit
   11380              : 
   11381              :                Ptr ->
   11382              :                       +----------------+
   11383              :                       | NoOfParam = 1  |
   11384              :                       |----------------|
   11385              :                       | Param 1        |
   11386              :                       |----------------|         +-------------+
   11387              :                       | ProcSym | Type |         | ReturnVal   |
   11388              :                       |----------------|         |-------------|
   11389              : */
   11390              : 
   11391          125 : static void BuildCapFunction (unsigned int ProcSym, bool ConstExpr)
   11392              : {
   11393          125 :   unsigned int optok;
   11394          125 :   unsigned int functok;
   11395          125 :   unsigned int combinedtok;
   11396          125 :   unsigned int NoOfParam;
   11397          125 :   unsigned int Res;
   11398          125 :   unsigned int Var;
   11399              : 
   11400          125 :   M2Quads_PopT (&NoOfParam);
   11401          125 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11402          125 :   if (NoOfParam == 1)
   11403              :     {
   11404          125 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   11405          125 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   11406          125 :       M2Quads_PopN (NoOfParam+1);
   11407          125 :       if (ConstExprError (ProcSym, Var, optok, ConstExpr))
   11408              :         {
   11409              :           /* Create fake result.  */
   11410           12 :           combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
   11411           24 :           Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   11412           12 :           SymbolTable_PutVar (Res, M2Base_Char);
   11413           12 :           M2Quads_PushTFtok (Res, M2Base_Char, combinedtok);
   11414              :         }
   11415          113 :       else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   11416              :         {
   11417              :           /* avoid dangling else.  */
   11418          112 :           combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
   11419          224 :           Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   11420          112 :           SymbolTable_PutVar (Res, M2Base_Char);
   11421          224 :           GenQuadO (combinedtok, M2Quads_StandardFunctionOp, Res, ProcSym, Var, false);
   11422          112 :           M2Quads_PushTFtok (Res, M2Base_Char, combinedtok);
   11423              :         }
   11424              :       else
   11425              :         {
   11426              :           /* avoid dangling else.  */
   11427            1 :           M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%AkCAP} must be a variable or constant, seen {%1ad} {%1&s}", 76, Var);
   11428              :         }
   11429              :     }
   11430              :   else
   11431              :     {
   11432            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkCAP} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
   11433              :     }
   11434          124 : }
   11435              : 
   11436              : 
   11437              : /*
   11438              :    BuildChrFunction - builds the pseudo procedure call CHR.
   11439              :                       This procedure is actually a "macro" for
   11440              :                       CHR(x) --> CONVERT(CHAR, x)
   11441              :                       However we cannot push tokens back onto the input stack
   11442              :                       because the compiler is currently building a function
   11443              :                       call and expecting a ReturnVar on the stack.
   11444              :                       Hence we manipulate the stack and call
   11445              :                       BuildConvertFunction.
   11446              : 
   11447              :                       The Stack:
   11448              : 
   11449              : 
   11450              :                       Entry                      Exit
   11451              : 
   11452              :                Ptr ->
   11453              :                       +----------------+
   11454              :                       | NoOfParam      |
   11455              :                       |----------------|
   11456              :                       | Param 1        |
   11457              :                       |----------------|
   11458              :                       | Param 2        |
   11459              :                       |----------------|
   11460              :                       .                .
   11461              :                       .                .
   11462              :                       .                .
   11463              :                       |----------------|
   11464              :                       | Param #        |
   11465              :                       |----------------|
   11466              :                       | ProcSym | Type |         Empty
   11467              :                       |----------------|
   11468              : */
   11469              : 
   11470         1024 : static void BuildChrFunction (unsigned int ProcSym, bool ConstExpr)
   11471              : {
   11472         1024 :   unsigned int functok;
   11473         1024 :   unsigned int combinedtok;
   11474         1024 :   unsigned int optok;
   11475         1024 :   unsigned int ReturnVar;
   11476         1024 :   unsigned int NoOfParam;
   11477         1024 :   unsigned int Var;
   11478              : 
   11479         1024 :   M2Quads_PopT (&NoOfParam);
   11480         1024 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11481         1024 :   if (NoOfParam == 1)
   11482              :     {
   11483         1024 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   11484         1024 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   11485         1024 :       M2Quads_PopN (NoOfParam+1);
   11486         1024 :       if (ConstExprError (ProcSym, Var, optok, ConstExpr))
   11487              :         {
   11488              :           /* Generate fake result.  */
   11489           12 :           combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
   11490           24 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   11491           12 :           SymbolTable_PutVar (ReturnVar, M2Base_Char);
   11492           12 :           M2Quads_PushTFtok (ReturnVar, M2Base_Char, combinedtok);
   11493              :         }
   11494         1012 :       else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   11495              :         {
   11496              :           /* avoid dangling else.  */
   11497              :           /* 
   11498              :             Build macro: CONVERT( CHAR, Var )
   11499              :   */
   11500         1011 :           M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
   11501         1011 :           M2Quads_PushTtok (M2Base_Char, functok);
   11502         1011 :           M2Quads_PushTtok (Var, optok);
   11503         1011 :           M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
   11504         1011 :           BuildConvertFunction (M2Base_Convert, ConstExpr);  /* Two parameters  */
   11505              :         }
   11506              :       else
   11507              :         {
   11508              :           /* avoid dangling else.  */
   11509            1 :           M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%AkCHR} must be a variable or constant, seen {%1ad} {%1&s}", 76, Var);
   11510              :         }
   11511              :     }
   11512              :   else
   11513              :     {
   11514            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkCHR} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
   11515              :     }
   11516         1023 : }
   11517              : 
   11518              : 
   11519              : /*
   11520              :    BuildOrdFunction - builds the pseudo procedure call ORD.
   11521              :                       This procedure is actually a "macro" for
   11522              :                       ORD(x) --> CONVERT(GetSType(sym), x)
   11523              :                       However we cannot push tokens back onto the input stack
   11524              :                       because the compiler is currently building a function
   11525              :                       call and expecting a ReturnVar on the stack.
   11526              :                       Hence we manipulate the stack and call
   11527              :                       BuildConvertFunction.
   11528              : 
   11529              :                       The Stack:
   11530              : 
   11531              : 
   11532              :                       Entry                      Exit
   11533              : 
   11534              :                Ptr ->
   11535              :                       +----------------+
   11536              :                       | NoOfParam      |
   11537              :                       |----------------|
   11538              :                       | Param 1        |
   11539              :                       |----------------|
   11540              :                       | Param 2        |
   11541              :                       |----------------|
   11542              :                       .                .
   11543              :                       .                .
   11544              :                       .                .
   11545              :                       |----------------|
   11546              :                       | Param #        |
   11547              :                       |----------------|
   11548              :                       | ProcSym | Type |         Empty
   11549              :                       |----------------|
   11550              : */
   11551              : 
   11552         4724 : static void BuildOrdFunction (unsigned int Sym, bool ConstExpr)
   11553              : {
   11554         4724 :   unsigned int combinedtok;
   11555         4724 :   unsigned int functok;
   11556         4724 :   unsigned int optok;
   11557         4724 :   unsigned int ReturnVar;
   11558         4724 :   unsigned int NoOfParam;
   11559         4724 :   unsigned int Type;
   11560         4724 :   unsigned int Var;
   11561              : 
   11562         4724 :   M2Quads_PopT (&NoOfParam);
   11563         4724 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11564         4724 :   if (NoOfParam == 1)
   11565              :     {
   11566         4724 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   11567         4724 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   11568         4724 :       M2Quads_PopN (NoOfParam+1);
   11569         4724 :       if (ConstExprError (Sym, Var, optok, ConstExpr))
   11570              :         {
   11571              :           /* Generate fake result.  */
   11572           12 :           combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
   11573           24 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   11574           12 :           SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
   11575           12 :           M2Quads_PushTFtok (ReturnVar, M2Base_Cardinal, combinedtok);
   11576              :         }
   11577         4712 :       else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   11578              :         {
   11579              :           /* avoid dangling else.  */
   11580         4712 :           Type = SymbolTable_GetSType (Sym);
   11581              :           /* 
   11582              :             Build macro: CONVERT( CARDINAL, Var )
   11583              :   */
   11584         4712 :           M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
   11585         4712 :           M2Quads_PushTtok (Type, optok);
   11586         4712 :           M2Quads_PushTtok (Var, optok);
   11587         4712 :           M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
   11588         4712 :           BuildConvertFunction (M2Base_Convert, ConstExpr);  /* Two parameters  */
   11589              :         }
   11590              :       else
   11591              :         {
   11592              :           /* avoid dangling else.  */
   11593            0 :           M2MetaError_MetaErrorT2 (optok, (const char *) "the parameter to {%1Aa} must be a variable or constant, seen {%2ad} {%2&s}", 74, Sym, Var);
   11594              :         }
   11595              :     }
   11596              :   else
   11597              :     {
   11598            0 :       M2MetaError_MetaErrorT2 (functok, (const char *) "the pseudo procedure {%1Aa} only has one parameter, seen {%2n} parameters", 73, Sym, NoOfParam);
   11599              :     }
   11600         4724 : }
   11601              : 
   11602              : 
   11603              : /*
   11604              :    BuildIntFunction - builds the pseudo procedure call INT.
   11605              :                       This procedure is actually a "macro" for
   11606              :                       INT(x) --> CONVERT(INTEGER, x)
   11607              :                       However we cannot push tokens back onto the input stack
   11608              :                       because the compiler is currently building a function
   11609              :                       call and expecting a ReturnVar on the stack.
   11610              :                       Hence we manipulate the stack and call
   11611              :                       BuildConvertFunction.
   11612              : 
   11613              :                       The Stack:
   11614              : 
   11615              : 
   11616              :                       Entry                      Exit
   11617              : 
   11618              :                Ptr ->
   11619              :                       +----------------+
   11620              :                       | NoOfParam      |
   11621              :                       |----------------|
   11622              :                       | Param 1        |
   11623              :                       |----------------|
   11624              :                       | Param 2        |
   11625              :                       |----------------|
   11626              :                       .                .
   11627              :                       .                .
   11628              :                       .                .
   11629              :                       |----------------|
   11630              :                       | Param #        |
   11631              :                       |----------------|
   11632              :                       | ProcSym | Type |         Empty
   11633              :                       |----------------|
   11634              : */
   11635              : 
   11636            6 : static void BuildIntFunction (unsigned int Sym, bool ConstExpr)
   11637              : {
   11638            6 :   unsigned int combinedtok;
   11639            6 :   unsigned int functok;
   11640            6 :   unsigned int optok;
   11641            6 :   unsigned int ReturnVar;
   11642            6 :   unsigned int NoOfParam;
   11643            6 :   unsigned int Type;
   11644            6 :   unsigned int Var;
   11645              : 
   11646            6 :   M2Quads_PopT (&NoOfParam);
   11647            6 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11648            6 :   if (NoOfParam == 1)
   11649              :     {
   11650            6 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   11651            6 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   11652            6 :       M2Quads_PopN (NoOfParam+1);
   11653            6 :       if (ConstExprError (Sym, Var, optok, ConstExpr))
   11654              :         {
   11655              :           /* Generate fake result.  */
   11656            6 :           combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
   11657           12 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   11658            6 :           SymbolTable_PutVar (ReturnVar, M2Base_Integer);
   11659            6 :           M2Quads_PushTFtok (ReturnVar, M2Base_Integer, combinedtok);
   11660              :         }
   11661            0 :       else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   11662              :         {
   11663              :           /* avoid dangling else.  */
   11664            0 :           Type = SymbolTable_GetSType (Sym);  /* return type of function  */
   11665              :           /* Build macro: CONVERT( CARDINAL, Var ).  */
   11666            0 :           M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
   11667            0 :           M2Quads_PushTtok (Type, functok);
   11668            0 :           M2Quads_PushTtok (Var, optok);
   11669            0 :           M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
   11670            0 :           BuildConvertFunction (M2Base_Convert, ConstExpr);  /* Two parameters  */
   11671              :         }
   11672              :       else
   11673              :         {
   11674              :           /* avoid dangling else.  */
   11675            0 :           combinedtok = M2LexBuf_MakeVirtualTok (functok, optok, optok);
   11676            0 :           M2MetaError_MetaErrorT2 (optok, (const char *) "the parameter to {%1Ea} must be a variable or constant, seen {%2ad} {%2&s}", 74, Sym, Var);
   11677            0 :           M2Quads_PushTtok (combinedtok, SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType));
   11678              :         }
   11679              :     }
   11680              :   else
   11681              :     {
   11682            0 :       M2MetaError_MetaErrorT2 (functok, (const char *) "the pseudo procedure {%1Ea} only has one parameter, seen {%2n} parameters", 73, Sym, NoOfParam);
   11683            0 :       M2Quads_PushTtok (functok, SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType));
   11684              :     }
   11685            6 : }
   11686              : 
   11687              : 
   11688              : /*
   11689              :    BuildMakeAdrFunction - builds the pseudo procedure call MAKEADR.
   11690              : 
   11691              :                           The Stack:
   11692              : 
   11693              : 
   11694              :                           Entry                      Exit
   11695              : 
   11696              :                    Ptr ->
   11697              :                           +----------------+
   11698              :                           | NoOfParam      |
   11699              :                           |----------------|
   11700              :                           | Param 1        |
   11701              :                           |----------------|
   11702              :                           | Param 2        |
   11703              :                           |----------------|
   11704              :                           .                .
   11705              :                           .                .
   11706              :                           .                .
   11707              :                           |----------------|
   11708              :                           | Param #        |
   11709              :                           |----------------|
   11710              :                           | ProcSym | Type |         Empty
   11711              :                           |----------------|
   11712              : */
   11713              : 
   11714           12 : static void BuildMakeAdrFunction (void)
   11715              : {
   11716           12 :   unsigned int functok;
   11717           12 :   unsigned int starttok;
   11718           12 :   unsigned int endtok;
   11719           12 :   unsigned int resulttok;
   11720           12 :   bool AreConst;
   11721           12 :   unsigned int i;
   11722           12 :   unsigned int pi;
   11723           12 :   unsigned int NoOfParameters;
   11724           12 :   unsigned int ReturnVar;
   11725              : 
   11726           12 :   M2Quads_PopT (&NoOfParameters);
   11727           12 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParameters+1));
   11728           12 :   if (NoOfParameters > 0)
   11729              :     {
   11730           12 :       starttok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParameters+1));  /* ADR token.  */
   11731           12 :       endtok = static_cast<unsigned int> (M2Quads_OperandTok (1));  /* last parameter.  */
   11732           24 :       GenQuad (M2Quads_ParamOp, 0, M2System_MakeAdr, M2System_MakeAdr);  /* last parameter.  */
   11733           12 :       i = NoOfParameters;
   11734              :       /* stack index referencing stacked parameter, i  */
   11735           12 :       pi = 1;
   11736           24 :       while (i > 0)
   11737              :         {
   11738           12 :           GenQuadO (M2Quads_OperandTok (pi), M2Quads_ParamOp, i, M2System_MakeAdr, M2Quads_OperandT (pi), true);
   11739           12 :           i -= 1;
   11740           12 :           pi += 1;
   11741              :         }
   11742              :       AreConst = true;
   11743              :       i = 1;
   11744           24 :       while (i <= NoOfParameters)
   11745              :         {
   11746           12 :           if (SymbolTable_IsVar (M2Quads_OperandT (i)))
   11747              :             {
   11748              :               AreConst = false;
   11749              :             }
   11750           12 :           else if (! (SymbolTable_IsConst (M2Quads_OperandT (i))))
   11751              :             {
   11752              :               /* avoid dangling else.  */
   11753            0 :               M2MetaError_MetaError1 ((const char *) "problem in the {%1EN} argument for {%kMAKEADR}, all arguments to {%kMAKEADR} must be either variables or constants", 114, i);
   11754              :             }
   11755           12 :           i += 1;
   11756              :         }
   11757              :       /* ReturnVar - will have the type of the procedure  */
   11758           12 :       resulttok = M2LexBuf_MakeVirtualTok (starttok, starttok, endtok);
   11759           12 :       ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (AreConst));
   11760           12 :       SymbolTable_PutVar (ReturnVar, SymbolTable_GetSType (M2System_MakeAdr));
   11761           24 :       GenQuadO (resulttok, M2Quads_FunctValueOp, ReturnVar, SymbolTable_NulSym, M2System_MakeAdr, true);
   11762           12 :       M2Quads_PopN (NoOfParameters+1);
   11763           12 :       M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (M2System_MakeAdr), resulttok);
   11764              :     }
   11765              :   else
   11766              :     {
   11767            0 :       M2MetaError_MetaError1 ((const char *) "the pseudo procedure {%EkMAKEADR} requires at least one parameter, seen {%1n}", 77, NoOfParameters);
   11768            0 :       M2Quads_PopN (1);
   11769            0 :       M2Quads_PushTFtok (M2Base_Nil, SymbolTable_GetSType (M2System_MakeAdr), functok);
   11770              :     }
   11771           12 : }
   11772              : 
   11773              : 
   11774              : /*
   11775              :    BuildShiftFunction - builds the pseudo procedure call SHIFT.
   11776              : 
   11777              :                         PROCEDURE SHIFT (val: <any type>;
   11778              :                                          num: INTEGER): <any type> ;
   11779              : 
   11780              :                        "Returns a bit sequence obtained from val by
   11781              :                         shifting up or down (left or right) by the
   11782              :                         absolute value of num, introducing
   11783              :                         zeros as necessary.  The direction is down if
   11784              :                         the sign of num is negative, otherwise the
   11785              :                         direction is up."
   11786              : 
   11787              :                         The Stack:
   11788              : 
   11789              :                         Entry                      Exit
   11790              : 
   11791              :                  Ptr ->
   11792              :                         +----------------+
   11793              :                         | NoOfParam      |
   11794              :                         |----------------|
   11795              :                         | Param 1        |
   11796              :                         |----------------|
   11797              :                         | Param 2        |                        <- Ptr
   11798              :                         |----------------|         +------------+
   11799              :                         | ProcSym | Type |         | ReturnVar  |
   11800              :                         |----------------|         |------------|
   11801              : */
   11802              : 
   11803          682 : static void BuildShiftFunction (void)
   11804              : {
   11805          682 :   unsigned int combinedtok;
   11806          682 :   unsigned int paramtok;
   11807          682 :   unsigned int functok;
   11808          682 :   unsigned int vartok;
   11809          682 :   unsigned int exptok;
   11810          682 :   unsigned int r;
   11811          682 :   unsigned int procSym;
   11812          682 :   unsigned int returnVar;
   11813          682 :   unsigned int NoOfParam;
   11814          682 :   unsigned int derefExp;
   11815          682 :   unsigned int Exp;
   11816          682 :   unsigned int varSet;
   11817              : 
   11818          682 :   M2Quads_PopT (&NoOfParam);
   11819          682 :   paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   11820          682 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11821          682 :   if (NoOfParam == 2)
   11822              :     {
   11823          682 :       PopTrwtok (&Exp, &r, &exptok);
   11824          682 :       MarkAsRead (r);
   11825          682 :       M2Quads_PopTtok (&varSet, &vartok);
   11826          682 :       M2Quads_PopT (&procSym);
   11827          682 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
   11828          682 :       if (((SymbolTable_GetSType (varSet)) != SymbolTable_NulSym) && ((SymbolTable_IsSet (SymbolTable_GetDType (varSet))) || (M2System_IsGenericSystemType (SymbolTable_GetDType (varSet)))))
   11829              :         {
   11830          682 :           derefExp = DereferenceLValue (exptok, Exp);
   11831          682 :           BuildRange (M2Range_InitShiftCheck (varSet, derefExp));
   11832          682 :           returnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
   11833          682 :           SymbolTable_PutVar (returnVar, SymbolTable_GetSType (varSet));
   11834         1364 :           GenQuadO (combinedtok, M2Quads_LogicalShiftOp, returnVar, varSet, derefExp, true);
   11835          682 :           M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (varSet), combinedtok);
   11836              :         }
   11837              :       else
   11838              :         {
   11839            0 :           M2MetaError_MetaErrorT1 (vartok, (const char *) "SYSTEM procedure {%1EkSHIFT} expects a constant or variable which has a type of SET as its first parameter, seen {%1ad} {%1&s}", 126, varSet);
   11840            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, combinedtok);
   11841              :         }
   11842              :     }
   11843              :   else
   11844              :     {
   11845            0 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   11846            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%kSHIFT} requires at least two parameters, seen {%1En}", 76, NoOfParam);
   11847            0 :       M2Quads_PopN (NoOfParam+1);
   11848            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, combinedtok);
   11849              :     }
   11850          682 : }
   11851              : 
   11852              : 
   11853              : /*
   11854              :    BuildRotateFunction - builds the pseudo procedure call ROTATE.
   11855              : 
   11856              :                          PROCEDURE ROTATE (val: <any type>;
   11857              :                                            num: INTEGER): <any type> ;
   11858              : 
   11859              :                         "Returns a bit sequence obtained from val
   11860              :                          by rotating up or down (left or right) by
   11861              :                          the absolute value of num.  The direction is
   11862              :                          down if the sign of num is negative, otherwise
   11863              :                          the direction is up."
   11864              : 
   11865              :                          The Stack:
   11866              : 
   11867              :                          Entry                      Exit
   11868              : 
   11869              :                   Ptr ->
   11870              :                          +----------------+
   11871              :                          | NoOfParam      |
   11872              :                          |----------------|
   11873              :                          | Param 1        |
   11874              :                          |----------------|
   11875              :                          | Param 2        |                        <- Ptr
   11876              :                          |----------------|         +------------+
   11877              :                          | ProcSym | Type |         | ReturnVar  |
   11878              :                          |----------------|         |------------|
   11879              : */
   11880              : 
   11881          406 : static void BuildRotateFunction (void)
   11882              : {
   11883          406 :   unsigned int combinedtok;
   11884          406 :   unsigned int functok;
   11885          406 :   unsigned int vartok;
   11886          406 :   unsigned int exptok;
   11887          406 :   unsigned int r;
   11888          406 :   unsigned int procSym;
   11889          406 :   unsigned int returnVar;
   11890          406 :   unsigned int NoOfParam;
   11891          406 :   unsigned int derefExp;
   11892          406 :   unsigned int Exp;
   11893          406 :   unsigned int varSet;
   11894              : 
   11895          406 :   M2Quads_PopT (&NoOfParam);
   11896          406 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11897          406 :   if (NoOfParam == 2)
   11898              :     {
   11899          406 :       PopTrwtok (&Exp, &r, &exptok);
   11900          406 :       MarkAsRead (r);
   11901          406 :       M2Quads_PopTtok (&varSet, &vartok);
   11902          406 :       M2Quads_PopT (&procSym);
   11903          406 :       if (((SymbolTable_GetSType (varSet)) != SymbolTable_NulSym) && ((SymbolTable_IsSet (SymbolTable_GetDType (varSet))) || (M2System_IsGenericSystemType (SymbolTable_GetDType (varSet)))))
   11904              :         {
   11905          406 :           combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
   11906          406 :           derefExp = DereferenceLValue (exptok, Exp);
   11907          406 :           BuildRange (M2Range_InitRotateCheck (varSet, derefExp));
   11908          406 :           returnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
   11909          406 :           SymbolTable_PutVar (returnVar, SymbolTable_GetSType (varSet));
   11910          812 :           GenQuadO (combinedtok, M2Quads_LogicalRotateOp, returnVar, varSet, derefExp, true);
   11911          406 :           M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (varSet), combinedtok);
   11912              :         }
   11913              :       else
   11914              :         {
   11915            0 :           M2MetaError_MetaErrorT1 (vartok, (const char *) "SYSTEM procedure {%EkROTATE} expects a constant or variable which has a type of SET as its first parameter, seen {%1ad} {%1&s}", 126, varSet);
   11916            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
   11917              :         }
   11918              :     }
   11919              :   else
   11920              :     {
   11921            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "SYSTEM procedure {%EkROTATE} expects 2 parameters and was given {%1n} parameters", 80, NoOfParam);
   11922            0 :       M2Quads_PopN (NoOfParam+1);
   11923            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
   11924              :     }
   11925          406 : }
   11926              : 
   11927              : 
   11928              : /*
   11929              :    BuildValFunction - builds the pseudo procedure call VAL.
   11930              :                       This procedure is actually a "macro" for
   11931              :                       VAL(Type, x) --> CONVERT(Type, x)
   11932              :                       However we cannot push tokens back onto the input stack
   11933              :                       because the compiler is currently building a function
   11934              :                       call and expecting a ReturnVar on the stack.
   11935              :                       Hence we manipulate the stack and call
   11936              :                       BuildConvertFunction.
   11937              : 
   11938              :                       The Stack:
   11939              : 
   11940              : 
   11941              :                       Entry                      Exit
   11942              : 
   11943              :                Ptr ->
   11944              :                       +----------------+
   11945              :                       | NoOfParam      |
   11946              :                       |----------------|
   11947              :                       | Param 1        |
   11948              :                       |----------------|
   11949              :                       | Param 2        |
   11950              :                       |----------------|
   11951              :                       .                .
   11952              :                       .                .
   11953              :                       .                .
   11954              :                       |----------------|
   11955              :                       | Param #        |
   11956              :                       |----------------|
   11957              :                       | ProcSym | Type |         Empty
   11958              :                       |----------------|
   11959              : */
   11960              : 
   11961         4920 : static void BuildValFunction (unsigned int ProcSym, bool ConstExpr)
   11962              : {
   11963         4920 :   unsigned int combinedtok;
   11964         4920 :   unsigned int functok;
   11965         4920 :   unsigned int ReturnVar;
   11966         4920 :   unsigned int NoOfParam;
   11967         4920 :   unsigned int Exp;
   11968         4920 :   unsigned int Type;
   11969         4920 :   unsigned int tok;
   11970         4920 :   unsigned int r;
   11971         4920 :   unsigned int typetok;
   11972         4920 :   unsigned int exptok;
   11973              : 
   11974         4920 :   M2Quads_PopT (&NoOfParam);
   11975         4920 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11976         4920 :   if (NoOfParam == 2)
   11977              :     {
   11978         4920 :       PopTrwtok (&Exp, &r, &exptok);
   11979         4920 :       MarkAsRead (r);
   11980         4920 :       M2Quads_PopTtok (&Type, &typetok);
   11981         4920 :       M2Quads_PopTtok (&ProcSym, &tok);
   11982         4920 :       if (SymbolTable_IsUnknown (Type))
   11983              :         {
   11984              :           /* It is sensible not to try and recover when we dont know the return type.  */
   11985            6 :           M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type found in builtin procedure function {%AkVAL} {%1ad} {%1&s}", 74, Type);
   11986              :           /* Non recoverable error.  */
   11987            0 :           SymbolTable_UnknownReported (Type);
   11988              :         }
   11989         4914 :       else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
   11990              :         {
   11991              :           /* avoid dangling else.  */
   11992              :           /* Generate fake result.  */
   11993            6 :           combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
   11994           12 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
   11995            6 :           SymbolTable_PutVar (ReturnVar, Type);
   11996            6 :           M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   11997              :         }
   11998         4908 :       else if (((((((SymbolTable_IsSet (Type)) || (SymbolTable_IsEnumeration (Type))) || (SymbolTable_IsSubrange (Type))) || (SymbolTable_IsType (Type))) || (SymbolTable_IsPointer (Type))) || (SymbolTable_IsProcType (Type))) && (((SymbolTable_IsVar (Exp)) || (SymbolTable_IsConst (Exp))) || (SymbolTable_IsProcedure (Exp))))
   11999              :         {
   12000              :           /* avoid dangling else.  */
   12001              :           /* 
   12002              :             Build macro: CONVERT( Type, Var )
   12003              :   */
   12004         4908 :           M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
   12005         4908 :           M2Quads_PushTtok (Type, typetok);
   12006         4908 :           M2Quads_PushTtok (Exp, exptok);
   12007         4908 :           M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
   12008         4908 :           BuildConvertFunction (M2Base_Convert, ConstExpr);
   12009              :         }
   12010              :       else
   12011              :         {
   12012              :           /* avoid dangling else.  */
   12013              :           /* non recoverable error.  */
   12014            0 :           M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkVAL} has the following formal parameter declaration {%kVAL} (type, expression)", 104);
   12015              :         }
   12016              :     }
   12017              :   else
   12018              :     {
   12019              :       /* non recoverable error.  */
   12020            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the builtin procedure {%AkVAL} expects 2 parameters, a type and an expression, but was given {%1n} parameters", 109, NoOfParam);
   12021              :     }
   12022         4914 : }
   12023              : 
   12024              : 
   12025              : /*
   12026              :    BuildCastFunction - builds the pseudo procedure call CAST.
   12027              :                        This procedure is actually a "macro" for
   12028              :                        CAST(Type, x) --> Type(x)
   12029              :                        However we cannot push tokens back onto the input stack
   12030              :                        because the compiler is currently building a function
   12031              :                        call and expecting a ReturnVar on the stack.
   12032              :                        Hence we manipulate the stack and call
   12033              :                        BuildConvertFunction.
   12034              : 
   12035              :                        The Stack:
   12036              : 
   12037              : 
   12038              :                        Entry                      Exit
   12039              : 
   12040              :                 Ptr ->
   12041              :                        +----------------+
   12042              :                        | NoOfParam      |
   12043              :                        |----------------|
   12044              :                        | Param 1        |
   12045              :                        |----------------|
   12046              :                        | Param 2        |
   12047              :                        |----------------|
   12048              :                        .                .
   12049              :                        .                .
   12050              :                        .                .
   12051              :                        |----------------|
   12052              :                        | Param #        |
   12053              :                        |----------------|
   12054              :                        | ProcSym | Type |         Empty
   12055              :                        |----------------|
   12056              : */
   12057              : 
   12058          156 : static void BuildCastFunction (unsigned int ProcSym, bool ConstExpr)
   12059              : {
   12060          156 :   unsigned int combinedtok;
   12061          156 :   unsigned int exptok;
   12062          156 :   unsigned int typetok;
   12063          156 :   unsigned int functok;
   12064          156 :   unsigned int ReturnVar;
   12065          156 :   unsigned int NoOfParam;
   12066          156 :   unsigned int Exp;
   12067          156 :   unsigned int Type;
   12068              : 
   12069          156 :   M2Quads_PopT (&NoOfParam);
   12070          156 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   12071          156 :   if (NoOfParam == 2)
   12072              :     {
   12073          156 :       Type = static_cast<unsigned int> (M2Quads_OperandT (2));
   12074          156 :       typetok = static_cast<unsigned int> (M2Quads_OperandTok (2));
   12075          156 :       Exp = static_cast<unsigned int> (M2Quads_OperandT (1));
   12076          156 :       exptok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   12077          156 :       if (SymbolTable_IsUnknown (Type))
   12078              :         {
   12079              :           /* We cannot recover if we dont have a type.  */
   12080            0 :           M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type {%1Aad} found in {%kCAST} {%1&s}", 48, Type);
   12081              :           /* Non recoverable error.  */
   12082            0 :           SymbolTable_UnknownReported (Type);
   12083              :         }
   12084          156 :       else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
   12085              :         {
   12086              :           /* avoid dangling else.  */
   12087              :           /* Generate fake result.  */
   12088            0 :           combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
   12089            0 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
   12090            0 :           SymbolTable_PutVar (ReturnVar, Type);
   12091            0 :           M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12092              :         }
   12093          156 :       else if (((((((SymbolTable_IsSet (Type)) || (SymbolTable_IsEnumeration (Type))) || (SymbolTable_IsSubrange (Type))) || (SymbolTable_IsType (Type))) || (SymbolTable_IsPointer (Type))) || (SymbolTable_IsArray (Type))) || (SymbolTable_IsProcType (Type)))
   12094              :         {
   12095              :           /* avoid dangling else.  */
   12096          156 :           if (SymbolTable_IsConst (Exp))
   12097              :             {
   12098           30 :               M2Quads_PopN (NoOfParam+1);
   12099              :               /* 
   12100              :                Build macro: Type( Var )
   12101              :   */
   12102           30 :               M2Quads_PushTFtok (Type, static_cast<unsigned int> (SymbolTable_NulSym), typetok);
   12103           30 :               M2Quads_PushTtok (Exp, exptok);
   12104           30 :               M2Quads_PushT (static_cast<unsigned int> (1));  /* one parameter  */
   12105           30 :               BuildTypeCoercion (ConstExpr);  /* one parameter  */
   12106              :             }
   12107          126 :           else if ((SymbolTable_IsVar (Exp)) || (SymbolTable_IsProcedure (Exp)))
   12108              :             {
   12109              :               /* avoid dangling else.  */
   12110          126 :               M2Quads_PopN (NoOfParam+1);
   12111          126 :               combinedtok = M2LexBuf_MakeVirtual2Tok (functok, exptok);
   12112          126 :               ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
   12113          126 :               SymbolTable_PutVar (ReturnVar, Type);
   12114          252 :               GenQuadO (combinedtok, M2Quads_CastOp, ReturnVar, Type, Exp, false);
   12115          126 :               M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12116              :             }
   12117              :           else
   12118              :             {
   12119              :               /* avoid dangling else.  */
   12120              :               /* non recoverable error.  */
   12121            0 :               M2MetaError_MetaErrorT0 (functok, (const char *) "the second parameter to the builtin procedure {%AkCAST} must either be a variable, constant or a procedure.  The formal parameters to cast are {%kCAST} (type, variable or constant or procedure)", 193);
   12122              :             }
   12123              :         }
   12124              :       else
   12125              :         {
   12126              :           /* avoid dangling else.  */
   12127              :           /* non recoverable error.  */
   12128            0 :           M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkCAST} has the following formal parameter declaration {%kCAST} (type, expression)", 106);
   12129              :         }
   12130              :     }
   12131              :   else
   12132              :     {
   12133              :       /* non recoverable error.  */
   12134            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the builtin procedure {%AkCAST} `expects 2 parameters, a type and an expression, but was given {%1n} parameters", 111, NoOfParam);
   12135              :     }
   12136          156 : }
   12137              : 
   12138              : 
   12139              : /*
   12140              :    BuildConvertFunction - builds the pseudo function CONVERT.
   12141              :                           CONVERT( Type, Variable ) ;
   12142              : 
   12143              :                           The Stack:
   12144              : 
   12145              : 
   12146              :                           Entry                      Exit
   12147              : 
   12148              :                    Ptr ->
   12149              :                           +----------------+
   12150              :                           | NoOfParam      |
   12151              :                           |----------------|
   12152              :                           | Param 1        |
   12153              :                           |----------------|
   12154              :                           | Param 2        |
   12155              :                           |----------------|
   12156              :                           .                .
   12157              :                           .                .
   12158              :                           .                .
   12159              :                           |----------------|
   12160              :                           | Param #        |                                 <- Ptr
   12161              :                           |----------------|         +---------------------+
   12162              :                           | ProcSym | Type |         | ReturnVar | Param1  |
   12163              :                           |----------------|         |---------------------|
   12164              : 
   12165              :                           Quadruples:
   12166              : 
   12167              :                           ConvertOp  ReturnVar  Param1  Param2
   12168              : 
   12169              :                           Converts variable Param2 into a variable Param1
   12170              :                           with a type Param1.
   12171              : */
   12172              : 
   12173        56535 : static void BuildConvertFunction (unsigned int ProcSym, bool ConstExpr)
   12174              : {
   12175        56535 :   unsigned int combinedtok;
   12176        56535 :   unsigned int functok;
   12177        56535 :   unsigned int typetok;
   12178        56535 :   unsigned int exptok;
   12179        56535 :   unsigned int t;
   12180        56535 :   unsigned int r;
   12181        56535 :   unsigned int Exp;
   12182        56535 :   unsigned int Type;
   12183        56535 :   unsigned int NoOfParam;
   12184        56535 :   unsigned int ReturnVar;
   12185              : 
   12186        56535 :   M2Quads_PopT (&NoOfParam);
   12187        56535 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   12188        56535 :   if (NoOfParam == 2)
   12189              :     {
   12190        56535 :       PopTrwtok (&Exp, &r, &exptok);
   12191        56535 :       MarkAsRead (r);
   12192        56535 :       M2Quads_PopTtok (&Type, &typetok);
   12193        56535 :       M2Quads_PopT (&ProcSym);
   12194        56535 :       if (SymbolTable_IsUnknown (Type))
   12195              :         {
   12196              :           /* We cannot recover if we dont have a type.  */
   12197            0 :           M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type {%1Aad} found in {%kCONVERT} {%1&s}", 51, Type);
   12198              :           /* Non recoverable error.  */
   12199            0 :           SymbolTable_UnknownReported (Type);
   12200              :         }
   12201        56535 :       else if (SymbolTable_IsUnknown (Exp))
   12202              :         {
   12203              :           /* avoid dangling else.  */
   12204              :           /* We cannot recover if we dont have an expression.  */
   12205            0 :           M2MetaError_MetaErrorT1 (typetok, (const char *) "unknown {%1Ad} {%1ad} found in {%kCONVERT} {%1&s}", 49, Exp);
   12206              :           /* Non recoverable error.  */
   12207            0 :           SymbolTable_UnknownReported (Exp);
   12208              :         }
   12209        56535 :       else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
   12210              :         {
   12211              :           /* avoid dangling else.  */
   12212              :           /* Generate fake result.  */
   12213            0 :           combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
   12214            0 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
   12215            0 :           SymbolTable_PutVar (ReturnVar, Type);
   12216            0 :           M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12217              :         }
   12218        56535 :       else if ((((((((SymbolTable_IsSet (Type)) || (SymbolTable_IsEnumeration (Type))) || (SymbolTable_IsSubrange (Type))) || (SymbolTable_IsType (Type))) || (SymbolTable_IsPointer (Type))) || (SymbolTable_IsProcType (Type))) || (SymbolTable_IsRecord (Type))) && (((SymbolTable_IsVar (Exp)) || (SymbolTable_IsConst (Exp))) || (SymbolTable_IsProcedure (Exp))))
   12219              :         {
   12220              :           /* avoid dangling else.  */
   12221              :           /* firstly dereference Var  */
   12222        56529 :           if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
   12223              :             {
   12224            0 :               t = SymbolTable_MakeTemporary (exptok, SymbolTable_RightValue);
   12225            0 :               SymbolTable_PutVar (t, SymbolTable_GetSType (Exp));
   12226            0 :               CheckPointerThroughNil (exptok, Exp);
   12227            0 :               doIndrX (exptok, t, Exp);
   12228            0 :               Exp = t;
   12229              :             }
   12230        56529 :           combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
   12231       113058 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
   12232        56529 :           SymbolTable_PutVar (ReturnVar, Type);
   12233       113058 :           GenQuadO (combinedtok, M2Quads_ConvertOp, ReturnVar, Type, Exp, true);
   12234        56529 :           M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12235              :         }
   12236              :       else
   12237              :         {
   12238              :           /* avoid dangling else.  */
   12239              :           /* non recoverable error.  */
   12240            6 :           M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkCONVERT} has the following formal parameter declaration {%kCONVERT} (type, expression)", 112);
   12241              :         }
   12242              :     }
   12243              :   else
   12244              :     {
   12245              :       /* non recoverable error.  */
   12246            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the builtin procedure {%AkCONVERT} expects 2 parameters, a type and an expression, but was given {%1n} parameters", 113, NoOfParam);
   12247              :     }
   12248        56529 : }
   12249              : 
   12250              : 
   12251              : /*
   12252              :    CheckBaseTypeValue - checks to see whether the value, min, really exists.
   12253              : */
   12254              : 
   12255         2026 : static unsigned int CheckBaseTypeValue (unsigned int tok, unsigned int type, unsigned int min, unsigned int func)
   12256              : {
   12257         2026 :   if (((type == M2Base_Real) || (type == M2Base_LongReal)) || (type == M2Base_ShortReal))
   12258              :     {
   12259          102 :       SymbolTable_PushValue (min);
   12260          102 :       if (! (M2ALU_IsValueAndTreeKnown ()))
   12261              :         {
   12262            0 :           M2MetaError_MetaErrorT2 (tok, (const char *) "{%1Ead} ({%2ad}) cannot be calculated at compile time for the target architecture", 81, func, type);
   12263            0 :           return SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType);
   12264              :         }
   12265              :     }
   12266              :   return min;
   12267              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   12268              :   __builtin_unreachable ();
   12269              : }
   12270              : 
   12271              : 
   12272              : /*
   12273              :    GetTypeMin - returns the minimium value of type and generate an error
   12274              :                 if this is unavailable.
   12275              : */
   12276              : 
   12277         1326 : static unsigned int GetTypeMin (unsigned int tok, unsigned int func, unsigned int type)
   12278              : {
   12279         1326 :   unsigned int min;
   12280              : 
   12281         1326 :   min = GetTypeMinLower (tok, func, type);
   12282         1326 :   if (min == SymbolTable_NulSym)
   12283              :     {
   12284            0 :       M2MetaError_MetaErrorT1 (tok, (const char *) "unable to obtain the {%AkMIN} value for type {%1ad}", 51, type);
   12285              :     }
   12286         1326 :   return min;
   12287              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   12288              :   __builtin_unreachable ();
   12289              : }
   12290              : 
   12291              : 
   12292              : /*
   12293              :    GetTypeMinLower - obtain the maximum value for type.
   12294              : */
   12295              : 
   12296         1326 : static unsigned int GetTypeMinLower (unsigned int tok, unsigned int func, unsigned int type)
   12297              : {
   12298         1326 :   unsigned int min;
   12299         1326 :   unsigned int max;
   12300              : 
   12301         1326 :   if (SymbolTable_IsSubrange (type))
   12302              :     {
   12303          306 :       min = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
   12304          306 :       SymbolTable_PutVar (min, type);
   12305          612 :       GenQuad (M2Quads_SubrangeLowOp, min, SymbolTable_NulSym, type);
   12306          306 :       return min;
   12307              :     }
   12308         1020 :   else if (SymbolTable_IsSet (SymbolTable_SkipType (type)))
   12309              :     {
   12310              :       /* avoid dangling else.  */
   12311           60 :       return GetTypeMin (tok, func, SymbolTable_GetSType (SymbolTable_SkipType (type)));
   12312              :     }
   12313          960 :   else if ((M2Base_IsBaseType (type)) || (SymbolTable_IsEnumeration (type)))
   12314              :     {
   12315              :       /* avoid dangling else.  */
   12316          758 :       M2Base_GetBaseTypeMinMax (type, &min, &max);
   12317          758 :       min = CheckBaseTypeValue (tok, type, min, func);
   12318          758 :       return min;
   12319              :     }
   12320          202 :   else if (M2System_IsSystemType (type))
   12321              :     {
   12322              :       /* avoid dangling else.  */
   12323          186 :       M2System_GetSystemTypeMinMax (type, &min, &max);
   12324          186 :       return min;
   12325              :     }
   12326           16 :   else if ((SymbolTable_GetSType (type)) == SymbolTable_NulSym)
   12327              :     {
   12328              :       /* avoid dangling else.  */
   12329              :       return SymbolTable_NulSym;
   12330              :     }
   12331              :   else
   12332              :     {
   12333              :       /* avoid dangling else.  */
   12334           16 :       return GetTypeMin (tok, func, SymbolTable_GetSType (type));
   12335              :     }
   12336              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   12337              :   __builtin_unreachable ();
   12338              : }
   12339              : 
   12340              : 
   12341              : /*
   12342              :    GetTypeMax - returns the maximum value of type and generate an error
   12343              :                 if this is unavailable.
   12344              : */
   12345              : 
   12346         2258 : static unsigned int GetTypeMax (unsigned int tok, unsigned int func, unsigned int type)
   12347              : {
   12348         2258 :   unsigned int max;
   12349              : 
   12350         2258 :   max = GetTypeMaxLower (tok, func, type);
   12351         2258 :   if (max == SymbolTable_NulSym)
   12352              :     {
   12353            0 :       M2MetaError_MetaErrorT1 (tok, (const char *) "unable to obtain the {%AkMAX} value for type {%1ad}", 51, type);
   12354              :     }
   12355         2258 :   return max;
   12356              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   12357              :   __builtin_unreachable ();
   12358              : }
   12359              : 
   12360              : 
   12361              : /*
   12362              :    GetTypeMaxLower - obtain the maximum value for type.
   12363              : */
   12364              : 
   12365         2258 : static unsigned int GetTypeMaxLower (unsigned int tok, unsigned int func, unsigned int type)
   12366              : {
   12367         2258 :   unsigned int min;
   12368         2258 :   unsigned int max;
   12369              : 
   12370         2258 :   if (SymbolTable_IsSubrange (type))
   12371              :     {
   12372          562 :       max = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
   12373          562 :       SymbolTable_PutVar (max, type);
   12374         1124 :       GenQuad (M2Quads_SubrangeHighOp, max, SymbolTable_NulSym, type);
   12375          562 :       return max;
   12376              :     }
   12377         1696 :   else if (SymbolTable_IsSet (SymbolTable_SkipType (type)))
   12378              :     {
   12379              :       /* avoid dangling else.  */
   12380          210 :       return GetTypeMax (tok, func, SymbolTable_GetSType (SymbolTable_SkipType (type)));
   12381              :     }
   12382         1486 :   else if ((M2Base_IsBaseType (type)) || (SymbolTable_IsEnumeration (type)))
   12383              :     {
   12384              :       /* avoid dangling else.  */
   12385         1268 :       M2Base_GetBaseTypeMinMax (type, &min, &max);
   12386         1268 :       min = CheckBaseTypeValue (tok, type, min, func);
   12387         1268 :       return max;
   12388              :     }
   12389          218 :   else if (M2System_IsSystemType (type))
   12390              :     {
   12391              :       /* avoid dangling else.  */
   12392          202 :       M2System_GetSystemTypeMinMax (type, &min, &max);
   12393          202 :       return max;
   12394              :     }
   12395           16 :   else if ((SymbolTable_GetSType (type)) == SymbolTable_NulSym)
   12396              :     {
   12397              :       /* avoid dangling else.  */
   12398              :       return SymbolTable_NulSym;
   12399              :     }
   12400              :   else
   12401              :     {
   12402              :       /* avoid dangling else.  */
   12403           16 :       return GetTypeMax (tok, func, SymbolTable_GetSType (type));
   12404              :     }
   12405              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   12406              :   __builtin_unreachable ();
   12407              : }
   12408              : 
   12409              : 
   12410              : /*
   12411              :    BuildMinFunction - builds the pseudo function call Min.
   12412              : 
   12413              :                       The Stack:
   12414              : 
   12415              :                       Entry                      Exit
   12416              : 
   12417              :                Ptr ->
   12418              :                       +----------------+
   12419              :                       | NoOfParam=1    |
   12420              :                       |----------------|
   12421              :                       | Param 1        |
   12422              :                       |----------------|
   12423              :                       | ProcSym | Type |         Empty
   12424              :                       |----------------|
   12425              : */
   12426              : 
   12427         1250 : static void BuildMinFunction (void)
   12428              : {
   12429         1250 :   unsigned int combinedtok;
   12430         1250 :   unsigned int functok;
   12431         1250 :   unsigned int vartok;
   12432         1250 :   unsigned int func;
   12433         1250 :   unsigned int min;
   12434         1250 :   unsigned int NoOfParam;
   12435         1250 :   unsigned int Var;
   12436              : 
   12437         1250 :   M2Quads_PopT (&NoOfParam);
   12438         1250 :   func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   12439         1250 :   functok = OperandTtok (NoOfParam+1);
   12440         1250 :   if (NoOfParam == 1)
   12441              :     {
   12442         1250 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   12443         1250 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   12444         1250 :       M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function  */
   12445         1250 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);  /* destroy arguments to this function  */
   12446         1250 :       if (SymbolTable_IsAModula2Type (Var))
   12447              :         {
   12448         1226 :           min = GetTypeMin (vartok, func, Var);
   12449         1226 :           M2Quads_PushTFtok (min, SymbolTable_GetSType (min), combinedtok);
   12450              :         }
   12451           24 :       else if (SymbolTable_IsVar (Var))
   12452              :         {
   12453              :           /* avoid dangling else.  */
   12454           24 :           min = GetTypeMin (vartok, func, SymbolTable_GetSType (Var));
   12455           24 :           M2Quads_PushTFtok (min, SymbolTable_GetSType (Var), combinedtok);
   12456              :         }
   12457              :       else
   12458              :         {
   12459              :           /* avoid dangling else.  */
   12460              :           /* non recoverable error.  */
   12461            0 :           M2MetaError_MetaErrorT1 (vartok, (const char *) "parameter to {%AkMIN} must be a type or a variable, seen {%1ad} {%1&s}", 70, Var);
   12462              :         }
   12463              :     }
   12464              :   else
   12465              :     {
   12466              :       /* non recoverable error.  */
   12467            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkMIN} only has one parameter, seen  {%1n}", 82, NoOfParam);
   12468              :     }
   12469         1250 : }
   12470              : 
   12471              : 
   12472              : /*
   12473              :    BuildMaxFunction - builds the pseudo function call Max.
   12474              : 
   12475              :                       The Stack:
   12476              : 
   12477              :                       Entry                      Exit
   12478              : 
   12479              :                Ptr ->
   12480              :                       +----------------+
   12481              :                       | NoOfParam=1    |
   12482              :                       |----------------|
   12483              :                       | Param 1        |
   12484              :                       |----------------|
   12485              :                       | ProcSym | Type |         Empty
   12486              :                       |----------------|
   12487              : */
   12488              : 
   12489         2032 : static void BuildMaxFunction (void)
   12490              : {
   12491         2032 :   unsigned int combinedtok;
   12492         2032 :   unsigned int functok;
   12493         2032 :   unsigned int vartok;
   12494         2032 :   unsigned int func;
   12495         2032 :   unsigned int max;
   12496         2032 :   unsigned int NoOfParam;
   12497         2032 :   unsigned int Var;
   12498              : 
   12499         2032 :   M2Quads_PopT (&NoOfParam);
   12500         2032 :   func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   12501         2032 :   functok = OperandTtok (NoOfParam+1);
   12502         2032 :   if (NoOfParam == 1)
   12503              :     {
   12504         2032 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   12505         2032 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   12506         2032 :       M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function  */
   12507         2032 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);  /* destroy arguments to this function  */
   12508         2032 :       if (SymbolTable_IsAModula2Type (Var))
   12509              :         {
   12510         2032 :           max = GetTypeMax (vartok, func, Var);
   12511         2032 :           M2Quads_PushTFtok (max, SymbolTable_GetSType (max), combinedtok);
   12512              :         }
   12513            0 :       else if (SymbolTable_IsVar (Var))
   12514              :         {
   12515              :           /* avoid dangling else.  */
   12516            0 :           max = GetTypeMax (vartok, func, SymbolTable_GetSType (Var));
   12517            0 :           M2Quads_PushTFtok (max, SymbolTable_GetSType (Var), combinedtok);
   12518              :         }
   12519              :       else
   12520              :         {
   12521              :           /* avoid dangling else.  */
   12522              :           /* non recoverable error.  */
   12523            0 :           M2MetaError_MetaErrorT1 (vartok, (const char *) "parameter to {%AkMAX} must be a type or a variable, seen {%1ad} {%1&s}", 70, Var);
   12524              :         }
   12525              :     }
   12526              :   else
   12527              :     {
   12528              :       /* non recoverable error.  */
   12529            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkMAX} only has one parameter, seen {%1n}", 81, NoOfParam);
   12530              :     }
   12531         2032 : }
   12532              : 
   12533              : 
   12534              : /*
   12535              :    BuildTruncFunction - builds the pseudo procedure call TRUNC.
   12536              :                         This procedure is actually a "macro" for
   12537              :                         TRUNC(x) --> CONVERT(INTEGER, x)
   12538              :                         However we cannot push tokens back onto the input stack
   12539              :                         because the compiler is currently building a function
   12540              :                         call and expecting a ReturnVar on the stack.
   12541              :                         Hence we manipulate the stack and call
   12542              :                         BuildConvertFunction.
   12543              : 
   12544              :                         The Stack:
   12545              : 
   12546              : 
   12547              :                         Entry                      Exit
   12548              : 
   12549              :                  Ptr ->
   12550              :                         +----------------+
   12551              :                         | NoOfParam      |
   12552              :                         |----------------|
   12553              :                         | Param 1        |
   12554              :                         |----------------|
   12555              :                         | Param 2        |
   12556              :                         |----------------|
   12557              :                         .                .
   12558              :                         .                .
   12559              :                         .                .
   12560              :                         |----------------|
   12561              :                         | Param #        |
   12562              :                         |----------------|
   12563              :                         | ProcSym | Type |         Empty
   12564              :                         |----------------|
   12565              : */
   12566              : 
   12567           60 : static void BuildTruncFunction (unsigned int Sym, bool ConstExpr)
   12568              : {
   12569           60 :   unsigned int combinedtok;
   12570           60 :   unsigned int vartok;
   12571           60 :   unsigned int functok;
   12572           60 :   unsigned int NoOfParam;
   12573           60 :   unsigned int ReturnVar;
   12574           60 :   unsigned int ProcSym;
   12575           60 :   unsigned int Type;
   12576           60 :   unsigned int Var;
   12577              : 
   12578           60 :   M2Quads_PopT (&NoOfParam);
   12579           60 :   M2Debug_Assert (M2Base_IsTrunc (M2Quads_OperandT (NoOfParam+1)));
   12580           60 :   functok = OperandTtok (NoOfParam+1);
   12581           60 :   if (NoOfParam == 1)
   12582              :     {
   12583           60 :       ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "CONVERT", 7));
   12584           60 :       if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
   12585              :         {
   12586           60 :           Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   12587           60 :           vartok = OperandTtok (1);
   12588           60 :           Type = SymbolTable_GetSType (Sym);
   12589           60 :           M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function  */
   12590           60 :           if (ConstExprError (Sym, Var, vartok, ConstExpr))
   12591              :             {
   12592              :               /* Generate fake result.  */
   12593            6 :               combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
   12594           12 :               ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   12595            6 :               SymbolTable_PutVar (ReturnVar, Type);
   12596            6 :               M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12597              :             }
   12598           54 :           else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   12599              :             {
   12600              :               /* avoid dangling else.  */
   12601           54 :               if (M2Base_IsRealType (SymbolTable_GetSType (Var)))
   12602              :                 {
   12603              :                   /* build macro: CONVERT( INTEGER, Var ).  */
   12604           54 :                   M2Quads_PushTFtok (ProcSym, static_cast<unsigned int> (SymbolTable_NulSym), functok);
   12605           54 :                   M2Quads_PushTtok (Type, functok);
   12606           54 :                   M2Quads_PushTtok (Var, vartok);
   12607           54 :                   M2Quads_PushT (static_cast<unsigned int> (2));  /* two parameters  */
   12608           54 :                   BuildConvertFunction (M2Base_Convert, ConstExpr);  /* two parameters  */
   12609              :                 }
   12610              :               else
   12611              :                 {
   12612            0 :                   M2MetaError_MetaErrorT1 (functok, (const char *) "argument to {%1Ead} must be a float point type", 46, Sym);
   12613            0 :                   M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), Type), Type, functok);
   12614              :                 }
   12615              :             }
   12616              :           else
   12617              :             {
   12618              :               /* avoid dangling else.  */
   12619            0 :               M2MetaError_MetaErrorT2 (vartok, (const char *) "argument to {%1Ead} must be a variable or constant, seen {%2ad} {%2&s}", 70, Sym, Var);
   12620            0 :               M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), Type), Type, functok);
   12621              :             }
   12622              :         }
   12623              :       else
   12624              :         {
   12625            0 :           M2Error_InternalError ((const char *) "CONVERT procedure not found for TRUNC substitution", 50);
   12626              :         }
   12627              :     }
   12628              :   else
   12629              :     {
   12630              :       /* non recoverable error.  */
   12631            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkTRUNC} only has one parameter, seen  {%1n}", 84, NoOfParam);
   12632              :     }
   12633           60 : }
   12634              : 
   12635              : 
   12636              : /*
   12637              :    BuildFloatFunction - builds the pseudo procedure call FLOAT.
   12638              :                         This procedure is actually a "macro" for
   12639              :                         FLOAT(x) --> CONVERT(REAL, x)
   12640              :                         However we cannot push tokens back onto the input stack
   12641              :                         because the compiler is currently building a function
   12642              :                         call and expecting a ReturnVar on the stack.
   12643              :                         Hence we manipulate the stack and call
   12644              :                         BuildConvertFunction.
   12645              : 
   12646              :                         The Stack:
   12647              : 
   12648              : 
   12649              :                         Entry                      Exit
   12650              : 
   12651              :                  Ptr ->
   12652              :                         +----------------+
   12653              :                         | NoOfParam      |
   12654              :                         |----------------|
   12655              :                         | Param 1        |
   12656              :                         |----------------|
   12657              :                         | Param 2        |
   12658              :                         |----------------|
   12659              :                         .                .
   12660              :                         .                .
   12661              :                         .                .
   12662              :                         |----------------|
   12663              :                         | Param #        |
   12664              :                         |----------------|
   12665              :                         | ProcSym | Type |         Empty
   12666              :                         |----------------|
   12667              : */
   12668              : 
   12669           88 : static void BuildFloatFunction (unsigned int Sym, bool ConstExpr)
   12670              : {
   12671           88 :   unsigned int combinedtok;
   12672           88 :   unsigned int vartok;
   12673           88 :   unsigned int functok;
   12674           88 :   unsigned int NoOfParam;
   12675           88 :   unsigned int ReturnVar;
   12676           88 :   unsigned int Type;
   12677           88 :   unsigned int Var;
   12678           88 :   unsigned int ProcSym;
   12679              : 
   12680           88 :   M2Quads_PopT (&NoOfParam);
   12681           88 :   functok = OperandTtok (NoOfParam+1);
   12682           88 :   Type = SymbolTable_GetSType (Sym);
   12683           88 :   if (NoOfParam == 1)
   12684              :     {
   12685           88 :       ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "CONVERT", 7));
   12686           88 :       if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
   12687              :         {
   12688           88 :           Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   12689           88 :           vartok = OperandTtok (1);
   12690           88 :           M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function.  */
   12691           88 :           if (ConstExprError (Sym, Var, vartok, ConstExpr))
   12692              :             {
   12693              :               /* Generate fake result.  */
   12694            6 :               combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
   12695           12 :               ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   12696            6 :               SymbolTable_PutVar (ReturnVar, Type);
   12697            6 :               M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12698              :             }
   12699           82 :           else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   12700              :             {
   12701              :               /* avoid dangling else.  */
   12702              :               /* build macro: CONVERT (REAL, Var).  */
   12703           82 :               M2Quads_PushTFtok (ProcSym, static_cast<unsigned int> (SymbolTable_NulSym), functok);
   12704           82 :               M2Quads_PushTtok (Type, functok);
   12705           82 :               M2Quads_PushTtok (Var, vartok);
   12706           82 :               M2Quads_PushT (static_cast<unsigned int> (2));  /* two parameters.  */
   12707           82 :               BuildConvertFunction (ProcSym, ConstExpr);  /* two parameters.  */
   12708              :             }
   12709              :           else
   12710              :             {
   12711              :               /* avoid dangling else.  */
   12712            0 :               M2MetaError_MetaErrorT1 (vartok, (const char *) "argument to {%1Ead} must be a variable or constant", 50, ProcSym);
   12713            0 :               M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0.0", 3), Type), Type, functok);
   12714              :             }
   12715              :         }
   12716              :       else
   12717              :         {
   12718            0 :           M2Error_InternalError ((const char *) "CONVERT procedure not found for FLOAT substitution", 50);
   12719              :         }
   12720              :     }
   12721              :   else
   12722              :     {
   12723            0 :       M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function.  */
   12724            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter", 61, Sym);  /* destroy arguments to this function.  */
   12725            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0.0", 3), Type), Type, functok);
   12726              :     }
   12727           88 : }
   12728              : 
   12729              : 
   12730              : /*
   12731              :    BuildReFunction - builds the pseudo procedure call RE.
   12732              : 
   12733              :                      The Stack:
   12734              : 
   12735              : 
   12736              :                          Entry                      Exit
   12737              : 
   12738              :                  Ptr ->
   12739              :                         +----------------+
   12740              :                         | NoOfParam      |
   12741              :                         |----------------|
   12742              :                         | Param 1        |
   12743              :                         |----------------|
   12744              :                         | Param 2        |
   12745              :                         |----------------|
   12746              :                         .                .
   12747              :                         .                .
   12748              :                         .                .
   12749              :                         |----------------|
   12750              :                         | Param #        |
   12751              :                         |----------------|
   12752              :                         | ProcSym | Type |         Empty
   12753              :                         |----------------|
   12754              : */
   12755              : 
   12756           60 : static void BuildReFunction (unsigned int Sym, bool ConstExpr)
   12757              : {
   12758           60 :   unsigned int func;
   12759           60 :   unsigned int combinedtok;
   12760           60 :   unsigned int vartok;
   12761           60 :   unsigned int functok;
   12762           60 :   unsigned int NoOfParam;
   12763           60 :   unsigned int ReturnVar;
   12764           60 :   unsigned int Type;
   12765           60 :   unsigned int Var;
   12766              : 
   12767           60 :   M2Quads_PopT (&NoOfParam);
   12768           60 :   functok = OperandTtok (NoOfParam+1);
   12769           60 :   func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   12770           60 :   if (NoOfParam == 1)
   12771              :     {
   12772           60 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   12773           60 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   12774           60 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
   12775           60 :       Type = M2Base_ComplexToScalar (SymbolTable_GetDType (Var));
   12776           60 :       M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function  */
   12777           60 :       if (ConstExprError (Sym, Var, vartok, ConstExpr))
   12778              :         {
   12779              :           /* Generate fake result.  */
   12780            6 :           combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
   12781           12 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   12782            6 :           SymbolTable_PutVar (ReturnVar, Type);
   12783            6 :           M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12784              :         }
   12785           54 :       else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   12786              :         {
   12787              :           /* avoid dangling else.  */
   12788          108 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   12789           54 :           SymbolTable_PutVar (ReturnVar, Type);
   12790          108 :           GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Re, Var, false);
   12791           54 :           M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12792              :         }
   12793              :       else
   12794              :         {
   12795              :           /* avoid dangling else.  */
   12796            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, combinedtok);
   12797            0 :           M2MetaError_MetaErrorT2 (vartok, (const char *) "the parameter to the builtin procedure function {%1Ead} must be a constant or a variable, seen {%2ad} {%2&s}", 108, func, Var);
   12798              :         }
   12799              :     }
   12800              :   else
   12801              :     {
   12802            0 :       M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function  */
   12803            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, functok);  /* destroy arguments to this function  */
   12804            0 :       M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter, seen {%2n}", 73, func, NoOfParam);
   12805              :     }
   12806           60 : }
   12807              : 
   12808              : 
   12809              : /*
   12810              :    BuildImFunction - builds the pseudo procedure call IM.
   12811              : 
   12812              :                      The Stack:
   12813              : 
   12814              : 
   12815              :                          Entry                      Exit
   12816              : 
   12817              :                  Ptr ->
   12818              :                         +----------------+
   12819              :                         | NoOfParam      |
   12820              :                         |----------------|
   12821              :                         | Param 1        |
   12822              :                         |----------------|
   12823              :                         | Param 2        |
   12824              :                         |----------------|
   12825              :                         .                .
   12826              :                         .                .
   12827              :                         .                .
   12828              :                         |----------------|
   12829              :                         | Param #        |
   12830              :                         |----------------|
   12831              :                         | ProcSym | Type |         Empty
   12832              :                         |----------------|
   12833              : */
   12834              : 
   12835           60 : static void BuildImFunction (unsigned int Sym, bool ConstExpr)
   12836              : {
   12837           60 :   unsigned int func;
   12838           60 :   unsigned int combinedtok;
   12839           60 :   unsigned int vartok;
   12840           60 :   unsigned int functok;
   12841           60 :   unsigned int NoOfParam;
   12842           60 :   unsigned int ReturnVar;
   12843           60 :   unsigned int Type;
   12844           60 :   unsigned int Var;
   12845              : 
   12846           60 :   M2Quads_PopT (&NoOfParam);
   12847           60 :   functok = OperandTtok (NoOfParam+1);
   12848           60 :   func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   12849           60 :   if (NoOfParam == 1)
   12850              :     {
   12851           60 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   12852           60 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   12853           60 :       Type = M2Base_ComplexToScalar (SymbolTable_GetDType (Var));
   12854           60 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
   12855           60 :       M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function  */
   12856           60 :       if (ConstExprError (Sym, Var, vartok, ConstExpr))
   12857              :         {
   12858              :           /* Generate fake result.  */
   12859            6 :           combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
   12860           12 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   12861            6 :           SymbolTable_PutVar (ReturnVar, Type);
   12862            6 :           M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12863              :         }
   12864           54 :       else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   12865              :         {
   12866              :           /* avoid dangling else.  */
   12867          108 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   12868           54 :           SymbolTable_PutVar (ReturnVar, M2Base_ComplexToScalar (SymbolTable_GetDType (Var)));
   12869          108 :           GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Im, Var, false);
   12870           54 :           M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), combinedtok);
   12871              :         }
   12872              :       else
   12873              :         {
   12874              :           /* avoid dangling else.  */
   12875            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, combinedtok);
   12876            0 :           M2MetaError_MetaErrorT2 (vartok, (const char *) "the parameter to the builtin procedure function {%1Ead} must be a constant or a variable, seen {%2ad} {%2&s}", 108, func, Var);
   12877              :         }
   12878              :     }
   12879              :   else
   12880              :     {
   12881            0 :       M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function  */
   12882            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, functok);  /* destroy arguments to this function  */
   12883            0 :       M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter, seen {%2n}", 73, func, NoOfParam);
   12884              :     }
   12885           60 : }
   12886              : 
   12887              : 
   12888              : /*
   12889              :    BuildCmplxFunction - builds the pseudo procedure call CMPLX.
   12890              : 
   12891              :                         The Stack:
   12892              : 
   12893              : 
   12894              :                         Entry                      Exit
   12895              : 
   12896              :                  Ptr ->
   12897              :                         +----------------+
   12898              :                         | NoOfParam      |
   12899              :                         |----------------|
   12900              :                         | Param 1        |
   12901              :                         |----------------|
   12902              :                         | Param 2        |
   12903              :                         |----------------|
   12904              :                         .                .
   12905              :                         .                .
   12906              :                         .                .
   12907              :                         |----------------|
   12908              :                         | Param #        |
   12909              :                         |----------------|
   12910              :                         | ProcSym | Type |         Empty
   12911              :                         |----------------|
   12912              : */
   12913              : 
   12914          492 : static void BuildCmplxFunction (unsigned int func, bool ConstExpr)
   12915              : {
   12916          492 :   bool failure;
   12917          492 :   unsigned int functok;
   12918          492 :   unsigned int rtok;
   12919          492 :   unsigned int ltok;
   12920          492 :   unsigned int combinedtok;
   12921          492 :   unsigned int NoOfParam;
   12922          492 :   unsigned int type;
   12923          492 :   unsigned int ReturnVar;
   12924          492 :   unsigned int l;
   12925          492 :   unsigned int r;
   12926              : 
   12927          492 :   M2Quads_PopT (&NoOfParam);
   12928          492 :   functok = OperandTtok (NoOfParam+1);
   12929          492 :   if (NoOfParam == 2)
   12930              :     {
   12931          492 :       l = static_cast<unsigned int> (M2Quads_OperandT (2));
   12932          492 :       ltok = OperandTtok (2);
   12933          492 :       r = static_cast<unsigned int> (M2Quads_OperandT (1));
   12934          492 :       rtok = OperandTtok (1);
   12935          492 :       combinedtok = M2LexBuf_MakeVirtual2Tok (functok, rtok);
   12936          492 :       M2Quads_PopN (NoOfParam+1);  /* Destroy arguments to this function.  */
   12937          492 :       type = M2Base_GetCmplxReturnType (SymbolTable_GetDType (l), SymbolTable_GetDType (r));  /* Destroy arguments to this function.  */
   12938          570 :       ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant ((SymbolTable_IsConst (l)) && (SymbolTable_IsConst (r))));
   12939          492 :       SymbolTable_PutVar (ReturnVar, type);
   12940          492 :       failure = false;
   12941          492 :       if (ConstExprError (func, l, ltok, ConstExpr))
   12942              :         {
   12943              :           /* ConstExprError has generated an error message we will fall through
   12944              :             and check the right operand.  */
   12945              :           failure = true;
   12946              :         }
   12947          492 :       if (ConstExprError (func, r, rtok, ConstExpr))
   12948              :         {
   12949              :           /* Right operand is in error as a variable.  */
   12950              :           failure = true;
   12951              :         }
   12952          486 :       if (failure)
   12953              :         {
   12954              :           /* Generate a fake result if either operand was a variable (and we
   12955              :             are in a const expression).  */
   12956            6 :           M2Quads_PushTFtok (ReturnVar, type, combinedtok);
   12957              :         }
   12958          486 :       else if (((SymbolTable_IsVar (l)) || (SymbolTable_IsConst (l))) && ((SymbolTable_IsVar (r)) || (SymbolTable_IsConst (r))))
   12959              :         {
   12960              :           /* avoid dangling else.  */
   12961          486 :           M2Base_CheckExpressionCompatible (combinedtok, SymbolTable_GetSType (l), SymbolTable_GetSType (r));
   12962          486 :           GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Cmplx, SymbolTable_Make2Tuple (l, r), true);
   12963          486 :           M2Quads_PushTFtok (ReturnVar, type, combinedtok);
   12964              :         }
   12965              :       else
   12966              :         {
   12967              :           /* avoid dangling else.  */
   12968            0 :           if ((SymbolTable_IsVar (l)) || (SymbolTable_IsConst (l)))
   12969              :             {
   12970            0 :               M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure {%1Ead} requires two parameters, both must be variables or constants but the second parameter is {%2d}", 124, func, r);
   12971              :             }
   12972              :           else
   12973              :             {
   12974            0 :               M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure {%1Ead} requires two parameters, both must be variables or constants but the first parameter is {%2d}", 123, func, l);
   12975              :             }
   12976            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_CType), M2Base_CType, combinedtok);
   12977              :         }
   12978              :     }
   12979              :   else
   12980              :     {
   12981            0 :       M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure {%1Ead} requires two parameters, seen {%2n}", 65, func, NoOfParam);
   12982            0 :       M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function  */
   12983            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_CType), M2Base_CType, functok);  /* destroy arguments to this function  */
   12984              :     }
   12985          492 : }
   12986              : 
   12987              : 
   12988              : /*
   12989              :    BuildAdrFunction - builds the pseudo function ADR
   12990              :                       The Stack:
   12991              : 
   12992              : 
   12993              :                       Entry                      Exit
   12994              : 
   12995              :                Ptr ->
   12996              :                       +----------------+
   12997              :                       | NoOfParam      |
   12998              :                       |----------------|
   12999              :                       | Param 1        |
   13000              :                       |----------------|
   13001              :                       | Param 2        |
   13002              :                       |----------------|
   13003              :                       .                .
   13004              :                       .                .
   13005              :                       .                .
   13006              :                       |----------------|
   13007              :                       | Param #        |                        <- Ptr
   13008              :                       |----------------|         +------------+
   13009              :                       | ProcSym | Type |         | ReturnVar  |
   13010              :                       |----------------|         |------------|
   13011              : 
   13012              : */
   13013              : 
   13014       180150 : static void BuildAdrFunction (void)
   13015              : {
   13016       180150 :   unsigned int param;
   13017       180150 :   unsigned int paramTok;
   13018       180150 :   unsigned int combinedTok;
   13019       180150 :   unsigned int procTok;
   13020       180150 :   unsigned int t;
   13021       180150 :   unsigned int UnboundedSym;
   13022       180150 :   unsigned int Dim;
   13023       180150 :   unsigned int Field;
   13024       180150 :   unsigned int noOfParameters;
   13025       180150 :   unsigned int procSym;
   13026       180150 :   unsigned int returnVar;
   13027       180150 :   unsigned int Type;
   13028       180150 :   unsigned int rw;
   13029              : 
   13030       180150 :   M2Quads_DisplayStack ();
   13031       180150 :   M2Quads_PopT (&noOfParameters);
   13032       180150 :   procSym = static_cast<unsigned int> (M2Quads_OperandT (noOfParameters+1));
   13033       180150 :   procTok = static_cast<unsigned int> (M2Quads_OperandTok (noOfParameters+1));  /* token of procedure ADR.  */
   13034       180150 :   paramTok = static_cast<unsigned int> (M2Quads_OperandTok (1));  /* last parameter.  */
   13035       180150 :   param = static_cast<unsigned int> (M2Quads_OperandT (1));  /* last parameter.  */
   13036       180150 :   combinedTok = M2LexBuf_MakeVirtualTok (procTok, procTok, static_cast<unsigned int> (M2Reserved_endtok));
   13037       180150 :   if (noOfParameters != 1)
   13038              :     {
   13039            0 :       M2MetaError_MetaErrorNT0 (combinedTok, (const char *) "SYSTEM procedure ADR expects 1 parameter", 40);
   13040            0 :       M2Quads_PopN (noOfParameters+1);  /* destroy the arguments and function  */
   13041            0 :       M2Quads_PushTF (M2Base_Nil, M2System_Address);  /* destroy the arguments and function  */
   13042              :     }
   13043       180150 :   else if (SymbolTable_IsConstString (param))
   13044              :     {
   13045              :       /* avoid dangling else.  */
   13046       172339 :       returnVar = MakeLeftValue (combinedTok, param, SymbolTable_RightValue, SymbolTable_GetSType (procSym));
   13047       172339 :       M2Quads_PopN (noOfParameters+1);  /* destroy the arguments and function  */
   13048       172339 :       M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (returnVar), combinedTok);  /* destroy the arguments and function  */
   13049              :     }
   13050         7811 :   else if ((! (SymbolTable_IsVar (param))) && (! (SymbolTable_IsProcedure (param))))
   13051              :     {
   13052              :       /* avoid dangling else.  */
   13053            1 :       M2MetaError_MetaErrorT1 (paramTok, (const char *) "SYSTEM procedure ADR expects a variable, procedure or a constant string as its parameter, seen {%1Ed} {%1&s}", 108, param);
   13054            1 :       M2Quads_PopN (noOfParameters+1);  /* destroy the arguments and function  */
   13055            1 :       M2Quads_PushTFtok (M2Base_Nil, M2System_Address, combinedTok);  /* destroy the arguments and function  */
   13056              :     }
   13057         7810 :   else if (SymbolTable_IsProcedure (param))
   13058              :     {
   13059              :       /* avoid dangling else.  */
   13060           24 :       returnVar = MakeLeftValue (combinedTok, param, SymbolTable_RightValue, SymbolTable_GetSType (procSym));
   13061           24 :       M2Quads_PopN (noOfParameters+1);  /* destroy the arguments and function  */
   13062           24 :       M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (returnVar), combinedTok);  /* destroy the arguments and function  */
   13063              :     }
   13064              :   else
   13065              :     {
   13066              :       /* avoid dangling else.  */
   13067         7786 :       Type = SymbolTable_GetSType (param);
   13068         7786 :       Dim = static_cast<unsigned int> (OperandD (1));
   13069         7786 :       MarkArrayWritten (param);
   13070         7786 :       MarkArrayWritten (M2Quads_OperandA (1));
   13071              :       /* if the operand is an unbounded which has not been indexed
   13072              :          then we will lookup its address from the unbounded record.
   13073              :          Otherwise we obtain the address of the operand.
   13074              :   */
   13075         7786 :       if ((SymbolTable_IsUnbounded (Type)) && (Dim == 0))
   13076              :         {
   13077              :           /* we will reference the address field of the unbounded structure  */
   13078         2370 :           UnboundedSym = param;
   13079         2370 :           rw = static_cast<unsigned int> (OperandRW (1));
   13080         2370 :           PushTFrw (UnboundedSym, SymbolTable_GetSType (UnboundedSym), rw);
   13081         2370 :           Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
   13082         2370 :           M2Quads_PushTF (Field, SymbolTable_GetSType (Field));
   13083         2370 :           M2Quads_PushT (static_cast<unsigned int> (1));
   13084         2370 :           M2Quads_BuildDesignatorRecord (combinedTok);
   13085         2370 :           PopTrw (&returnVar, &rw);
   13086         2370 :           if ((SymbolTable_GetMode (returnVar)) == SymbolTable_LeftValue)
   13087              :             {
   13088            0 :               t = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
   13089            0 :               SymbolTable_PutVar (t, SymbolTable_GetSType (procSym));
   13090            0 :               doIndrX (combinedTok, t, returnVar);
   13091            0 :               returnVar = t;
   13092              :             }
   13093              :           else
   13094              :             {
   13095              :               /* we need to cast returnVar into ADDRESS  */
   13096         2370 :               t = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
   13097         2370 :               SymbolTable_PutVar (t, SymbolTable_GetSType (procSym));
   13098         2370 :               GenQuadO (combinedTok, M2Quads_ConvertOp, t, SymbolTable_GetSType (procSym), returnVar, false);
   13099         2370 :               returnVar = t;
   13100              :             }
   13101              :         }
   13102              :       else
   13103              :         {
   13104         5416 :           returnVar = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
   13105         5416 :           SymbolTable_PutVar (returnVar, SymbolTable_GetSType (procSym));
   13106         5416 :           if ((SymbolTable_GetMode (param)) == SymbolTable_LeftValue)
   13107              :             {
   13108          440 :               SymbolTable_PutVar (returnVar, SymbolTable_GetSType (procSym));
   13109          440 :               GenQuadO (combinedTok, M2Quads_ConvertOp, returnVar, SymbolTable_GetSType (procSym), param, false);
   13110              :             }
   13111              :           else
   13112              :             {
   13113         4976 :               GenQuadO (combinedTok, M2Quads_AddrOp, returnVar, SymbolTable_NulSym, param, false);
   13114              :             }
   13115         5416 :           SymbolTable_PutWriteQuad (param, SymbolTable_GetMode (param), NextQuad-1);
   13116         5416 :           rw = static_cast<unsigned int> (OperandMergeRW (1));
   13117         5416 :           M2Debug_Assert (SymbolTable_IsLegal (rw));
   13118              :         }
   13119         7786 :       M2Quads_PopN (noOfParameters+1);  /* destroy the arguments and function  */
   13120         7786 :       PushTFrwtok (returnVar, SymbolTable_GetSType (returnVar), rw, combinedTok);  /* destroy the arguments and function  */
   13121              :     }
   13122       180150 : }
   13123              : 
   13124              : 
   13125              : /*
   13126              :    BuildSizeFunction - builds the pseudo function SIZE
   13127              :                        The Stack:
   13128              : 
   13129              : 
   13130              :                        Entry                      Exit
   13131              : 
   13132              :                 Ptr ->
   13133              :                        +----------------+
   13134              :                        | NoOfParam      |
   13135              :                        |----------------|
   13136              :                        | Param 1        |
   13137              :                        |----------------|
   13138              :                        | Param 2        |
   13139              :                        |----------------|
   13140              :                        .                .
   13141              :                        .                .
   13142              :                        .                .
   13143              :                        |----------------|
   13144              :                        | Param #        |                        <- Ptr
   13145              :                        |----------------|         +------------+
   13146              :                        | ProcSym | Type |         | ReturnVar  |
   13147              :                        |----------------|         |------------|
   13148              : */
   13149              : 
   13150         2099 : static void BuildSizeFunction (void)
   13151              : {
   13152         2099 :   unsigned int resulttok;
   13153         2099 :   unsigned int paramtok;
   13154         2099 :   unsigned int functok;
   13155         2099 :   unsigned int dim;
   13156         2099 :   unsigned int Type;
   13157         2099 :   unsigned int NoOfParam;
   13158         2099 :   unsigned int ProcSym;
   13159         2099 :   unsigned int ReturnVar;
   13160              : 
   13161         2099 :   M2Quads_PopT (&NoOfParam);
   13162         2099 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   13163         2099 :   functok = OperandTtok (NoOfParam+1);
   13164         2099 :   if (NoOfParam != 1)
   13165              :     {
   13166            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "{%E} SYSTEM procedure function {%kSIZE} requires one parameter, seen {%1n}", 74, NoOfParam);
   13167            0 :       resulttok = functok;
   13168            0 :       ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
   13169              :     }
   13170              :   else
   13171              :     {
   13172         2099 :       paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   13173         2099 :       resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   13174         2099 :       if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
   13175              :         {
   13176          992 :           BuildSizeCheckEnd (ProcSym);  /* Quadruple generation now on.  */
   13177          992 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);  /* Quadruple generation now on.  */
   13178          992 :           GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, M2Quads_OperandT (1), true);
   13179              :         }
   13180         1107 :       else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
   13181              :         {
   13182              :           /* avoid dangling else.  */
   13183         1100 :           BuildSizeCheckEnd (ProcSym);  /* Quadruple generation now on.  */
   13184         1100 :           Type = SymbolTable_GetSType (M2Quads_OperandT (1));  /* Quadruple generation now on.  */
   13185         1100 :           if (SymbolTable_IsUnbounded (Type))
   13186              :             {
   13187              :               /* Eg. SIZE(a) ; where a is unbounded dereference HIGH and multiply by the TYPE.  */
   13188          168 :               dim = static_cast<unsigned int> (OperandD (1));
   13189          168 :               if (dim == 0)
   13190              :                 {
   13191           72 :                   ReturnVar = calculateMultipicand (resulttok, M2Quads_OperandT (1), Type, dim);
   13192              :                 }
   13193              :               else
   13194              :                 {
   13195           96 :                   ReturnVar = calculateMultipicand (resulttok, M2Quads_OperandA (1), Type, dim);
   13196              :                 }
   13197              :             }
   13198              :           else
   13199              :             {
   13200          932 :               ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
   13201          932 :               if (Type == SymbolTable_NulSym)
   13202              :                 {
   13203            0 :                   M2MetaError_MetaErrorT1 (resulttok, (const char *) "cannot get the type and size of {%1Ead}", 39, M2Quads_OperandT (1));
   13204              :                 }
   13205          932 :               GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, Type, true);
   13206              :             }
   13207              :         }
   13208              :       else
   13209              :         {
   13210              :           /* avoid dangling else.  */
   13211            7 :           M2MetaError_MetaErrorT1 (paramtok, (const char *) "{%E}SYSTEM procedure {%kSIZE} expects a variable or type as its parameter, seen {%1Ed} {%1&s}", 93, M2Quads_OperandT (1));
   13212            7 :           ReturnVar = SymbolTable_MakeConstLit (paramtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
   13213              :         }
   13214              :     }
   13215         2099 :   M2Quads_PopN (NoOfParam+1);  /* Destroy the arguments and function.  */
   13216         2099 :   M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok);  /* Destroy the arguments and function.  */
   13217         2099 : }
   13218              : 
   13219              : 
   13220              : /*
   13221              :    BuildTSizeFunction - builds the pseudo function TSIZE
   13222              :                         The Stack:
   13223              : 
   13224              : 
   13225              :                         Entry                      Exit
   13226              : 
   13227              :                  Ptr ->
   13228              :                         +----------------+
   13229              :                         | NoOfParam      |
   13230              :                         |----------------|
   13231              :                         | Param 1        |
   13232              :                         |----------------|
   13233              :                         | Param 2        |
   13234              :                         |----------------|
   13235              :                         .                .
   13236              :                         .                .
   13237              :                         .                .
   13238              :                         |----------------|
   13239              :                         | Param #        |                        <- Ptr
   13240              :                         |----------------|         +------------+
   13241              :                         | ProcSym | Type |         | ReturnVar  |
   13242              :                         |----------------|         |------------|
   13243              : 
   13244              : */
   13245              : 
   13246         4774 : static void BuildTSizeFunction (void)
   13247              : {
   13248         4774 :   unsigned int resulttok;
   13249         4774 :   unsigned int paramtok;
   13250         4774 :   unsigned int functok;
   13251         4774 :   unsigned int NoOfParam;
   13252         4774 :   unsigned int ProcSym;
   13253         4774 :   unsigned int Record;
   13254         4774 :   unsigned int ReturnVar;
   13255              : 
   13256         4774 :   M2Quads_PopT (&NoOfParam);
   13257         4774 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   13258         4774 :   functok = OperandTtok (NoOfParam);
   13259         4774 :   BuildSizeCheckEnd (ProcSym);  /* quadruple generation now on  */
   13260         4774 :   if (NoOfParam == 1)  /* quadruple generation now on  */
   13261              :     {
   13262         4774 :       paramtok = OperandTtok (1);
   13263         4774 :       resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   13264         4774 :       if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
   13265              :         {
   13266         4740 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
   13267         4740 :           SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
   13268         4740 :           GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, M2Quads_OperandT (1), false);
   13269              :         }
   13270           34 :       else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
   13271              :         {
   13272              :           /* avoid dangling else.  */
   13273           28 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
   13274           28 :           SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
   13275           28 :           GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, SymbolTable_GetSType (M2Quads_OperandT (1)), false);
   13276              :         }
   13277              :       else
   13278              :         {
   13279              :           /* avoid dangling else.  */
   13280              :           /* Spellcheck.  */
   13281            6 :           M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTSIZE} expects a variable or type as its first parameter, seen {%1Ed} {%1&s}", 109, M2Quads_OperandT (1));
   13282            6 :           ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
   13283              :         }
   13284              :     }
   13285            0 :   else if (NoOfParam == 0)
   13286              :     {
   13287              :       /* avoid dangling else.  */
   13288            0 :       resulttok = functok;
   13289            0 :       M2MetaError_MetaErrorT0 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTSIZE} expects either one or two parameters, seen none", 87);
   13290            0 :       ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
   13291              :     }
   13292              :   else
   13293              :     {
   13294              :       /* avoid dangling else.  */
   13295            0 :       Record = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
   13296            0 :       paramtok = OperandTtok (1);
   13297            0 :       resulttok = OperandTtok (NoOfParam);
   13298            0 :       if (SymbolTable_IsRecord (Record))
   13299              :         {
   13300            0 :           paramtok = OperandTtok (1);
   13301            0 :           resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   13302            0 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
   13303            0 :           SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
   13304            0 :           GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, Record, false);
   13305              :         }
   13306              :       else
   13307              :         {
   13308            0 :           resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   13309            0 :           M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTSIZE} expects the first parameter to be a record type, seen {%1d} {%1&s}", 106, Record);
   13310            0 :           ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
   13311              :         }
   13312              :     }
   13313         4774 :   M2Quads_PopN (NoOfParam+1);  /* destroy the arguments and function  */
   13314         4774 :   M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok);  /* destroy the arguments and function  */
   13315         4774 : }
   13316              : 
   13317              : 
   13318              : /*
   13319              :    BuildTBitSizeFunction - builds the pseudo function TBITSIZE
   13320              :                            The Stack:
   13321              : 
   13322              : 
   13323              :                            Entry                      Exit
   13324              : 
   13325              :                    Ptr ->
   13326              :                            +----------------+
   13327              :                            | NoOfParam      |
   13328              :                            |----------------|
   13329              :                            | Param 1        |
   13330              :                            |----------------|
   13331              :                            | Param 2        |
   13332              :                            |----------------|
   13333              :                            .                .
   13334              :                            .                .
   13335              :                            .                .
   13336              :                            |----------------|
   13337              :                            | Param #        |                        <- Ptr
   13338              :                            |----------------|         +------------+
   13339              :                            | ProcSym | Type |         | ReturnVar  |
   13340              :                            |----------------|         |------------|
   13341              : 
   13342              : */
   13343              : 
   13344         6496 : static void BuildTBitSizeFunction (void)
   13345              : {
   13346         6496 :   unsigned int resulttok;
   13347         6496 :   unsigned int paramtok;
   13348         6496 :   unsigned int functok;
   13349         6496 :   unsigned int NoOfParam;
   13350         6496 :   unsigned int ProcSym;
   13351         6496 :   unsigned int Record;
   13352         6496 :   unsigned int ReturnVar;
   13353              : 
   13354         6496 :   M2Quads_PopT (&NoOfParam);
   13355         6496 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   13356         6496 :   functok = OperandTtok (NoOfParam);
   13357         6496 :   BuildSizeCheckEnd (ProcSym);  /* quadruple generation now on  */
   13358         6496 :   if (NoOfParam == 1)  /* quadruple generation now on  */
   13359              :     {
   13360         6496 :       paramtok = OperandTtok (1);
   13361         6496 :       resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   13362         6496 :       if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
   13363              :         {
   13364         6424 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
   13365         6424 :           GenQuadO (resulttok, M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1), false);
   13366              :         }
   13367           72 :       else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
   13368              :         {
   13369              :           /* avoid dangling else.  */
   13370           72 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
   13371           72 :           GenQuadO (resulttok, M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1), false);
   13372              :         }
   13373              :       else
   13374              :         {
   13375              :           /* avoid dangling else.  */
   13376            0 :           M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTBITSIZE} expects a variable as its first parameter, seen {%1d} {%1&s}", 103, M2Quads_OperandT (1));
   13377            0 :           ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
   13378              :         }
   13379              :     }
   13380            0 :   else if (NoOfParam == 0)
   13381              :     {
   13382              :       /* avoid dangling else.  */
   13383            0 :       resulttok = functok;
   13384            0 :       M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure function {%kTBITSIZE} expects either one or two parameters, seen none", 90);
   13385            0 :       ReturnVar = SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
   13386              :     }
   13387              :   else
   13388              :     {
   13389              :       /* avoid dangling else.  */
   13390            0 :       Record = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
   13391            0 :       paramtok = OperandTtok (1);
   13392            0 :       resulttok = OperandTtok (NoOfParam);
   13393            0 :       if (SymbolTable_IsRecord (Record))
   13394              :         {
   13395            0 :           paramtok = OperandTtok (1);
   13396            0 :           resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   13397            0 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
   13398            0 :           GenQuad (M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1));
   13399              :         }
   13400              :       else
   13401              :         {
   13402            0 :           resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   13403            0 :           M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTBITSIZE} expects the first parameter to be a record type, seen {%1d} {%1&s}", 109, Record);
   13404            0 :           ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
   13405              :         }
   13406              :     }
   13407         6496 :   M2Quads_PopN (NoOfParam+1);  /* destroy the arguments and function  */
   13408         6496 :   M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok);  /* destroy the arguments and function  */
   13409         6496 : }
   13410              : 
   13411              : 
   13412              : /*
   13413              :    ExpectingParameterType -
   13414              : */
   13415              : 
   13416        91878 : static void ExpectingParameterType (unsigned int BlockSym, unsigned int Type)
   13417              : {
   13418        91878 :   if (! (SymbolTable_IsAModula2Type (Type)))
   13419              :     {
   13420              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   13421            6 :       if (((Type == SymbolTable_NulSym) || (SymbolTable_IsPartialUnbounded (Type))) || (SymbolTable_IsUnknown (Type)))
   13422              :         {
   13423            0 :           if (SymbolTable_IsUnknown (Type))
   13424              :             {
   13425              :               /* Spellcheck.  */
   13426            0 :               M2MetaError_MetaError2 ((const char *) "the type used in the formal parameter declaration in {%1Md} {%1a} is unknown {%2&s}", 83, BlockSym, Type);
   13427            0 :               SymbolTable_UnknownReported (Type);
   13428              :             }
   13429              :           else
   13430              :             {
   13431            0 :               M2MetaError_MetaError1 ((const char *) "the type used in the formal parameter declaration in {%1Md} {%1a} is unknown", 76, BlockSym);
   13432              :             }
   13433              :         }
   13434              :       else
   13435              :         {
   13436              :           /* --fixme-- filter spellcheck on type.  */
   13437            6 :           M2MetaError_MetaError2 ((const char *) "the type {%1Ead} used in the formal parameter declaration in {%2Md} {%2a} was not declared as a type", 100, Type, BlockSym);
   13438              :         }
   13439              :     }
   13440        91878 : }
   13441              : 
   13442              : 
   13443              : /*
   13444              :    ExpectingVariableType -
   13445              : */
   13446              : 
   13447        83281 : static void ExpectingVariableType (unsigned int BlockSym, unsigned int Type)
   13448              : {
   13449        83281 :   if (! (SymbolTable_IsAModula2Type (Type)))
   13450              :     {
   13451              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   13452            0 :       if (Type == SymbolTable_NulSym)
   13453              :         {
   13454            0 :           M2MetaError_MetaError1 ((const char *) "the type used during the variable declaration section in procedure {%1EMad} is unknown", 86, BlockSym);
   13455            0 :           M2MetaError_MetaError1 ((const char *) "the type used during the variable declaration section in procedure {%1Ead} is unknown", 85, BlockSym);
   13456              :         }
   13457            0 :       else if ((SymbolTable_IsPartialUnbounded (Type)) || (SymbolTable_IsUnknown (Type)))
   13458              :         {
   13459              :           /* avoid dangling else.  */
   13460              :           /* Spellcheck.  */
   13461            0 :           M2MetaError_MetaError2 ((const char *) "the type {%1EMad} used during variable declaration section in procedure {%2ad} is unknown {%1&s}", 96, Type, BlockSym);
   13462            0 :           M2MetaError_MetaError2 ((const char *) "the type {%1Ead} used during variable declaration section in procedure {%2Mad} is unknown", 89, Type, BlockSym);
   13463            0 :           SymbolTable_UnknownReported (Type);
   13464              :         }
   13465              :       else
   13466              :         {
   13467              :           /* avoid dangling else.  */
   13468            0 :           M2MetaError_MetaError2 ((const char *) "the {%1d} {%1Ea} is not a type and therefore cannot be used to declare a variable in {%2d} {%2a}", 96, Type, BlockSym);
   13469              :         }
   13470              :     }
   13471        83281 : }
   13472              : 
   13473              : 
   13474              : /*
   13475              :    CheckVariablesAndParameterTypesInBlock - checks to make sure that block, BlockSym, has
   13476              :                                             parameters types and variable types which are legal.
   13477              : */
   13478              : 
   13479       182486 : static void CheckVariablesAndParameterTypesInBlock (unsigned int BlockSym)
   13480              : {
   13481       182486 :   unsigned int i;
   13482       182486 :   unsigned int n;
   13483       182486 :   unsigned int ParamNo;
   13484              : 
   13485       182486 :   if (SymbolTable_IsProcedure (BlockSym))
   13486              :     {
   13487        81768 :       ParamNo = SymbolTable_NoOfParamAny (BlockSym);
   13488              :     }
   13489              :   else
   13490              :     {
   13491              :       ParamNo = 0;
   13492              :     }
   13493       182486 :   i = 1;
   13494      1319702 :   do {
   13495      1319702 :     n = SymbolTable_GetNth (BlockSym, i);
   13496      1319702 :     if (((n != SymbolTable_NulSym) && (! (SymbolTable_IsTemporary (n)))) && ((SymbolTable_IsProcedure (BlockSym)) || (((SymbolTable_IsDefImp (BlockSym)) && ((SymbolTable_GetMainModule ()) == BlockSym)) || (SymbolTable_IsModule (BlockSym)))))
   13497              :       {
   13498              :         /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   13499       175159 :         if (i <= ParamNo)
   13500              :           {
   13501              :             /* n is a parameter  */
   13502        91878 :             ExpectingParameterType (BlockSym, SymbolTable_GetSType (n));
   13503              :           }
   13504              :         else
   13505              :           {
   13506              :             /* n is a local variable  */
   13507        83281 :             ExpectingVariableType (BlockSym, SymbolTable_GetSType (n));
   13508              :           }
   13509              :       }
   13510      1319702 :     i += 1;
   13511      1319702 :   } while (! (n == SymbolTable_NulSym));
   13512       182486 : }
   13513              : 
   13514              : 
   13515              : /*
   13516              :    IsNeverAltered - returns TRUE if variable, sym, is never altered
   13517              :                     between quadruples: Start..End
   13518              : */
   13519              : 
   13520           30 : static bool IsNeverAltered (unsigned int sym, unsigned int Start, unsigned int End)
   13521              : {
   13522           30 :   unsigned int WriteStart;
   13523           30 :   unsigned int WriteEnd;
   13524              : 
   13525           30 :   SymbolTable_GetWriteLimitQuads (sym, SymbolTable_GetMode (sym), Start, End, &WriteStart, &WriteEnd);
   13526           30 :   return (WriteStart == 0) && (WriteEnd == 0);
   13527              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   13528              :   __builtin_unreachable ();
   13529              : }
   13530              : 
   13531              : 
   13532              : /*
   13533              :    IsConditionVariable - returns TRUE if the condition at quadruple, q, is variable.
   13534              : */
   13535              : 
   13536           24 : static bool IsConditionVariable (unsigned int q, unsigned int Start, unsigned int End)
   13537              : {
   13538           24 :   M2Quads_QuadOperator op;
   13539           24 :   unsigned int op1;
   13540           24 :   unsigned int op2;
   13541           24 :   unsigned int op3;
   13542           24 :   bool LeftFixed;
   13543           24 :   bool RightFixed;
   13544              : 
   13545           24 :   M2Quads_GetQuad (q, &op, &op1, &op2, &op3);
   13546           24 :   if (op == M2Quads_GotoOp)
   13547              :     {
   13548              :       return false;
   13549              :     }
   13550              :   else
   13551              :     {
   13552           24 :       LeftFixed = SymbolTable_IsConst (op1);
   13553           24 :       RightFixed = SymbolTable_IsConst (op2);
   13554           24 :       if (! LeftFixed)
   13555              :         {
   13556           24 :           LeftFixed = IsNeverAltered (op1, Start, End);
   13557              :         }
   13558           24 :       if (! RightFixed)
   13559              :         {
   13560            6 :           RightFixed = IsNeverAltered (op2, Start, End);
   13561              :         }
   13562           24 :       return ! (LeftFixed && RightFixed);
   13563              :     }
   13564              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   13565              :   __builtin_unreachable ();
   13566              : }
   13567              : 
   13568              : 
   13569              : /*
   13570              :    IsInfiniteLoop - returns TRUE if an infinite loop is found.
   13571              :                     Given a backwards jump at, End, it returns a BOOLEAN which depends on
   13572              :                     whether a jump is found to jump beyond, End. If a conditonal jump is found
   13573              :                     to pass over, End, the condition is tested for global variables, procedure variables and
   13574              :                     constants.
   13575              : 
   13576              :                          constant        - ignored
   13577              :                          variables       - tested to see whether they are altered inside the loop
   13578              :                          global variable - the procedure tests to see whether it is altered as above
   13579              :                                            but will also test to see whether this loop calls a procedure
   13580              :                                            in which case it believes the loop NOT to be infinite
   13581              :                                            (as this procedure call might alter the global variable)
   13582              : 
   13583              :                     Note that this procedure can easily be fooled by the user altering variables
   13584              :                     with pointers.
   13585              : */
   13586              : 
   13587           24 : static bool IsInfiniteLoop (unsigned int End)
   13588              : {
   13589           24 :   bool SeenCall;
   13590           24 :   bool IsGlobal;
   13591           24 :   unsigned int Current;
   13592           24 :   unsigned int Start;
   13593           24 :   M2Quads_QuadOperator op;
   13594           24 :   unsigned int op1;
   13595           24 :   unsigned int op2;
   13596           24 :   unsigned int op3;
   13597              : 
   13598           24 :   SeenCall = false;
   13599           24 :   IsGlobal = false;
   13600           24 :   M2Quads_GetQuad (End, &op, &op1, &op2, &Start);
   13601           24 :   Current = Start;
   13602          216 :   while (Current != End)
   13603              :     {
   13604          216 :       M2Quads_GetQuad (Current, &op, &op1, &op2, &op3);
   13605              :       /* remember that this function is only called once we have optimized the redundant gotos and conditionals  */
   13606          216 :       if ((M2Quads_IsConditional (Current)) && ! IsGlobal)
   13607              :         {
   13608           24 :           IsGlobal = ((SymbolTable_IsVar (op1)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op1))))) || ((SymbolTable_IsVar (op2)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op2)))));
   13609              :         }
   13610          216 :       if (op == M2Quads_CallOp)
   13611              :         {
   13612           12 :           SeenCall = true;
   13613              :         }
   13614          216 :       if ((op == M2Quads_GotoOp) || ((M2Quads_IsConditional (Current)) && (IsConditionVariable (Current, Start, End))))
   13615              :         {
   13616           24 :           if ((op3 > End) || (op3 < Start))
   13617              :             {
   13618              :               return false;  /* may jump out of this loop, good  */
   13619              :             }
   13620              :         }
   13621          192 :       Current = M2Quads_GetNextQuad (Current);
   13622              :     }
   13623            0 :   M2Quads_GetQuad (End, &op, &op1, &op2, &op3);
   13624            0 :   if (M2Quads_IsConditional (End))
   13625              :     {
   13626              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   13627            0 :       if (IsConditionVariable (End, Start, End))
   13628              :         {
   13629              :           return false;
   13630              :         }
   13631              :       else
   13632              :         {
   13633            0 :           if (! IsGlobal)
   13634              :             {
   13635            0 :               IsGlobal = ((SymbolTable_IsVar (op1)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op1))))) || ((SymbolTable_IsVar (op2)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op2)))));
   13636              :             }
   13637              :         }
   13638              :     }
   13639              :   /* we have found a likely infinite loop if no conditional uses a global and no procedure call was seen  */
   13640            0 :   return ! (IsGlobal && SeenCall);
   13641              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   13642              :   __builtin_unreachable ();
   13643              : }
   13644              : 
   13645              : 
   13646              : /*
   13647              :    CheckVariablesInBlock - given a block, BlockSym, check whether all variables are used.
   13648              : */
   13649              : 
   13650       182486 : static void CheckVariablesInBlock (unsigned int BlockSym)
   13651              : {
   13652            0 :   CheckVariablesAndParameterTypesInBlock (BlockSym);
   13653            0 : }
   13654              : 
   13655              : 
   13656              : /*
   13657              :    CheckFunctionReturn - checks to see that a RETURN statement was present in a function.
   13658              : */
   13659              : 
   13660        81768 : static void CheckFunctionReturn (unsigned int ProcSym)
   13661              : {
   13662        81768 :   M2Quads_QuadOperator Op;
   13663        81768 :   unsigned int Op1;
   13664        81768 :   unsigned int Op2;
   13665        81768 :   unsigned int Op3;
   13666        81768 :   unsigned int Scope;
   13667        81768 :   unsigned int Start;
   13668        81768 :   unsigned int End;
   13669              : 
   13670        81768 :   if ((SymbolTable_GetSType (ProcSym)) != SymbolTable_NulSym)
   13671              :     {
   13672              :       /* yes it is a function  */
   13673        19166 :       SymbolTable_GetProcedureQuads (ProcSym, &Scope, &Start, &End);
   13674        19166 :       M2Quads_GetQuad (Start, &Op, &Op1, &Op2, &Op3);
   13675        19166 :       if (Start == 0)
   13676              :         {
   13677            0 :           M2Error_InternalError ((const char *) "incorrect start quad", 20);
   13678              :         }
   13679       778172 :       while (((Start != End) && (Op != M2Quads_ReturnValueOp)) && (Op != M2Quads_InlineOp))
   13680              :         {
   13681       759006 :           Start = M2Quads_GetNextQuad (Start);
   13682       759006 :           M2Quads_GetQuad (Start, &Op, &Op1, &Op2, &Op3);
   13683              :         }
   13684        19166 :       if ((Op != M2Quads_ReturnValueOp) && (Op != M2Quads_InlineOp))
   13685              :         {
   13686              :           /* an InlineOp can always be used to emulate a RETURN  */
   13687            6 :           M2MetaError_MetaError1 ((const char *) "procedure function {%1Ea} does not RETURN a value", 49, ProcSym);
   13688              :         }
   13689              :     }
   13690        81768 : }
   13691              : 
   13692              : 
   13693              : /*
   13694              :    CheckReturnType - checks to see that the return type from currentProc is
   13695              :                      assignment compatible with actualType.
   13696              : */
   13697              : 
   13698        28111 : static void CheckReturnType (unsigned int tokno, unsigned int currentProc, unsigned int actualVal, unsigned int actualType)
   13699              : {
   13700        28111 :   unsigned int procType;
   13701        28111 :   DynamicStrings_String s1;
   13702        28111 :   DynamicStrings_String s2;
   13703        28111 :   NameKey_Name n1;
   13704        28111 :   NameKey_Name n2;
   13705              : 
   13706        28111 :   procType = SymbolTable_GetSType (currentProc);
   13707        28111 :   if (procType == SymbolTable_NulSym)
   13708              :     {
   13709            0 :       M2MetaError_MetaError1 ((const char *) "attempting to RETURN a value from procedure {%1Ea} which was not a declared as a procedure function", 99, currentProc);
   13710              :     }
   13711        28111 :   else if (M2Base_AssignmentRequiresWarning (actualType, SymbolTable_GetSType (currentProc)))
   13712              :     {
   13713              :       /* avoid dangling else.  */
   13714            0 :       M2MetaError_MetaError2 ((const char *) "attempting to RETURN a value {%1Wa} with an incompatible type {%1Wtsa} from a procedure function {%1a} which returns {%1tsa}", 124, actualVal, currentProc);
   13715              :     }
   13716        28111 :   else if (! (M2Base_IsAssignmentCompatible (actualType, procType)))
   13717              :     {
   13718              :       /* avoid dangling else.  */
   13719            0 :       n1 = SymbolTable_GetSymName (actualType);
   13720            0 :       n2 = SymbolTable_GetSymName (procType);
   13721            0 :       M2Error_WriteFormat2 ((const char *) "attempting to RETURN a value with an incompatible type (%a) from a function which returns (%a)", 94, (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
   13722              :     }
   13723        28111 :   else if ((SymbolTable_IsProcedure (actualVal)) && (! (M2Base_IsAssignmentCompatible (actualVal, procType))))
   13724              :     {
   13725              :       /* avoid dangling else.  */
   13726              :       /* 
   13727              :       MetaWarnings2('attempting to RETURN a value with an incompatible type {%1ad} from function {%2a} which returns {%2ta}',
   13728              :                     actualVal, currentProc)
   13729              : 
   13730              :       --fixme--  introduce MetaWarning, MetaWarning2, MetaWarning3 into M2MetaError
   13731              :   */
   13732            0 :       s1 = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (actualVal)));
   13733            0 :       s2 = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (procType)));
   13734            0 :       M2Error_ErrorString (M2Error_NewWarning (M2LexBuf_GetTokenNo ()), FormatStrings_Sprintf2 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "attempting to RETURN a value with a (possibly on other targets) incompatible type (%s) from a function which returns (%s)", 121)), (const unsigned char *) &s1, (sizeof (s1)-1), (const unsigned char *) &s2, (sizeof (s2)-1)));
   13735              :     }
   13736        28111 :   else if ((SymbolTable_IsProcedure (actualVal)) && (! (M2Base_IsAssignmentCompatible (actualVal, SymbolTable_GetSType (CurrentProc)))))
   13737              :     {
   13738              :       /* avoid dangling else.  */
   13739            0 :       n1 = SymbolTable_GetSymName (actualVal);
   13740            0 :       n2 = SymbolTable_GetSymName (SymbolTable_GetSType (currentProc));
   13741            0 :       M2Error_WriteFormat2 ((const char *) "attempting to RETURN a value with an incompatible type (%a) from a function which returns (%a)", 94, (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
   13742              :     }
   13743              :   else
   13744              :     {
   13745              :       /* avoid dangling else.  */
   13746              :       /* this checks the types are compatible, not the data contents.  */
   13747        28111 :       BuildRange (M2Range_InitTypesReturnTypeCheck (tokno, currentProc, actualVal));
   13748              :     }
   13749        28111 : }
   13750              : 
   13751              : 
   13752              : /*
   13753              :    BuildReturnLower - check the return type and value to ensure type
   13754              :                       compatibility and no range overflow will occur.
   13755              : */
   13756              : 
   13757        28111 : static void BuildReturnLower (unsigned int tokcombined, unsigned int tokexpr, unsigned int e1, unsigned int t1)
   13758              : {
   13759        28111 :   unsigned int e2;
   13760        28111 :   unsigned int t2;
   13761              : 
   13762              :   /* This will check that the type returned is compatible with
   13763              :       the formal return type of the procedure.  */
   13764        28111 :   CheckReturnType (tokcombined, CurrentProc, e1, t1);
   13765              :   /* Dereference LeftValue if necessary.  */
   13766        28111 :   if ((SymbolTable_GetMode (e1)) == SymbolTable_LeftValue)
   13767              :     {
   13768          172 :       t2 = SymbolTable_GetSType (CurrentProc);
   13769          172 :       e2 = SymbolTable_MakeTemporary (tokexpr, SymbolTable_RightValue);
   13770          172 :       SymbolTable_PutVar (e2, t2);
   13771          172 :       CheckPointerThroughNil (tokexpr, e1);
   13772          172 :       doIndrX (tokexpr, e2, e1);
   13773          172 :       e1 = e2;
   13774              :     }
   13775              :   /* Here we check the data contents to ensure no overflow.  */
   13776        28111 :   BuildRange (M2Range_InitReturnRangeCheck (tokcombined, CurrentProc, e1));
   13777        28111 :   GenQuadOtok (tokcombined, M2Quads_ReturnValueOp, e1, SymbolTable_NulSym, CurrentProc, false, tokcombined, M2LexBuf_UnknownTokenNo, SymbolTable_GetDeclaredMod (CurrentProc));
   13778        28111 : }
   13779              : 
   13780              : 
   13781              : /*
   13782              :    IsReadOnly - a helper procedure function to detect constants.
   13783              : */
   13784              : 
   13785       276474 : static bool IsReadOnly (unsigned int sym)
   13786              : {
   13787       276474 :   return (SymbolTable_IsConst (sym)) || ((SymbolTable_IsVar (sym)) && (SymbolTable_IsVarConst (sym)));
   13788              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   13789              :   __builtin_unreachable ();
   13790              : }
   13791              : 
   13792              : 
   13793              : /*
   13794              :    BuildDesignatorError - removes the designator from the stack and replaces
   13795              :                           it with an error symbol.
   13796              : */
   13797              : 
   13798           54 : static void BuildDesignatorError (const char *message_, unsigned int _message_high)
   13799              : {
   13800           54 :   unsigned int combinedTok;
   13801           54 :   unsigned int arrayTok;
   13802           54 :   unsigned int exprTok;
   13803           54 :   unsigned int e;
   13804           54 :   unsigned int d;
   13805           54 :   unsigned int error;
   13806           54 :   unsigned int Sym;
   13807           54 :   unsigned int Type;
   13808           54 :   char message[_message_high+1];
   13809              : 
   13810              :   /* make a local copy of each unbounded array.  */
   13811           54 :   memcpy (message, message_, _message_high+1);
   13812              : 
   13813           54 :   M2Quads_PopTtok (&e, &exprTok);
   13814           54 :   PopTFDtok (&Sym, &Type, &d, &arrayTok);
   13815           54 :   combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, exprTok);
   13816           54 :   error = SymbolTable_MakeError (combinedTok, NameKey_MakeKey ((const char *) message, _message_high));
   13817           54 :   PushTFDtok (error, Type, d, arrayTok);
   13818           54 : }
   13819              : 
   13820              : 
   13821              : /*
   13822              :    BuildDesignatorPointerError - removes the designator from the stack and replaces
   13823              :                                  it with an error symbol.
   13824              : */
   13825              : 
   13826            2 : static void BuildDesignatorPointerError (unsigned int type, unsigned int rw, unsigned int tokpos, const char *message_, unsigned int _message_high)
   13827              : {
   13828            2 :   unsigned int error;
   13829            2 :   char message[_message_high+1];
   13830              : 
   13831              :   /* make a local copy of each unbounded array.  */
   13832            2 :   memcpy (message, message_, _message_high+1);
   13833              : 
   13834            2 :   error = SymbolTable_MakeError (tokpos, NameKey_MakeKey ((const char *) message, _message_high));
   13835            2 :   if ((SymbolTable_GetSType (type)) != SymbolTable_NulSym)
   13836              :     {
   13837            2 :       type = SymbolTable_GetSType (type);
   13838              :     }
   13839            2 :   PushTFrwtok (error, type, rw, tokpos);
   13840            2 : }
   13841              : 
   13842              : 
   13843              : /*
   13844              :    BuildDesignatorArrayStaticDynamic - Builds the array referencing.
   13845              :                                        The purpose of this procedure is to work out
   13846              :                                        whether the DesignatorArray is a static or
   13847              :                                        dynamic array and to call the appropriate
   13848              :                                        BuildRoutine.
   13849              : 
   13850              :                                        The Stack is expected to contain:
   13851              : 
   13852              : 
   13853              :                                        Entry                   Exit
   13854              :                                        =====                   ====
   13855              : 
   13856              :                                 Ptr ->
   13857              :                                        +--------------+
   13858              :                                        | e            |                        <- Ptr
   13859              :                                        |--------------|        +------------+
   13860              :                                        | Sym  | Type  |        | S    | T   |
   13861              :                                        |--------------|        |------------|
   13862              : */
   13863              : 
   13864        57020 : static void BuildDesignatorArrayStaticDynamic (void)
   13865              : {
   13866        57020 :   unsigned int combinedTok;
   13867        57020 :   unsigned int arrayTok;
   13868        57020 :   unsigned int exprTok;
   13869        57020 :   unsigned int e;
   13870        57020 :   unsigned int type;
   13871        57020 :   unsigned int dim;
   13872        57020 :   unsigned int result;
   13873        57020 :   unsigned int Sym;
   13874        57020 :   unsigned int Type;
   13875              : 
   13876        57020 :   if (SymbolTable_IsConst (M2Quads_OperandT (2)))
   13877              :     {
   13878          204 :       type = SymbolTable_GetDType (M2Quads_OperandT (2));
   13879          204 :       if ((type != SymbolTable_NulSym) && (SymbolTable_IsArray (type)))
   13880              :         {
   13881          204 :           M2Quads_PopTtok (&e, &exprTok);
   13882          204 :           PopTFDtok (&Sym, &Type, &dim, &arrayTok);
   13883          204 :           result = SymbolTable_MakeTemporary (exprTok, SymbolTable_RightValue);
   13884          204 :           SymbolTable_PutVar (result, Type);
   13885          204 :           M2Quads_PushTFtok (result, SymbolTable_GetSType (result), exprTok);
   13886          204 :           M2Quads_PushTtok (Sym, arrayTok);
   13887          204 :           combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, exprTok);
   13888          204 :           SymbolTable_PutVarConst (result, true);
   13889          204 :           M2Quads_BuildAssignConstant (combinedTok);
   13890          204 :           PushTFDtok (result, SymbolTable_GetDType (result), dim, arrayTok);
   13891          204 :           M2Quads_PushTtok (e, exprTok);
   13892              :         }
   13893              :     }
   13894        57020 :   if ((! (SymbolTable_IsVar (M2Quads_OperandT (2)))) && (! (SymbolTable_IsTemporary (M2Quads_OperandT (2)))))
   13895              :     {
   13896           18 :       M2MetaError_MetaErrorT1 (OperandTtok (2), (const char *) "can only access arrays using constants, variables or formal parameters not {%1Ead}", 82, M2Quads_OperandT (2));
   13897           18 :       BuildDesignatorError ((const char *) "bad array access", 16);
   13898              :     }
   13899        57020 :   Sym = static_cast<unsigned int> (M2Quads_OperandT (2));
   13900        57020 :   Type = SymbolTable_GetDType (Sym);
   13901        57020 :   arrayTok = OperandTtok (2);
   13902        57020 :   if (Type == SymbolTable_NulSym)
   13903              :     {
   13904            0 :       if ((arrayTok == M2LexBuf_UnknownTokenNo) || (arrayTok == M2LexBuf_BuiltinTokenNo))
   13905              :         {
   13906            0 :           arrayTok = M2LexBuf_GetTokenNo ();
   13907              :         }
   13908            0 :       M2MetaError_MetaErrorT0 (arrayTok, (const char *) "type of array is undefined", 26);
   13909            0 :       BuildDesignatorError ((const char *) "bad array access", 16);
   13910              :     }
   13911        57020 :   else if (SymbolTable_IsUnbounded (Type))
   13912              :     {
   13913              :       /* avoid dangling else.  */
   13914         8994 :       BuildDynamicArray ();
   13915              :     }
   13916        48026 :   else if (SymbolTable_IsArray (Type))
   13917              :     {
   13918              :       /* avoid dangling else.  */
   13919        47996 :       BuildStaticArray ();
   13920              :     }
   13921              :   else
   13922              :     {
   13923              :       /* avoid dangling else.  */
   13924           30 :       M2MetaError_MetaErrorT1 (arrayTok, (const char *) "can only index static or dynamic arrays, {%1Ead} is not an array but a {%tadv}", 78, Sym);
   13925           30 :       BuildDesignatorError ((const char *) "bad array access", 16);
   13926              :     }
   13927        57014 : }
   13928              : 
   13929              : 
   13930              : /*
   13931              :    BuildStaticArray - Builds the array referencing for static arrays.
   13932              :                       The Stack is expected to contain:
   13933              : 
   13934              : 
   13935              :                       Entry                   Exit
   13936              :                       =====                   ====
   13937              : 
   13938              :               Ptr ->
   13939              :                       +--------------+
   13940              :                       | e            |                       <- Ptr
   13941              :                       |--------------|        +------------+
   13942              :                       | Sym  | Type  |        | S    | T   |
   13943              :                       |--------------|        |------------|
   13944              : */
   13945              : 
   13946        47996 : static void BuildStaticArray (void)
   13947              : {
   13948        47996 :   unsigned int combinedTok;
   13949        47996 :   unsigned int indexTok;
   13950        47996 :   unsigned int arrayTok;
   13951        47996 :   unsigned int rw;
   13952        47996 :   unsigned int Dim;
   13953        47996 :   unsigned int Array;
   13954        47996 :   unsigned int Index;
   13955        47996 :   unsigned int BackEndType;
   13956        47996 :   unsigned int Type;
   13957        47996 :   unsigned int Adr;
   13958              : 
   13959        47996 :   Index = static_cast<unsigned int> (M2Quads_OperandT (1));
   13960        47996 :   indexTok = OperandTtok (1);
   13961        47996 :   Array = static_cast<unsigned int> (M2Quads_OperandT (2));
   13962        47996 :   arrayTok = OperandTtok (2);
   13963        47996 :   Type = SymbolTable_SkipType (M2Quads_OperandF (2));
   13964        47996 :   rw = static_cast<unsigned int> (OperandMergeRW (2));
   13965        47996 :   M2Debug_Assert (SymbolTable_IsLegal (rw));
   13966        47996 :   Dim = static_cast<unsigned int> (OperandD (2));
   13967        47996 :   Dim += 1;
   13968        47996 :   if ((SymbolTable_GetMode (Index)) == SymbolTable_LeftValue)
   13969              :     {
   13970          176 :       Index = MakeRightValue (indexTok, Index, SymbolTable_GetSType (Index));
   13971              :     }
   13972        47990 :   BuildRange (M2Range_InitStaticArraySubscriptRangeCheck (SymbolTable_GetArraySubscript (Type), Index, Dim));
   13973              :   /* now make Adr point to the address of the indexed element  */
   13974        47990 :   combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, indexTok);
   13975        47990 :   Adr = SymbolTable_MakeTemporary (combinedTok, SymbolTable_LeftValue);
   13976        47990 :   if (SymbolTable_IsVar (Array))
   13977              :     {
   13978              :       /* BuildDesignatorArray may have detected des is a constant.  */
   13979        47990 :       SymbolTable_PutVarConst (Adr, SymbolTable_IsVarConst (Array));
   13980              :     }
   13981        47990 :   SymbolTable_PutVarArrayRef (Adr, true);
   13982              :   /* 
   13983              :       From now on it must reference the array element by its lvalue
   13984              :       - so we create the type of the referenced entity
   13985              :   */
   13986        47990 :   BackEndType = SymbolTable_MakePointer (combinedTok, NameKey_NulName);
   13987        47990 :   SymbolTable_PutPointer (BackEndType, SymbolTable_GetDType (Type));
   13988              :   /* PutVar(Adr, BackEndType) ;  */
   13989        47990 :   SymbolTable_PutLeftValueFrontBackType (Adr, SymbolTable_GetDType (Type), BackEndType);
   13990        95980 :   GenQuadO (combinedTok, M2Quads_ArrayOp, Adr, Index, Array, true);
   13991        47990 :   M2Quads_PopN (2);  /* remove all parameters to this procedure  */
   13992        47990 :   PushTFDrwtok (Adr, SymbolTable_GetSType (Adr), Dim, rw, combinedTok);  /* remove all parameters to this procedure  */
   13993        47990 : }
   13994              : 
   13995              : 
   13996              : /*
   13997              :    calculateMultipicand - generates quadruples which calculate the
   13998              :                           multiplicand for the array at dimension, dim.
   13999              : */
   14000              : 
   14001        12052 : static unsigned int calculateMultipicand (unsigned int tok, unsigned int arraySym, unsigned int arrayType, unsigned int dim)
   14002              : {
   14003        12052 :   unsigned int ti;
   14004        12052 :   unsigned int tj;
   14005        12052 :   unsigned int tk;
   14006        12052 :   unsigned int tl;
   14007              : 
   14008        12052 :   if (dim == (SymbolTable_GetDimension (arrayType)))
   14009              :     {
   14010              :       /* ti has no type since constant  */
   14011        10268 :       ti = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
   14012        10268 :       SymbolTable_PutVar (ti, M2Base_Cardinal);
   14013        10268 :       GenQuadO (tok, M2Quads_ElementSizeOp, ti, arrayType, 1, true);
   14014              :     }
   14015              :   else
   14016              :     {
   14017         1784 :       dim += 1;
   14018         1784 :       tk = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
   14019         1784 :       SymbolTable_PutVar (tk, M2Base_Cardinal);
   14020         1784 :       GenHigh (tok, tk, dim, arraySym);
   14021         1784 :       tl = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
   14022         1784 :       SymbolTable_PutVar (tl, M2Base_Cardinal);
   14023         1784 :       GenQuadOtok (tok, M2Quads_AddOp, tl, tk, SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal), true, tok, tok, tok);
   14024         1784 :       tj = calculateMultipicand (tok, arraySym, arrayType, dim);
   14025         1784 :       ti = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
   14026         1784 :       SymbolTable_PutVar (ti, M2Base_Cardinal);
   14027         1784 :       GenQuadO (tok, M2Quads_MultOp, ti, tj, tl, true);
   14028              :     }
   14029        12052 :   return ti;
   14030              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   14031              :   __builtin_unreachable ();
   14032              : }
   14033              : 
   14034              : 
   14035              : /*
   14036              :    ConvertToAddress - convert sym to an address.
   14037              : */
   14038              : 
   14039         9078 : static unsigned int ConvertToAddress (unsigned int tokpos, unsigned int sym)
   14040              : {
   14041         9078 :   unsigned int adr;
   14042              : 
   14043         9078 :   if ((SymbolTable_GetSType (sym)) == M2System_Address)
   14044              :     {
   14045              :       return sym;
   14046              :     }
   14047              :   else
   14048              :     {
   14049         9066 :       M2Quads_PushTF (SymbolTable_RequestSym (tokpos, NameKey_MakeKey ((const char *) "CONVERT", 7)), static_cast<unsigned int> (SymbolTable_NulSym));
   14050         9066 :       M2Quads_PushT (M2System_Address);
   14051         9066 :       M2Quads_PushTtok (sym, tokpos);
   14052         9066 :       M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
   14053         9066 :       BuildConvertFunction (M2Base_Convert, false);  /* Two parameters  */
   14054         9066 :       M2Quads_PopT (&adr);
   14055         9066 :       return adr;
   14056              :     }
   14057              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   14058              :   __builtin_unreachable ();
   14059              : }
   14060              : 
   14061              : 
   14062              : /*
   14063              :    BuildDynamicArray - Builds the array referencing for dynamic arrays.
   14064              :                        The Stack is expected to contain:
   14065              : 
   14066              : 
   14067              :                        Entry                          Exit
   14068              :                        =====                          ====
   14069              : 
   14070              :                Ptr ->
   14071              :                        +-----------------------+
   14072              :                        | Index                 |                                    <- Ptr
   14073              :                        |-----------------------|      +---------------------------+
   14074              :                        | ArraySym | Type | Dim |      | S  | T | ArraySym | Dim+1 |
   14075              :                        |-----------------------|      |---------------------------|
   14076              : 
   14077              : 
   14078              :    if Dim=1
   14079              :    then
   14080              :       S := base of ArraySym + TSIZE(Type)*Index
   14081              :    else
   14082              :       S := S + TSIZE(Type)*Index
   14083              :    fi
   14084              : */
   14085              : 
   14086         8994 : static void BuildDynamicArray (void)
   14087              : {
   14088         8994 :   unsigned int combinedTok;
   14089         8994 :   unsigned int arrayTok;
   14090         8994 :   unsigned int indexTok;
   14091         8994 :   unsigned int Sym;
   14092         8994 :   unsigned int idx;
   14093         8994 :   unsigned int Type;
   14094         8994 :   unsigned int Adr;
   14095         8994 :   unsigned int ArraySym;
   14096         8994 :   unsigned int BackEndType;
   14097         8994 :   unsigned int UnboundedType;
   14098         8994 :   unsigned int PtrToBase;
   14099         8994 :   unsigned int Base;
   14100         8994 :   unsigned int Dim;
   14101         8994 :   unsigned int rw;
   14102         8994 :   unsigned int ti;
   14103         8994 :   unsigned int tj;
   14104         8994 :   unsigned int tk;
   14105         8994 :   unsigned int tka;
   14106              : 
   14107         8994 :   M2Quads_DisplayStack ();
   14108         8994 :   Sym = static_cast<unsigned int> (M2Quads_OperandT (2));
   14109         8994 :   Type = SymbolTable_SkipType (M2Quads_OperandF (2));
   14110         8994 :   arrayTok = static_cast<unsigned int> (M2Quads_OperandTok (2));
   14111         8994 :   indexTok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   14112         8994 :   combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, indexTok);
   14113         8994 :   Dim = static_cast<unsigned int> (OperandD (2));
   14114         8994 :   rw = static_cast<unsigned int> (OperandMergeRW (2));
   14115         8994 :   M2Debug_Assert (SymbolTable_IsLegal (rw));
   14116         8994 :   Dim += 1;
   14117         8994 :   if (Dim == 1)
   14118              :     {
   14119              :       /* 
   14120              :          Base has type address since
   14121              :          BuildDesignatorRecord references by address.
   14122              : 
   14123              :          Build a record for retrieving the address of dynamic array.
   14124              :          BuildDesignatorRecord will generate the required quadruples,
   14125              :          therefore build sets up the stack for BuildDesignatorRecord
   14126              :          which will generate the quads to access the record.
   14127              :   */
   14128         8856 :       ArraySym = Sym;
   14129         8856 :       UnboundedType = SymbolTable_GetUnboundedRecordType (SymbolTable_GetSType (Sym));
   14130         8856 :       PushTFrwtok (Sym, UnboundedType, rw, arrayTok);
   14131         8856 :       M2Quads_PushTF (SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (Sym)), SymbolTable_GetSType (SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (Sym))));
   14132         8856 :       M2Quads_PushT (static_cast<unsigned int> (1));  /* One record field to dereference  */
   14133         8856 :       M2Quads_BuildDesignatorRecord (combinedTok);  /* One record field to dereference  */
   14134         8856 :       M2Quads_PopT (&PtrToBase);
   14135         8856 :       M2Quads_DisplayStack ();
   14136              :       /* Now actually copy Unbounded.ArrayAddress into base  */
   14137         8856 :       if ((SymbolTable_GetMode (PtrToBase)) == SymbolTable_LeftValue)
   14138              :         {
   14139            0 :           Base = SymbolTable_MakeTemporary (arrayTok, SymbolTable_RightValue);
   14140            0 :           SymbolTable_PutVar (Base, M2System_Address);  /* has type ADDRESS  */
   14141            0 :           CheckPointerThroughNil (arrayTok, PtrToBase);  /* has type ADDRESS  */
   14142            0 :           GenQuad (M2Quads_IndrXOp, Base, M2System_Address, PtrToBase);  /* Base = *PtrToBase  */
   14143              :         }
   14144              :       else
   14145              :         {
   14146         8856 :           M2Debug_Assert ((SymbolTable_GetMode (PtrToBase)) != SymbolTable_ImmediateValue);
   14147         8856 :           Base = PtrToBase;
   14148              :         }
   14149              :     }
   14150              :   else
   14151              :     {
   14152              :       /* Base already calculated previously and pushed to stack  */
   14153          138 :       UnboundedType = SymbolTable_SkipType (M2Quads_OperandF (2));
   14154          138 :       Base = Sym;
   14155          138 :       ArraySym = static_cast<unsigned int> (M2Quads_OperandA (2));
   14156              :     }
   14157         8994 :   M2Debug_Assert ((SymbolTable_GetSType (Sym)) == Type);
   14158         8994 :   ti = calculateMultipicand (indexTok, Sym, Type, Dim);
   14159         8994 :   idx = static_cast<unsigned int> (M2Quads_OperandT (1));
   14160         8994 :   if ((SymbolTable_IsConst (idx)) && (SymbolTable_IsConst (ti)))
   14161              :     {
   14162              :       /* tj has no type since constant  */
   14163          460 :       tj = SymbolTable_MakeTemporary (indexTok, SymbolTable_ImmediateValue);
   14164          460 :       tk = SymbolTable_MakeTemporary (indexTok, SymbolTable_ImmediateValue);
   14165          460 :       SymbolTable_PutVar (tj, M2Base_Cardinal);
   14166          460 :       SymbolTable_PutVar (tk, M2Base_Cardinal);
   14167              :     }
   14168              :   else
   14169              :     {
   14170              :       /* tj has Cardinal type since we have multiplied array indices  */
   14171         8534 :       tj = SymbolTable_MakeTemporary (indexTok, SymbolTable_RightValue);
   14172         8534 :       if ((SymbolTable_GetSType (idx)) != M2Base_Cardinal)
   14173              :         {
   14174          270 :           M2Quads_PushTF (SymbolTable_RequestSym (indexTok, NameKey_MakeKey ((const char *) "CONVERT", 7)), static_cast<unsigned int> (SymbolTable_NulSym));
   14175          270 :           M2Quads_PushT (M2Base_Cardinal);
   14176          270 :           M2Quads_PushTtok (idx, indexTok);
   14177          270 :           M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
   14178          270 :           BuildConvertFunction (M2Base_Convert, false);  /* Two parameters  */
   14179          270 :           M2Quads_PopT (&idx);
   14180              :         }
   14181         8534 :       SymbolTable_PutVar (tj, M2Base_Cardinal);
   14182         8534 :       tk = SymbolTable_MakeTemporary (indexTok, SymbolTable_RightValue);
   14183         8534 :       SymbolTable_PutVar (tk, M2Base_Cardinal);
   14184              :     }
   14185         8994 :   BuildRange (M2Range_InitDynamicArraySubscriptRangeCheck (ArraySym, idx, Dim));
   14186         8994 :   M2Quads_PushTtok (tj, indexTok);
   14187         8994 :   M2Quads_PushTtok (idx, indexTok);
   14188         8994 :   BuildAssignmentWithoutBounds (indexTok, false, true);
   14189        17988 :   GenQuad (M2Quads_MultOp, tk, ti, tj);
   14190        17988 :   Adr = SymbolTable_MakeTemporary (combinedTok, SymbolTable_LeftValue);
   14191         8994 :   SymbolTable_PutVarArrayRef (Adr, true);
   14192              :   /* 
   14193              :       Ok must reference by address
   14194              :       - but we contain the type of the referenced entity
   14195              :   */
   14196         8994 :   BackEndType = SymbolTable_MakePointer (combinedTok, NameKey_NulName);
   14197         8994 :   SymbolTable_PutPointer (BackEndType, SymbolTable_GetSType (Type));
   14198              :   /* Create a temporary pointer for addition.  */
   14199         8994 :   tka = ConvertToAddress (combinedTok, tk);
   14200         8994 :   if (Dim == (SymbolTable_GetDimension (Type)))
   14201              :     {
   14202         8676 :       SymbolTable_PutLeftValueFrontBackType (Adr, SymbolTable_GetSType (Type), BackEndType);
   14203        17352 :       GenQuadOtok (combinedTok, M2Quads_AddOp, Adr, Base, tka, false, combinedTok, combinedTok, combinedTok);
   14204         8676 :       M2Quads_PopN (2);
   14205         8676 :       PushTFADrwtok (Adr, SymbolTable_GetSType (Adr), ArraySym, Dim, rw, combinedTok);
   14206              :     }
   14207              :   else
   14208              :     {
   14209              :       /* more to index  */
   14210          318 :       SymbolTable_PutLeftValueFrontBackType (Adr, Type, BackEndType);
   14211          636 :       GenQuadOtok (combinedTok, M2Quads_AddOp, Adr, Base, tka, false, combinedTok, combinedTok, combinedTok);
   14212          318 :       M2Quads_PopN (2);
   14213          318 :       PushTFADrwtok (Adr, SymbolTable_GetSType (Adr), ArraySym, Dim, rw, combinedTok);
   14214              :     }
   14215         8994 : }
   14216              : 
   14217              : 
   14218              : /*
   14219              :    DebugLocation -
   14220              : */
   14221              : 
   14222        58792 : static void DebugLocation (unsigned int tok, const char *message_, unsigned int _message_high)
   14223              : {
   14224        58792 :   char message[_message_high+1];
   14225              : 
   14226              :   /* make a local copy of each unbounded array.  */
   14227        58792 :   memcpy (message, message_, _message_high+1);
   14228              : 
   14229        58792 :   if (DebugTokPos)
   14230              :     {
   14231              :       M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) message, _message_high), tok);
   14232              :     }
   14233        58792 : }
   14234              : 
   14235              : 
   14236              : /*
   14237              :    PushWith - pushes sym and type onto the with stack. It checks for
   14238              :               previous declaration of this record type.
   14239              : */
   14240              : 
   14241         6190 : static void PushWith (unsigned int Sym, unsigned int Type, unsigned int Ref, unsigned int Tok)
   14242              : {
   14243         6190 :   unsigned int i;
   14244         6190 :   unsigned int n;
   14245         6190 :   M2Quads_WithFrame f;
   14246              : 
   14247         6190 :   if (M2Options_Pedantic)
   14248              :     {
   14249            0 :       n = M2StackAddress_NoOfItemsInStackAddress (WithStack);
   14250            0 :       i = 1;  /* Top of the stack.  */
   14251              :       /* Search for other declarations of the with using Type.  */
   14252            0 :       while (i <= n)
   14253              :         {
   14254            0 :           f = static_cast<M2Quads_WithFrame> (M2StackAddress_PeepAddress (WithStack, i));
   14255            0 :           if (f->RecordSym == Type)
   14256              :             {
   14257            0 :               M2MetaError_MetaErrorT1 (Tok, (const char *) "cannot have nested {%kWITH} statements referencing the same {%kRECORD} {%1Ead}", 78, Sym);
   14258            0 :               M2MetaError_MetaErrorT1 (f->RecordTokPos, (const char *) "cannot have nested {%kWITH} statements referencing the same {%kRECORD} {%1Ead}", 78, f->RecordSym);
   14259              :             }
   14260            0 :           i += 1;
   14261              :         }
   14262              :     }
   14263         6190 :   Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T4));
   14264         6190 :   f->RecordSym = Sym;
   14265         6190 :   f->RecordType = Type;
   14266         6190 :   f->RecordRef = Ref;
   14267         6190 :   f->rw = Sym;
   14268         6190 :   f->RecordTokPos = Tok;
   14269         6190 :   M2StackAddress_PushAddress (WithStack, reinterpret_cast <void *> (f));
   14270         6190 : }
   14271              : 
   14272         6190 : static void PopWith (void)
   14273              : {
   14274         6190 :   M2Quads_WithFrame f;
   14275              : 
   14276         6190 :   f = static_cast<M2Quads_WithFrame> (M2StackAddress_PopAddress (WithStack));
   14277         6190 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T4));
   14278         6190 : }
   14279              : 
   14280              : 
   14281              : /*
   14282              :    BuildAccessWithField - similar to BuildDesignatorRecord except it
   14283              :                           does not perform the address operation.
   14284              :                           The address will have been computed at the
   14285              :                           beginning of the WITH statement.
   14286              :                           It also stops the GenQuad procedure from examining the
   14287              :                           with stack.
   14288              : 
   14289              :                           The Stack
   14290              : 
   14291              :                           Entry
   14292              : 
   14293              :                    Ptr ->
   14294              :                           +--------------+
   14295              :                           | Field | Type1|                          <- Ptr
   14296              :                           |-------|------|          +-------------+
   14297              :                           | Adr   | Type2|          | Sym  | Type1|
   14298              :                           |--------------|          |-------------|
   14299              : */
   14300              : 
   14301        31040 : static void BuildAccessWithField (void)
   14302              : {
   14303        31040 :   unsigned int rectok;
   14304        31040 :   unsigned int fieldtok;
   14305        31040 :   bool OldSuppressWith;
   14306        31040 :   unsigned int rw;
   14307        31040 :   unsigned int Field;
   14308        31040 :   unsigned int FieldType;
   14309        31040 :   unsigned int Record;
   14310        31040 :   unsigned int RecordType;
   14311        31040 :   unsigned int Ref;
   14312              : 
   14313        31040 :   OldSuppressWith = SuppressWith;
   14314        31040 :   SuppressWith = true;
   14315              :   /* 
   14316              :       now the WITH cannot look at the stack of outstanding WITH records.
   14317              :   */
   14318        31040 :   M2Quads_PopTFtok (&Field, &FieldType, &fieldtok);
   14319        31040 :   PopTFrwtok (&Record, &RecordType, &rw, &rectok);
   14320        31040 :   Ref = SymbolTable_MakeComponentRef (SymbolTable_MakeComponentRecord (fieldtok, SymbolTable_RightValue, Record), Field);
   14321        31040 :   SymbolTable_PutVarConst (Ref, IsReadOnly (Record));
   14322        62080 :   GenQuadO (fieldtok, M2Quads_RecordFieldOp, Ref, Record, Field, true);
   14323        31040 :   PushTFrwtok (Ref, FieldType, rw, fieldtok);
   14324        31040 :   SuppressWith = OldSuppressWith;
   14325        31040 : }
   14326              : 
   14327              : 
   14328              : /*
   14329              :    SafeCheckWithField - only call CheckWithReference if the top of stack
   14330              :                         contains a record field.
   14331              : */
   14332              : 
   14333        12100 : static void SafeCheckWithField (void)
   14334              : {
   14335        12100 :   if (SymbolTable_IsRecordField (M2Quads_OperandT (1)))
   14336              :     {
   14337           24 :       M2Quads_CheckWithReference ();
   14338              :     }
   14339        12100 : }
   14340              : 
   14341              : 
   14342              : /*
   14343              :    PushConstructor -
   14344              : */
   14345              : 
   14346        48360 : static void PushConstructor (unsigned int sym)
   14347              : {
   14348        48360 :   M2Quads_ConstructorFrame c;
   14349              : 
   14350        48360 :   Storage_ALLOCATE ((void **) &c, sizeof (M2Quads__T1));
   14351        48360 :   c->type = SymbolTable_SkipType (sym);
   14352        48360 :   c->index = 1;
   14353        48360 :   M2StackAddress_PushAddress (ConstructorStack, reinterpret_cast <void *> (c));
   14354        48360 : }
   14355              : 
   14356              : 
   14357              : /*
   14358              :    AddFieldTo - adds field to value.
   14359              : */
   14360              : 
   14361        25842 : static unsigned int AddFieldTo (unsigned int value, unsigned int field, unsigned int valuetok, unsigned int fieldtok)
   14362              : {
   14363        25842 :   if (SymbolTable_IsSet (SymbolTable_GetDType (value)))
   14364              :     {
   14365        12100 :       SymbolTable_PutConstSet (value);
   14366        12100 :       M2Quads_PushTtok (value, valuetok);
   14367        12100 :       M2Quads_PushTtok (field, fieldtok);
   14368        12100 :       M2Quads_BuildInclBit ();
   14369        12100 :       M2Quads_PopT (&value);
   14370              :     }
   14371              :   else
   14372              :     {
   14373        13742 :       SymbolTable_PushValue (value);
   14374        13742 :       M2ALU_AddField (fieldtok, field);
   14375        13742 :       SymbolTable_PopValue (value);
   14376              :     }
   14377        25842 :   return value;
   14378              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   14379              :   __builtin_unreachable ();
   14380              : }
   14381              : 
   14382              : 
   14383              : /*
   14384              :    CheckLogicalOperator - returns a logical operator if the operands imply
   14385              :                           a logical operation should be performed.
   14386              : */
   14387              : 
   14388        79026 : static NameKey_Name CheckLogicalOperator (NameKey_Name Tok, unsigned int left, unsigned int lefttype)
   14389              : {
   14390        79026 :   if ((((Tok == M2Reserved_PlusTok) || (Tok == M2Reserved_TimesTok)) || (Tok == M2Reserved_DivideTok)) || (Tok == M2Reserved_MinusTok))
   14391              :     {
   14392              :       /* --fixme-- when we add complex arithmetic, we must check constructor is not a complex constant.  */
   14393        69763 :       if ((((lefttype != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_SkipType (lefttype)))) || (SymbolTable_IsConstSet (left))) || (SymbolTable_IsConstructor (left)))
   14394              :         {
   14395              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   14396         1482 :           if (Tok == M2Reserved_PlusTok)
   14397              :             {
   14398         1008 :               return LogicalOrTok;
   14399              :             }
   14400          474 :           else if (Tok == M2Reserved_DivideTok)
   14401              :             {
   14402              :               /* avoid dangling else.  */
   14403          124 :               return LogicalXorTok;
   14404              :             }
   14405          350 :           else if (Tok == M2Reserved_TimesTok)
   14406              :             {
   14407              :               /* avoid dangling else.  */
   14408          284 :               return LogicalAndTok;
   14409              :             }
   14410           66 :           else if (Tok == M2Reserved_MinusTok)
   14411              :             {
   14412              :               /* avoid dangling else.  */
   14413           66 :               return LogicalDifferenceTok;
   14414              :             }
   14415              :         }
   14416              :     }
   14417              :   return Tok;
   14418              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   14419              :   __builtin_unreachable ();
   14420              : }
   14421              : 
   14422              : 
   14423              : /*
   14424              :    CheckDivModRem - initiates calls to check the divisor for DIV, MOD, REM
   14425              :                     expressions.
   14426              : */
   14427              : 
   14428        78426 : static void CheckDivModRem (unsigned int TokPos, NameKey_Name tok, unsigned int d, unsigned int e)
   14429              : {
   14430        78426 :   if (tok == M2Reserved_DivTok)
   14431              :     {
   14432         6789 :       BuildRange (M2Range_InitWholeZeroDivisionCheck (TokPos, d, e));
   14433              :     }
   14434        71637 :   else if (tok == M2Reserved_ModTok)
   14435              :     {
   14436              :       /* avoid dangling else.  */
   14437         2378 :       BuildRange (M2Range_InitWholeZeroDivisionCheck (TokPos, d, e));
   14438              :     }
   14439        69259 :   else if (tok == M2Reserved_RemTok)
   14440              :     {
   14441              :       /* avoid dangling else.  */
   14442           96 :       BuildRange (M2Range_InitWholeZeroRemainderCheck (TokPos, d, e));
   14443              :     }
   14444        78426 : }
   14445              : 
   14446              : 
   14447              : /*
   14448              :    doConvert - convert, sym, to a new symbol with, type.
   14449              :                Return the new symbol.
   14450              : */
   14451              : 
   14452         5220 : static unsigned int doConvert (unsigned int type, unsigned int sym)
   14453              : {
   14454         5220 :   if ((SymbolTable_GetSType (sym)) != type)
   14455              :     {
   14456         1086 :       M2Quads_PushTF (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym));
   14457         1086 :       M2Quads_PushT (type);
   14458         1086 :       M2Quads_PushT (sym);
   14459         1086 :       M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
   14460         1086 :       BuildConvertFunction (M2Base_Convert, false);  /* Two parameters  */
   14461         1080 :       M2Quads_PopT (&sym);
   14462              :     }
   14463         5214 :   return sym;
   14464              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   14465              :   __builtin_unreachable ();
   14466              : }
   14467              : 
   14468              : 
   14469              : /*
   14470              :    doBuildBinaryOp - build the binary op, with or without type
   14471              :                      checking.
   14472              : */
   14473              : 
   14474        92464 : static void doBuildBinaryOp (bool checkTypes, bool checkOverflow)
   14475              : {
   14476        92464 :   DynamicStrings_String s;
   14477        92464 :   NameKey_Name NewOp;
   14478        92464 :   NameKey_Name Operator;
   14479        92464 :   unsigned int OperatorPos;
   14480        92464 :   unsigned int OldPos;
   14481        92464 :   unsigned int leftrw;
   14482        92464 :   unsigned int rightrw;
   14483        92464 :   unsigned int t1;
   14484        92464 :   unsigned int f1;
   14485        92464 :   unsigned int t2;
   14486        92464 :   unsigned int f2;
   14487        92464 :   unsigned int lefttype;
   14488        92464 :   unsigned int righttype;
   14489        92464 :   unsigned int left;
   14490        92464 :   unsigned int right;
   14491        92464 :   unsigned int leftpos;
   14492        92464 :   unsigned int rightpos;
   14493        92464 :   unsigned int value;
   14494              : 
   14495        92464 :   Operator = static_cast<NameKey_Name> (M2Quads_OperandT (2));
   14496        92464 :   if (Operator == M2Reserved_OrTok)
   14497              :     {
   14498         3630 :       CheckBooleanId ();
   14499         3630 :       PopBooltok (&t1, &f1, &rightpos);
   14500         3630 :       M2Quads_PopTtok (&Operator, &OperatorPos);
   14501         3630 :       PopBooltok (&t2, &f2, &leftpos);
   14502         3630 :       M2Debug_Assert (f2 == 0);
   14503         3630 :       OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
   14504         3630 :       PushBooltok (Merge (t1, t2), f1, OperatorPos);
   14505              :     }
   14506        88834 :   else if ((Operator == M2Reserved_AndTok) || (Operator == M2Reserved_AmbersandTok))
   14507              :     {
   14508              :       /* avoid dangling else.  */
   14509         9808 :       CheckBooleanId ();
   14510         9808 :       PopBooltok (&t1, &f1, &rightpos);
   14511         9808 :       M2Quads_PopTtok (&Operator, &OperatorPos);
   14512         9808 :       PopBooltok (&t2, &f2, &leftpos);
   14513         9808 :       M2Debug_Assert (t2 == 0);
   14514         9808 :       OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
   14515         9808 :       PushBooltok (t1, Merge (f1, f2), OperatorPos);
   14516              :     }
   14517              :   else
   14518              :     {
   14519              :       /* avoid dangling else.  */
   14520        79026 :       PopTFrwtok (&right, &righttype, &rightrw, &rightpos);
   14521        79026 :       M2Quads_PopTtok (&Operator, &OperatorPos);
   14522        79026 :       PopTFrwtok (&left, &lefttype, &leftrw, &leftpos);
   14523        79026 :       MarkAsRead (rightrw);
   14524        79026 :       MarkAsRead (leftrw);
   14525        79026 :       NewOp = CheckLogicalOperator (Operator, left, lefttype);  /* right, righttype,  */
   14526        79026 :       if (NewOp == Operator)
   14527              :         {
   14528              :           /* avoid dangling else.  */
   14529              :           /* 
   14530              :             BinaryOps and UnaryOps only work with immediate and
   14531              :             offset addressing.  This is fine for calculating
   14532              :             array and record offsets but we need to get the real
   14533              :             values to perform normal arithmetic. Not address
   14534              :             arithmetic.
   14535              : 
   14536              :             However the set operators will dereference LValues
   14537              :             (to optimize large set arithemetic)
   14538              :   */
   14539        77544 :           if ((SymbolTable_GetMode (right)) == SymbolTable_LeftValue)
   14540              :             {
   14541          298 :               value = SymbolTable_MakeTemporary (rightpos, SymbolTable_RightValue);
   14542          298 :               SymbolTable_PutVar (value, righttype);
   14543          298 :               CheckPointerThroughNil (rightpos, right);
   14544          298 :               doIndrX (rightpos, value, right);
   14545          298 :               right = value;
   14546              :             }
   14547        77544 :           if ((SymbolTable_GetMode (left)) == SymbolTable_LeftValue)
   14548              :             {
   14549          852 :               value = SymbolTable_MakeTemporary (leftpos, SymbolTable_RightValue);
   14550          852 :               SymbolTable_PutVar (value, lefttype);
   14551          852 :               CheckPointerThroughNil (leftpos, left);
   14552          852 :               doIndrX (leftpos, value, left);
   14553          852 :               left = value;
   14554              :             }
   14555              :         }
   14556              :       /* CheckForGenericNulSet(e1, e2, t1, t2)  */
   14557        79026 :       OldPos = OperatorPos;
   14558        79026 :       OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
   14559        79026 :       if (((Operator == M2Reserved_PlusTok) && (SymbolTable_IsConstString (left))) && (SymbolTable_IsConstString (right)))
   14560              :         {
   14561          492 :           value = SymbolTable_MakeConstString (OperatorPos, NameKey_NulName);
   14562          492 :           SymbolTable_PutConstStringKnown (OperatorPos, value, NameKey_NulName, false, false);
   14563          492 :           GenQuadOtok (OperatorPos, MakeOp (M2Reserved_PlusTok), value, left, right, false, OperatorPos, leftpos, rightpos);
   14564              :         }
   14565              :       else
   14566              :         {
   14567        78534 :           if (checkTypes)
   14568              :             {
   14569        60212 :               BuildRange (M2Range_InitTypesExpressionCheck (OperatorPos, left, right, false, false));
   14570              :             }
   14571       121899 :           value = SymbolTable_MakeTemporaryFromExpressions (OperatorPos, right, left, AreConstant ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right))));
   14572        78426 :           CheckDivModRem (OperatorPos, NewOp, value, right);
   14573        78426 :           if (DebugTokPos)
   14574              :             {
   14575              :               s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (M2LexBuf_GetTokenName (Operator)));
   14576              :               M2Error_WarnStringAt (s, OldPos);
   14577              :               s = DynamicStrings_InitString ((const char *) "left", 4);
   14578              :               M2Error_WarnStringAt (s, leftpos);
   14579              :               s = DynamicStrings_InitString ((const char *) "right", 5);
   14580              :               M2Error_WarnStringAt (s, rightpos);
   14581              :               s = DynamicStrings_InitString ((const char *) "caret", 5);
   14582              :               M2Error_WarnStringAt (s, OldPos);
   14583              :               s = DynamicStrings_InitString ((const char *) "combined", 8);
   14584              :               M2Error_WarnStringAt (s, OperatorPos);
   14585              :             }
   14586              :           /* MetaErrorT1 (GetDeclaredMod (t), 'in binary with a {%1av}', t)  */
   14587        78426 :           GenQuadOtok (OperatorPos, MakeOp (NewOp), value, left, right, checkOverflow, OperatorPos, leftpos, rightpos);
   14588              :         }
   14589        78918 :       M2Quads_PushTFtok (value, SymbolTable_GetSType (value), OperatorPos);
   14590              :     }
   14591        92356 : }
   14592              : 
   14593              : 
   14594              : /*
   14595              :    AreConstant - returns immediate addressing mode if b is true else
   14596              :                  offset mode is returned. b determines whether the
   14597              :                  operands are all constant - in which case we can use
   14598              :                  a constant temporary variable.
   14599              : */
   14600              : 
   14601       159958 : static SymbolTable_ModeOfAddr AreConstant (bool b)
   14602              : {
   14603       159958 :   if (b)
   14604              :     {
   14605              :       return SymbolTable_ImmediateValue;
   14606              :     }
   14607              :   else
   14608              :     {
   14609        60083 :       return SymbolTable_RightValue;
   14610              :     }
   14611              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   14612              :   __builtin_unreachable ();
   14613              : }
   14614              : 
   14615              : 
   14616              : /*
   14617              :    ConvertBooleanToVariable - converts a BoolStack(i) from a Boolean True|False
   14618              :                               exit pair into a variable containing the value TRUE or
   14619              :                               FALSE.  The parameter i is relative to the top
   14620              :                               of the stack.
   14621              : */
   14622              : 
   14623         7378 : static void ConvertBooleanToVariable (unsigned int tok, unsigned int i)
   14624              : {
   14625         7378 :   unsigned int Des;
   14626         7378 :   M2Quads_BoolFrame f;
   14627              : 
   14628         7378 :   M2Debug_Assert (IsBoolean (i));
   14629              :   /* We need to convert the boolean top of stack into a variable or
   14630              :       constant boolean.  */
   14631        14756 :   Des = SymbolTable_MakeTemporary (tok, AreConstant (M2Quads_IsInConstExpression ()));
   14632         7378 :   SymbolTable_PutVar (Des, M2Base_Boolean);
   14633         7378 :   SymbolTable_PutVarConditional (Des, true);
   14634         7378 :   M2Quads_PushTtok (Des, tok);  /* we have just increased the stack so we must use i+1  */
   14635         7378 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, i+1));  /* we have just increased the stack so we must use i+1  */
   14636        14756 :   PushBool (f->TrueExit, f->FalseExit);
   14637         7378 :   BuildAssignmentWithoutBounds (tok, false, true);
   14638              :   /* Restored stack after the BuildAssign... above.  */
   14639         7378 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, i));
   14640         7378 :   f->TrueExit = Des;  /* Alter Stack(i) to contain the variable.  */
   14641         7378 :   f->FalseExit = M2Base_Boolean;  /* Alter Stack(i) to contain the variable.  */
   14642         7378 :   f->BooleanOp = false;  /* No longer a Boolean True|False pair.  */
   14643         7378 :   f->Unbounded = SymbolTable_NulSym;  /* No longer a Boolean True|False pair.  */
   14644         7378 :   f->Dimension = 0;
   14645         7378 :   f->ReadWrite = SymbolTable_NulSym;
   14646         7378 :   f->tokenno = tok;
   14647         7378 :   f->Annotation = DynamicStrings_KillString (f->Annotation);
   14648         7378 :   f->Annotation = DynamicStrings_InitString ((const char *) "%1s(%1d)|%2s(%2d)||boolean var|type", 35);
   14649         7378 :   f->RangeDep = 0;
   14650         7378 : }
   14651              : 
   14652              : 
   14653              : /*
   14654              :    DumpQuadSummary -
   14655              : */
   14656              : 
   14657            0 : static void DumpQuadSummary (unsigned int quad)
   14658              : {
   14659            0 :   M2Quads_QuadFrame f;
   14660              : 
   14661            0 :   if (quad != 0)
   14662              :     {
   14663            0 :       f = GetQF (quad);
   14664            0 :       M2Printf_printf2 ((const char *) "%d  op3 = %d\\n", 14, (const unsigned char *) &quad, (sizeof (quad)-1), (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
   14665              :     }
   14666            0 : }
   14667              : 
   14668              : 
   14669              : /*
   14670              :    BuildRelOpFromBoolean - builds a relational operator sequence of quadruples
   14671              :                            instead of using a temporary boolean variable.
   14672              :                            This function can only be used when we perform
   14673              :                            the following translation:
   14674              : 
   14675              :                            (a=b) # (c=d)  alternatively   (a=b) = (c=d)
   14676              :                                  ^                              ^
   14677              : 
   14678              :                            it only allows # = to be used as >= <= > < all
   14679              :                            assume a particular value for TRUE and FALSE.
   14680              :                            (In which case the user should specify ORD)
   14681              : 
   14682              : 
   14683              :                            before
   14684              : 
   14685              :                            q      if r1      op1     op2     t2
   14686              :                            q+1    Goto                       f2
   14687              :                            ...
   14688              :                            q+n    if r2      op3     op4     t1
   14689              :                            q+n+1  Goto                       f1
   14690              : 
   14691              :                            after (in case of =)
   14692              : 
   14693              :                            q    if r1      op1     op2     q+2
   14694              :                            q+1  Goto                       q+4
   14695              :                            q+2  if r2      op3     op4     t
   14696              :                            q+3  Goto                       f
   14697              :                            q+4  if r2      op3     op4     f
   14698              :                            q+5  Goto                       t
   14699              : 
   14700              :                            after (in case of #)
   14701              : 
   14702              :                            q      if r1      op1     op2     q+2
   14703              :                            q+1    Goto                       q+n+2
   14704              :                            q+2    ...
   14705              :                            ...    ...
   14706              :                            q+n    if r2      op3     op4     f
   14707              :                            q+n+1  Goto                       t
   14708              :                            q+n+2  if r2      op3     op4     t
   14709              :                            q+n+3  Goto                       f
   14710              : 
   14711              :                            The Stack is expected to contain:
   14712              : 
   14713              : 
   14714              :                            Entry                   Exit
   14715              :                            =====                   ====
   14716              : 
   14717              :                     Ptr ->
   14718              :                            +------------+
   14719              :                            | t1 | f1    |
   14720              :                            |------------|
   14721              :                            | Operator   |                          <- Ptr
   14722              :                            |------------|          +------------+
   14723              :                            | t2 | f2    |          | t    | f   |
   14724              :                            |------------|          |------------|
   14725              : 
   14726              : 
   14727              : */
   14728              : 
   14729            0 : static void BuildRelOpFromBoolean (unsigned int tokpos)
   14730              : {
   14731            0 :   unsigned int Tok;
   14732            0 :   unsigned int t1;
   14733            0 :   unsigned int f1;
   14734            0 :   unsigned int t2;
   14735            0 :   unsigned int f2;
   14736            0 :   M2Quads_QuadFrame f;
   14737              : 
   14738            0 :   M2Debug_Assert ((IsBoolean (1)) && (IsBoolean (3)));
   14739            0 :   if ((M2Quads_OperandT (2)) == M2Reserved_EqualTok)
   14740              :     {
   14741              :       /* Are the two boolean expressions the same?  */
   14742            0 :       PopBool (&t1, &f1);
   14743            0 :       M2Quads_PopT (&Tok);
   14744            0 :       PopBool (&t2, &f2);
   14745              :       /* Give the false exit a second chance.  */
   14746            0 :       BackPatch (t2, t1);  /* q    if   _     _    q+2  */
   14747            0 :       BackPatch (f2, NextQuad);  /* q+1  if   _     _    q+4  */
   14748            0 :       M2Debug_Assert (NextQuad == (f1+1));  /* q+1  if   _     _    q+4  */
   14749            0 :       f = GetQF (t1);
   14750            0 :       GenQuadO (tokpos, f->Operator, f->Operand1, f->Operand2, 0, false);
   14751            0 :       GenQuadO (tokpos, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
   14752            0 :       PushBooltok (Merge (NextQuad-1, t1), Merge (NextQuad-2, f1), tokpos);
   14753              :     }
   14754            0 :   else if (((M2Quads_OperandT (2)) == M2Reserved_HashTok) || ((M2Quads_OperandT (2)) == M2Reserved_LessGreaterTok))
   14755              :     {
   14756              :       /* avoid dangling else.  */
   14757            0 :       if (M2Options_CompilerDebugging)
   14758              :         {
   14759            0 :           M2Printf_printf0 ((const char *) "BuildRelOpFromBoolean (NotEqualTok)\\n", 37);
   14760            0 :           M2Quads_DisplayStack ();
   14761              :         }
   14762              :       /* Are the two boolean expressions different?  */
   14763            0 :       PopBool (&t1, &f1);
   14764            0 :       M2Quads_PopT (&Tok);
   14765            0 :       PopBool (&t2, &f2);
   14766            0 :       if (M2Options_CompilerDebugging)
   14767              :         {
   14768            0 :           M2Printf_printf2 ((const char *) "t1 = %d, f1 = %d\\n", 18, (const unsigned char *) &t1, (sizeof (t1)-1), (const unsigned char *) &f1, (sizeof (f1)-1));
   14769            0 :           M2Printf_printf2 ((const char *) "t2 = %d, f2 = %d\\n", 18, (const unsigned char *) &t2, (sizeof (t2)-1), (const unsigned char *) &f2, (sizeof (f2)-1));
   14770            0 :           DumpQuadSummary (t1);
   14771            0 :           DumpQuadSummary (f1);
   14772            0 :           DumpQuadSummary (t2);
   14773            0 :           DumpQuadSummary (f2);
   14774              :         }
   14775              :       /* Give the false exit a second chance.  */
   14776            0 :       BackPatch (t2, t1);  /* q    if   _     _    q+2  */
   14777            0 :       BackPatch (f2, NextQuad);  /* q+1  if   _     _    q+4  */
   14778            0 :       M2Debug_Assert (NextQuad == (f1+1));  /* q+1  if   _     _    q+4  */
   14779            0 :       f = GetQF (t1);
   14780            0 :       GenQuadO (tokpos, f->Operator, f->Operand1, f->Operand2, 0, false);
   14781            0 :       GenQuadO (tokpos, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
   14782            0 :       PushBooltok (Merge (NextQuad-2, f1), Merge (NextQuad-1, t1), tokpos);
   14783              :     }
   14784              :   else
   14785              :     {
   14786              :       /* avoid dangling else.  */
   14787            0 :       M2MetaError_MetaError0 ((const char *) "only allowed to use the relation operators {%Ek=} {%Ek#} rather than {%Ek<} or {%Ek>} on {%EkBOOLEAN} expressions as these do not imply an ordinal value for {%kTRUE} or {%kFALSE}", 178);
   14788              :     }
   14789            0 : }
   14790              : 
   14791              : 
   14792              : /*
   14793              :    CheckVariableOrConstantOrProcedure - checks to make sure sym is a variable, constant or procedure.
   14794              : */
   14795              : 
   14796       184592 : static void CheckVariableOrConstantOrProcedure (unsigned int tokpos, unsigned int sym)
   14797              : {
   14798       184592 :   unsigned int type;
   14799              : 
   14800       184592 :   type = SymbolTable_GetSType (sym);
   14801       184592 :   if (SymbolTable_IsUnknown (sym))
   14802              :     {
   14803              :       /* Spellcheck.  */
   14804           12 :       M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1EUad} has not been declared {%1&s}", 37, sym);
   14805           12 :       SymbolTable_UnknownReported (sym);
   14806              :     }
   14807       184580 :   else if ((M2System_IsPseudoSystemFunction (sym)) || (M2Base_IsPseudoBaseFunction (sym)))
   14808              :     {
   14809              :       /* avoid dangling else.  */
   14810            6 :       M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1Ead} expected a variable, procedure, constant or expression, not an intrinsic procedure function", 99, sym);
   14811              :     }
   14812       184574 :   else if (((((! (SymbolTable_IsConst (sym))) && (! (SymbolTable_IsVar (sym)))) && (! (SymbolTable_IsProcedure (sym)))) && (! (SymbolTable_IsTemporary (sym)))) && ! MustNotCheckBounds)
   14813              :     {
   14814              :       /* avoid dangling else.  */
   14815            0 :       M2MetaError_MetaErrorsT1 (tokpos, (const char *) "{%1Ead} expected a variable, procedure, constant or expression", 62, (const char *) "and it was declared as a {%1Ddv}", 32, sym);
   14816              :     }
   14817       184574 :   else if ((type != SymbolTable_NulSym) && (SymbolTable_IsArray (type)))
   14818              :     {
   14819              :       /* avoid dangling else.  */
   14820            0 :       M2MetaError_MetaErrorsT1 (tokpos, (const char *) "{%1EU} not expecting an array variable as an operand for either comparison or binary operation", 94, (const char *) "it was declared as a {%1Ddv}", 28, sym);
   14821              :     }
   14822       184574 :   else if (((SymbolTable_IsConstString (sym)) && (SymbolTable_IsConstStringKnown (sym))) && ((SymbolTable_GetStringLength (tokpos, sym)) > 1))
   14823              :     {
   14824              :       /* avoid dangling else.  */
   14825            0 :       M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1EU} not expecting a string constant as an operand for either comparison or binary operation", 94, sym);
   14826              :     }
   14827       184592 : }
   14828              : 
   14829              : 
   14830              : /*
   14831              :    MakeOp - returns the equalent quadruple operator to a token, t.
   14832              : */
   14833              : 
   14834       171214 : static M2Quads_QuadOperator MakeOp (NameKey_Name t)
   14835              : {
   14836       171214 :   if (t == ArithPlusTok)
   14837              :     {
   14838              :       return M2Quads_ArithAddOp;
   14839              :     }
   14840       171214 :   else if (t == M2Reserved_PlusTok)
   14841              :     {
   14842              :       /* avoid dangling else.  */
   14843              :       return M2Quads_AddOp;
   14844              :     }
   14845       146255 :   else if (t == M2Reserved_MinusTok)
   14846              :     {
   14847              :       /* avoid dangling else.  */
   14848              :       return M2Quads_SubOp;
   14849              :     }
   14850       123331 :   else if (t == M2Reserved_DivTok)
   14851              :     {
   14852              :       /* avoid dangling else.  */
   14853              :       return M2Quads_DivM2Op;
   14854              :     }
   14855       116542 :   else if (t == M2Reserved_DivideTok)
   14856              :     {
   14857              :       /* avoid dangling else.  */
   14858              :       return M2Quads_DivTruncOp;
   14859              :     }
   14860       114084 :   else if (t == M2Reserved_RemTok)
   14861              :     {
   14862              :       /* avoid dangling else.  */
   14863              :       return M2Quads_ModTruncOp;
   14864              :     }
   14865       113988 :   else if (t == M2Reserved_ModTok)
   14866              :     {
   14867              :       /* avoid dangling else.  */
   14868              :       return M2Quads_ModM2Op;
   14869              :     }
   14870       111610 :   else if (t == M2Reserved_TimesTok)
   14871              :     {
   14872              :       /* avoid dangling else.  */
   14873              :       return M2Quads_MultOp;
   14874              :     }
   14875        93760 :   else if (t == M2Reserved_HashTok)
   14876              :     {
   14877              :       /* avoid dangling else.  */
   14878              :       return M2Quads_IfNotEquOp;
   14879              :     }
   14880        80972 :   else if (t == M2Reserved_LessGreaterTok)
   14881              :     {
   14882              :       /* avoid dangling else.  */
   14883              :       return M2Quads_IfNotEquOp;
   14884              :     }
   14885        80888 :   else if (t == M2Reserved_GreaterEqualTok)
   14886              :     {
   14887              :       /* avoid dangling else.  */
   14888              :       return M2Quads_IfGreEquOp;
   14889              :     }
   14890        70250 :   else if (t == M2Reserved_LessEqualTok)
   14891              :     {
   14892              :       /* avoid dangling else.  */
   14893              :       return M2Quads_IfLessEquOp;
   14894              :     }
   14895        65398 :   else if (t == M2Reserved_EqualTok)
   14896              :     {
   14897              :       /* avoid dangling else.  */
   14898              :       return M2Quads_IfEquOp;
   14899              :     }
   14900        17716 :   else if (t == M2Reserved_LessTok)
   14901              :     {
   14902              :       /* avoid dangling else.  */
   14903              :       return M2Quads_IfLessOp;
   14904              :     }
   14905        10108 :   else if (t == M2Reserved_GreaterTok)
   14906              :     {
   14907              :       /* avoid dangling else.  */
   14908              :       return M2Quads_IfGreOp;
   14909              :     }
   14910         3952 :   else if (t == M2Reserved_InTok)
   14911              :     {
   14912              :       /* avoid dangling else.  */
   14913              :       return M2Quads_IfInOp;
   14914              :     }
   14915         1464 :   else if (t == LogicalOrTok)
   14916              :     {
   14917              :       /* avoid dangling else.  */
   14918              :       return M2Quads_LogicalOrOp;
   14919              :     }
   14920          474 :   else if (t == LogicalAndTok)
   14921              :     {
   14922              :       /* avoid dangling else.  */
   14923              :       return M2Quads_LogicalAndOp;
   14924              :     }
   14925          190 :   else if (t == LogicalXorTok)
   14926              :     {
   14927              :       /* avoid dangling else.  */
   14928              :       return M2Quads_LogicalXorOp;
   14929              :     }
   14930           66 :   else if (t == LogicalDifferenceTok)
   14931              :     {
   14932              :       /* avoid dangling else.  */
   14933              :       return M2Quads_LogicalDiffOp;
   14934              :     }
   14935              :   else
   14936              :     {
   14937              :       /* avoid dangling else.  */
   14938            0 :       M2Error_InternalError ((const char *) "binary operation not implemented yet", 36);
   14939              :     }
   14940              :   ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
   14941              :   __builtin_unreachable ();
   14942              : }
   14943              : 
   14944              : 
   14945              : /*
   14946              :    GenQuadO - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
   14947              : */
   14948              : 
   14949      5433301 : static void GenQuadO (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow)
   14950              : {
   14951      1209094 :   GenQuadOTrash (TokPos, Operation, Op1, Op2, Op3, overflow, SymbolTable_NulSym);
   14952       719435 : }
   14953              : 
   14954              : 
   14955              : /*
   14956              :    GenQuadOTrash - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
   14957              : */
   14958              : 
   14959      5435131 : static void GenQuadOTrash (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow, unsigned int trash)
   14960              : {
   14961      5435131 :   M2Quads_QuadFrame f;
   14962              : 
   14963              :   /* WriteString('Potential Quad: ') ;  */
   14964      5435131 :   if (QuadrupleGeneration)
   14965              :     {
   14966      5432886 :       if (NextQuad != Head)
   14967              :         {
   14968      5417587 :           f = GetQF (NextQuad-1);
   14969      5417587 :           f->Next = NextQuad;
   14970              :         }
   14971      5432886 :       PutQuadO (NextQuad, Operation, Op1, Op2, Op3, overflow);
   14972      5432886 :       f = GetQF (NextQuad);
   14973      5432886 :       f->Trash = trash;
   14974      5432886 :       f->Next = 0;
   14975      5432886 :       f->LineNo = M2LexBuf_GetLineNo ();
   14976      5432886 :       if (TokPos == M2LexBuf_UnknownTokenNo)
   14977              :         {
   14978      3249145 :           f->TokenNo = M2LexBuf_GetTokenNo ();
   14979              :         }
   14980              :       else
   14981              :         {
   14982      2183741 :           f->TokenNo = TokPos;
   14983              :         }
   14984      5432886 :       if (M2Options_GetDebugTraceQuad ())
   14985              :         {
   14986            0 :           M2Printf_printf0 ((const char *) "generating: ", 12);
   14987            0 :           M2Quads_DisplayQuad (NextQuad);
   14988              :         }
   14989              :       /* MetaErrorT1 (TokenNo, '{%1On}', NextQuad)  */
   14990      5432886 :       CheckBreak (NextQuad);
   14991      5432886 :       NewQuad (&NextQuad);
   14992              :     }
   14993      5435131 : }
   14994              : 
   14995              : 
   14996              : /*
   14997              :    GenQuad - Generate a quadruple with Operation, Op1, Op2, Op3.
   14998              : */
   14999              : 
   15000      3178425 : static void GenQuad (M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3)
   15001              : {
   15002      2193582 :   GenQuadO (M2LexBuf_UnknownTokenNo, Operation, Op1, Op2, Op3, true);
   15003       622185 : }
   15004              : 
   15005              : 
   15006              : /*
   15007              :    GenQuadOtok - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
   15008              : */
   15009              : 
   15010       577912 : static void GenQuadOtok (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow, unsigned int Op1Pos, unsigned int Op2Pos, unsigned int Op3Pos)
   15011              : {
   15012       485616 :   GenQuadOTypetok (TokPos, Operation, Op1, Op2, Op3, overflow, true, Op1Pos, Op2Pos, Op3Pos);
   15013       252807 : }
   15014              : 
   15015              : 
   15016              : /*
   15017              :    GenQuadOTypetok - assigns the fields of the quadruple with
   15018              :                      the parameters.
   15019              : */
   15020              : 
   15021       882387 : static void GenQuadOTypetok (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow, bool typecheck, unsigned int Op1Pos, unsigned int Op2Pos, unsigned int Op3Pos)
   15022              : {
   15023       882387 :   M2Quads_QuadFrame f;
   15024              : 
   15025              :   /* WriteString('Potential Quad: ') ;  */
   15026       882387 :   if (QuadrupleGeneration)
   15027              :     {
   15028       881696 :       if (NextQuad != Head)
   15029              :         {
   15030       881696 :           f = GetQF (NextQuad-1);
   15031       881696 :           f->Next = NextQuad;
   15032              :         }
   15033       881696 :       PutQuadOType (NextQuad, Operation, Op1, Op2, Op3, overflow, typecheck);
   15034       881696 :       f = GetQF (NextQuad);
   15035       881696 :       f->Next = 0;
   15036       881696 :       f->LineNo = M2LexBuf_GetLineNo ();
   15037       881696 :       if (TokPos == M2LexBuf_UnknownTokenNo)
   15038              :         {
   15039            0 :           f->TokenNo = M2LexBuf_GetTokenNo ();
   15040              :         }
   15041              :       else
   15042              :         {
   15043       881696 :           f->TokenNo = TokPos;
   15044              :         }
   15045       881696 :       f->op1pos = Op1Pos;
   15046       881696 :       f->op2pos = Op2Pos;
   15047       881696 :       f->op3pos = Op3Pos;
   15048       881696 :       if (M2Options_GetDebugTraceQuad ())
   15049              :         {
   15050            0 :           M2Printf_printf0 ((const char *) "generating: ", 12);
   15051            0 :           M2Quads_DisplayQuad (NextQuad);
   15052              :         }
   15053              :       /* MetaErrorT1 (TokenNo, '{%1On}', NextQuad)  */
   15054       881696 :       CheckBreak (NextQuad);
   15055       881696 :       NewQuad (&NextQuad);
   15056              :     }
   15057       882387 : }
   15058              : 
   15059              : 
   15060              : /*
   15061              :    DumpUntil - dump all quadruples until we seen the ending quadruple
   15062              :                with procsym in the third operand.
   15063              :                Return the quad number containing the match.
   15064              : */
   15065              : 
   15066            0 : static unsigned int DumpUntil (M2Quads_QuadOperator ending, unsigned int procsym, unsigned int quad)
   15067              : {
   15068            0 :   M2Quads_QuadOperator op;
   15069            0 :   unsigned int op1;
   15070            0 :   unsigned int op2;
   15071            0 :   unsigned int op3;
   15072            0 :   M2Quads_QuadFrame f;
   15073              : 
   15074            0 :   M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "\\n...\\n\\n", 9);
   15075            0 :   do {
   15076            0 :     M2Quads_GetQuad (quad, &op, &op1, &op2, &op3);
   15077            0 :     M2Quads_DisplayQuad (quad);
   15078            0 :     f = GetQF (quad);
   15079            0 :     quad = f->Next;
   15080            0 :   } while (! ((op == ending) && (op3 == procsym)));
   15081            0 :   return quad;
   15082              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15083              :   __builtin_unreachable ();
   15084              : }
   15085              : 
   15086              : 
   15087              : /*
   15088              :    GetCtorInit - return the init procedure for the module.
   15089              : */
   15090              : 
   15091            0 : static unsigned int GetCtorInit (unsigned int sym)
   15092              : {
   15093            0 :   unsigned int ctor;
   15094            0 :   unsigned int init;
   15095            0 :   unsigned int fini;
   15096            0 :   unsigned int dep;
   15097              : 
   15098            0 :   SymbolTable_GetModuleCtors (sym, &ctor, &init, &fini, &dep);
   15099            0 :   return init;
   15100              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15101              :   __builtin_unreachable ();
   15102              : }
   15103              : 
   15104              : 
   15105              : /*
   15106              :    GetCtorFini - return the fini procedure for the module.
   15107              : */
   15108              : 
   15109            0 : static unsigned int GetCtorFini (unsigned int sym)
   15110              : {
   15111            0 :   unsigned int ctor;
   15112            0 :   unsigned int init;
   15113            0 :   unsigned int fini;
   15114            0 :   unsigned int dep;
   15115              : 
   15116            0 :   SymbolTable_GetModuleCtors (sym, &ctor, &init, &fini, &dep);
   15117            0 :   return fini;
   15118              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15119              :   __builtin_unreachable ();
   15120              : }
   15121              : 
   15122              : 
   15123              : /*
   15124              :    DumpQuadrupleFilter -
   15125              : */
   15126              : 
   15127            0 : static void DumpQuadrupleFilter (void)
   15128              : {
   15129            0 :   M2Quads_QuadFrame f;
   15130            0 :   unsigned int i;
   15131            0 :   M2Quads_QuadOperator op;
   15132            0 :   unsigned int op1;
   15133            0 :   unsigned int op2;
   15134            0 :   unsigned int op3;
   15135              : 
   15136            0 :   i = Head;
   15137            0 :   while (i != 0)
   15138              :     {
   15139            0 :       M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
   15140            0 :       if ((op == M2Quads_ProcedureScopeOp) && (M2LangDump_IsDumpRequired (op3, true)))
   15141              :         {
   15142            0 :           i = DumpUntil (M2Quads_KillLocalVarOp, op3, i);
   15143              :         }
   15144            0 :       else if ((op == M2Quads_InitStartOp) && (M2LangDump_IsDumpRequired (GetCtorInit (op3), true)))
   15145              :         {
   15146              :           /* avoid dangling else.  */
   15147            0 :           i = DumpUntil (M2Quads_InitEndOp, op3, i);
   15148              :         }
   15149            0 :       else if ((op == M2Quads_FinallyStartOp) && (M2LangDump_IsDumpRequired (GetCtorFini (op3), true)))
   15150              :         {
   15151              :           /* avoid dangling else.  */
   15152            0 :           i = DumpUntil (M2Quads_FinallyEndOp, op3, i);
   15153              :         }
   15154              :       else
   15155              :         {
   15156              :           /* avoid dangling else.  */
   15157            0 :           f = GetQF (i);
   15158            0 :           i = f->Next;
   15159              :         }
   15160              :     }
   15161            0 : }
   15162              : 
   15163              : 
   15164              : /*
   15165              :    DumpQuadrupleAll - dump all quadruples.
   15166              : */
   15167              : 
   15168            0 : static void DumpQuadrupleAll (void)
   15169              : {
   15170            0 :   M2Quads_QuadFrame f;
   15171            0 :   unsigned int i;
   15172              : 
   15173            0 :   i = Head;
   15174            0 :   while (i != 0)
   15175              :     {
   15176            0 :       M2Quads_DisplayQuad (i);
   15177            0 :       f = GetQF (i);
   15178            0 :       i = f->Next;
   15179              :     }
   15180            0 : }
   15181              : 
   15182              : 
   15183              : /*
   15184              :    BackPatch - Makes each of the quadruples on the list pointed to by
   15185              :                QuadNo take quadruple Value as a target.
   15186              : */
   15187              : 
   15188       419205 : static void BackPatch (unsigned int QuadNo, unsigned int Value)
   15189              : {
   15190       419205 :   unsigned int i;
   15191       419205 :   M2Quads_QuadFrame f;
   15192              : 
   15193       419205 :   if (QuadrupleGeneration)
   15194              :     {
   15195       666401 :       while (QuadNo != 0)
   15196              :         {
   15197       247213 :           f = GetQF (QuadNo);
   15198       247213 :           i = f->Operand3;  /* Next Link along the BackPatch  */
   15199       247213 :           ManipulateReference (QuadNo, Value);  /* Filling in the BackPatch.  */
   15200       247213 :           QuadNo = i;
   15201              :         }
   15202              :     }
   15203       419205 : }
   15204              : 
   15205              : 
   15206              : /*
   15207              :    Merge - joins two quad lists, QuadList2 to the end of QuadList1.
   15208              :            A QuadList of value zero is a nul list.
   15209              : */
   15210              : 
   15211        54916 : static unsigned int Merge (unsigned int QuadList1, unsigned int QuadList2)
   15212              : {
   15213        54916 :   unsigned int i;
   15214        54916 :   unsigned int j;
   15215        54916 :   M2Quads_QuadFrame f;
   15216              : 
   15217        54916 :   if (QuadList1 == 0)
   15218              :     {
   15219              :       return QuadList2;
   15220              :     }
   15221        26970 :   else if (QuadList2 == 0)
   15222              :     {
   15223              :       /* avoid dangling else.  */
   15224              :       return QuadList1;
   15225              :     }
   15226              :   else
   15227              :     {
   15228              :       /* avoid dangling else.  */
   15229              :       i = QuadList1;
   15230        52842 :       do {
   15231        52842 :         j = i;
   15232        52842 :         f = GetQF (i);
   15233        52842 :         i = f->Operand3;
   15234        52842 :       } while (! (i == 0));
   15235        23690 :       ManipulateReference (j, QuadList2);
   15236        23690 :       return QuadList1;
   15237              :     }
   15238              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15239              :   __builtin_unreachable ();
   15240              : }
   15241              : 
   15242              : 
   15243              : /*
   15244              :    DisplayProcedureAttributes -
   15245              : */
   15246              : 
   15247            0 : static void DisplayProcedureAttributes (unsigned int proc)
   15248              : {
   15249            0 :   if (SymbolTable_IsCtor (proc))
   15250              :     {
   15251            0 :       M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (ctor)", 7);
   15252              :     }
   15253            0 :   if (SymbolTable_IsPublic (proc))
   15254              :     {
   15255            0 :       M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (public)", 9);
   15256              :     }
   15257            0 :   if (SymbolTable_IsExtern (proc))
   15258              :     {
   15259            0 :       M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (extern)", 9);
   15260              :     }
   15261            0 :   if (SymbolTable_IsMonoName (proc))
   15262              :     {
   15263            0 :       M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (mononame)", 11);
   15264              :     }
   15265            0 : }
   15266              : 
   15267              : 
   15268              : /*
   15269              :    WriteQuad - Writes out the Quad BufferQuad.
   15270              : */
   15271              : 
   15272            0 : static void WriteQuad (unsigned int BufferQuad)
   15273              : {
   15274            0 :   NameKey_Name n1;
   15275            0 :   NameKey_Name n2;
   15276            0 :   M2Quads_QuadFrame f;
   15277            0 :   NameKey_Name n;
   15278            0 :   unsigned int l;
   15279              : 
   15280            0 :   f = GetQF (BufferQuad);
   15281            0 :   M2Quads_WriteOperator (f->Operator);
   15282            0 :   M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " [%d]", 5, (const unsigned char *) &f->NoOfTimesReferenced, (sizeof (f->NoOfTimesReferenced)-1));
   15283            0 :   if (f->ConstExpr)
   15284              :     {
   15285            0 :       M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " const ", 7);
   15286              :     }
   15287              :   else
   15288              :     {
   15289            0 :       M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "       ", 7);
   15290              :     }
   15291            0 :   switch (f->Operator)
   15292              :     {
   15293            0 :       case M2Quads_LastForIteratorOp:
   15294            0 :         M2Quads_WriteOperand (f->Operand1);
   15295            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15296            0 :         M2Quads_WriteOperand (f->Operand2);
   15297            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15298            0 :         M2Quads_WriteOperand (f->Operand3);
   15299            0 :         break;
   15300              : 
   15301            0 :       case M2Quads_HighOp:
   15302            0 :         M2Quads_WriteOperand (f->Operand1);
   15303            0 :         M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "  %4d  ", 7, (const unsigned char *) &f->Operand2, (sizeof (f->Operand2)-1));
   15304            0 :         M2Quads_WriteOperand (f->Operand3);
   15305            0 :         break;
   15306              : 
   15307            0 :       case M2Quads_InitAddressOp:
   15308            0 :       case M2Quads_SavePriorityOp:
   15309            0 :       case M2Quads_RestorePriorityOp:
   15310            0 :       case M2Quads_SubrangeLowOp:
   15311            0 :       case M2Quads_SubrangeHighOp:
   15312            0 :       case M2Quads_BecomesOp:
   15313            0 :       case M2Quads_InclOp:
   15314            0 :       case M2Quads_ExclOp:
   15315            0 :       case M2Quads_UnboundedOp:
   15316            0 :       case M2Quads_ReturnValueOp:
   15317            0 :       case M2Quads_FunctValueOp:
   15318            0 :       case M2Quads_NegateOp:
   15319            0 :       case M2Quads_AddrOp:
   15320            0 :       case M2Quads_StringConvertCnulOp:
   15321            0 :       case M2Quads_StringConvertM2nulOp:
   15322            0 :       case M2Quads_StringLengthOp:
   15323            0 :         M2Quads_WriteOperand (f->Operand1);
   15324            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15325            0 :         M2Quads_WriteOperand (f->Operand3);
   15326            0 :         break;
   15327              : 
   15328            0 :       case M2Quads_ElementSizeOp:
   15329            0 :       case M2Quads_IfInOp:
   15330            0 :       case M2Quads_IfNotInOp:
   15331            0 :       case M2Quads_IfNotEquOp:
   15332            0 :       case M2Quads_IfEquOp:
   15333            0 :       case M2Quads_IfLessOp:
   15334            0 :       case M2Quads_IfGreOp:
   15335            0 :       case M2Quads_IfLessEquOp:
   15336            0 :       case M2Quads_IfGreEquOp:
   15337            0 :         M2Quads_WriteOperand (f->Operand1);
   15338            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15339            0 :         M2Quads_WriteOperand (f->Operand2);
   15340            0 :         M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "  %4d", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
   15341            0 :         break;
   15342              : 
   15343            0 :       case M2Quads_InlineOp:
   15344            0 :       case M2Quads_RetryOp:
   15345            0 :       case M2Quads_TryOp:
   15346            0 :       case M2Quads_GotoOp:
   15347            0 :         M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d", 3, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
   15348            0 :         break;
   15349              : 
   15350            0 :       case M2Quads_StatementNoteOp:
   15351            0 :         l = M2LexBuf_TokenToLineNo (f->Operand3, 0);
   15352            0 :         n = M2LexBuf_GetTokenName (f->Operand3);
   15353            0 :         M2Printf_fprintf4 (M2LangDump_GetDumpFile (), (const char *) "%a:%d:%a (tokenno %d)", 21, (const unsigned char *) &f->Operand1, (sizeof (f->Operand1)-1), (const unsigned char *) &l, (sizeof (l)-1), (const unsigned char *) &n, (sizeof (n)-1), (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
   15354            0 :         break;
   15355              : 
   15356            0 :       case M2Quads_LineNumberOp:
   15357            0 :         M2Printf_fprintf2 (M2LangDump_GetDumpFile (), (const char *) "%a:%d", 5, (const unsigned char *) &f->Operand1, (sizeof (f->Operand1)-1), (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
   15358            0 :         break;
   15359              : 
   15360            0 :       case M2Quads_EndFileOp:
   15361            0 :         n1 = SymbolTable_GetSymName (f->Operand3);
   15362            0 :         M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%a", 2, (const unsigned char *) &n1, (sizeof (n1)-1));
   15363            0 :         break;
   15364              : 
   15365            0 :       case M2Quads_ThrowOp:
   15366            0 :       case M2Quads_ReturnOp:
   15367            0 :       case M2Quads_CallOp:
   15368            0 :       case M2Quads_KillLocalVarOp:
   15369            0 :         M2Quads_WriteOperand (f->Operand3);
   15370            0 :         break;
   15371              : 
   15372            0 :       case M2Quads_ProcedureScopeOp:
   15373            0 :         n1 = SymbolTable_GetSymName (f->Operand2);
   15374            0 :         n2 = SymbolTable_GetSymName (f->Operand3);
   15375            0 :         M2Printf_fprintf4 (M2LangDump_GetDumpFile (), (const char *) "  %4d  %a  %a(%d)", 17, (const unsigned char *) &f->Operand1, (sizeof (f->Operand1)-1), (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1), (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
   15376            0 :         DisplayProcedureAttributes (f->Operand3);
   15377            0 :         break;
   15378              : 
   15379            0 :       case M2Quads_NewLocalVarOp:
   15380            0 :       case M2Quads_FinallyStartOp:
   15381            0 :       case M2Quads_FinallyEndOp:
   15382            0 :       case M2Quads_InitEndOp:
   15383            0 :       case M2Quads_InitStartOp:
   15384            0 :         n1 = SymbolTable_GetSymName (f->Operand2);
   15385            0 :         n2 = SymbolTable_GetSymName (f->Operand3);
   15386            0 :         M2Printf_fprintf3 (M2LangDump_GetDumpFile (), (const char *) "  %4d  %a  %a", 13, (const unsigned char *) &f->Operand1, (sizeof (f->Operand1)-1), (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
   15387            0 :         break;
   15388              : 
   15389            0 :       case M2Quads_ModuleScopeOp:
   15390            0 :       case M2Quads_StartModFileOp:
   15391            0 :         n1 = SymbolTable_GetSymName (f->Operand3);
   15392            0 :         M2Printf_fprintf4 (M2LangDump_GetDumpFile (), (const char *) "%a:%d  %a(%d)", 13, (const unsigned char *) &f->Operand2, (sizeof (f->Operand2)-1), (const unsigned char *) &f->Operand1, (sizeof (f->Operand1)-1), (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
   15393            0 :         break;
   15394              : 
   15395            0 :       case M2Quads_StartDefFileOp:
   15396            0 :         n1 = SymbolTable_GetSymName (f->Operand3);
   15397            0 :         M2Printf_fprintf2 (M2LangDump_GetDumpFile (), (const char *) "  %4d  %a", 9, (const unsigned char *) &f->Operand1, (sizeof (f->Operand1)-1), (const unsigned char *) &n1, (sizeof (n1)-1));
   15398            0 :         break;
   15399              : 
   15400            0 :       case M2Quads_OptParamOp:
   15401            0 :       case M2Quads_ParamOp:
   15402            0 :         M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d  ", 5, (const unsigned char *) &f->Operand1, (sizeof (f->Operand1)-1));
   15403            0 :         M2Quads_WriteOperand (f->Operand2);
   15404            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15405            0 :         M2Quads_WriteOperand (f->Operand3);
   15406            0 :         break;
   15407              : 
   15408            0 :       case M2Quads_SizeOp:
   15409            0 :       case M2Quads_RecordFieldOp:
   15410            0 :       case M2Quads_IndrXOp:
   15411            0 :       case M2Quads_XIndrOp:
   15412            0 :       case M2Quads_ArrayOp:
   15413            0 :       case M2Quads_LogicalShiftOp:
   15414            0 :       case M2Quads_LogicalRotateOp:
   15415            0 :       case M2Quads_LogicalOrOp:
   15416            0 :       case M2Quads_LogicalAndOp:
   15417            0 :       case M2Quads_LogicalXorOp:
   15418            0 :       case M2Quads_LogicalDiffOp:
   15419            0 :       case M2Quads_ArithAddOp:
   15420            0 :       case M2Quads_CoerceOp:
   15421            0 :       case M2Quads_ConvertOp:
   15422            0 :       case M2Quads_CastOp:
   15423            0 :       case M2Quads_AddOp:
   15424            0 :       case M2Quads_SubOp:
   15425            0 :       case M2Quads_MultOp:
   15426            0 :       case M2Quads_DivM2Op:
   15427            0 :       case M2Quads_ModM2Op:
   15428            0 :       case M2Quads_ModFloorOp:
   15429            0 :       case M2Quads_DivCeilOp:
   15430            0 :       case M2Quads_ModCeilOp:
   15431            0 :       case M2Quads_DivFloorOp:
   15432            0 :       case M2Quads_ModTruncOp:
   15433            0 :       case M2Quads_DivTruncOp:
   15434            0 :         M2Quads_WriteOperand (f->Operand1);
   15435            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15436            0 :         M2Quads_WriteOperand (f->Operand2);
   15437            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15438            0 :         M2Quads_WriteOperand (f->Operand3);
   15439            0 :         break;
   15440              : 
   15441              :       case M2Quads_DummyOp:
   15442              :       case M2Quads_CodeOnOp:
   15443              :       case M2Quads_CodeOffOp:
   15444              :       case M2Quads_ProfileOnOp:
   15445              :       case M2Quads_ProfileOffOp:
   15446              :       case M2Quads_OptimizeOnOp:
   15447              :       case M2Quads_OptimizeOffOp:
   15448              :         break;
   15449              : 
   15450            0 :       case M2Quads_BuiltinConstOp:
   15451            0 :         M2Quads_WriteOperand (f->Operand1);
   15452            0 :         M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "   %a", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
   15453            0 :         break;
   15454              : 
   15455            0 :       case M2Quads_BuiltinTypeInfoOp:
   15456            0 :         M2Quads_WriteOperand (f->Operand1);
   15457            0 :         M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "   %a", 5, (const unsigned char *) &f->Operand2, (sizeof (f->Operand2)-1));
   15458            0 :         M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "   %a", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
   15459            0 :         break;
   15460              : 
   15461            0 :       case M2Quads_StandardFunctionOp:
   15462            0 :         M2Quads_WriteOperand (f->Operand1);
   15463            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15464            0 :         M2Quads_WriteOperand (f->Operand2);
   15465            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15466            0 :         M2Quads_WriteOperand (f->Operand3);
   15467            0 :         break;
   15468              : 
   15469              :       case M2Quads_CatchBeginOp:
   15470              :       case M2Quads_CatchEndOp:
   15471              :         break;
   15472              : 
   15473            0 :       case M2Quads_RangeCheckOp:
   15474            0 :       case M2Quads_ErrorOp:
   15475            0 :         M2Range_WriteRangeCheck (f->Operand3);
   15476            0 :         break;
   15477              : 
   15478            0 :       case M2Quads_SaveExceptionOp:
   15479            0 :       case M2Quads_RestoreExceptionOp:
   15480            0 :         M2Quads_WriteOperand (f->Operand1);
   15481            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15482            0 :         M2Quads_WriteOperand (f->Operand3);
   15483            0 :         break;
   15484              : 
   15485              : 
   15486            0 :       default:
   15487            0 :         M2Error_InternalError ((const char *) "quadruple not recognised", 24);
   15488            0 :         break;
   15489              :     }
   15490            0 : }
   15491              : 
   15492              : 
   15493              : /*
   15494              :    WriteOperand - displays the operands name, symbol id and mode of addressing.
   15495              : */
   15496              : 
   15497            0 : static void WriteMode (SymbolTable_ModeOfAddr Mode)
   15498              : {
   15499            0 :   switch (Mode)
   15500              :     {
   15501            0 :       case SymbolTable_ImmediateValue:
   15502            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "i", 1);
   15503            0 :         break;
   15504              : 
   15505            0 :       case SymbolTable_NoValue:
   15506            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "n", 1);
   15507            0 :         break;
   15508              : 
   15509            0 :       case SymbolTable_RightValue:
   15510            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "r", 1);
   15511            0 :         break;
   15512              : 
   15513            0 :       case SymbolTable_LeftValue:
   15514            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "l", 1);
   15515            0 :         break;
   15516              : 
   15517              : 
   15518            0 :       default:
   15519            0 :         M2Error_InternalError ((const char *) "unrecognised mode", 17);
   15520            0 :         break;
   15521              :     }
   15522            0 : }
   15523              : 
   15524              : 
   15525              : /*
   15526              :    PushExit - pushes the exit value onto the EXIT stack.
   15527              : */
   15528              : 
   15529          610 : static void PushExit (unsigned int Exit)
   15530              : {
   15531            0 :   M2StackWord_PushWord (ExitStack, Exit);
   15532           94 : }
   15533              : 
   15534              : 
   15535              : /*
   15536              :    PopExit - pops the exit value from the EXIT stack.
   15537              : */
   15538              : 
   15539          610 : static unsigned int PopExit (void)
   15540              : {
   15541            0 :   return M2StackWord_PopWord (ExitStack);
   15542              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15543              :   __builtin_unreachable ();
   15544              : }
   15545              : 
   15546              : 
   15547              : /*
   15548              :    PushFor - pushes the exit value onto the FOR stack.
   15549              : */
   15550              : 
   15551        10422 : static void PushFor (unsigned int Exit)
   15552              : {
   15553            0 :   M2StackWord_PushWord (ForStack, Exit);
   15554            0 : }
   15555              : 
   15556              : 
   15557              : /*
   15558              :    PopFor - pops the exit value from the FOR stack.
   15559              : */
   15560              : 
   15561        10416 : static unsigned int PopFor (void)
   15562              : {
   15563            0 :   return M2StackWord_PopWord (ForStack);
   15564              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15565              :   __builtin_unreachable ();
   15566              : }
   15567              : 
   15568              : 
   15569              : /*
   15570              :    OperandTno - returns the ident operand stored in the true position
   15571              :                 on the boolean stack.  This is exactly the same as
   15572              :                 OperandT but it has no IsBoolean checking.
   15573              : */
   15574              : 
   15575    214541580 : static unsigned int OperandTno (unsigned int pos)
   15576              : {
   15577    214541580 :   M2Quads_BoolFrame f;
   15578              : 
   15579    214541580 :   M2Debug_Assert (pos > 0);
   15580    214541580 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   15581    214541580 :   return static_cast<unsigned int> (f->TrueExit);
   15582              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15583              :   __builtin_unreachable ();
   15584              : }
   15585              : 
   15586              : 
   15587              : /*
   15588              :    OperandFno - returns the ident operand stored in the false position
   15589              :                 on the boolean stack.  This is exactly the same as
   15590              :                 OperandF but it has no IsBoolean checking.
   15591              : */
   15592              : 
   15593       178228 : static unsigned int OperandFno (unsigned int pos)
   15594              : {
   15595       178228 :   M2Quads_BoolFrame f;
   15596              : 
   15597       178228 :   M2Debug_Assert (pos > 0);
   15598       178228 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   15599       178228 :   return static_cast<unsigned int> (f->FalseExit);
   15600              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15601              :   __builtin_unreachable ();
   15602              : }
   15603              : 
   15604              : 
   15605              : /*
   15606              :    OperandTtok - returns the token associated with the position, pos
   15607              :                  on the boolean stack.
   15608              : */
   15609              : 
   15610     58928138 : static unsigned int OperandTtok (unsigned int pos)
   15611              : {
   15612     58928138 :   M2Quads_BoolFrame f;
   15613              : 
   15614     58928138 :   M2Debug_Assert (pos > 0);
   15615     58928138 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   15616     58928138 :   return f->tokenno;
   15617              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15618              :   __builtin_unreachable ();
   15619              : }
   15620              : 
   15621              : 
   15622              : /*
   15623              :    PopBooltok - Pops a True and a False exit quad number from the True/False
   15624              :                 stack.
   15625              : */
   15626              : 
   15627       227356 : static void PopBooltok (unsigned int *True, unsigned int *False, unsigned int *tokno)
   15628              : {
   15629       227356 :   M2Quads_BoolFrame f;
   15630              : 
   15631       227356 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   15632       227356 :   (*True) = f->TrueExit;
   15633       227356 :   (*False) = f->FalseExit;
   15634       227356 :   (*tokno) = f->tokenno;
   15635       227356 :   M2Debug_Assert (f->BooleanOp);
   15636       227356 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   15637       227356 : }
   15638              : 
   15639              : 
   15640              : /*
   15641              :    PushBooltok - Push a True and a False exit quad numbers onto the
   15642              :                  True/False stack.
   15643              : */
   15644              : 
   15645       234734 : static void PushBooltok (unsigned int True, unsigned int False, unsigned int tokno)
   15646              : {
   15647       234734 :   M2Quads_BoolFrame f;
   15648              : 
   15649       234734 :   M2Debug_Assert (True <= NextQuad);
   15650       234734 :   M2Debug_Assert (False <= NextQuad);
   15651       234734 :   f = newBoolFrame ();
   15652       234734 :   f->TrueExit = True;
   15653       234734 :   f->FalseExit = False;
   15654       234734 :   f->BooleanOp = true;
   15655       234734 :   f->tokenno = tokno;
   15656       234734 :   f->Annotation = static_cast<DynamicStrings_String> (NULL);
   15657       234734 :   f->RangeDep = 0;
   15658       234734 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   15659       234734 :   M2Quads_Annotate ((const char *) "<q%1d>|<q%2d>||true quad|false quad", 35);
   15660       234734 : }
   15661              : 
   15662              : 
   15663              : /*
   15664              :    PopBool - Pops a True and a False exit quad number from the True/False
   15665              :              stack.
   15666              : */
   15667              : 
   15668       193684 : static void PopBool (unsigned int *True, unsigned int *False)
   15669              : {
   15670       193684 :   unsigned int tokno;
   15671              : 
   15672        10044 :   PopBooltok (True, False, &tokno);
   15673            0 : }
   15674              : 
   15675              : 
   15676              : /*
   15677              :    PushBool - Push a True and a False exit quad numbers onto the
   15678              :               True/False stack.
   15679              : */
   15680              : 
   15681       122204 : static void PushBool (unsigned int True, unsigned int False)
   15682              : {
   15683         7378 :   PushBooltok (True, False, M2LexBuf_UnknownTokenNo);
   15684        13438 : }
   15685              : 
   15686              : 
   15687              : /*
   15688              :    IsBoolean - returns true is the Stack position pos contains a Boolean
   15689              :                Exit. False is returned if an Ident is stored.
   15690              : */
   15691              : 
   15692    277434681 : static bool IsBoolean (unsigned int pos)
   15693              : {
   15694    277434681 :   M2Quads_BoolFrame f;
   15695              : 
   15696    277434681 :   M2Debug_Assert (pos > 0);
   15697    277434681 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   15698    277434681 :   return f->BooleanOp;
   15699              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15700              :   __builtin_unreachable ();
   15701              : }
   15702              : 
   15703              : 
   15704              : /*
   15705              :    OperandD - returns possible array dimension associated with the ident
   15706              :               operand stored on the boolean stack.
   15707              : */
   15708              : 
   15709       688559 : static unsigned int OperandD (unsigned int pos)
   15710              : {
   15711       688559 :   M2Quads_BoolFrame f;
   15712              : 
   15713       688559 :   M2Debug_Assert (pos > 0);
   15714       688559 :   M2Debug_Assert (! (IsBoolean (pos)));
   15715       688559 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   15716       688559 :   return static_cast<unsigned int> (f->Dimension);
   15717              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15718              :   __builtin_unreachable ();
   15719              : }
   15720              : 
   15721              : 
   15722              : /*
   15723              :    OperandRW - returns the rw operand stored on the boolean stack.
   15724              : */
   15725              : 
   15726       751195 : static unsigned int OperandRW (unsigned int pos)
   15727              : {
   15728       751195 :   M2Quads_BoolFrame f;
   15729              : 
   15730       751195 :   M2Debug_Assert (pos > 0);
   15731       751195 :   M2Debug_Assert (! (IsBoolean (pos)));
   15732       751195 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   15733       751195 :   return static_cast<unsigned int> (f->ReadWrite);
   15734              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15735              :   __builtin_unreachable ();
   15736              : }
   15737              : 
   15738              : 
   15739              : /*
   15740              :    OperandMergeRW - returns the rw operand if not NulSym else it
   15741              :                     returns True.
   15742              : */
   15743              : 
   15744       727251 : static unsigned int OperandMergeRW (unsigned int pos)
   15745              : {
   15746       727251 :   if ((OperandRW (pos)) == SymbolTable_NulSym)
   15747              :     {
   15748       705677 :       return M2Quads_OperandT (pos);
   15749              :     }
   15750              :   else
   15751              :     {
   15752        21574 :       return OperandRW (pos);
   15753              :     }
   15754              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15755              :   __builtin_unreachable ();
   15756              : }
   15757              : 
   15758              : 
   15759              : /*
   15760              :    OperandRangeDep - return the range dependant associated with the quad stack.
   15761              : */
   15762              : 
   15763       142599 : static unsigned int OperandRangeDep (unsigned int pos)
   15764              : {
   15765       142599 :   M2Quads_BoolFrame f;
   15766              : 
   15767       142599 :   M2Debug_Assert (! (IsBoolean (pos)));
   15768       142599 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   15769       142599 :   return f->RangeDep;
   15770              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15771              :   __builtin_unreachable ();
   15772              : }
   15773              : 
   15774              : 
   15775              : /*
   15776              :    PutRangeDep - assigns the quad stack pos RangeDep to dep.
   15777              : */
   15778              : 
   15779       539229 : static void PutRangeDep (unsigned int pos, unsigned int dep)
   15780              : {
   15781       539229 :   M2Quads_BoolFrame f;
   15782              : 
   15783       539229 :   M2Debug_Assert (! (IsBoolean (pos)));
   15784       539229 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   15785       539229 :   f->RangeDep = dep;
   15786       539229 : }
   15787              : 
   15788              : 
   15789              : /*
   15790              :    UseLineNote - uses the line note and returns it to the free list.
   15791              : */
   15792              : 
   15793         5220 : static void UseLineNote (M2Quads_LineNote l)
   15794              : {
   15795         5220 :   M2Quads_QuadFrame f;
   15796              : 
   15797         5220 :   f = GetQF (NextQuad-1);
   15798         5220 :   if ((f->Operator == M2Quads_LineNumberOp) && (f->Operand1 == ((unsigned int ) (l->File))))
   15799              :     {}  /* empty.  */
   15800              :   else
   15801              :     {
   15802              :       /* do nothing  */
   15803              :       if (false)
   15804              :         {
   15805              :           GenQuad (M2Quads_LineNumberOp, (unsigned int ) (l->File), SymbolTable_NulSym, (unsigned int ) (l->Line));
   15806              :         }
   15807              :     }
   15808         5220 :   l->Next = FreeLineList;
   15809         5220 :   FreeLineList = l;
   15810         5220 : }
   15811              : 
   15812              : 
   15813              : /*
   15814              :    PopLineNo - pops a line note from the line stack.
   15815              : */
   15816              : 
   15817         5220 : static M2Quads_LineNote PopLineNo (void)
   15818              : {
   15819         5220 :   M2Quads_LineNote l;
   15820              : 
   15821         5220 :   l = static_cast<M2Quads_LineNote> (M2StackAddress_PopAddress (LineStack));
   15822         5220 :   if (l == NULL)
   15823              :     {
   15824            0 :       M2Error_InternalError ((const char *) "no line note available", 22);
   15825              :     }
   15826         5220 :   return l;
   15827              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15828              :   __builtin_unreachable ();
   15829              : }
   15830              : 
   15831              : 
   15832              : /*
   15833              :    InitLineNote - creates a line note and initializes it to
   15834              :                   contain, file, line.
   15835              : */
   15836              : 
   15837         5220 : static M2Quads_LineNote InitLineNote (NameKey_Name file, unsigned int line)
   15838              : {
   15839         5220 :   M2Quads_LineNote l;
   15840              : 
   15841         5220 :   if (FreeLineList == NULL)
   15842              :     {
   15843         2412 :       Storage_ALLOCATE ((void **) &l, sizeof (M2Quads__T6));
   15844              :     }
   15845              :   else
   15846              :     {
   15847         2808 :       l = FreeLineList;
   15848         2808 :       FreeLineList = FreeLineList->Next;
   15849              :     }
   15850         5220 :   l->File = file;
   15851         5220 :   l->Line = line;
   15852         5220 :   return l;
   15853              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15854              :   __builtin_unreachable ();
   15855              : }
   15856              : 
   15857              : 
   15858              : /*
   15859              :    PushLineNote -
   15860              : */
   15861              : 
   15862         5220 : static void PushLineNote (M2Quads_LineNote l)
   15863              : {
   15864            0 :   M2StackAddress_PushAddress (LineStack, reinterpret_cast <void *> (l));
   15865            0 : }
   15866              : 
   15867              : 
   15868              : /*
   15869              :    BuildStmtNoteTok - adds a nop (with an assigned tokenno location) to the code.
   15870              : */
   15871              : 
   15872       551414 : static void BuildStmtNoteTok (unsigned int tokenno)
   15873              : {
   15874       551414 :   NameKey_Name filename;
   15875       551414 :   M2Quads_QuadFrame f;
   15876              : 
   15877       551414 :   f = GetQF (NextQuad-1);
   15878              :   /* no need to have multiple notes at the same position.  */
   15879       551414 :   if ((f->Operator != M2Quads_StatementNoteOp) || (f->Operand3 != tokenno))
   15880              :     {
   15881       543982 :       filename = NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()));
   15882       543982 :       GenQuad (M2Quads_StatementNoteOp, (unsigned int ) (filename), SymbolTable_NulSym, tokenno);
   15883              :     }
   15884       551414 : }
   15885              : 
   15886              : 
   15887              : /*
   15888              :    GetRecordOrField -
   15889              : */
   15890              : 
   15891        12306 : static unsigned int GetRecordOrField (void)
   15892              : {
   15893        12306 :   unsigned int f;
   15894              : 
   15895        12306 :   VarientFieldNo += 1;
   15896        12306 :   f = static_cast<unsigned int> (Lists_GetItemFromList (VarientFields, VarientFieldNo));
   15897        12306 :   if (DebugVarients)
   15898              :     {
   15899              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   15900              :       if (SymbolTable_IsRecord (f))
   15901              :         {
   15902              :           M2Printf_printf2 ((const char *) "out list: record %d is %d\\n", 27, (const unsigned char *) &VarientFieldNo, (sizeof (VarientFieldNo)-1), (const unsigned char *) &f, (sizeof (f)-1));
   15903              :         }
   15904              :       else
   15905              :         {
   15906              :           M2Printf_printf2 ((const char *) "out list: varient field %d is %d\\n", 34, (const unsigned char *) &VarientFieldNo, (sizeof (VarientFieldNo)-1), (const unsigned char *) &f, (sizeof (f)-1));
   15907              :         }
   15908              :     }
   15909        12306 :   return f;
   15910              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15911              :   __builtin_unreachable ();
   15912              : }
   15913              : 
   15914              : 
   15915              : /*
   15916              :    PushTFAD - Push True, False, Array, Dim, numbers onto the
   15917              :               True/False stack.  True and False are assumed to
   15918              :               contain Symbols or Ident etc.
   15919              : */
   15920              : 
   15921          384 : static void PushTFAD (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim)
   15922              : {
   15923          384 :   M2Quads_BoolFrame f;
   15924              : 
   15925          384 :   f = newBoolFrame ();
   15926          384 :   f->TrueExit = static_cast<unsigned int> (True);
   15927          384 :   f->FalseExit = static_cast<unsigned int> (False);
   15928          384 :   f->Unbounded = static_cast<unsigned int> (Array);
   15929          384 :   f->Dimension = static_cast<unsigned int> (Dim);
   15930          384 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   15931          384 : }
   15932              : 
   15933              : 
   15934              : /*
   15935              :    PushTFADtok - Push True, False, Array, Dim, numbers onto the
   15936              :                  True/False stack.  True and False are assumed to
   15937              :                  contain Symbols or Ident etc.
   15938              : */
   15939              : 
   15940         3024 : static void PushTFADtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int tokno)
   15941              : {
   15942         3024 :   M2Quads_BoolFrame f;
   15943              : 
   15944         3024 :   f = newBoolFrame ();
   15945         3024 :   f->TrueExit = static_cast<unsigned int> (True);
   15946         3024 :   f->FalseExit = static_cast<unsigned int> (False);
   15947         3024 :   f->Unbounded = static_cast<unsigned int> (Array);
   15948         3024 :   f->Dimension = static_cast<unsigned int> (Dim);
   15949         3024 :   f->tokenno = tokno;
   15950         3024 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   15951         3024 : }
   15952              : 
   15953              : 
   15954              : /*
   15955              :    PushTFADrwtok - Push True, False, Array, Dim, rw, numbers onto the
   15956              :                    True/False stack.  True and False are assumed to
   15957              :                    contain Symbols or Ident etc.
   15958              : */
   15959              : 
   15960         8994 : static void PushTFADrwtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int rw, unsigned int Tok)
   15961              : {
   15962         8994 :   M2Quads_BoolFrame f;
   15963              : 
   15964         8994 :   f = newBoolFrame ();
   15965         8994 :   f->TrueExit = static_cast<unsigned int> (True);
   15966         8994 :   f->FalseExit = static_cast<unsigned int> (False);
   15967         8994 :   f->Unbounded = static_cast<unsigned int> (Array);
   15968         8994 :   f->Dimension = static_cast<unsigned int> (Dim);
   15969         8994 :   f->ReadWrite = static_cast<unsigned int> (rw);
   15970         8994 :   f->tokenno = Tok;
   15971         8994 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   15972         8994 : }
   15973              : 
   15974              : 
   15975              : /*
   15976              :    PopTFrwtok - Pop a True and False number from the True/False stack.
   15977              :                 True and False are assumed to contain Symbols or Ident etc.
   15978              : */
   15979              : 
   15980       316404 : static void PopTFrwtok (unsigned int *True, unsigned int *False, unsigned int *rw, unsigned int *tokno)
   15981              : {
   15982       316404 :   M2Quads_BoolFrame f;
   15983              : 
   15984       316404 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   15985       316404 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   15986       316404 :   (*False) = static_cast<unsigned int> (f->FalseExit);
   15987       316404 :   M2Debug_Assert (! f->BooleanOp);
   15988       316404 :   (*rw) = static_cast<unsigned int> (f->ReadWrite);
   15989       316404 :   (*tokno) = f->tokenno;
   15990       316404 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   15991       316404 : }
   15992              : 
   15993              : 
   15994              : /*
   15995              :    PushTFrwtok - Push an item onto the stack in the T (true) position,
   15996              :                  it is assummed to be a token and its token location is recorded.
   15997              : */
   15998              : 
   15999       349382 : static void PushTFrwtok (unsigned int True, unsigned int False, unsigned int rw, unsigned int tokno)
   16000              : {
   16001       349382 :   M2Quads_BoolFrame f;
   16002              : 
   16003       349382 :   f = newBoolFrame ();
   16004       349382 :   f->TrueExit = static_cast<unsigned int> (True);
   16005       349382 :   f->FalseExit = static_cast<unsigned int> (False);
   16006       349382 :   f->ReadWrite = static_cast<unsigned int> (rw);
   16007       349382 :   f->tokenno = tokno;
   16008       349382 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   16009       349382 : }
   16010              : 
   16011              : 
   16012              : /*
   16013              :    PushTFDtok - Push True, False, Dim, numbers onto the
   16014              :                 True/False stack.  True and False are assumed to
   16015              :                 contain Symbols or Ident etc.
   16016              : */
   16017              : 
   16018          258 : static void PushTFDtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int Tok)
   16019              : {
   16020          258 :   M2Quads_BoolFrame f;
   16021              : 
   16022          258 :   f = newBoolFrame ();
   16023          258 :   f->TrueExit = static_cast<unsigned int> (True);
   16024          258 :   f->FalseExit = static_cast<unsigned int> (False);
   16025          258 :   f->Dimension = static_cast<unsigned int> (Dim);
   16026          258 :   f->tokenno = Tok;
   16027          258 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   16028          258 : }
   16029              : 
   16030              : 
   16031              : /*
   16032              :    PopTFDtok - Pop a True, False, Dim number from the True/False stack.
   16033              :                True and False are assumed to contain Symbols or Ident etc.
   16034              : */
   16035              : 
   16036          258 : static void PopTFDtok (unsigned int *True, unsigned int *False, unsigned int *Dim, unsigned int *Tok)
   16037              : {
   16038          258 :   M2Quads_BoolFrame f;
   16039              : 
   16040          258 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   16041          258 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   16042          258 :   (*False) = static_cast<unsigned int> (f->FalseExit);
   16043          258 :   (*Dim) = static_cast<unsigned int> (f->Dimension);
   16044          258 :   (*Tok) = f->tokenno;
   16045          258 :   M2Debug_Assert (! f->BooleanOp);
   16046          258 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   16047          258 : }
   16048              : 
   16049              : 
   16050              : /*
   16051              :    PushTFDrwtok - Push True, False, Dim, numbers onto the
   16052              :                   True/False stack.  True and False are assumed to
   16053              :                   contain Symbols or Ident etc.
   16054              : */
   16055              : 
   16056        47990 : static void PushTFDrwtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int rw, unsigned int Tok)
   16057              : {
   16058        47990 :   M2Quads_BoolFrame f;
   16059              : 
   16060        47990 :   f = newBoolFrame ();
   16061        47990 :   f->TrueExit = static_cast<unsigned int> (True);
   16062        47990 :   f->FalseExit = static_cast<unsigned int> (False);
   16063        47990 :   f->Dimension = static_cast<unsigned int> (Dim);
   16064        47990 :   f->ReadWrite = static_cast<unsigned int> (rw);
   16065        47990 :   f->tokenno = Tok;
   16066        47990 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   16067        47990 : }
   16068              : 
   16069              : 
   16070              : /*
   16071              :    PushTFrw - Push a True and False numbers onto the True/False stack.
   16072              :               True and False are assumed to contain Symbols or Ident etc.
   16073              :               It also pushes the higher level symbol which is associated
   16074              :               with the True symbol.  Eg record variable or array variable.
   16075              : */
   16076              : 
   16077         2370 : static void PushTFrw (unsigned int True, unsigned int False, unsigned int rw)
   16078              : {
   16079         2370 :   M2Quads_BoolFrame f;
   16080              : 
   16081         2370 :   f = newBoolFrame ();
   16082         2370 :   f->TrueExit = static_cast<unsigned int> (True);
   16083         2370 :   f->FalseExit = static_cast<unsigned int> (False);
   16084         2370 :   f->ReadWrite = rw;
   16085         2370 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   16086         2370 : }
   16087              : 
   16088              : 
   16089              : /*
   16090              :    PopTFrw - Pop a True and False number from the True/False stack.
   16091              :              True and False are assumed to contain Symbols or Ident etc.
   16092              : */
   16093              : 
   16094        31040 : static void PopTFrw (unsigned int *True, unsigned int *False, unsigned int *rw)
   16095              : {
   16096        31040 :   M2Quads_BoolFrame f;
   16097              : 
   16098        31040 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   16099        31040 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   16100        31040 :   (*False) = static_cast<unsigned int> (f->FalseExit);
   16101        31040 :   M2Debug_Assert (! f->BooleanOp);
   16102        31040 :   (*rw) = static_cast<unsigned int> (f->ReadWrite);
   16103        31040 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   16104        31040 : }
   16105              : 
   16106              : 
   16107              : /*
   16108              :    newBoolFrame - creates a new BoolFrame with all fields initialised to their defaults.
   16109              : */
   16110              : 
   16111    352913180 : static M2Quads_BoolFrame newBoolFrame (void)
   16112              : {
   16113    352913180 :   M2Quads_BoolFrame f;
   16114              : 
   16115    352913180 :   Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   16116    352913180 :   f->TrueExit = 0;
   16117    352913180 :   f->FalseExit = 0;
   16118    352913180 :   f->Unbounded = SymbolTable_NulSym;
   16119    352913180 :   f->BooleanOp = false;
   16120    352913180 :   f->Dimension = 0;
   16121    352913180 :   f->ReadWrite = SymbolTable_NulSym;
   16122    352913180 :   f->name = SymbolTable_NulSym;
   16123    352913180 :   f->Annotation = static_cast<DynamicStrings_String> (NULL);
   16124    352913180 :   f->tokenno = M2LexBuf_UnknownTokenNo;
   16125    352913180 :   return f;
   16126              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16127              :   __builtin_unreachable ();
   16128              : }
   16129              : 
   16130              : 
   16131              : /*
   16132              :    PushTrwtok - Push an item onto the True/False stack. The False value will be zero.
   16133              : */
   16134              : 
   16135          156 : static void PushTrwtok (unsigned int True, unsigned int rw, unsigned int tok)
   16136              : {
   16137          156 :   M2Quads_BoolFrame f;
   16138              : 
   16139          156 :   f = newBoolFrame ();
   16140          156 :   f->TrueExit = static_cast<unsigned int> (True);
   16141          156 :   f->ReadWrite = static_cast<unsigned int> (rw);
   16142          156 :   f->tokenno = tok;
   16143          156 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   16144          156 : }
   16145              : 
   16146              : 
   16147              : /*
   16148              :    PopTrw - Pop a True field and rw symbol from the stack.
   16149              : */
   16150              : 
   16151         2370 : static void PopTrw (unsigned int *True, unsigned int *rw)
   16152              : {
   16153         2370 :   M2Quads_BoolFrame f;
   16154              : 
   16155         2370 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   16156         2370 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   16157         2370 :   M2Debug_Assert (! f->BooleanOp);
   16158         2370 :   (*rw) = static_cast<unsigned int> (f->ReadWrite);
   16159         2370 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   16160         2370 : }
   16161              : 
   16162              : 
   16163              : /*
   16164              :    PopTrwtok - Pop a True field and rw symbol from the stack.
   16165              : */
   16166              : 
   16167      1091287 : static void PopTrwtok (unsigned int *True, unsigned int *rw, unsigned int *tok)
   16168              : {
   16169      1091287 :   M2Quads_BoolFrame f;
   16170              : 
   16171      1091287 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   16172      1091287 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   16173      1091287 :   M2Debug_Assert (! f->BooleanOp);
   16174      1091287 :   (*rw) = static_cast<unsigned int> (f->ReadWrite);
   16175      1091287 :   (*tok) = f->tokenno;
   16176      1091287 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   16177      1091287 : }
   16178              : 
   16179              : 
   16180              : /*
   16181              :    gdbhook - a debugger convenience hook.
   16182              : */
   16183              : 
   16184            0 : static void gdbhook (void)
   16185              : {
   16186            0 : }
   16187              : 
   16188              : 
   16189              : /*
   16190              :    BreakWhenQuadCreated - to be called interactively by gdb.
   16191              : */
   16192              : 
   16193        15674 : static void BreakWhenQuadCreated (unsigned int quad)
   16194              : {
   16195        15674 :   BreakQuad = quad;
   16196            0 : }
   16197              : 
   16198              : 
   16199              : /*
   16200              :    CheckBreak - if quad = BreakQuad then call gdbhook.
   16201              : */
   16202              : 
   16203            0 : static void CheckBreak (unsigned int quad)
   16204              : {
   16205            0 :   if (quad == BreakQuad)
   16206              :     {
   16207            0 :       gdbhook ();
   16208              :     }
   16209            0 : }
   16210              : 
   16211              : 
   16212              : /*
   16213              :    Init - initialize the M2Quads module, all the stacks, all the lists
   16214              :           and the quads list.
   16215              : */
   16216              : 
   16217        15674 : static void Init (void)
   16218              : {
   16219        15674 :   BreakWhenQuadCreated (0);  /* Disable the intereactive quad watch.  */
   16220              :   /* To examine the quad table when a quad is created run cc1gm2 from gdb
   16221              :       and set a break point on gdbhook.
   16222              :       (gdb) break gdbhook
   16223              :       (gdb) run
   16224              :       Now below interactively call BreakWhenQuadCreated with the quad
   16225              :       under investigation.  */
   16226        15674 :   gdbhook ();
   16227              :   /* Now is the time to interactively call gdb, for example:
   16228              :       (gdb) print BreakWhenQuadCreated (1234)
   16229              :       (gdb) cont
   16230              :       and you will arrive at gdbhook when this quad is created.  */
   16231        15674 :   LogicalOrTok = NameKey_MakeKey ((const char *) "_LOR", 4);
   16232        15674 :   LogicalAndTok = NameKey_MakeKey ((const char *) "_LAND", 5);
   16233        15674 :   LogicalXorTok = NameKey_MakeKey ((const char *) "_LXOR", 5);
   16234        15674 :   LogicalDifferenceTok = NameKey_MakeKey ((const char *) "_LDIFF", 6);
   16235        15674 :   ArithPlusTok = NameKey_MakeKey ((const char *) "_ARITH_+", 8);
   16236        15674 :   QuadArray = Indexing_InitIndexTuned (1, (1024*1024) / 16, 16);
   16237        15674 :   FreeList = 1;
   16238        15674 :   NewQuad (&NextQuad);
   16239        15674 :   M2Debug_Assert (NextQuad == 1);
   16240        15674 :   BoolStack = M2StackAddress_InitStackAddress ();
   16241        15674 :   ExitStack = M2StackWord_InitStackWord ();
   16242        15674 :   RepeatStack = M2StackWord_InitStackWord ();
   16243        15674 :   WhileStack = M2StackWord_InitStackWord ();
   16244        15674 :   ForStack = M2StackWord_InitStackWord ();
   16245        15674 :   WithStack = M2StackAddress_InitStackAddress ();
   16246        15674 :   ReturnStack = M2StackWord_InitStackWord ();
   16247        15674 :   LineStack = M2StackAddress_InitStackAddress ();
   16248        15674 :   PriorityStack = M2StackWord_InitStackWord ();
   16249        15674 :   TryStack = M2StackWord_InitStackWord ();
   16250        15674 :   CatchStack = M2StackWord_InitStackWord ();
   16251        15674 :   ExceptStack = M2StackWord_InitStackWord ();
   16252        15674 :   ConstructorStack = M2StackAddress_InitStackAddress ();
   16253        15674 :   ConstParamStack = M2StackWord_InitStackWord ();
   16254        15674 :   ConstExprStack = M2StackWord_InitStackWord ();
   16255              :   /* StressStack ;  */
   16256        15674 :   SuppressWith = false;
   16257        15674 :   Head = 1;
   16258        15674 :   LastQuadNo = 0;
   16259        15674 :   MustNotCheckBounds = false;
   16260        15674 :   InitQuad = 0;
   16261        15674 :   GrowInitialization = 0;
   16262        15674 :   ForInfo = Indexing_InitIndex (1);
   16263        15674 :   QuadrupleGeneration = true;
   16264        15674 :   BuildingHigh = false;
   16265        15674 :   BuildingSize = false;
   16266        15674 :   AutoStack = M2StackWord_InitStackWord ();
   16267        15674 :   IsAutoOn = true;
   16268        15674 :   InConstExpression = false;
   16269        15674 :   InConstParameters = false;
   16270        15674 :   FreeLineList = NULL;
   16271        15674 :   Lists_InitList (&VarientFields);
   16272        15674 :   VarientFieldNo = 0;
   16273        15674 :   NoOfQuads = 0;
   16274        15674 :   QuadMemDiag = M2Diagnostic_InitMemDiagnostic ((const char *) "M2Quad:Quadruples", 17, (const char *) "{0N} total quadruples {1d} consuming {2M} ram {0M} ({2P})", 57);
   16275        15674 : }
   16276              : 
   16277              : 
   16278              : /*
   16279              :    SetOptionCoding - builds a code quadruple if the profiling
   16280              :                      option was given to the compiler.
   16281              : */
   16282              : 
   16283            0 : extern "C" void M2Quads_SetOptionCoding (bool b)
   16284              : {
   16285            0 :   if (b != M2Options_Coding)
   16286              :     {
   16287            0 :       if (b)
   16288              :         {
   16289            0 :           M2Quads_BuildCodeOn ();
   16290              :         }
   16291              :       else
   16292              :         {
   16293            0 :           M2Quads_BuildCodeOff ();
   16294              :         }
   16295            0 :       M2Options_Coding = b;
   16296              :     }
   16297            0 : }
   16298              : 
   16299              : 
   16300              : /*
   16301              :    SetOptionProfiling - builds a profile quadruple if the profiling
   16302              :                         option was given to the compiler.
   16303              : */
   16304              : 
   16305            0 : extern "C" void M2Quads_SetOptionProfiling (bool b)
   16306              : {
   16307            0 :   if (b != M2Options_Profiling)
   16308              :     {
   16309            0 :       if (b)
   16310              :         {
   16311            0 :           M2Quads_BuildProfileOn ();
   16312              :         }
   16313              :       else
   16314              :         {
   16315            0 :           M2Quads_BuildProfileOff ();
   16316              :         }
   16317            0 :       M2Options_Profiling = b;
   16318              :     }
   16319            0 : }
   16320              : 
   16321              : 
   16322              : /*
   16323              :    SetOptionOptimizing - builds a quadruple to say that the optimization option
   16324              :                          has been found in a comment.
   16325              : */
   16326              : 
   16327            0 : extern "C" void M2Quads_SetOptionOptimizing (bool b)
   16328              : {
   16329            0 :   if (b)
   16330              :     {
   16331            0 :       M2Quads_BuildOptimizeOn ();
   16332              :     }
   16333              :   else
   16334              :     {
   16335            0 :       M2Quads_BuildOptimizeOff ();
   16336              :     }
   16337            0 : }
   16338              : 
   16339              : 
   16340              : /*
   16341              :    Opposite - returns the opposite comparison operator.
   16342              : */
   16343              : 
   16344        82188 : extern "C" M2Quads_QuadOperator M2Quads_Opposite (M2Quads_QuadOperator Operator)
   16345              : {
   16346        82188 :   M2Quads_QuadOperator Op;
   16347              : 
   16348        82188 :   switch (Operator)
   16349              :     {
   16350              :       case M2Quads_IfNotEquOp:
   16351              :         Op = M2Quads_IfEquOp;
   16352              :         break;
   16353              : 
   16354              :       case M2Quads_IfEquOp:
   16355              :         Op = M2Quads_IfNotEquOp;
   16356              :         break;
   16357              : 
   16358              :       case M2Quads_IfLessEquOp:
   16359              :         Op = M2Quads_IfGreOp;
   16360              :         break;
   16361              : 
   16362              :       case M2Quads_IfGreOp:
   16363              :         Op = M2Quads_IfLessEquOp;
   16364              :         break;
   16365              : 
   16366              :       case M2Quads_IfGreEquOp:
   16367              :         Op = M2Quads_IfLessOp;
   16368              :         break;
   16369              : 
   16370              :       case M2Quads_IfLessOp:
   16371              :         Op = M2Quads_IfGreEquOp;
   16372              :         break;
   16373              : 
   16374              :       case M2Quads_IfInOp:
   16375              :         Op = M2Quads_IfNotInOp;
   16376              :         break;
   16377              : 
   16378              :       case M2Quads_IfNotInOp:
   16379              :         Op = M2Quads_IfInOp;
   16380              :         break;
   16381              : 
   16382              : 
   16383            0 :       default:
   16384            0 :         M2Error_InternalError ((const char *) "unexpected operator", 19);
   16385        82188 :         break;
   16386              :     }
   16387        82188 :   return Op;
   16388              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16389              :   __builtin_unreachable ();
   16390              : }
   16391              : 
   16392              : 
   16393              : /*
   16394              :    IsReferenced - returns true if QuadNo is referenced by another quadruple.
   16395              : */
   16396              : 
   16397    259950585 : extern "C" bool M2Quads_IsReferenced (unsigned int QuadNo)
   16398              : {
   16399    259950585 :   M2Quads_QuadFrame f;
   16400              : 
   16401    259950585 :   f = GetQF (QuadNo);
   16402    259950585 :   return ((f->Operator == M2Quads_ProcedureScopeOp) || (f->Operator == M2Quads_NewLocalVarOp)) || (f->NoOfTimesReferenced > 0);
   16403              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16404              :   __builtin_unreachable ();
   16405              : }
   16406              : 
   16407              : 
   16408              : /*
   16409              :    IsBackReference - returns TRUE if quadruple, q, is referenced from a quad further on.
   16410              : */
   16411              : 
   16412        97025 : extern "C" bool M2Quads_IsBackReference (unsigned int q)
   16413              : {
   16414        97025 :   unsigned int i;
   16415        97025 :   M2Quads_QuadOperator op;
   16416        97025 :   unsigned int op1;
   16417        97025 :   unsigned int op2;
   16418        97025 :   unsigned int op3;
   16419              : 
   16420        97025 :   i = q;
   16421      3803984 :   while (i != 0)
   16422              :     {
   16423      3803984 :       M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
   16424      3803984 :       switch (op)
   16425              :         {
   16426              :           case M2Quads_NewLocalVarOp:
   16427              :           case M2Quads_KillLocalVarOp:
   16428              :           case M2Quads_FinallyStartOp:
   16429              :           case M2Quads_FinallyEndOp:
   16430              :           case M2Quads_InitEndOp:
   16431              :           case M2Quads_InitStartOp:
   16432              :           case M2Quads_EndFileOp:
   16433              :           case M2Quads_StartDefFileOp:
   16434              :           case M2Quads_StartModFileOp:
   16435              :             return false;  /* run into end of procedure or module  */
   16436       168340 :             break;
   16437              : 
   16438       168340 :           case M2Quads_GotoOp:
   16439       168340 :           case M2Quads_IfEquOp:
   16440       168340 :           case M2Quads_IfLessEquOp:
   16441       168340 :           case M2Quads_IfGreEquOp:
   16442       168340 :           case M2Quads_IfGreOp:
   16443       168340 :           case M2Quads_IfLessOp:
   16444       168340 :           case M2Quads_IfNotEquOp:
   16445       168340 :           case M2Quads_IfInOp:
   16446       168340 :           case M2Quads_IfNotInOp:
   16447       168340 :             if (op3 == q)  /* run into end of procedure or module  */
   16448              :               {
   16449              :                 return true;
   16450              :               }
   16451              :             break;
   16452              : 
   16453              : 
   16454              :           default:
   16455              :             break;
   16456              :         }
   16457      3706959 :       i = M2Quads_GetNextQuad (i);
   16458              :     }
   16459            0 :   M2Error_InternalError ((const char *) "fix this for the sake of efficiency..", 37);
   16460              :   ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
   16461              :   __builtin_unreachable ();
   16462              : }
   16463              : 
   16464              : 
   16465              : /*
   16466              :    IsUnConditional - returns true if QuadNo is an unconditional jump.
   16467              : */
   16468              : 
   16469    528183338 : extern "C" bool M2Quads_IsUnConditional (unsigned int QuadNo)
   16470              : {
   16471    528183338 :   M2Quads_QuadFrame f;
   16472              : 
   16473    528183338 :   f = GetQF (QuadNo);
   16474    528183338 :   switch (f->Operator)
   16475              :     {
   16476              :       case M2Quads_ThrowOp:
   16477              :       case M2Quads_RetryOp:
   16478              :       case M2Quads_CallOp:
   16479              :       case M2Quads_ReturnOp:
   16480              :       case M2Quads_GotoOp:
   16481              :         return true;
   16482    507589237 :         break;
   16483              : 
   16484              : 
   16485    507589237 :       default:
   16486    507589237 :         return false;
   16487              :         break;
   16488              :     }
   16489              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16490              :   __builtin_unreachable ();
   16491              : }
   16492              : 
   16493              : 
   16494              : /*
   16495              :    IsConditional - returns true if QuadNo is a conditional jump.
   16496              : */
   16497              : 
   16498    528290737 : extern "C" bool M2Quads_IsConditional (unsigned int QuadNo)
   16499              : {
   16500    528290737 :   M2Quads_QuadFrame f;
   16501              : 
   16502    528290737 :   f = GetQF (QuadNo);
   16503    528290737 :   switch (f->Operator)
   16504              :     {
   16505              :       case M2Quads_IfInOp:
   16506              :       case M2Quads_IfNotInOp:
   16507              :       case M2Quads_IfEquOp:
   16508              :       case M2Quads_IfNotEquOp:
   16509              :       case M2Quads_IfLessOp:
   16510              :       case M2Quads_IfLessEquOp:
   16511              :       case M2Quads_IfGreOp:
   16512              :       case M2Quads_IfGreEquOp:
   16513              :         return true;
   16514    524308874 :         break;
   16515              : 
   16516              : 
   16517    524308874 :       default:
   16518    524308874 :         return false;
   16519              :         break;
   16520              :     }
   16521              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16522              :   __builtin_unreachable ();
   16523              : }
   16524              : 
   16525              : 
   16526              : /*
   16527              :    IsBackReferenceConditional - returns TRUE if quadruple, q, is referenced from
   16528              :                                 a conditional quad further on.
   16529              : */
   16530              : 
   16531            0 : extern "C" bool M2Quads_IsBackReferenceConditional (unsigned int q)
   16532              : {
   16533            0 :   unsigned int i;
   16534            0 :   M2Quads_QuadOperator op;
   16535            0 :   unsigned int op1;
   16536            0 :   unsigned int op2;
   16537            0 :   unsigned int op3;
   16538              : 
   16539            0 :   i = q;
   16540            0 :   while (i != 0)
   16541              :     {
   16542            0 :       M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
   16543            0 :       switch (op)
   16544              :         {
   16545              :           case M2Quads_NewLocalVarOp:
   16546              :           case M2Quads_KillLocalVarOp:
   16547              :           case M2Quads_FinallyStartOp:
   16548              :           case M2Quads_FinallyEndOp:
   16549              :           case M2Quads_InitEndOp:
   16550              :           case M2Quads_InitStartOp:
   16551              :           case M2Quads_EndFileOp:
   16552              :           case M2Quads_StartDefFileOp:
   16553              :           case M2Quads_StartModFileOp:
   16554              :             return false;  /* run into end of procedure or module  */
   16555            0 :             break;
   16556              : 
   16557            0 :           case M2Quads_TryOp:
   16558            0 :           case M2Quads_RetryOp:
   16559            0 :           case M2Quads_GotoOp:
   16560            0 :           case M2Quads_IfEquOp:
   16561            0 :           case M2Quads_IfLessEquOp:
   16562            0 :           case M2Quads_IfGreEquOp:
   16563            0 :           case M2Quads_IfGreOp:
   16564            0 :           case M2Quads_IfLessOp:
   16565            0 :           case M2Quads_IfNotEquOp:
   16566            0 :           case M2Quads_IfInOp:
   16567            0 :           case M2Quads_IfNotInOp:
   16568            0 :             if ((op3 == q) && (M2Quads_IsConditional (q)))  /* run into end of procedure or module  */
   16569              :               {
   16570              :                 return true;
   16571              :               }
   16572            0 :             break;
   16573              : 
   16574              : 
   16575              :           default:
   16576              :             return false;
   16577            0 :             break;
   16578              :         }
   16579            0 :       i = M2Quads_GetNextQuad (i);
   16580              :     }
   16581            0 :   M2Error_InternalError ((const char *) "fix this for the sake of efficiency..", 37);
   16582              :   ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
   16583              :   __builtin_unreachable ();
   16584              : }
   16585              : 
   16586              : 
   16587              : /*
   16588              :    IsGoto - returns true if QuadNo is a goto operation.
   16589              : */
   16590              : 
   16591        97025 : extern "C" bool M2Quads_IsGoto (unsigned int QuadNo)
   16592              : {
   16593        97025 :   return IsQuadA (QuadNo, M2Quads_GotoOp);
   16594              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16595              :   __builtin_unreachable ();
   16596              : }
   16597              : 
   16598              : 
   16599              : /*
   16600              :    IsCall - returns true if QuadNo is a call operation.
   16601              : */
   16602              : 
   16603    528280363 : extern "C" bool M2Quads_IsCall (unsigned int QuadNo)
   16604              : {
   16605    528280363 :   return IsQuadA (QuadNo, M2Quads_CallOp);
   16606              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16607              :   __builtin_unreachable ();
   16608              : }
   16609              : 
   16610              : 
   16611              : /*
   16612              :    IsReturn - returns true if QuadNo is a return operation.
   16613              : */
   16614              : 
   16615    528442403 : extern "C" bool M2Quads_IsReturn (unsigned int QuadNo)
   16616              : {
   16617    528442403 :   return IsQuadA (QuadNo, M2Quads_ReturnOp);
   16618              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16619              :   __builtin_unreachable ();
   16620              : }
   16621              : 
   16622              : 
   16623              : /*
   16624              :    IsProcedureScope - returns true if QuadNo is a ProcedureScope operation.
   16625              : */
   16626              : 
   16627            0 : extern "C" bool M2Quads_IsProcedureScope (unsigned int QuadNo)
   16628              : {
   16629            0 :   return IsQuadA (QuadNo, M2Quads_ProcedureScopeOp);
   16630              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16631              :   __builtin_unreachable ();
   16632              : }
   16633              : 
   16634              : 
   16635              : /*
   16636              :    IsNewLocalVar - returns true if QuadNo is a NewLocalVar operation.
   16637              : */
   16638              : 
   16639            0 : extern "C" bool M2Quads_IsNewLocalVar (unsigned int QuadNo)
   16640              : {
   16641            0 :   return IsQuadA (QuadNo, M2Quads_NewLocalVarOp);
   16642              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16643              :   __builtin_unreachable ();
   16644              : }
   16645              : 
   16646              : 
   16647              : /*
   16648              :    IsKillLocalVar - returns true if QuadNo is a KillLocalVar operation.
   16649              : */
   16650              : 
   16651       254909 : extern "C" bool M2Quads_IsKillLocalVar (unsigned int QuadNo)
   16652              : {
   16653       254909 :   return IsQuadA (QuadNo, M2Quads_KillLocalVarOp);
   16654              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16655              :   __builtin_unreachable ();
   16656              : }
   16657              : 
   16658              : 
   16659              : /*
   16660              :    IsCatchBegin - returns true if QuadNo is a catch begin quad.
   16661              : */
   16662              : 
   16663       137120 : extern "C" bool M2Quads_IsCatchBegin (unsigned int QuadNo)
   16664              : {
   16665       137120 :   return IsQuadA (QuadNo, M2Quads_CatchBeginOp);
   16666              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16667              :   __builtin_unreachable ();
   16668              : }
   16669              : 
   16670              : 
   16671              : /*
   16672              :    IsCatchEnd - returns true if QuadNo is a catch end quad.
   16673              : */
   16674              : 
   16675       153728 : extern "C" bool M2Quads_IsCatchEnd (unsigned int QuadNo)
   16676              : {
   16677       153728 :   return IsQuadA (QuadNo, M2Quads_CatchEndOp);
   16678              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16679              :   __builtin_unreachable ();
   16680              : }
   16681              : 
   16682              : 
   16683              : /*
   16684              :    IsInitStart - returns true if QuadNo is a init start quad.
   16685              : */
   16686              : 
   16687       137120 : extern "C" bool M2Quads_IsInitStart (unsigned int QuadNo)
   16688              : {
   16689       137120 :   return IsQuadA (QuadNo, M2Quads_InitStartOp);
   16690              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16691              :   __builtin_unreachable ();
   16692              : }
   16693              : 
   16694              : 
   16695              : /*
   16696              :    IsInitEnd - returns true if QuadNo is a init end quad.
   16697              : */
   16698              : 
   16699       137120 : extern "C" bool M2Quads_IsInitEnd (unsigned int QuadNo)
   16700              : {
   16701       137120 :   return IsQuadA (QuadNo, M2Quads_InitEndOp);
   16702              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16703              :   __builtin_unreachable ();
   16704              : }
   16705              : 
   16706              : 
   16707              : /*
   16708              :    IsFinallyStart - returns true if QuadNo is a finally start quad.
   16709              : */
   16710              : 
   16711       131666 : extern "C" bool M2Quads_IsFinallyStart (unsigned int QuadNo)
   16712              : {
   16713       131666 :   return IsQuadA (QuadNo, M2Quads_FinallyStartOp);
   16714              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16715              :   __builtin_unreachable ();
   16716              : }
   16717              : 
   16718              : 
   16719              : /*
   16720              :    IsFinallyEnd - returns true if QuadNo is a finally end quad.
   16721              : */
   16722              : 
   16723       126212 : extern "C" bool M2Quads_IsFinallyEnd (unsigned int QuadNo)
   16724              : {
   16725       126212 :   return IsQuadA (QuadNo, M2Quads_FinallyEndOp);
   16726              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16727              :   __builtin_unreachable ();
   16728              : }
   16729              : 
   16730              : 
   16731              : /*
   16732              :    IsBecomes - return TRUE if QuadNo is a BecomesOp.
   16733              : */
   16734              : 
   16735            0 : extern "C" bool M2Quads_IsBecomes (unsigned int QuadNo)
   16736              : {
   16737            0 :   return IsQuadA (QuadNo, M2Quads_BecomesOp);
   16738              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16739              :   __builtin_unreachable ();
   16740              : }
   16741              : 
   16742              : 
   16743              : /*
   16744              :    IsDummy - return TRUE if QuadNo is a DummyOp.
   16745              : */
   16746              : 
   16747            0 : extern "C" bool M2Quads_IsDummy (unsigned int QuadNo)
   16748              : {
   16749            0 :   return IsQuadA (QuadNo, M2Quads_DummyOp);
   16750              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16751              :   __builtin_unreachable ();
   16752              : }
   16753              : 
   16754              : 
   16755              : /*
   16756              :    IsQuadConstExpr - returns TRUE if QuadNo is part of a constant expression.
   16757              : */
   16758              : 
   16759            0 : extern "C" bool M2Quads_IsQuadConstExpr (unsigned int QuadNo)
   16760              : {
   16761            0 :   M2Quads_QuadFrame f;
   16762              : 
   16763            0 :   f = GetQF (QuadNo);
   16764            0 :   return f->ConstExpr;
   16765              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16766              :   __builtin_unreachable ();
   16767              : }
   16768              : 
   16769              : 
   16770              : /*
   16771              :    SetQuadConstExpr - sets the constexpr field to value.
   16772              : */
   16773              : 
   16774            0 : extern "C" void M2Quads_SetQuadConstExpr (unsigned int QuadNo, bool value)
   16775              : {
   16776            0 :   M2Quads_QuadFrame f;
   16777              : 
   16778            0 :   f = GetQF (QuadNo);
   16779            0 :   f->ConstExpr = value;
   16780            0 : }
   16781              : 
   16782              : 
   16783              : /*
   16784              :    GetQuadDest - returns the jump destination associated with quad.
   16785              : */
   16786              : 
   16787            0 : extern "C" unsigned int M2Quads_GetQuadDest (unsigned int QuadNo)
   16788              : {
   16789            0 :   return M2Quads_GetQuadOp3 (QuadNo);
   16790              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16791              :   __builtin_unreachable ();
   16792              : }
   16793              : 
   16794              : 
   16795              : /*
   16796              :    GetQuadOp1 - returns the 1st operand associated with quad.
   16797              : */
   16798              : 
   16799            0 : extern "C" unsigned int M2Quads_GetQuadOp1 (unsigned int QuadNo)
   16800              : {
   16801            0 :   M2Quads_QuadFrame f;
   16802              : 
   16803            0 :   f = GetQF (QuadNo);
   16804            0 :   return f->Operand1;
   16805              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16806              :   __builtin_unreachable ();
   16807              : }
   16808              : 
   16809              : 
   16810              : /*
   16811              :    GetQuadOp2 - returns the 2nd operand associated with quad.
   16812              : */
   16813              : 
   16814            0 : extern "C" unsigned int M2Quads_GetQuadOp2 (unsigned int QuadNo)
   16815              : {
   16816            0 :   M2Quads_QuadFrame f;
   16817              : 
   16818            0 :   f = GetQF (QuadNo);
   16819            0 :   return f->Operand2;
   16820              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16821              :   __builtin_unreachable ();
   16822              : }
   16823              : 
   16824              : 
   16825              : /*
   16826              :    GetQuadOp3 - returns the 3rd operand associated with quad.
   16827              : */
   16828              : 
   16829            0 : extern "C" unsigned int M2Quads_GetQuadOp3 (unsigned int QuadNo)
   16830              : {
   16831            0 :   M2Quads_QuadFrame f;
   16832              : 
   16833            0 :   f = GetQF (QuadNo);
   16834            0 :   return f->Operand3;
   16835              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16836              :   __builtin_unreachable ();
   16837              : }
   16838              : 
   16839              : 
   16840              : /*
   16841              :    IsInitialisingConst - returns TRUE if the quadruple is setting
   16842              :                          a const (op1) with a value.
   16843              : */
   16844              : 
   16845            0 : extern "C" bool M2Quads_IsInitialisingConst (unsigned int QuadNo)
   16846              : {
   16847            0 :   M2Quads_QuadOperator op;
   16848            0 :   unsigned int op1;
   16849            0 :   unsigned int op2;
   16850            0 :   unsigned int op3;
   16851              : 
   16852            0 :   M2Quads_GetQuad (QuadNo, &op, &op1, &op2, &op3);
   16853            0 :   return (OpUsesOp1 (op)) && (SymbolTable_IsConst (op1));
   16854              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16855              :   __builtin_unreachable ();
   16856              : }
   16857              : 
   16858              : 
   16859              : /*
   16860              :    IsConstQuad - return TRUE if the quadruple is marked as a constexpr.
   16861              : */
   16862              : 
   16863            0 : extern "C" bool M2Quads_IsConstQuad (unsigned int quad)
   16864              : {
   16865            0 :   M2Quads_QuadFrame f;
   16866              : 
   16867            0 :   f = GetQF (quad);
   16868            0 :   return f->ConstExpr;
   16869              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16870              :   __builtin_unreachable ();
   16871              : }
   16872              : 
   16873              : 
   16874              : /*
   16875              :    IsConditionalBooleanQuad - return TRUE if operand 1 is a boolean result.
   16876              : */
   16877              : 
   16878       425884 : extern "C" bool M2Quads_IsConditionalBooleanQuad (unsigned int quad)
   16879              : {
   16880       425884 :   M2Quads_QuadFrame f;
   16881              : 
   16882       425884 :   f = GetQF (quad);
   16883       425884 :   return ((OpUsesOp1 (f->Operator)) && ((SymbolTable_IsVar (f->Operand1)) || (SymbolTable_IsConst (f->Operand1)))) && (SymbolTable_IsVarConditional (f->Operand1));
   16884              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16885              :   __builtin_unreachable ();
   16886              : }
   16887              : 
   16888              : 
   16889              : /*
   16890              :    IsOptimizeOn - returns true if the Optimize flag was true at QuadNo.
   16891              : */
   16892              : 
   16893            0 : extern "C" bool M2Quads_IsOptimizeOn (unsigned int QuadNo)
   16894              : {
   16895            0 :   M2Quads_QuadFrame f;
   16896            0 :   unsigned int n;
   16897            0 :   unsigned int q;
   16898            0 :   bool On;
   16899              : 
   16900            0 :   On = M2Options_Optimizing;
   16901            0 :   q = Head;
   16902            0 :   while ((q != 0) && (q != QuadNo))
   16903              :     {
   16904            0 :       f = GetQF (q);
   16905            0 :       if (f->Operator == M2Quads_OptimizeOnOp)
   16906              :         {
   16907              :           On = true;
   16908              :         }
   16909            0 :       else if (f->Operator == M2Quads_OptimizeOffOp)
   16910              :         {
   16911              :           /* avoid dangling else.  */
   16912            0 :           On = false;
   16913              :         }
   16914            0 :       n = f->Next;
   16915            0 :       q = n;
   16916              :     }
   16917            0 :   return On;
   16918              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16919              :   __builtin_unreachable ();
   16920              : }
   16921              : 
   16922              : 
   16923              : /*
   16924              :    IsProfileOn - returns true if the Profile flag was true at QuadNo.
   16925              : */
   16926              : 
   16927            0 : extern "C" bool M2Quads_IsProfileOn (unsigned int QuadNo)
   16928              : {
   16929            0 :   M2Quads_QuadFrame f;
   16930            0 :   unsigned int n;
   16931            0 :   unsigned int q;
   16932            0 :   bool On;
   16933              : 
   16934            0 :   On = M2Options_Profiling;
   16935            0 :   q = Head;
   16936            0 :   while ((q != 0) && (q != QuadNo))
   16937              :     {
   16938            0 :       f = GetQF (q);
   16939            0 :       if (f->Operator == M2Quads_ProfileOnOp)
   16940              :         {
   16941              :           On = true;
   16942              :         }
   16943            0 :       else if (f->Operator == M2Quads_ProfileOffOp)
   16944              :         {
   16945              :           /* avoid dangling else.  */
   16946            0 :           On = false;
   16947              :         }
   16948            0 :       n = f->Next;
   16949            0 :       q = n;
   16950              :     }
   16951            0 :   return On;
   16952              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16953              :   __builtin_unreachable ();
   16954              : }
   16955              : 
   16956              : 
   16957              : /*
   16958              :    IsCodeOn - returns true if the Code flag was true at QuadNo.
   16959              : */
   16960              : 
   16961            0 : extern "C" bool M2Quads_IsCodeOn (unsigned int QuadNo)
   16962              : {
   16963            0 :   M2Quads_QuadFrame f;
   16964            0 :   unsigned int n;
   16965            0 :   unsigned int q;
   16966            0 :   bool On;
   16967              : 
   16968            0 :   On = M2Options_Coding;
   16969            0 :   q = Head;
   16970            0 :   while ((q != 0) && (q != QuadNo))
   16971              :     {
   16972            0 :       f = GetQF (q);
   16973            0 :       if (f->Operator == M2Quads_CodeOnOp)
   16974              :         {
   16975              :           On = true;
   16976              :         }
   16977            0 :       else if (f->Operator == M2Quads_CodeOffOp)
   16978              :         {
   16979              :           /* avoid dangling else.  */
   16980            0 :           On = false;
   16981              :         }
   16982            0 :       n = f->Next;
   16983            0 :       q = n;
   16984              :     }
   16985            0 :   return On;
   16986              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16987              :   __builtin_unreachable ();
   16988              : }
   16989              : 
   16990              : 
   16991              : /*
   16992              :    IsPseudoQuad - returns true if QuadNo is a compiler directive.
   16993              :                   ie code, profile and optimize.
   16994              :                      StartFile, EndFile,
   16995              : */
   16996              : 
   16997     23406537 : extern "C" bool M2Quads_IsPseudoQuad (unsigned int QuadNo)
   16998              : {
   16999     23406537 :   M2Quads_QuadFrame f;
   17000              : 
   17001     23406537 :   f = GetQF (QuadNo);
   17002     23406537 :   return ((((((((f->Operator == M2Quads_CodeOnOp) || (f->Operator == M2Quads_CodeOffOp)) || (f->Operator == M2Quads_ProfileOnOp)) || (f->Operator == M2Quads_ProfileOffOp)) || (f->Operator == M2Quads_OptimizeOnOp)) || (f->Operator == M2Quads_OptimizeOffOp)) || (f->Operator == M2Quads_EndFileOp)) || (f->Operator == M2Quads_StartDefFileOp)) || (f->Operator == M2Quads_StartModFileOp);
   17003              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17004              :   __builtin_unreachable ();
   17005              : }
   17006              : 
   17007              : 
   17008              : /*
   17009              :    IsDefOrModFile - returns TRUE if QuadNo is a start of Module or Def file
   17010              :                     directive.
   17011              : */
   17012              : 
   17013    528183338 : extern "C" bool M2Quads_IsDefOrModFile (unsigned int QuadNo)
   17014              : {
   17015    528183338 :   M2Quads_QuadFrame f;
   17016              : 
   17017    528183338 :   f = GetQF (QuadNo);
   17018    528183338 :   return (f->Operator == M2Quads_StartDefFileOp) || (f->Operator == M2Quads_StartModFileOp);
   17019              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17020              :   __builtin_unreachable ();
   17021              : }
   17022              : 
   17023              : 
   17024              : /*
   17025              :    DumpQuadruples - dump all quadruples providing the -fq, -fdump-lang-quad,
   17026              :                     -fdump-lang-quad= or -fdump-lang-all were issued to the
   17027              :                     command line.
   17028              : */
   17029              : 
   17030        73022 : extern "C" void M2Quads_DumpQuadruples (const char *title_, unsigned int _title_high)
   17031              : {
   17032        73022 :   char title[_title_high+1];
   17033              : 
   17034              :   /* make a local copy of each unbounded array.  */
   17035        73022 :   memcpy (title, title_, _title_high+1);
   17036              : 
   17037        73022 :   if (M2Options_GetDumpQuad ())
   17038              :     {
   17039            0 :       M2LangDump_CreateDumpQuad ((const char *) title, _title_high);
   17040            0 :       if ((M2Options_GetM2DumpFilter ()) == NULL)
   17041              :         {
   17042            0 :           DumpQuadrupleAll ();
   17043              :         }
   17044              :       else
   17045              :         {
   17046            0 :           DumpQuadrupleFilter ();
   17047              :         }
   17048            0 :       M2LangDump_CloseDumpQuad ();
   17049              :     }
   17050        73022 : }
   17051              : 
   17052              : 
   17053              : /*
   17054              :    DisplayQuadRange - displays all quads in list range, start..end.
   17055              : */
   17056              : 
   17057            0 : extern "C" void M2Quads_DisplayQuadRange (unsigned int scope, unsigned int start, unsigned int end)
   17058              : {
   17059            0 :   M2Quads_QuadFrame f;
   17060              : 
   17061            0 :   M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "Quadruples for scope: %d\\n", 26, (const unsigned char *) &scope, (sizeof (scope)-1));
   17062            0 :   while ((start <= end) && (start != 0))
   17063              :     {
   17064            0 :       M2Quads_DisplayQuad (start);
   17065            0 :       f = GetQF (start);
   17066            0 :       start = f->Next;
   17067              :     }
   17068            0 : }
   17069              : 
   17070              : 
   17071              : /*
   17072              :    DisplayQuad - displays a quadruple, QuadNo.
   17073              : */
   17074              : 
   17075            0 : extern "C" void M2Quads_DisplayQuad (unsigned int QuadNo)
   17076              : {
   17077            0 :   if (QuadNo != 0)
   17078              :     {
   17079            0 :       DSdbEnter ();
   17080            0 :       M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d  ", 5, (const unsigned char *) &QuadNo, (sizeof (QuadNo)-1));
   17081            0 :       WriteQuad (QuadNo);
   17082            0 :       M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "\\n", 2);
   17083            0 :       DSdbExit ();
   17084              :     }
   17085            0 : }
   17086              : 
   17087              : 
   17088              : /*
   17089              :    GetLastFileQuad - returns the Quadruple number of the last StartDefFile or
   17090              :                      StartModFile quadruple.
   17091              : */
   17092              : 
   17093            0 : extern "C" unsigned int M2Quads_GetLastFileQuad (unsigned int QuadNo)
   17094              : {
   17095            0 :   M2Quads_QuadFrame f;
   17096            0 :   unsigned int q;
   17097            0 :   unsigned int i;
   17098            0 :   unsigned int FileQuad;
   17099              : 
   17100            0 :   q = Head;
   17101            0 :   FileQuad = 0;
   17102            0 :   do {
   17103            0 :     f = GetQF (q);
   17104            0 :     if ((f->Operator == M2Quads_StartModFileOp) || (f->Operator == M2Quads_StartDefFileOp))
   17105              :       {
   17106            0 :         FileQuad = q;
   17107              :       }
   17108            0 :     i = f->Next;
   17109            0 :     q = i;
   17110            0 :   } while (! ((i == QuadNo) || (i == 0)));
   17111            0 :   M2Debug_Assert (i != 0);
   17112            0 :   M2Debug_Assert (FileQuad != 0);
   17113            0 :   return FileQuad;
   17114              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17115              :   __builtin_unreachable ();
   17116              : }
   17117              : 
   17118              : 
   17119              : /*
   17120              :    GetLastQuadNo - returns the last quadruple number referenced
   17121              :                    by a GetQuad.
   17122              : */
   17123              : 
   17124            0 : extern "C" unsigned int M2Quads_GetLastQuadNo (void)
   17125              : {
   17126            0 :   return LastQuadNo;
   17127              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17128              :   __builtin_unreachable ();
   17129              : }
   17130              : 
   17131              : 
   17132              : /*
   17133              :    QuadToTokenNo - Converts a QuadNo into the approprate token number of the
   17134              :                    source file, the line number is returned.
   17135              : 
   17136              :                    This may be used to yield an idea where abouts in the
   17137              :                    source file the code generetion is
   17138              :                    processing.
   17139              : */
   17140              : 
   17141      7456763 : extern "C" unsigned int M2Quads_QuadToTokenNo (unsigned int QuadNo)
   17142              : {
   17143      7456763 :   M2Quads_QuadFrame f;
   17144              : 
   17145      7456763 :   if ((((LastQuadNo == 0) && (! (M2Pass_IsNoPass ()))) && (! (M2Pass_IsPassCodeGeneration ()))) || (! (Indexing_InBounds (QuadArray, QuadNo))))
   17146              :     {
   17147            0 :       return 0;
   17148              :     }
   17149              :   else
   17150              :     {
   17151      7456763 :       f = GetQF (QuadNo);
   17152      7456763 :       return f->TokenNo;
   17153              :     }
   17154              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17155              :   __builtin_unreachable ();
   17156              : }
   17157              : 
   17158              : 
   17159              : /*
   17160              :    QuadToLineNo - Converts a QuadNo into the approprate line number of the
   17161              :                   source file, the line number is returned.
   17162              : 
   17163              :                   This may be used to yield an idea where abouts in the
   17164              :                   source file the code generetion is
   17165              :                   processing.
   17166              : */
   17167              : 
   17168            0 : extern "C" unsigned int M2Quads_QuadToLineNo (unsigned int QuadNo)
   17169              : {
   17170            0 :   M2Quads_QuadFrame f;
   17171              : 
   17172            0 :   if ((((LastQuadNo == 0) && (! (M2Pass_IsNoPass ()))) && (! (M2Pass_IsPassCodeGeneration ()))) || (! (Indexing_InBounds (QuadArray, QuadNo))))
   17173              :     {
   17174            0 :       return 0;
   17175              :     }
   17176              :   else
   17177              :     {
   17178            0 :       f = GetQF (QuadNo);
   17179            0 :       return f->LineNo;
   17180              :     }
   17181              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17182              :   __builtin_unreachable ();
   17183              : }
   17184              : 
   17185              : 
   17186              : /*
   17187              :    GetQuad - returns the Quadruple QuadNo.
   17188              : */
   17189              : 
   17190   2682970632 : extern "C" void M2Quads_GetQuad (unsigned int QuadNo, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3)
   17191              : {
   17192   2682970632 :   M2Quads_QuadFrame f;
   17193              : 
   17194   2682970632 :   f = GetQF (QuadNo);
   17195   2682970632 :   LastQuadNo = QuadNo;
   17196   2682970632 :   (*Op) = f->Operator;
   17197   2682970632 :   (*Oper1) = f->Operand1;
   17198   2682970632 :   (*Oper2) = f->Operand2;
   17199   2682970632 :   (*Oper3) = f->Operand3;
   17200   2682970632 : }
   17201              : 
   17202              : 
   17203              : /*
   17204              :    GetQuadOp - returns the operator for quad.
   17205              : */
   17206              : 
   17207           24 : extern "C" M2Quads_QuadOperator M2Quads_GetQuadOp (unsigned int quad)
   17208              : {
   17209           24 :   M2Quads_QuadFrame f;
   17210              : 
   17211           24 :   f = GetQF (quad);
   17212           24 :   return f->Operator;
   17213              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17214              :   __builtin_unreachable ();
   17215              : }
   17216              : 
   17217              : 
   17218              : /*
   17219              :    GetM2OperatorDesc - returns the Modula-2 string associated with the quad operator
   17220              :                        (if possible).  It returns NIL if no there is not an obvious match
   17221              :                        in Modula-2.  It is assummed that the string will be used during
   17222              :                        construction of error messages and therefore keywords are
   17223              :                        wrapped with a format specifier.
   17224              : */
   17225              : 
   17226           31 : extern "C" DynamicStrings_String M2Quads_GetM2OperatorDesc (M2Quads_QuadOperator op)
   17227              : {
   17228           31 :   switch (op)
   17229              :     {
   17230            6 :       case M2Quads_NegateOp:
   17231            6 :         return DynamicStrings_InitString ((const char *) "-", 1);
   17232           18 :         break;
   17233              : 
   17234           18 :       case M2Quads_AddOp:
   17235           18 :         return DynamicStrings_InitString ((const char *) "+", 1);
   17236            0 :         break;
   17237              : 
   17238            0 :       case M2Quads_SubOp:
   17239            0 :         return DynamicStrings_InitString ((const char *) "-", 1);
   17240            0 :         break;
   17241              : 
   17242            0 :       case M2Quads_MultOp:
   17243            0 :         return DynamicStrings_InitString ((const char *) "*", 1);
   17244            0 :         break;
   17245              : 
   17246            0 :       case M2Quads_DivM2Op:
   17247            0 :       case M2Quads_DivCeilOp:
   17248            0 :       case M2Quads_DivFloorOp:
   17249            0 :       case M2Quads_DivTruncOp:
   17250            0 :         return DynamicStrings_InitString ((const char *) "{%kDIV}", 7);
   17251            0 :         break;
   17252              : 
   17253            0 :       case M2Quads_ModM2Op:
   17254            0 :       case M2Quads_ModCeilOp:
   17255            0 :       case M2Quads_ModFloorOp:
   17256            0 :         return DynamicStrings_InitString ((const char *) "{%kMOD}", 7);
   17257            0 :         break;
   17258              : 
   17259            0 :       case M2Quads_ModTruncOp:
   17260            0 :         return DynamicStrings_InitString ((const char *) "{%kREM}", 7);
   17261            0 :         break;
   17262              : 
   17263            0 :       case M2Quads_LogicalOrOp:
   17264            0 :         return DynamicStrings_InitString ((const char *) "{%kOR}", 6);
   17265            0 :         break;
   17266              : 
   17267            0 :       case M2Quads_LogicalAndOp:
   17268            0 :         return DynamicStrings_InitString ((const char *) "{%kAND}", 7);
   17269            0 :         break;
   17270              : 
   17271            0 :       case M2Quads_InclOp:
   17272            0 :         return DynamicStrings_InitString ((const char *) "{%kINCL}", 8);
   17273            0 :         break;
   17274              : 
   17275            0 :       case M2Quads_ExclOp:
   17276            0 :         return DynamicStrings_InitString ((const char *) "{%kEXCL}", 8);
   17277            7 :         break;
   17278              : 
   17279            7 :       case M2Quads_IfEquOp:
   17280            7 :         return DynamicStrings_InitString ((const char *) "=", 1);
   17281            0 :         break;
   17282              : 
   17283            0 :       case M2Quads_IfLessEquOp:
   17284            0 :         return DynamicStrings_InitString ((const char *) "<=", 2);
   17285            0 :         break;
   17286              : 
   17287            0 :       case M2Quads_IfGreEquOp:
   17288            0 :         return DynamicStrings_InitString ((const char *) ">=", 2);
   17289            0 :         break;
   17290              : 
   17291            0 :       case M2Quads_IfGreOp:
   17292            0 :         return DynamicStrings_InitString ((const char *) ">", 1);
   17293            0 :         break;
   17294              : 
   17295            0 :       case M2Quads_IfLessOp:
   17296            0 :         return DynamicStrings_InitString ((const char *) "<", 1);
   17297            0 :         break;
   17298              : 
   17299            0 :       case M2Quads_IfNotEquOp:
   17300            0 :         return DynamicStrings_InitString ((const char *) "#", 1);
   17301            0 :         break;
   17302              : 
   17303            0 :       case M2Quads_IfInOp:
   17304            0 :         return DynamicStrings_InitString ((const char *) "IN", 2);
   17305            0 :         break;
   17306              : 
   17307            0 :       case M2Quads_IfNotInOp:
   17308            0 :         return DynamicStrings_InitString ((const char *) "NOT IN", 6);
   17309              :         break;
   17310              : 
   17311              : 
   17312              :       default:
   17313              :         return static_cast<DynamicStrings_String> (NULL);
   17314              :         break;
   17315              :     }
   17316              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17317              :   __builtin_unreachable ();
   17318              : }
   17319              : 
   17320              : 
   17321              : /*
   17322              :    GetQuadtok - returns the Quadruple QuadNo.
   17323              : */
   17324              : 
   17325    173335803 : extern "C" void M2Quads_GetQuadtok (unsigned int QuadNo, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3, unsigned int *Op1Pos, unsigned int *Op2Pos, unsigned int *Op3Pos)
   17326              : {
   17327    173335803 :   M2Quads_QuadFrame f;
   17328              : 
   17329    173335803 :   f = GetQF (QuadNo);
   17330    173335803 :   LastQuadNo = QuadNo;
   17331    173335803 :   (*Op) = f->Operator;
   17332    173335803 :   (*Oper1) = f->Operand1;
   17333    173335803 :   (*Oper2) = f->Operand2;
   17334    173335803 :   (*Oper3) = f->Operand3;
   17335    173335803 :   (*Op1Pos) = f->op1pos;
   17336    173335803 :   (*Op2Pos) = f->op2pos;
   17337    173335803 :   (*Op3Pos) = f->op3pos;
   17338    173335803 : }
   17339              : 
   17340              : 
   17341              : /*
   17342              :    GetQuadOtok - returns the Quadruple QuadNo.
   17343              : */
   17344              : 
   17345      6989103 : extern "C" void M2Quads_GetQuadOtok (unsigned int QuadNo, unsigned int *tok, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3, bool *overflowChecking, bool *constExpr, unsigned int *Op1Pos, unsigned int *Op2Pos, unsigned int *Op3Pos)
   17346              : {
   17347      6989103 :   M2Quads_QuadFrame f;
   17348              : 
   17349      6989103 :   f = GetQF (QuadNo);
   17350      6989103 :   LastQuadNo = QuadNo;
   17351      6989103 :   (*Op) = f->Operator;
   17352      6989103 :   (*Oper1) = f->Operand1;
   17353      6989103 :   (*Oper2) = f->Operand2;
   17354      6989103 :   (*Oper3) = f->Operand3;
   17355      6989103 :   (*Op1Pos) = f->op1pos;
   17356      6989103 :   (*Op2Pos) = f->op2pos;
   17357      6989103 :   (*Op3Pos) = f->op3pos;
   17358      6989103 :   (*tok) = f->TokenNo;
   17359      6989103 :   (*overflowChecking) = f->CheckOverflow;
   17360      6989103 :   (*constExpr) = f->ConstExpr;
   17361      6989103 : }
   17362              : 
   17363              : 
   17364              : /*
   17365              :    GetQuadOTypetok - returns the fields associated with quadruple QuadNo.
   17366              : */
   17367              : 
   17368         6668 : extern "C" void M2Quads_GetQuadOTypetok (unsigned int QuadNo, unsigned int *tok, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3, bool *overflowChecking, bool *typeChecking, bool *constExpr, unsigned int *Op1Pos, unsigned int *Op2Pos, unsigned int *Op3Pos)
   17369              : {
   17370         6668 :   M2Quads_QuadFrame f;
   17371              : 
   17372         6668 :   f = GetQF (QuadNo);
   17373         6668 :   LastQuadNo = QuadNo;
   17374         6668 :   (*Op) = f->Operator;
   17375         6668 :   (*Oper1) = f->Operand1;
   17376         6668 :   (*Oper2) = f->Operand2;
   17377         6668 :   (*Oper3) = f->Operand3;
   17378         6668 :   (*Op1Pos) = f->op1pos;
   17379         6668 :   (*Op2Pos) = f->op2pos;
   17380         6668 :   (*Op3Pos) = f->op3pos;
   17381         6668 :   (*tok) = f->TokenNo;
   17382         6668 :   (*overflowChecking) = f->CheckOverflow;
   17383         6668 :   (*typeChecking) = f->CheckType;
   17384         6668 :   (*constExpr) = f->ConstExpr;
   17385         6668 : }
   17386              : 
   17387              : 
   17388              : /*
   17389              :    PutQuadOtok - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
   17390              :                  sets a boolean to determinine whether overflow should be checked.
   17391              : */
   17392              : 
   17393        82181 : extern "C" void M2Quads_PutQuadOtok (unsigned int QuadNo, unsigned int tok, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflowChecking, bool constExpr, unsigned int Op1Pos, unsigned int Op2Pos, unsigned int Op3Pos)
   17394              : {
   17395        82181 :   M2Quads_QuadFrame f;
   17396              : 
   17397        82181 :   if (QuadrupleGeneration)
   17398              :     {
   17399        82181 :       M2Quads_EraseQuad (QuadNo);
   17400        82181 :       AddQuadInformation (QuadNo, Op, Oper1, Oper2, Oper3);
   17401        82181 :       f = GetQF (QuadNo);
   17402        82181 :       f->Operator = Op;
   17403        82181 :       f->Operand1 = Oper1;
   17404        82181 :       f->Operand2 = Oper2;
   17405        82181 :       f->Operand3 = Oper3;
   17406        82181 :       f->CheckOverflow = overflowChecking;
   17407        82181 :       f->op1pos = Op1Pos;
   17408        82181 :       f->op2pos = Op2Pos;
   17409        82181 :       f->op3pos = Op3Pos;
   17410        82181 :       f->TokenNo = tok;
   17411        82181 :       f->ConstExpr = constExpr;
   17412              :     }
   17413        82181 : }
   17414              : 
   17415              : 
   17416              : /*
   17417              :    PutQuad - overwrites a quadruple QuadNo with Op, Oper1, Oper2, Oper3
   17418              : */
   17419              : 
   17420        14721 : extern "C" void M2Quads_PutQuad (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
   17421              : {
   17422        14721 :   PutQuadO (QuadNo, Op, Oper1, Oper2, Oper3, true);
   17423        14721 : }
   17424              : 
   17425              : 
   17426              : /*
   17427              :    GetFirstQuad - returns the first quadruple.
   17428              : */
   17429              : 
   17430       801534 : extern "C" unsigned int M2Quads_GetFirstQuad (void)
   17431              : {
   17432       801534 :   return Head;
   17433              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17434              :   __builtin_unreachable ();
   17435              : }
   17436              : 
   17437              : 
   17438              : /*
   17439              :    GetNextQuad - returns the Quadruple number following QuadNo.
   17440              : */
   17441              : 
   17442   3385034129 : extern "C" unsigned int M2Quads_GetNextQuad (unsigned int QuadNo)
   17443              : {
   17444   3385034129 :   M2Quads_QuadFrame f;
   17445              : 
   17446   3385034129 :   f = GetQF (QuadNo);
   17447   3385034129 :   return f->Next;
   17448              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17449              :   __builtin_unreachable ();
   17450              : }
   17451              : 
   17452              : 
   17453              : /*
   17454              :    GetRealQuad - returns the Quadruple number of the real quadruple
   17455              :                  at QuadNo or beyond.
   17456              : */
   17457              : 
   17458     15341236 : extern "C" unsigned int M2Quads_GetRealQuad (unsigned int QuadNo)
   17459              : {
   17460     15341236 :   M2Quads_QuadFrame f;
   17461              : 
   17462     23323530 :   while (QuadNo != 0)
   17463              :     {
   17464     23323530 :       if (Indexing_InBounds (QuadArray, QuadNo))
   17465              :         {
   17466     23239043 :           f = GetQF (QuadNo);
   17467     23239043 :           if ((((! (M2Quads_IsPseudoQuad (QuadNo))) && (f->Operator != M2Quads_DummyOp)) && (f->Operator != M2Quads_LineNumberOp)) && (f->Operator != M2Quads_StatementNoteOp))
   17468              :             {
   17469              :               return QuadNo;
   17470              :             }
   17471      7982294 :           QuadNo += 1;
   17472              :         }
   17473              :       else
   17474              :         {
   17475              :           return 0;
   17476              :         }
   17477              :     }
   17478              :   return 0;
   17479              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17480              :   __builtin_unreachable ();
   17481              : }
   17482              : 
   17483              : 
   17484              : /*
   17485              :    SubQuad - subtracts a quadruple QuadNo from a list Head.
   17486              : */
   17487              : 
   17488      1928561 : extern "C" void M2Quads_SubQuad (unsigned int QuadNo)
   17489              : {
   17490      1928561 :   unsigned int i;
   17491      1928561 :   M2Quads_QuadFrame f;
   17492      1928561 :   M2Quads_QuadFrame g;
   17493              : 
   17494      1928561 :   CheckBreak (QuadNo);
   17495      1928561 :   f = GetQF (QuadNo);
   17496      1928561 :   AlterReference (Head, QuadNo, f->Next);
   17497      1928561 :   UndoReadWriteInfo (QuadNo, f->Operator, f->Operand1, f->Operand2, f->Operand3);
   17498      1928561 :   if (Head == QuadNo)
   17499              :     {
   17500            0 :       Head = f->Next;
   17501              :     }
   17502              :   else
   17503              :     {
   17504      1928561 :       i = Head;
   17505      1928561 :       g = GetQF (i);
   17506   5044066260 :       while (g->Next != QuadNo)
   17507              :         {
   17508   5040209138 :           i = g->Next;
   17509   5040209138 :           g = GetQF (i);
   17510              :         }
   17511      1928561 :       g->Next = f->Next;
   17512              :     }
   17513      1928561 :   f->Operator = M2Quads_DummyOp;
   17514      1928561 :   NoOfQuads -= 1;
   17515      1928561 : }
   17516              : 
   17517              : 
   17518              : /*
   17519              :    EraseQuad - erases a quadruple QuadNo, the quadruple is still in the list
   17520              :                but wiped clean.
   17521              : */
   17522              : 
   17523      6411484 : extern "C" void M2Quads_EraseQuad (unsigned int QuadNo)
   17524              : {
   17525      6411484 :   M2Quads_QuadFrame f;
   17526              : 
   17527      6411484 :   CheckBreak (QuadNo);
   17528      6411484 :   f = GetQF (QuadNo);
   17529      6411484 :   UndoReadWriteInfo (QuadNo, f->Operator, f->Operand1, f->Operand2, f->Operand3);
   17530      6411484 :   f->Operator = M2Quads_DummyOp;  /* finally blank it out  */
   17531      6411484 :   f->Operand1 = 0;  /* finally blank it out  */
   17532      6411484 :   f->Operand2 = 0;
   17533      6411484 :   f->Operand3 = 0;
   17534      6411484 :   f->Trash = 0;
   17535      6411484 :   f->op1pos = M2LexBuf_UnknownTokenNo;
   17536      6411484 :   f->op2pos = M2LexBuf_UnknownTokenNo;
   17537      6411484 :   f->op3pos = M2LexBuf_UnknownTokenNo;
   17538      6411484 :   f->ConstExpr = false;
   17539      6411484 : }
   17540              : 
   17541              : 
   17542              : /*
   17543              :    CountQuads - returns the number of quadruples.
   17544              : */
   17545              : 
   17546      9219529 : extern "C" unsigned int M2Quads_CountQuads (void)
   17547              : {
   17548      9219529 :   return NoOfQuads;
   17549              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17550              :   __builtin_unreachable ();
   17551              : }
   17552              : 
   17553              : 
   17554              : /*
   17555              :    BuildScaffold - generate the main, init, finish functions if
   17556              :                    no -c and this is the application module.
   17557              : */
   17558              : 
   17559        15827 : extern "C" void M2Quads_BuildScaffold (unsigned int tok, unsigned int moduleSym)
   17560              : {
   17561        15827 :   if ((SymbolTable_GetMainModule ()) == moduleSym)
   17562              :     {
   17563        15299 :       M2Scaffold_DeclareScaffold (tok);
   17564        15299 :       if (M2Options_ScaffoldMain || ! M2Options_cflag)
   17565              :         {
   17566              :           /* There are module init/fini functions and
   17567              :             application init/fini functions.
   17568              :             Here we create the application pair.  */
   17569         2783 :           BuildM2LinkFunction (tok);
   17570         2783 :           BuildM2MainFunction (tok);
   17571         2783 :           BuildM2InitFunction (tok, moduleSym);  /* Application init.  */
   17572         2783 :           BuildM2FiniFunction (tok, moduleSym);  /* Application fini.  */
   17573              :         }
   17574              :        /* Application fini.  */
   17575        15299 :       BuildM2DepFunction (tok, moduleSym);  /* Per module dependency.  */
   17576              :       /* Each module needs a ctor to register the module
   17577              :          init/finish/dep with M2RTS.  */
   17578        15299 :       BuildM2CtorFunction (tok, moduleSym);
   17579              :     }
   17580          528 :   else if (M2Options_WholeProgram)
   17581              :     {
   17582              :       /* avoid dangling else.  */
   17583          528 :       M2Scaffold_DeclareScaffold (tok);
   17584          528 :       BuildM2DepFunction (tok, moduleSym);  /* Per module dependency.  */
   17585              :       /* Each module needs a ctor to register the module
   17586              :          init/finish/dep with M2RTS.  */
   17587          528 :       BuildM2CtorFunction (tok, moduleSym);
   17588              :     }
   17589        15827 : }
   17590              : 
   17591              : 
   17592              : /*
   17593              :    StartBuildDefFile - generates a StartFileDefOp quadruple indicating the file
   17594              :                        that has produced the subsequent quadruples.
   17595              :                        The code generator uses the StartDefFileOp quadruples
   17596              :                        to relate any error to the appropriate file.
   17597              : 
   17598              : 
   17599              :                        Entry                   Exit
   17600              :                        =====                   ====
   17601              : 
   17602              : 
   17603              :                 Ptr ->                                        <- Ptr
   17604              :                        +------------+          +------------+
   17605              :                        | ModuleName |          | ModuleName |
   17606              :                        |------------|          |------------|
   17607              : 
   17608              : 
   17609              :                        Quadruples Produced
   17610              : 
   17611              :                        q     StartDefFileOp  _  _  ModuleSym
   17612              : */
   17613              : 
   17614       165950 : extern "C" void M2Quads_StartBuildDefFile (unsigned int tok)
   17615              : {
   17616       165950 :   NameKey_Name ModuleName;
   17617              : 
   17618       165950 :   M2Quads_PopT (&ModuleName);
   17619       165950 :   M2Quads_PushT (ModuleName);
   17620       165950 :   GenQuadO (tok, M2Quads_StartDefFileOp, tok, SymbolTable_NulSym, SymbolTable_GetModule (ModuleName), false);
   17621       165950 : }
   17622              : 
   17623              : 
   17624              : /*
   17625              :    StartBuildModFile - generates a StartModFileOp quadruple indicating the file
   17626              :                        that has produced the subsequent quadruples.
   17627              :                        The code generator uses the StartModFileOp quadruples
   17628              :                        to relate any error to the appropriate file.
   17629              : 
   17630              : 
   17631              :                        Entry                   Exit
   17632              :                        =====                   ====
   17633              : 
   17634              : 
   17635              :                 Ptr ->                                        <- Ptr
   17636              :                        +------------+          +------------+
   17637              :                        | ModuleName |          | ModuleName |
   17638              :                        |------------|          |------------|
   17639              : 
   17640              : 
   17641              :                        Quadruples Produced
   17642              : 
   17643              :                        q     StartModFileOp  lineno  filename  ModuleSym
   17644              : */
   17645              : 
   17646        84473 : extern "C" void M2Quads_StartBuildModFile (unsigned int tok)
   17647              : {
   17648        84473 :   GenQuadO (tok, M2Quads_StartModFileOp, tok, (unsigned int ) (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()))), SymbolTable_GetFileModule (), false);
   17649        84473 : }
   17650              : 
   17651              : 
   17652              : /*
   17653              :    EndBuildFile - generates an EndFileOp quadruple indicating the file
   17654              :                   that has produced the previous quadruples has ended.
   17655              : 
   17656              :                   Entry                   Exit
   17657              :                   =====                   ====
   17658              : 
   17659              : 
   17660              :            Ptr ->                                        <- Ptr
   17661              :                   +------------+          +------------+
   17662              :                   | ModuleName |          | ModuleName |
   17663              :                   |------------|          |------------|
   17664              : 
   17665              : 
   17666              :                   Quadruples Produced
   17667              : 
   17668              :                   q     EndFileOp  _  _  ModuleSym
   17669              : */
   17670              : 
   17671       250209 : extern "C" void M2Quads_EndBuildFile (unsigned int tok)
   17672              : {
   17673       250209 :   NameKey_Name ModuleName;
   17674              : 
   17675       250209 :   ModuleName = static_cast<NameKey_Name> (M2Quads_OperandT (1));
   17676       250209 :   GenQuadO (tok, M2Quads_EndFileOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_GetModule (ModuleName), false);
   17677       250209 : }
   17678              : 
   17679              : 
   17680              : /*
   17681              :    StartBuildInit - Sets the start of initialization code of the
   17682              :                     current module to the next quadruple.
   17683              : */
   17684              : 
   17685        84839 : extern "C" void M2Quads_StartBuildInit (unsigned int tok)
   17686              : {
   17687        84839 :   NameKey_Name name;
   17688        84839 :   unsigned int ModuleSym;
   17689              : 
   17690        84839 :   M2Quads_PopT (&name);
   17691        84839 :   ModuleSym = SymbolTable_GetCurrentModule ();
   17692       169678 :   M2Debug_Assert ((SymbolTable_IsModule (ModuleSym)) || (SymbolTable_IsDefImp (ModuleSym)));
   17693        84839 :   M2Debug_Assert ((SymbolTable_GetSymName (ModuleSym)) == name);
   17694        84833 :   SymbolTable_PutModuleStartQuad (ModuleSym, NextQuad);
   17695        84833 :   GenQuad (M2Quads_InitStartOp, tok, SymbolTable_GetFileModule (), ModuleSym);
   17696        84833 :   M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
   17697        84833 :   M2Quads_PushT (name);
   17698        84833 :   CheckVariablesAt (ModuleSym);
   17699        84833 :   CheckNeedPriorityBegin (tok, ModuleSym, ModuleSym);
   17700        84833 :   M2StackWord_PushWord (TryStack, NextQuad);
   17701        84833 :   M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
   17702        84833 :   if (SymbolTable_HasExceptionBlock (ModuleSym))
   17703              :     {
   17704           54 :       GenQuad (M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
   17705              :     }
   17706        84833 : }
   17707              : 
   17708              : 
   17709              : /*
   17710              :    EndBuildInit - Sets the end initialization code of a module.
   17711              : */
   17712              : 
   17713        84685 : extern "C" void M2Quads_EndBuildInit (unsigned int tok)
   17714              : {
   17715        84685 :   if (SymbolTable_HasExceptionBlock (SymbolTable_GetCurrentModule ()))
   17716              :     {
   17717           54 :       BuildRTExceptLeave (tok, true);
   17718           54 :       GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
   17719              :     }
   17720        84685 :   BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
   17721        84685 :   CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
   17722        84685 :   SymbolTable_PutModuleEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
   17723        84685 :   CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
   17724        84685 :   GenQuadO (tok, M2Quads_InitEndOp, tok, SymbolTable_GetFileModule (), SymbolTable_GetCurrentModule (), false);
   17725        84685 : }
   17726              : 
   17727              : 
   17728              : /*
   17729              :    StartBuildFinally - Sets the start of finalization code of the
   17730              :                        current module to the next quadruple.
   17731              : */
   17732              : 
   17733        16039 : extern "C" void M2Quads_StartBuildFinally (unsigned int tok)
   17734              : {
   17735        16039 :   NameKey_Name name;
   17736        16039 :   unsigned int ModuleSym;
   17737              : 
   17738        16039 :   M2Quads_PopT (&name);
   17739        16033 :   ModuleSym = SymbolTable_GetCurrentModule ();
   17740        32066 :   M2Debug_Assert ((SymbolTable_IsModule (ModuleSym)) || (SymbolTable_IsDefImp (ModuleSym)));
   17741        16033 :   M2Debug_Assert ((SymbolTable_GetSymName (ModuleSym)) == name);
   17742        16033 :   SymbolTable_PutModuleFinallyStartQuad (ModuleSym, NextQuad);
   17743        16033 :   GenQuadO (tok, M2Quads_FinallyStartOp, tok, SymbolTable_GetFileModule (), ModuleSym, false);
   17744        16033 :   M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
   17745        16033 :   M2Quads_PushT (name);
   17746              :   /* CheckVariablesAt(ModuleSym) ;  */
   17747        16033 :   CheckNeedPriorityBegin (tok, ModuleSym, ModuleSym);
   17748        16033 :   M2StackWord_PushWord (TryStack, NextQuad);
   17749        16033 :   M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
   17750        16033 :   if (SymbolTable_HasExceptionFinally (ModuleSym))
   17751              :     {
   17752            0 :       GenQuadO (tok, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
   17753              :     }
   17754        16033 : }
   17755              : 
   17756              : 
   17757              : /*
   17758              :    EndBuildFinally - Sets the end finalization code of a module.
   17759              : */
   17760              : 
   17761        16033 : extern "C" void M2Quads_EndBuildFinally (unsigned int tok)
   17762              : {
   17763        16033 :   if (SymbolTable_HasExceptionFinally (SymbolTable_GetCurrentModule ()))
   17764              :     {
   17765            0 :       BuildRTExceptLeave (tok, true);
   17766            0 :       GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
   17767              :     }
   17768        16033 :   BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
   17769        16033 :   CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
   17770        16033 :   SymbolTable_PutModuleFinallyEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
   17771        16033 :   CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
   17772        16033 :   GenQuadO (tok, M2Quads_FinallyEndOp, tok, SymbolTable_GetFileModule (), SymbolTable_GetCurrentModule (), false);
   17773        16033 : }
   17774              : 
   17775              : 
   17776              : /*
   17777              :    BuildExceptInitial - adds an CatchBeginOp, CatchEndOp quadruple
   17778              :                         in the current block.
   17779              : */
   17780              : 
   17781         2969 : extern "C" void M2Quads_BuildExceptInitial (unsigned int tok)
   17782              : {
   17783         2969 :   unsigned int previous;
   17784              : 
   17785              :   /* we have finished the 'try' block, so now goto the return
   17786              :       section which will tidy up (any) priorities before returning.
   17787              :   */
   17788         2969 :   GenQuadO (tok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PopWord (ReturnStack), false);
   17789         2969 :   M2StackWord_PushWord (ReturnStack, NextQuad-1);
   17790              :   /* 
   17791              :       this is the 'catch' block.
   17792              :   */
   17793         2969 :   BackPatch (M2StackWord_PeepWord (TryStack, 1), NextQuad);
   17794         2969 :   GenQuadO (tok, M2Quads_CatchBeginOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
   17795         2969 :   previous = static_cast<unsigned int> (M2StackWord_PopWord (CatchStack));
   17796         2969 :   if (previous != 0)
   17797              :     {
   17798            0 :       M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}only allowed one EXCEPT statement in a procedure or module", 62);
   17799              :     }
   17800         2969 :   M2StackWord_PushWord (CatchStack, NextQuad-1);
   17801         2969 :   BuildRTExceptEnter (tok);
   17802         2969 : }
   17803              : 
   17804              : 
   17805              : /*
   17806              :    BuildExceptFinally - adds an ExceptOp quadruple in a modules
   17807              :                         finally block.
   17808              : */
   17809              : 
   17810            0 : extern "C" void M2Quads_BuildExceptFinally (unsigned int tok)
   17811              : {
   17812            0 :   M2Quads_BuildExceptInitial (tok);
   17813            0 : }
   17814              : 
   17815              : 
   17816              : /*
   17817              :    BuildExceptProcedure - adds an ExceptOp quadruple in a procedure
   17818              :                           block.
   17819              : */
   17820              : 
   17821          168 : extern "C" void M2Quads_BuildExceptProcedure (unsigned int tok)
   17822              : {
   17823          168 :   M2Quads_BuildExceptInitial (tok);
   17824          168 : }
   17825              : 
   17826              : 
   17827              : /*
   17828              :    BuildRetry - adds an RetryOp quadruple.
   17829              : */
   17830              : 
   17831          168 : extern "C" void M2Quads_BuildRetry (unsigned int tok)
   17832              : {
   17833          168 :   if ((M2StackWord_PeepWord (CatchStack, 1)) == 0)
   17834              :     {
   17835            6 :       M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}the {%kRETRY} statement must occur after an {%kEXCEPT} statement in the same module or procedure block", 106);
   17836              :     }
   17837              :   else
   17838              :     {
   17839          162 :       BuildRTExceptLeave (tok, false);
   17840          162 :       GenQuadO (tok, M2Quads_RetryOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PeepWord (TryStack, 1), false);
   17841              :     }
   17842          168 : }
   17843              : 
   17844              : 
   17845              : /*
   17846              :    BuildReThrow - creates a ThrowOp _ _ NulSym, indicating that
   17847              :                   the exception needs to be rethrown.  The stack
   17848              :                   is unaltered.
   17849              : */
   17850              : 
   17851          222 : extern "C" void M2Quads_BuildReThrow (unsigned int tokenno)
   17852              : {
   17853          222 :   GenQuadO (tokenno, M2Quads_ThrowOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
   17854          222 : }
   17855              : 
   17856              : 
   17857              : /*
   17858              :    StartBuildInnerInit - Sets the start of initialization code of the
   17859              :                          inner module to the next quadruple.
   17860              : */
   17861              : 
   17862            0 : extern "C" void M2Quads_StartBuildInnerInit (unsigned int tok)
   17863              : {
   17864            0 :   SymbolTable_PutModuleStartQuad (SymbolTable_GetCurrentModule (), NextQuad);
   17865            0 :   GenQuadO (tok, M2Quads_InitStartOp, tok, SymbolTable_NulSym, SymbolTable_GetCurrentModule (), false);
   17866            0 :   M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
   17867            0 :   CheckNeedPriorityBegin (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
   17868            0 :   M2StackWord_PushWord (TryStack, NextQuad);
   17869            0 :   M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
   17870            0 :   if (SymbolTable_HasExceptionFinally (SymbolTable_GetCurrentModule ()))
   17871              :     {
   17872            0 :       GenQuadO (tok, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
   17873              :     }
   17874            0 : }
   17875              : 
   17876              : 
   17877              : /*
   17878              :    EndBuildInnerInit - Sets the end initialization code of a module.
   17879              : */
   17880              : 
   17881            0 : extern "C" void M2Quads_EndBuildInnerInit (unsigned int tok)
   17882              : {
   17883            0 :   if (SymbolTable_HasExceptionBlock (SymbolTable_GetCurrentModule ()))
   17884              :     {
   17885            0 :       BuildRTExceptLeave (tok, true);
   17886            0 :       GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
   17887              :     }
   17888            0 :   SymbolTable_PutModuleEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
   17889            0 :   CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
   17890            0 :   BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
   17891            0 :   CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
   17892            0 :   GenQuadO (tok, M2Quads_InitEndOp, tok, SymbolTable_NulSym, SymbolTable_GetCurrentModule (), false);
   17893            0 : }
   17894              : 
   17895              : 
   17896              : /*
   17897              :    BuildBuiltinConst - makes reference to a builtin constant within gm2.
   17898              : 
   17899              :                               Entry                 Exit
   17900              : 
   17901              :                        Ptr ->
   17902              :                               +------------+        +------------+
   17903              :                               | Ident      |        | Sym        |
   17904              :                               |------------|        |------------|
   17905              : 
   17906              :                        Quadruple produced:
   17907              : 
   17908              :                        q    Sym  BuiltinConstOp  Ident
   17909              : */
   17910              : 
   17911        30174 : extern "C" void M2Quads_BuildBuiltinConst (void)
   17912              : {
   17913        30174 :   unsigned int idtok;
   17914        30174 :   unsigned int Id;
   17915        30174 :   unsigned int Sym;
   17916              : 
   17917        30174 :   M2Quads_PopTtok (&Id, &idtok);
   17918        30174 :   Sym = SymbolTable_MakeTemporary (idtok, SymbolTable_ImmediateValue);
   17919        30174 :   SymbolTable_PutVar (Sym, M2Base_Integer);
   17920              :   /* 
   17921              :    CASE GetBuiltinConstType(KeyToCharStar(Name(Id))) OF
   17922              : 
   17923              :    0:  ErrorFormat1(NewError(GetTokenNo()),
   17924              :                     '%a unrecognised builtin constant', Id) |
   17925              :    1:  PutVar(Sym, Integer) |
   17926              :    2:  PutVar(Sym, Real)
   17927              : 
   17928              :    ELSE
   17929              :       InternalError ('unrecognised value')
   17930              :    END ;
   17931              :   */
   17932        30174 :   GenQuadO (idtok, M2Quads_BuiltinConstOp, Sym, SymbolTable_NulSym, Id, false);
   17933        30174 :   M2Quads_PushTtok (Sym, idtok);
   17934        30174 : }
   17935              : 
   17936              : 
   17937              : /*
   17938              :    BuildBuiltinTypeInfo - make reference to a builtin typeinfo function
   17939              :                           within gm2.
   17940              : 
   17941              :                                  Entry                 Exit
   17942              : 
   17943              :                           Ptr ->
   17944              :                                  +-------------+
   17945              :                                  | Type        |
   17946              :                                  |-------------|       +------------+
   17947              :                                  | Ident       |       | Sym        |
   17948              :                                  |-------------|       |------------|
   17949              : 
   17950              :                           Quadruple produced:
   17951              : 
   17952              :                           q    Sym  BuiltinTypeInfoOp  Type Ident
   17953              : */
   17954              : 
   17955          360 : extern "C" void M2Quads_BuildBuiltinTypeInfo (void)
   17956              : {
   17957          360 :   unsigned int idtok;
   17958          360 :   unsigned int Ident;
   17959          360 :   unsigned int Type;
   17960          360 :   unsigned int Sym;
   17961              : 
   17962          360 :   M2Quads_PopTtok (&Ident, &idtok);
   17963          360 :   M2Quads_PopT (&Type);
   17964          360 :   Sym = SymbolTable_MakeTemporary (M2LexBuf_BuiltinTokenNo, SymbolTable_ImmediateValue);
   17965          360 :   switch (m2builtins_GetBuiltinTypeInfoType (const_cast <const char * > (static_cast <char * > (NameKey_KeyToCharStar ((NameKey_Name) (Ident))))))
   17966              :     {
   17967            0 :       case 0:
   17968            0 :         M2Error_ErrorFormat1 (M2Error_NewError (idtok), (const char *) "%a unrecognised builtin constant", 32, (const unsigned char *) &Ident, (sizeof (Ident)-1));
   17969            0 :         break;
   17970              : 
   17971          192 :       case 1:
   17972          192 :         SymbolTable_PutVar (Sym, M2Base_Boolean);
   17973          192 :         break;
   17974              : 
   17975          120 :       case 2:
   17976          120 :         SymbolTable_PutVar (Sym, M2Base_ZType);
   17977          120 :         break;
   17978              : 
   17979           48 :       case 3:
   17980           48 :         SymbolTable_PutVar (Sym, M2Base_RType);
   17981           48 :         break;
   17982              : 
   17983              : 
   17984            0 :       default:
   17985            0 :         M2Error_InternalError ((const char *) "unrecognised value", 18);
   17986          360 :         break;
   17987              :     }
   17988          360 :   GenQuadO (idtok, M2Quads_BuiltinTypeInfoOp, Sym, Type, Ident, false);
   17989          360 :   M2Quads_PushTtok (Sym, idtok);
   17990          360 : }
   17991              : 
   17992              : 
   17993              : /*
   17994              :    BuildAssignment - Builds an assignment from the values given on the
   17995              :                      quad stack. Either an assignment to an
   17996              :                      arithmetic expression or an assignment to a
   17997              :                      boolean expression.  This procedure should not
   17998              :                      be called in CONST declarations.
   17999              :                      The Stack is expected to contain:
   18000              : 
   18001              : 
   18002              :        Either
   18003              : 
   18004              :                      Entry                   Exit
   18005              :                      =====                   ====
   18006              : 
   18007              :               Ptr ->
   18008              :                      +------------+
   18009              :                      | Expression |
   18010              :                      |------------|
   18011              :                      | Designator |
   18012              :                      |------------|          +------------+
   18013              :                      |            |          |            |  <- Ptr
   18014              :                      |------------|          |------------|
   18015              : 
   18016              : 
   18017              :                      Quadruples Produced
   18018              : 
   18019              :                      q     BecomesOp  Designator  _  Expression
   18020              : 
   18021              :        OR
   18022              : 
   18023              :                      Entry                   Exit
   18024              :                      =====                   ====
   18025              : 
   18026              :               Ptr ->
   18027              :                      +------------+
   18028              :                      | True |False|
   18029              :                      |------------|
   18030              :                      | Designator |
   18031              :                      |------------|          +------------+
   18032              :                      |            |          |            |  <- Ptr
   18033              :                      |------------|          |------------|
   18034              : 
   18035              : 
   18036              :                      Quadruples Produced
   18037              : 
   18038              :                      q     BecomesOp  Designator  _  TRUE
   18039              :                      q+1   GotoOp                    q+3
   18040              :                      q+2   BecomesOp  Designator  _  FALSE
   18041              : 
   18042              : */
   18043              : 
   18044       128200 : extern "C" void M2Quads_BuildAssignment (unsigned int becomesTokNo)
   18045              : {
   18046       128200 :   unsigned int des;
   18047       128200 :   unsigned int exp;
   18048       128200 :   unsigned int destok;
   18049       128200 :   unsigned int exptok;
   18050       128200 :   unsigned int combinedtok;
   18051              : 
   18052       128200 :   des = static_cast<unsigned int> (M2Quads_OperandT (2));
   18053       128200 :   if (IsReadOnly (des))
   18054              :     {
   18055           36 :       destok = static_cast<unsigned int> (M2Quads_OperandTok (2));
   18056           36 :       exptok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   18057           36 :       exp = static_cast<unsigned int> (M2Quads_OperandT (1));
   18058           36 :       if (DebugTokPos)
   18059              :         {
   18060              :           M2MetaError_MetaErrorT1 (destok, (const char *) "destok {%1Ead}", 14, des);
   18061              :           M2MetaError_MetaErrorT1 (exptok, (const char *) "exptok {%1Ead}", 14, exp);
   18062              :         }
   18063           36 :       combinedtok = M2LexBuf_MakeVirtualTok (becomesTokNo, destok, exptok);
   18064           36 :       if (DebugTokPos)
   18065              :         {
   18066              :           M2MetaError_MetaErrorT1 (combinedtok, (const char *) "combined {%1Ead}", 16, des);
   18067              :         }
   18068           36 :       if (IsBoolean (1))
   18069              :         {
   18070            0 :           M2MetaError_MetaErrorT1 (combinedtok, (const char *) "cannot assign expression to a constant designator {%1Ead}", 57, des);
   18071              :         }
   18072              :       else
   18073              :         {
   18074           36 :           exp = static_cast<unsigned int> (M2Quads_OperandT (1));
   18075           36 :           M2MetaError_MetaErrorT2 (combinedtok, (const char *) "cannot assign a constant designator {%1Ead} with an expression {%2Ead}", 70, des, exp);
   18076              :         }
   18077           36 :       M2Quads_PopN (2);  /* Remove both parameters.  */
   18078              :     }
   18079       128164 :   else if (SymbolTable_IsError (des))
   18080              :     {
   18081              :       /* avoid dangling else.  */
   18082           25 :       M2Quads_PopN (2);  /* Remove both parameters.  */
   18083              :     }
   18084              :   else
   18085              :     {
   18086              :       /* avoid dangling else.  */
   18087       128139 :       doBuildAssignment (becomesTokNo, true, true);
   18088              :     }
   18089       128194 : }
   18090              : 
   18091              : 
   18092              : /*
   18093              :    BuildAssignConstant - used to create constant in the CONST declaration.
   18094              :                          The stack is expected to contain:
   18095              : 
   18096              :        Either
   18097              : 
   18098              :                      Entry                   Exit
   18099              :                      =====                   ====
   18100              : 
   18101              :               Ptr ->
   18102              :                      +------------+
   18103              :                      | Expression |
   18104              :                      |------------|
   18105              :                      | Designator |
   18106              :                      |------------|          +------------+
   18107              :                      |            |          |            |  <- Ptr
   18108              :                      |------------|          |------------|
   18109              : 
   18110              : 
   18111              :                      Quadruples Produced
   18112              : 
   18113              :                      q     BecomesOp  Designator  _  Expression
   18114              : 
   18115              :        OR
   18116              : 
   18117              :                      Entry                   Exit
   18118              :                      =====                   ====
   18119              : 
   18120              :               Ptr ->
   18121              :                      +------------+
   18122              :                      | True |False|
   18123              :                      |------------|
   18124              :                      | Designator |
   18125              :                      |------------|          +------------+
   18126              :                      |            |          |            |  <- Ptr
   18127              :                      |------------|          |------------|
   18128              : 
   18129              : 
   18130              :                      Quadruples Produced
   18131              : 
   18132              :                      q     BecomesOp  Designator  _  TRUE
   18133              :                      q+1   GotoOp                    q+3
   18134              :                      q+2   BecomesOp  Designator  _  FALSE
   18135              : */
   18136              : 
   18137       300431 : extern "C" void M2Quads_BuildAssignConstant (unsigned int equalsTokNo)
   18138              : {
   18139       300431 :   doBuildAssignment (equalsTokNo, true, true);
   18140       300431 : }
   18141              : 
   18142              : 
   18143              : /*
   18144              :    BuildAlignment - builds an assignment to an alignment constant.
   18145              : 
   18146              :                     The Stack is expected to contain:
   18147              : 
   18148              : 
   18149              :                             Entry                   Exit
   18150              :                             =====                   ====
   18151              : 
   18152              :                     Ptr ->
   18153              :                             +---------------+
   18154              :                             | Expression    |
   18155              :                             |---------------|
   18156              :                             | bytealignment |
   18157              :                             |---------------|       empty
   18158              : */
   18159              : 
   18160           72 : extern "C" void M2Quads_BuildAlignment (unsigned int tokno)
   18161              : {
   18162           72 :   NameKey_Name name;
   18163           72 :   unsigned int expr;
   18164           72 :   unsigned int align;
   18165              : 
   18166           72 :   M2Quads_PopT (&expr);
   18167           72 :   M2Quads_PopT (&name);
   18168           72 :   if (name != (NameKey_MakeKey ((const char *) "bytealignment", 13)))
   18169              :     {
   18170            0 :       M2MetaError_MetaError1 ((const char *) "expecting bytealignment identifier, rather than {%1Ea}", 54, SymbolTable_MakeError (tokno, name));
   18171              :     }
   18172           72 :   FifoQueue_GetConstFromFifoQueue (&align);
   18173           72 :   M2Quads_PushT (align);
   18174           72 :   M2Quads_PushT (expr);
   18175           72 :   M2Quads_BuildAssignConstant (tokno);
   18176           72 : }
   18177              : 
   18178              : 
   18179              : /*
   18180              :    BuildBitLength - builds an assignment to a bit length constant.
   18181              : 
   18182              :                     The Stack is expected to contain:
   18183              : 
   18184              : 
   18185              :                            Entry                   Exit
   18186              :                            =====                   ====
   18187              : 
   18188              :                     Ptr ->
   18189              :                            +------------+
   18190              :                            | Expression |
   18191              :                            |------------|          empty
   18192              : */
   18193              : 
   18194            0 : extern "C" void M2Quads_BuildBitLength (unsigned int tokno)
   18195              : {
   18196            0 :   unsigned int expr;
   18197            0 :   unsigned int length;
   18198              : 
   18199            0 :   M2Quads_PopT (&expr);
   18200            0 :   FifoQueue_GetConstFromFifoQueue (&length);
   18201            0 :   M2Quads_PushT (length);
   18202            0 :   M2Quads_PushT (expr);
   18203            0 :   M2Quads_BuildAssignConstant (tokno);
   18204            0 : }
   18205              : 
   18206              : 
   18207              : /*
   18208              :    BuildPragmaField - builds an assignment to an alignment constant.
   18209              : 
   18210              :                       The Stack is expected to contain:
   18211              : 
   18212              : 
   18213              :                       Entry                   Exit
   18214              :                       =====                   ====
   18215              : 
   18216              :                Ptr ->
   18217              :                       +------------+
   18218              :                       | Expression |
   18219              :                       |------------|          empty
   18220              : */
   18221              : 
   18222           12 : extern "C" void M2Quads_BuildPragmaField (void)
   18223              : {
   18224           12 :   unsigned int expr;
   18225           12 :   unsigned int const_;
   18226           12 :   NameKey_Name name;
   18227              : 
   18228           12 :   M2Quads_PopT (&expr);
   18229           12 :   M2Quads_PopT (&name);
   18230           12 :   if ((name != (NameKey_MakeKey ((const char *) "unused", 6))) && (name != (NameKey_MakeKey ((const char *) "bytealignment", 13))))
   18231              :     {
   18232            0 :       M2MetaError_MetaError0 ((const char *) "only allowed to use the attribute {%Ekbytealignment} in the default record field alignment pragma", 97);
   18233              :     }
   18234           12 :   if (expr != SymbolTable_NulSym)
   18235              :     {
   18236           12 :       FifoQueue_GetConstFromFifoQueue (&const_);
   18237           12 :       M2Quads_PushT (const_);
   18238           12 :       M2Quads_PushT (expr);
   18239           12 :       M2Quads_BuildAssignConstant (M2LexBuf_GetTokenNo ());
   18240              :     }
   18241           12 : }
   18242              : 
   18243              : 
   18244              : /*
   18245              :    BuildDefaultFieldAlignment - builds an assignment to an alignment constant.
   18246              : 
   18247              :                                 The Stack is expected to contain:
   18248              : 
   18249              : 
   18250              :                                        Entry                   Exit
   18251              :                                        =====                   ====
   18252              : 
   18253              :                                 Ptr ->
   18254              :                                        +------------+
   18255              :                                        | Expression |
   18256              :                                        |------------|          empty
   18257              : */
   18258              : 
   18259           36 : extern "C" void M2Quads_BuildDefaultFieldAlignment (void)
   18260              : {
   18261           36 :   unsigned int expr;
   18262           36 :   unsigned int align;
   18263           36 :   NameKey_Name name;
   18264              : 
   18265           36 :   M2Quads_PopT (&expr);
   18266           36 :   M2Quads_PopT (&name);
   18267           36 :   if (name != (NameKey_MakeKey ((const char *) "bytealignment", 13)))
   18268              :     {
   18269            0 :       M2MetaError_MetaError0 ((const char *) "{%E}only allowed to use the attribute {%kbytealignment} in the default record field alignment pragma", 100);
   18270              :     }
   18271           36 :   FifoQueue_GetConstFromFifoQueue (&align);
   18272           36 :   M2Quads_PushT (align);
   18273           36 :   M2Quads_PushT (expr);
   18274           36 :   M2Quads_BuildAssignConstant (M2LexBuf_GetTokenNo ());
   18275           36 : }
   18276              : 
   18277              : 
   18278              : /*
   18279              :    BuildRepeat - Builds the repeat statement from the quad stack.
   18280              :                  The Stack is expected to contain:
   18281              : 
   18282              : 
   18283              :                  Entry                   Exit
   18284              :                  =====                   ====
   18285              : 
   18286              : 
   18287              :                  Empty
   18288              :                                                         <- Ptr
   18289              :                                          +------------+
   18290              :                                          | RepeatQuad |
   18291              :                                          |------------|
   18292              : 
   18293              : */
   18294              : 
   18295         1422 : extern "C" void M2Quads_BuildRepeat (void)
   18296              : {
   18297         1422 :   M2Quads_PushT (NextQuad);
   18298         1422 : }
   18299              : 
   18300              : 
   18301              : /*
   18302              :    BuildUntil - Builds the until part of the repeat statement
   18303              :                 from the quad stack.
   18304              :                 The Stack is expected to contain:
   18305              : 
   18306              : 
   18307              :                 Entry                   Exit
   18308              :                 =====                   ====
   18309              : 
   18310              :         Ptr ->
   18311              :                 +------------+
   18312              :                 | t   | f    |
   18313              :                 |------------|
   18314              :                 | RepeatQuad |          Empty
   18315              :                 |------------|
   18316              : */
   18317              : 
   18318         1422 : extern "C" void M2Quads_BuildUntil (void)
   18319              : {
   18320         1422 :   unsigned int t;
   18321         1422 :   unsigned int f;
   18322         1422 :   unsigned int Repeat;
   18323              : 
   18324         1422 :   CheckBooleanId ();
   18325         1422 :   PopBool (&t, &f);
   18326         1422 :   M2Quads_PopT (&Repeat);
   18327         1422 :   BackPatch (f, Repeat);  /* If False then keep on repeating  */
   18328         1422 :   BackPatch (t, NextQuad);  /* If True then exit repeat  */
   18329         1422 : }
   18330              : 
   18331              : 
   18332              : /*
   18333              :    BuildWhile - Builds the While part of the While statement
   18334              :                 from the quad stack.
   18335              :                 The Stack is expected to contain:
   18336              : 
   18337              : 
   18338              :                 Entry                   Exit
   18339              :                 =====                   ====
   18340              : 
   18341              :                                                        <- Ptr
   18342              :                                         |------------|
   18343              :                 Empty                   | WhileQuad  |
   18344              :                                         |------------|
   18345              : */
   18346              : 
   18347         7870 : extern "C" void M2Quads_BuildWhile (void)
   18348              : {
   18349         7870 :   M2Quads_PushT (NextQuad);
   18350         7870 : }
   18351              : 
   18352              : 
   18353              : /*
   18354              :    BuildDoWhile - Builds the Do part of the while statement
   18355              :                   from the quad stack.
   18356              :                   The Stack is expected to contain:
   18357              : 
   18358              : 
   18359              :                   Entry                   Exit
   18360              :                   =====                   ====
   18361              : 
   18362              :           Ptr ->
   18363              :                   +------------+          +------------+
   18364              :                   | t   | f    |          | 0    | f   |
   18365              :                   |------------|          |------------|
   18366              :                   | WhileQuad  |          | WhileQuad  |
   18367              :                   |------------|          |------------|
   18368              : 
   18369              :                   Quadruples
   18370              : 
   18371              :                   BackPatch t exit to the NextQuad
   18372              : */
   18373              : 
   18374         7870 : extern "C" void M2Quads_BuildDoWhile (void)
   18375              : {
   18376         7870 :   unsigned int t;
   18377         7870 :   unsigned int f;
   18378              : 
   18379         7870 :   CheckBooleanId ();
   18380         7870 :   PopBool (&t, &f);
   18381         7870 :   BackPatch (t, NextQuad);
   18382         7870 :   PushBool (0, f);
   18383         7870 : }
   18384              : 
   18385              : 
   18386              : /*
   18387              :    BuildEndWhile - Builds the end part of the while statement
   18388              :                    from the quad stack.
   18389              :                    The Stack is expected to contain:
   18390              : 
   18391              : 
   18392              :                    Entry                   Exit
   18393              :                    =====                   ====
   18394              : 
   18395              :            Ptr ->
   18396              :                    +------------+
   18397              :                    | t   | f    |
   18398              :                    |------------|
   18399              :                    | WhileQuad  |          Empty
   18400              :                    |------------|
   18401              : 
   18402              :                    Quadruples
   18403              : 
   18404              :                    q    GotoOp  WhileQuad
   18405              :                    False exit is backpatched with q+1
   18406              : */
   18407              : 
   18408         7870 : extern "C" void M2Quads_BuildEndWhile (int reltokpos)
   18409              : {
   18410         7870 :   unsigned int tok;
   18411         7870 :   unsigned int While;
   18412         7870 :   unsigned int t;
   18413         7870 :   unsigned int f;
   18414              : 
   18415         7870 :   tok = M2LexBuf_GetTokenNo ();
   18416         7870 :   tok = ((int ) (tok))+reltokpos;
   18417         7870 :   PopBool (&t, &f);
   18418         7870 :   M2Debug_Assert (t == 0);
   18419         7870 :   M2Quads_PopT (&While);
   18420         7870 :   GenQuadO (tok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, While, false);
   18421         7870 :   BackPatch (f, NextQuad);
   18422         7870 : }
   18423              : 
   18424              : 
   18425              : /*
   18426              :    BuildLoop - Builds the Loop part of the Loop statement
   18427              :                from the quad stack.
   18428              :                The Stack is expected to contain:
   18429              : 
   18430              : 
   18431              :                Entry                   Exit
   18432              :                =====                   ====
   18433              : 
   18434              :                                                       <- Ptr
   18435              :                Empty                   +------------+
   18436              :                                        | LoopQuad   |
   18437              :                                        |------------|
   18438              : */
   18439              : 
   18440          516 : extern "C" void M2Quads_BuildLoop (void)
   18441              : {
   18442          516 :   M2Quads_PushT (NextQuad);
   18443          516 :   PushExit (0);  /* Seperate Exit Stack for loop end  */
   18444          516 : }
   18445              : 
   18446              : 
   18447              : /*
   18448              :    BuildExit - Builds the Exit part of the Loop statement.
   18449              : */
   18450              : 
   18451           94 : extern "C" void M2Quads_BuildExit (void)
   18452              : {
   18453           94 :   if (M2StackWord_IsEmptyWord (ExitStack))
   18454              :     {
   18455            0 :       M2MetaError_MetaError0 ((const char *) "{%EkEXIT} is only allowed in a {%kLOOP} statement", 49);
   18456              :     }
   18457              :   else
   18458              :     {
   18459           94 :       GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
   18460           94 :       PushExit (Merge (PopExit (), NextQuad-1));
   18461              :     }
   18462           94 : }
   18463              : 
   18464              : 
   18465              : /*
   18466              :    BuildEndLoop - Builds the End part of the Loop statement
   18467              :                   from the quad stack.
   18468              :                   The Stack is expected to contain:
   18469              : 
   18470              : 
   18471              :                   Entry                   Exit
   18472              :                   =====                   ====
   18473              : 
   18474              :           Ptr ->
   18475              :                   +------------+
   18476              :                   | LoopQuad   |          Empty
   18477              :                   |------------|
   18478              : 
   18479              :                   Quadruples
   18480              : 
   18481              :                   Goto  _  _  LoopQuad
   18482              : */
   18483              : 
   18484          516 : extern "C" void M2Quads_BuildEndLoop (void)
   18485              : {
   18486          516 :   unsigned int Loop;
   18487              : 
   18488          516 :   M2Quads_PopT (&Loop);
   18489          516 :   GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, Loop);
   18490          516 :   BackPatch (PopExit (), NextQuad);
   18491          516 : }
   18492              : 
   18493              : 
   18494              : /*
   18495              :    BuildThenIf - Builds the Then part of the If statement
   18496              :                  from the quad stack.
   18497              :                  The Stack is expected to contain:
   18498              : 
   18499              : 
   18500              :                  Entry                   Exit
   18501              :                  =====                   ====
   18502              : 
   18503              :          Ptr ->                                          <- Ptr
   18504              :                  +------------+          +------------+
   18505              :                  | t   | f    |          | 0    | f   |
   18506              :                  |------------|          |------------|
   18507              : 
   18508              :                  Quadruples
   18509              : 
   18510              :                  The true exit is BackPatched to point to
   18511              :                  the NextQuad.
   18512              : */
   18513              : 
   18514        45164 : extern "C" void M2Quads_BuildThenIf (void)
   18515              : {
   18516        45164 :   unsigned int t;
   18517        45164 :   unsigned int f;
   18518              : 
   18519        45164 :   CheckBooleanId ();
   18520        45164 :   PopBool (&t, &f);
   18521        45164 :   BackPatch (t, NextQuad);
   18522        45164 :   PushBool (0, f);
   18523        45164 : }
   18524              : 
   18525              : 
   18526              : /*
   18527              :    BuildElse - Builds the Else part of the If statement
   18528              :                from the quad stack.
   18529              :                The Stack is expected to contain:
   18530              : 
   18531              : 
   18532              :                Entry                   Exit
   18533              :                =====                   ====
   18534              : 
   18535              :        Ptr ->
   18536              :                +------------+          +------------+
   18537              :                | t   | f    |          | t+q  | 0   |
   18538              :                |------------|          |------------|
   18539              : 
   18540              :                Quadruples
   18541              : 
   18542              :                q    GotoOp  _  _  0
   18543              :                q+1  <- BackPatched from f
   18544              : */
   18545              : 
   18546        15236 : extern "C" void M2Quads_BuildElse (void)
   18547              : {
   18548        15236 :   unsigned int t;
   18549        15236 :   unsigned int f;
   18550              : 
   18551        15236 :   GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
   18552        15236 :   PopBool (&t, &f);
   18553        15236 :   BackPatch (f, NextQuad);
   18554        15236 :   PushBool (Merge (t, NextQuad-1), 0);  /* NextQuad-1 = Goto Quad  */
   18555        15236 : }
   18556              : 
   18557              : 
   18558              : /*
   18559              :    BuildEndIf - Builds the End part of the If statement
   18560              :                 from the quad stack.
   18561              :                 The Stack is expected to contain:
   18562              : 
   18563              : 
   18564              :                 Entry                   Exit
   18565              :                 =====                   ====
   18566              : 
   18567              :         Ptr ->
   18568              :                 +------------+
   18569              :                 | t   | f    |          Empty
   18570              :                 |------------|
   18571              : 
   18572              :                 Quadruples
   18573              : 
   18574              :                 Both t and f are backpatched to point to the NextQuad
   18575              : */
   18576              : 
   18577        41884 : extern "C" void M2Quads_BuildEndIf (void)
   18578              : {
   18579        41884 :   unsigned int t;
   18580        41884 :   unsigned int f;
   18581              : 
   18582        41884 :   PopBool (&t, &f);
   18583        41884 :   BackPatch (t, NextQuad);
   18584        41884 :   BackPatch (f, NextQuad);
   18585        41884 : }
   18586              : 
   18587              : 
   18588              : /*
   18589              :    BuildElsif1 - Builds the Elsif part of the If statement
   18590              :                  from the quad stack.
   18591              :                  The Stack is expected to contain:
   18592              : 
   18593              : 
   18594              :                  Entry                   Exit
   18595              :                  =====                   ====
   18596              : 
   18597              :          Ptr ->
   18598              :                  +------------+          +------------+
   18599              :                  | t   | f    |          | t+q  | 0   |
   18600              :                  |------------|          |------------|
   18601              : 
   18602              :                  Quadruples
   18603              : 
   18604              :                  q    GotoOp  _  _  0
   18605              :                  q+1  <- BackPatched from f
   18606              : */
   18607              : 
   18608         3280 : extern "C" void M2Quads_BuildElsif1 (void)
   18609              : {
   18610         3280 :   unsigned int t;
   18611         3280 :   unsigned int f;
   18612              : 
   18613         3280 :   GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
   18614         3280 :   PopBool (&t, &f);
   18615         3280 :   BackPatch (f, NextQuad);
   18616         3280 :   PushBool (Merge (t, NextQuad-1), 0);  /* NextQuad-1 = Goto Quad  */
   18617         3280 : }
   18618              : 
   18619              : 
   18620              : /*
   18621              :    BuildElsif2 - Builds the Elsif until part of the If statement
   18622              :                  from the quad stack.
   18623              :                  The Stack is expected to contain:
   18624              : 
   18625              : 
   18626              :                  Entry                   Exit
   18627              :                  =====                   ====
   18628              : 
   18629              :           Ptr ->
   18630              :                  +--------------+
   18631              :                  | 0    | f1    |                            <- Ptr
   18632              :                  |--------------|          +---------------+
   18633              :                  | t2   | f2    |          | t2    | f1+f2 |
   18634              :                  |--------------|          |---------------|
   18635              : */
   18636              : 
   18637         3280 : extern "C" void M2Quads_BuildElsif2 (void)
   18638              : {
   18639         3280 :   unsigned int t1;
   18640         3280 :   unsigned int f1;
   18641         3280 :   unsigned int t2;
   18642         3280 :   unsigned int f2;
   18643              : 
   18644         3280 :   PopBool (&t1, &f1);
   18645         3280 :   M2Debug_Assert (t1 == 0);
   18646         3280 :   PopBool (&t2, &f2);
   18647         3280 :   PushBool (t2, Merge (f1, f2));
   18648         3280 : }
   18649              : 
   18650              : 
   18651              : /*
   18652              :    BuildForToByDo - Builds the For To By Do part of the For statement
   18653              :                     from the quad stack.
   18654              :                     The Stack is expected to contain:
   18655              : 
   18656              : 
   18657              :                     Entry                   Exit
   18658              :                     =====                   ====
   18659              : 
   18660              :                                                                <- Ptr
   18661              :                                             +----------------+
   18662              :              Ptr ->                         | RangeId        |
   18663              :                     +----------------+      |----------------|
   18664              :                     | BySym | ByType |      | ForQuad        |
   18665              :                     |----------------|      |----------------|
   18666              :                     | e2             |      | LastValue      |
   18667              :                     |----------------|      |----------------|
   18668              :                     | e1             |      | BySym | ByType |
   18669              :                     |----------------|      |----------------|
   18670              :                     | Ident          |      | IdentSym       |
   18671              :                     |----------------|      |----------------|
   18672              : 
   18673              : 
   18674              :                     x := e1 ;
   18675              :                     Note that LASTVALUE is calculated during M2GenGCC
   18676              :                          after all the types have been resolved.
   18677              :                     LASTVALUE := ((e2-e1) DIV BySym) * BySym + e1
   18678              :                     IF BySym<0
   18679              :                     THEN
   18680              :                        IF e1<e2
   18681              :                        THEN
   18682              :                           goto exit
   18683              :                        END
   18684              :                     ELSE
   18685              :                        IF e1>e2
   18686              :                        THEN
   18687              :                           goto exit
   18688              :                        END
   18689              :                     END ;
   18690              :                     LOOP
   18691              :                        body
   18692              :                        IF x=LASTVALUE
   18693              :                        THEN
   18694              :                           goto exit
   18695              :                        END ;
   18696              :                        INC(x, BySym)
   18697              :                     END
   18698              : 
   18699              :                     Quadruples:
   18700              : 
   18701              :                     q     BecomesOp  IdentSym  _  e1
   18702              :                     q+    LastForIteratorOp  LastValue  := ((e1-e2) DIV by) * by + e1
   18703              :                     q+1   if >=      by        0  q+..2
   18704              :                     q+2   GotoOp                  q+3
   18705              :                     q+3   If >=      e1  e2       q+5
   18706              :                     q+4   GotoOp                  exit
   18707              :                     q+5   ..
   18708              :                     q+..1 Goto                    q+..5
   18709              :                     q+..2 If >=      e2  e1       q+..4
   18710              :                     q+..3 GotoOp                  exit
   18711              :                     q+..4 ..
   18712              : 
   18713              :                     The For Loop is regarded:
   18714              : 
   18715              :                     For ident := e1 To e2 By by Do
   18716              : 
   18717              :                     End
   18718              : */
   18719              : 
   18720         2610 : extern "C" void M2Quads_BuildForToByDo (void)
   18721              : {
   18722         2610 :   M2Quads_LineNote l1;
   18723         2610 :   M2Quads_LineNote l2;
   18724         2610 :   NameKey_Name e1;
   18725         2610 :   NameKey_Name e2;
   18726         2610 :   NameKey_Name Id;
   18727         2610 :   unsigned int e1tok;
   18728         2610 :   unsigned int e2tok;
   18729         2610 :   unsigned int idtok;
   18730         2610 :   unsigned int bytok;
   18731         2610 :   unsigned int LastIterator;
   18732         2610 :   unsigned int exit1;
   18733         2610 :   unsigned int IdSym;
   18734         2610 :   unsigned int BySym;
   18735         2610 :   unsigned int ByType;
   18736         2610 :   unsigned int ForLoop;
   18737         2610 :   unsigned int RangeId;
   18738         2610 :   unsigned int t;
   18739         2610 :   unsigned int f;
   18740         2610 :   unsigned int etype;
   18741         2610 :   unsigned int t1;
   18742              : 
   18743         2610 :   l2 = PopLineNo ();
   18744         2610 :   l1 = PopLineNo ();
   18745         2610 :   UseLineNote (l1);
   18746         2610 :   PushFor (0);
   18747         2610 :   M2Quads_PopTFtok (&BySym, &ByType, &bytok);
   18748         2610 :   M2Quads_PopTtok (&e2, &e2tok);
   18749         2610 :   M2Quads_PopTtok (&e1, &e1tok);
   18750         2610 :   M2Quads_PopTtok (&Id, &idtok);
   18751         2610 :   IdSym = SymbolTable_RequestSym (idtok, Id);
   18752         2610 :   RangeId = M2Range_InitForLoopBeginRangeCheck (IdSym, idtok, e1, e1tok, e2, e2tok, BySym, bytok);
   18753         2610 :   BuildRange (RangeId);
   18754         2610 :   M2Quads_PushTtok (IdSym, idtok);
   18755         2610 :   M2Quads_PushTtok (e1, e1tok);
   18756         2610 :   BuildAssignmentWithoutBounds (idtok, true, true);
   18757         2610 :   UseLineNote (l2);
   18758         3492 :   LastIterator = SymbolTable_MakeTemporary (e2tok, AreConstant (((SymbolTable_IsConst (e1)) && (SymbolTable_IsConst (e2))) && (SymbolTable_IsConst (BySym))));
   18759         2610 :   SymbolTable_PutVar (LastIterator, SymbolTable_GetSType (IdSym));
   18760         2610 :   etype = M2Base_MixTypes (SymbolTable_GetSType (e1), SymbolTable_GetSType (e2), e2tok);
   18761         2610 :   e1 = doConvert (etype, e1);
   18762         2610 :   e2 = doConvert (etype, e2);
   18763         2604 :   ForLoopLastIterator (LastIterator, e1, e2, BySym, e1tok, e2tok, bytok);
   18764              :   /* q+2 GotoOp                  q+3  */
   18765         2604 :   M2Quads_PushTFtok (BySym, ByType, bytok);  /* BuildRelOp  1st parameter.  */
   18766         2604 :   M2Quads_PushT (M2Reserved_GreaterEqualTok);  /* 2nd parameter.  */
   18767              :   /* 3rd parameter.  */
   18768         2604 :   PushZero (bytok, ByType);
   18769         2604 :   M2Quads_BuildRelOp (e2tok);  /* Choose final expression position.  */
   18770         2604 :   PopBool (&t, &f);  /* Choose final expression position.  */
   18771         2604 :   BackPatch (f, NextQuad);
   18772              :   /* q+4 GotoOp                  Exit  */
   18773         2604 :   M2Quads_PushTFtok (e1, SymbolTable_GetSType (e1), e1tok);  /* BuildRelOp  1st parameter  */
   18774         2604 :   M2Quads_PushT (M2Reserved_GreaterEqualTok);  /* 2nd parameter  */
   18775         2604 :   M2Quads_PushTFtok (e2, SymbolTable_GetSType (e2), e2tok);  /* 3rd parameter  */
   18776         2604 :   M2Quads_BuildRelOp (e2tok);  /* Choose final expression position.  */
   18777         2604 :   PopBool (&t1, &exit1);  /* Choose final expression position.  */
   18778         2604 :   BackPatch (t1, NextQuad);
   18779         2604 :   PushFor (Merge (PopFor (), exit1));  /* Merge exit1.  */
   18780         2604 :   GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);  /* Merge exit1.  */
   18781         2604 :   ForLoop = NextQuad-1;
   18782              :   /* ELSE.  */
   18783         2604 :   BackPatch (t, NextQuad);
   18784         2604 :   M2Quads_PushTFtok (e2, SymbolTable_GetSType (e2), e2tok);  /* BuildRelOp  1st parameter  */
   18785         2604 :   M2Quads_PushT (M2Reserved_GreaterEqualTok);  /* 2nd parameter  */
   18786         2604 :   M2Quads_PushTFtok (e1, SymbolTable_GetSType (e1), e1tok);  /* 3rd parameter  */
   18787         2604 :   M2Quads_BuildRelOp (e2tok);  /* 3rd parameter  */
   18788         2604 :   PopBool (&t1, &exit1);
   18789         2604 :   BackPatch (t1, NextQuad);
   18790         2604 :   PushFor (Merge (PopFor (), exit1));  /* Merge exit1.  */
   18791         2604 :   BackPatch (ForLoop, NextQuad);  /* Fixes the start of the for loop.  */
   18792         2604 :   ForLoop = NextQuad;
   18793              :   /* And set up the stack.  */
   18794         2604 :   M2Quads_PushTFtok (IdSym, SymbolTable_GetSym (IdSym), idtok);
   18795         2604 :   M2Quads_PushTFtok (BySym, ByType, bytok);
   18796         2604 :   M2Quads_PushTFtok (LastIterator, SymbolTable_GetSType (LastIterator), e2tok);
   18797         2604 :   M2Quads_PushT (ForLoop);
   18798         2604 :   M2Quads_PushT (RangeId);
   18799         2604 : }
   18800              : 
   18801              : 
   18802              : /*
   18803              :    BuildPseudoBy - Builds the Non existant part of the By
   18804              :                    clause of the For statement
   18805              :                    from the quad stack.
   18806              :                    The Stack is expected to contain:
   18807              : 
   18808              : 
   18809              :                    Entry                   Exit
   18810              :                    =====                   ====
   18811              : 
   18812              :                                                            <- Ptr
   18813              :                                            +------------+
   18814              :             Ptr ->                         | BySym | t  |
   18815              :                    +------------+          |------------|
   18816              :                    | e    | t   |          | e     | t  |
   18817              :                    |------------|          |------------|
   18818              : */
   18819              : 
   18820         2244 : extern "C" void M2Quads_BuildPseudoBy (void)
   18821              : {
   18822         2244 :   unsigned int expr;
   18823         2244 :   unsigned int type;
   18824         2244 :   unsigned int dotok;
   18825              : 
   18826              :   /* As there is no BY token this position is the DO at the end of the last expression.  */
   18827         2244 :   M2Quads_PopTFtok (&expr, &type, &dotok);
   18828         2244 :   M2Quads_PushTFtok (expr, type, dotok);
   18829         2244 :   if (type == SymbolTable_NulSym)
   18830              :     {}  /* empty.  */
   18831              :   /* Use type.  */
   18832         2024 :   else if ((SymbolTable_IsEnumeration (SymbolTable_SkipType (type))) || ((SymbolTable_SkipType (type)) == M2Base_Char))
   18833              :     {
   18834              :       /* avoid dangling else.  */
   18835              :     }
   18836         1804 :   else if (M2Base_IsOrdinalType (SymbolTable_SkipType (type)))
   18837              :     {
   18838              :       /* avoid dangling else.  */
   18839         1804 :       type = M2Base_ZType;
   18840              :     }
   18841         2244 :   PushOne (dotok, type, (const char *) "the implied {%kFOR} loop increment will cause an overflow {%1ad}", 64);
   18842         2244 : }
   18843              : 
   18844              : 
   18845              : /*
   18846              :    BuildEndFor - Builds the End part of the For statement
   18847              :                  from the quad stack.
   18848              :                  The Stack is expected to contain:
   18849              : 
   18850              : 
   18851              :                  Entry                   Exit
   18852              :                  =====                   ====
   18853              : 
   18854              :          Ptr ->
   18855              :                  +----------------+
   18856              :                  | RangeId        |
   18857              :                  |----------------|
   18858              :                  | ForQuad        |
   18859              :                  |----------------|
   18860              :                  | LastValue      |
   18861              :                  |----------------|
   18862              :                  | BySym | ByType |
   18863              :                  |----------------|
   18864              :                  | IdSym          |      Empty
   18865              :                  |----------------|
   18866              : */
   18867              : 
   18868         2604 : extern "C" void M2Quads_BuildEndFor (unsigned int endpostok)
   18869              : {
   18870         2604 :   unsigned int t;
   18871         2604 :   unsigned int f;
   18872         2604 :   unsigned int tsym;
   18873         2604 :   unsigned int RangeId;
   18874         2604 :   unsigned int IncQuad;
   18875         2604 :   unsigned int ForQuad;
   18876         2604 :   unsigned int LastSym;
   18877         2604 :   unsigned int ByType;
   18878         2604 :   unsigned int BySym;
   18879         2604 :   unsigned int bytok;
   18880         2604 :   unsigned int IdSym;
   18881         2604 :   unsigned int idtok;
   18882              : 
   18883         2604 :   M2Quads_PopT (&RangeId);
   18884         2604 :   M2Quads_PopT (&ForQuad);
   18885         2604 :   M2Quads_PopT (&LastSym);
   18886         2604 :   M2Quads_PopTFtok (&BySym, &ByType, &bytok);
   18887         2604 :   M2Quads_PopTtok (&IdSym, &idtok);
   18888              :   /* IF IdSym=LastSym THEN exit END  */
   18889         2604 :   M2Quads_PushTF (IdSym, SymbolTable_GetSType (IdSym));
   18890         2604 :   M2Quads_PushT (M2Reserved_EqualTok);
   18891         2604 :   M2Quads_PushTF (LastSym, SymbolTable_GetSType (LastSym));
   18892         2604 :   M2Quads_BuildRelOp (endpostok);
   18893         2604 :   PopBool (&t, &f);
   18894         2604 :   BackPatch (t, NextQuad);
   18895         2604 :   GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
   18896         2604 :   PushFor (Merge (PopFor (), NextQuad-1));
   18897         2604 :   BackPatch (f, NextQuad);
   18898         2604 :   if ((SymbolTable_GetMode (IdSym)) == SymbolTable_LeftValue)
   18899              :     {
   18900              :       /* index variable is a LeftValue, therefore we must dereference it  */
   18901            0 :       tsym = SymbolTable_MakeTemporary (idtok, SymbolTable_RightValue);
   18902            0 :       SymbolTable_PutVar (tsym, SymbolTable_GetSType (IdSym));
   18903            0 :       CheckPointerThroughNil (idtok, IdSym);
   18904            0 :       doIndrX (endpostok, tsym, IdSym);
   18905            0 :       BuildRange (M2Range_InitForLoopEndRangeCheck (tsym, BySym));  /* --fixme-- pass endpostok.  */
   18906            0 :       IncQuad = NextQuad;
   18907              :       /* we have explicitly checked using the above and also
   18908              :          this addition can legitimately overflow if a cardinal type
   18909              :          is counting down.  The above test will generate a more
   18910              :          precise error message, so we suppress overflow detection
   18911              :          here.  */
   18912            0 :       GenQuadOTypetok (bytok, M2Quads_AddOp, tsym, tsym, BySym, false, false, idtok, idtok, bytok);
   18913            0 :       CheckPointerThroughNil (idtok, IdSym);
   18914            0 :       GenQuadOtok (idtok, M2Quads_XIndrOp, IdSym, SymbolTable_GetSType (IdSym), tsym, false, idtok, idtok, idtok);
   18915              :     }
   18916              :   else
   18917              :     {
   18918         2604 :       BuildRange (M2Range_InitForLoopEndRangeCheck (IdSym, BySym));
   18919         2604 :       IncQuad = NextQuad;
   18920              :       /* we have explicitly checked using the above and also
   18921              :          this addition can legitimately overflow if a cardinal type
   18922              :          is counting down.  The above test will generate a more
   18923              :          precise error message, so we suppress overflow detection
   18924              :          here.
   18925              : 
   18926              :          This quadruple suppresses the generic binary op type
   18927              :          check (performed in M2GenGCC.mod) as there
   18928              :          will be a more informative/exhaustive check performed by the
   18929              :          InitForLoopBeginRangeCheck setup in BuildForToByDo and
   18930              :          performed by M2Range.mod.  */
   18931         2604 :       GenQuadOTypetok (idtok, M2Quads_AddOp, IdSym, IdSym, BySym, false, false, idtok, idtok, bytok);
   18932              :     }
   18933         2604 :   GenQuadO (endpostok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, ForQuad, false);
   18934         2604 :   BackPatch (PopFor (), NextQuad);
   18935         2604 :   AddForInfo (ForQuad, NextQuad-1, IncQuad, IdSym, idtok);
   18936         2604 :   M2Range_PutRangeForIncrement (RangeId, IncQuad);
   18937         2604 : }
   18938              : 
   18939              : 
   18940              : /*
   18941              :    BuildCaseStart - starts the case statement.
   18942              :                     It initializes a backpatch list on the compile
   18943              :                     time stack, the list is used to contain all
   18944              :                     case break points. The list is later backpatched
   18945              :                     and contains all positions of the case statement
   18946              :                     which jump to the end of the case statement.
   18947              :                     The stack also contains room for a boolean
   18948              :                     expression, this is needed to allow , operator
   18949              :                     in the CaseField alternatives.
   18950              : 
   18951              :                     The Stack is expected to contain:
   18952              : 
   18953              : 
   18954              :                     Entry                   Exit
   18955              :                     =====                   ====
   18956              : 
   18957              :                                                            <- Ptr
   18958              :                                             +------------+
   18959              :                                             | 0    | 0   |
   18960              :                                             |------------|
   18961              :                                             | 0    | 0   |
   18962              :                     +-------------+         |------------|
   18963              :                     | Expr |      |         | Expr |     |
   18964              :                     |-------------|         |------------|
   18965              : */
   18966              : 
   18967         1002 : extern "C" void M2Quads_BuildCaseStart (void)
   18968              : {
   18969         1002 :   BuildRange (M2Range_InitCaseBounds (M2CaseList_PushCase (SymbolTable_NulSym, SymbolTable_NulSym, M2Quads_OperandT (1))));
   18970         1002 :   PushBool (0, 0);  /* BackPatch list initialized  */
   18971         1002 :   PushBool (0, 0);  /* Room for a boolean expression  */
   18972         1002 : }
   18973              : 
   18974              : 
   18975              : /*
   18976              :    BuildCaseStartStatementSequence - starts the statement sequence
   18977              :                                      inside a case clause.
   18978              :                                      BackPatches the true exit to the
   18979              :                                      NextQuad.
   18980              :                                      The Stack:
   18981              : 
   18982              :                                      Entry             Exit
   18983              : 
   18984              :                               Ptr ->                                  <- Ptr
   18985              :                                      +-----------+     +------------+
   18986              :                                      | t   | f   |     | 0   | f    |
   18987              :                                      |-----------|     |------------|
   18988              : */
   18989              : 
   18990         3892 : extern "C" void M2Quads_BuildCaseStartStatementSequence (void)
   18991              : {
   18992         3892 :   unsigned int t;
   18993         3892 :   unsigned int f;
   18994              : 
   18995         3892 :   PopBool (&t, &f);
   18996         3892 :   BackPatch (t, NextQuad);
   18997         3892 :   PushBool (0, f);
   18998         3892 : }
   18999              : 
   19000              : 
   19001              : /*
   19002              :    BuildCaseEndStatementSequence - ends the statement sequence
   19003              :                                    inside a case clause.
   19004              :                                    BackPatches the false exit f1 to the
   19005              :                                    NextQuad.
   19006              :                                    Asserts that t1 and f2 is 0
   19007              :                                    Pushes t2+q and 0
   19008              : 
   19009              :                                    Quadruples:
   19010              : 
   19011              :                                    q  GotoOp  _  _  0
   19012              : 
   19013              :                                    The Stack:
   19014              : 
   19015              :                                    Entry             Exit
   19016              : 
   19017              :                             Ptr ->                                  <- Ptr
   19018              :                                    +-----------+     +------------+
   19019              :                                    | t1  | f1  |     | 0    | 0   |
   19020              :                                    |-----------|     |------------|
   19021              :                                    | t2  | f2  |     | t2+q | 0   |
   19022              :                                    |-----------|     |------------|
   19023              : */
   19024              : 
   19025         3892 : extern "C" void M2Quads_BuildCaseEndStatementSequence (void)
   19026              : {
   19027         3892 :   unsigned int t1;
   19028         3892 :   unsigned int f1;
   19029         3892 :   unsigned int t2;
   19030         3892 :   unsigned int f2;
   19031              : 
   19032         3892 :   GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
   19033         3892 :   PopBool (&t1, &f1);
   19034         3892 :   PopBool (&t2, &f2);  /* t2 contains the break list for the case  */
   19035         3892 :   BackPatch (f1, NextQuad);  /* f1 no longer needed  */
   19036         3892 :   M2Debug_Assert (t1 == 0);  /* f1 no longer needed  */
   19037         3892 :   M2Debug_Assert (f2 == 0);
   19038         3892 :   PushBool (Merge (t2, NextQuad-1), 0);  /* NextQuad-1 = Goto Quad  */
   19039         3892 :   PushBool (0, 0);  /* Room for boolean expression  */
   19040         3892 : }
   19041              : 
   19042              : 
   19043              : /*
   19044              :    BuildCaseRange - builds the range testing quaruples for
   19045              :                     a case clause.
   19046              : 
   19047              :                     IF (e1>=ce1) AND (e1<=ce2)
   19048              :                     THEN
   19049              : 
   19050              :                     ELS..
   19051              : 
   19052              :                     The Stack:
   19053              : 
   19054              :                     Entry             Exit
   19055              : 
   19056              :              Ptr ->
   19057              :                     +-----------+
   19058              :                     | ce2       |                   <- Ptr
   19059              :                     |-----------|     +-----------+
   19060              :                     | ce1       |     | t   | f   |
   19061              :                     |-----------|     |-----------|
   19062              :                     | t1  | f1  |     | t1  | f1  |
   19063              :                     |-----------|     |-----------|
   19064              :                     | t2  | f2  |     | t2  | f2  |
   19065              :                     |-----------|     |-----------|
   19066              :                     | e1        |     | e1        |
   19067              :                     |-----------|     |-----------|
   19068              : */
   19069              : 
   19070          172 : extern "C" void M2Quads_BuildCaseRange (void)
   19071              : {
   19072          172 :   unsigned int ce1;
   19073          172 :   unsigned int ce2;
   19074          172 :   unsigned int combinedtok;
   19075          172 :   unsigned int ce1tok;
   19076          172 :   unsigned int ce2tok;
   19077          172 :   unsigned int e1tok;
   19078          172 :   unsigned int e1;
   19079          172 :   unsigned int t2;
   19080          172 :   unsigned int f2;
   19081          172 :   unsigned int t1;
   19082          172 :   unsigned int f1;
   19083              : 
   19084          172 :   M2Quads_PopTtok (&ce2, &ce2tok);
   19085          172 :   M2Quads_PopTtok (&ce1, &ce1tok);
   19086          172 :   combinedtok = M2LexBuf_MakeVirtualTok (ce2tok, ce2tok, ce1tok);
   19087          172 :   M2CaseList_AddRange (ce1, ce2, combinedtok);
   19088          172 :   PopBool (&t1, &f1);
   19089          172 :   PopBool (&t2, &f2);
   19090          172 :   M2Quads_PopTtok (&e1, &e1tok);
   19091          172 :   M2Quads_PushTtok (e1, e1tok);  /* leave e1 on bottom of stack when exit procedure  */
   19092          172 :   PushBool (t2, f2);  /* leave e1 on bottom of stack when exit procedure  */
   19093          172 :   PushBool (t1, f1);  /* also leave t1 and f1 on the bottom of the stack  */
   19094          172 :   M2Quads_PushTtok (e1, e1tok);  /* also leave t1 and f1 on the bottom of the stack  */
   19095          172 :   M2Quads_PushT (M2Reserved_GreaterEqualTok);
   19096          172 :   M2Quads_PushTtok (ce1, ce1tok);
   19097          172 :   M2Quads_BuildRelOp (combinedtok);
   19098          172 :   M2Quads_PushT (M2Reserved_AndTok);
   19099          172 :   M2Quads_RecordOp ();
   19100          172 :   M2Quads_PushTtok (e1, e1tok);
   19101          172 :   M2Quads_PushT (M2Reserved_LessEqualTok);
   19102          172 :   M2Quads_PushTtok (ce2, ce2tok);
   19103          172 :   M2Quads_BuildRelOp (combinedtok);
   19104          172 :   M2Quads_BuildBinaryOp ();
   19105          172 : }
   19106              : 
   19107              : 
   19108              : /*
   19109              :    BuildCaseEquality - builds the range testing quadruples for
   19110              :                        a case clause.
   19111              : 
   19112              :                        IF e1=ce1
   19113              :                        THEN
   19114              : 
   19115              :                        ELS..
   19116              : 
   19117              :                        The Stack:
   19118              : 
   19119              :                        Entry             Exit
   19120              : 
   19121              :                 Ptr ->
   19122              :                        +-----------+     +-----------+
   19123              :                        | ce1       |     | t   | f   |
   19124              :                        |-----------|     |-----------|
   19125              :                        | t1  | f1  |     | t1  | f1  |
   19126              :                        |-----------|     |-----------|
   19127              :                        | t2  | f2  |     | t2  | f2  |
   19128              :                        |-----------|     |-----------|
   19129              :                        | e1        |     | e1        |
   19130              :                        |-----------|     |-----------|
   19131              : */
   19132              : 
   19133         3770 : extern "C" void M2Quads_BuildCaseEquality (void)
   19134              : {
   19135         3770 :   unsigned int ce1tok;
   19136         3770 :   unsigned int e1tok;
   19137         3770 :   unsigned int ce1;
   19138         3770 :   unsigned int e1;
   19139         3770 :   unsigned int t2;
   19140         3770 :   unsigned int f2;
   19141         3770 :   unsigned int t1;
   19142         3770 :   unsigned int f1;
   19143              : 
   19144         3770 :   M2Quads_PopTtok (&ce1, &ce1tok);
   19145         3770 :   M2CaseList_AddRange (ce1, SymbolTable_NulSym, ce1tok);
   19146         3770 :   PopBool (&t1, &f1);
   19147         3770 :   PopBool (&t2, &f2);
   19148         3770 :   M2Quads_PopTtok (&e1, &e1tok);
   19149         3770 :   M2Quads_PushTtok (e1, e1tok);  /* leave e1 on bottom of stack when exit procedure  */
   19150         3770 :   PushBool (t2, f2);  /* also leave t2 and f2 on the bottom of the stack  */
   19151         3770 :   PushBool (t1, f1);  /* also leave t2 and f2 on the bottom of the stack  */
   19152         3770 :   M2Quads_PushTtok (e1, e1tok);
   19153         3770 :   M2Quads_PushT (M2Reserved_EqualTok);
   19154         3770 :   M2Quads_PushTtok (ce1, ce1tok);
   19155         3770 :   M2Quads_BuildRelOp (ce1tok);
   19156         3770 : }
   19157              : 
   19158              : 
   19159              : /*
   19160              :    BuildCaseList - merges two case tests into one
   19161              : 
   19162              :                    The Stack:
   19163              : 
   19164              :                    Entry             Exit
   19165              : 
   19166              :             Ptr ->
   19167              :                    +-----------+
   19168              :                    | t2  | f2  |
   19169              :                    |-----------|     +-------------+
   19170              :                    | t1  | f1  |     | t1+t2| f1+f2|
   19171              :                    |-----------|     |-------------|
   19172              : */
   19173              : 
   19174         3942 : extern "C" void M2Quads_BuildCaseList (void)
   19175              : {
   19176         3942 :   unsigned int t2;
   19177         3942 :   unsigned int f2;
   19178         3942 :   unsigned int t1;
   19179         3942 :   unsigned int f1;
   19180              : 
   19181         3942 :   PopBool (&t2, &f2);
   19182         3942 :   PopBool (&t1, &f1);
   19183         3942 :   PushBool (Merge (t1, t2), Merge (f1, f2));
   19184         3942 : }
   19185              : 
   19186              : 
   19187              : /*
   19188              :    BuildCaseOr - builds the , in the case clause.
   19189              : 
   19190              :                  The Stack:
   19191              : 
   19192              :                  Entry             Exit
   19193              : 
   19194              :           Ptr ->                                  <- Ptr
   19195              :                  +-----------+     +------------+
   19196              :                  | t   | f   |     | t    | 0   |
   19197              :                  |-----------|     |------------|
   19198              : */
   19199              : 
   19200           50 : extern "C" void M2Quads_BuildCaseOr (void)
   19201              : {
   19202           50 :   unsigned int t;
   19203           50 :   unsigned int f;
   19204              : 
   19205           50 :   PopBool (&t, &f);
   19206           50 :   BackPatch (f, NextQuad);
   19207           50 :   PushBool (t, 0);
   19208           50 : }
   19209              : 
   19210              : 
   19211              : /*
   19212              :    BuildCaseElse - builds the else of case clause.
   19213              : 
   19214              :                   The Stack:
   19215              : 
   19216              :                   Entry             Exit
   19217              : 
   19218              :            Ptr ->                                  <- Ptr
   19219              :                   +-----------+     +------------+
   19220              :                   | t   | f   |     | t    | 0   |
   19221              :                   |-----------|     |------------|
   19222              : */
   19223              : 
   19224         1002 : extern "C" void M2Quads_BuildCaseElse (void)
   19225              : {
   19226         1002 :   unsigned int t;
   19227         1002 :   unsigned int f;
   19228              : 
   19229         1002 :   PopBool (&t, &f);
   19230         1002 :   BackPatch (f, NextQuad);
   19231         1002 :   PushBool (t, 0);
   19232         1002 : }
   19233              : 
   19234              : 
   19235              : /*
   19236              :    BuildCaseEnd - builds the end of case clause.
   19237              : 
   19238              :                   The Stack:
   19239              : 
   19240              :                   Entry             Exit
   19241              : 
   19242              :            Ptr ->
   19243              :                   +-----------+
   19244              :                   | t1  | f1  |
   19245              :                   |-----------|
   19246              :                   | t2  | f2  |
   19247              :                   |-----------|
   19248              :                   | e1        |
   19249              :                   |-----------|     Empty
   19250              : */
   19251              : 
   19252         1002 : extern "C" void M2Quads_BuildCaseEnd (void)
   19253              : {
   19254         1002 :   unsigned int e1;
   19255         1002 :   unsigned int t;
   19256         1002 :   unsigned int f;
   19257              : 
   19258         1002 :   PopBool (&t, &f);
   19259         1002 :   BackPatch (f, NextQuad);
   19260         1002 :   BackPatch (t, NextQuad);
   19261         1002 :   PopBool (&t, &f);
   19262         1002 :   BackPatch (f, NextQuad);
   19263         1002 :   BackPatch (t, NextQuad);
   19264         1002 :   M2Quads_PopT (&e1);
   19265         1002 :   M2CaseList_PopCase ();
   19266         1002 : }
   19267              : 
   19268              : 
   19269              : /*
   19270              :    BuildCaseCheck - builds the case checking code to ensure that
   19271              :                     the program does not need an else clause at runtime.
   19272              :                     The stack is unaltered.
   19273              : */
   19274              : 
   19275          494 : extern "C" void M2Quads_BuildCaseCheck (void)
   19276              : {
   19277          494 :   BuildError (M2Range_InitNoElseRangeCheck ());
   19278          494 : }
   19279              : 
   19280              : 
   19281              : /*
   19282              :    BuildNulParam - Builds a nul parameter on the stack.
   19283              :                    The Stack:
   19284              : 
   19285              :                    Entry             Exit
   19286              : 
   19287              :                                                     <- Ptr
   19288              :                    Empty             +------------+
   19289              :                                      | 0          |
   19290              :                                      |------------|
   19291              : */
   19292              : 
   19293        18618 : extern "C" void M2Quads_BuildNulParam (void)
   19294              : {
   19295        18618 :   M2Quads_PushT (static_cast<unsigned int> (0));
   19296        18618 : }
   19297              : 
   19298              : 
   19299              : /*
   19300              :    BuildProcedureCall - builds a procedure call.
   19301              :                         Although this procedure does not directly
   19302              :                         destroy the procedure parameters, it calls
   19303              :                         routine which will manipulate the stack and
   19304              :                         so the entry and exit states of the stack are shown.
   19305              : 
   19306              :                         The Stack:
   19307              : 
   19308              : 
   19309              :                         Entry                      Exit
   19310              : 
   19311              :                  Ptr ->
   19312              :                         +----------------+
   19313              :                         | NoOfParam      |
   19314              :                         |----------------|
   19315              :                         | Param 1        |
   19316              :                         |----------------|
   19317              :                         | Param 2        |
   19318              :                         |----------------|
   19319              :                         .                .
   19320              :                         .                .
   19321              :                         .                .
   19322              :                         |----------------|
   19323              :                         | Param #        |
   19324              :                         |----------------|
   19325              :                         | ProcSym | Type |         Empty
   19326              :                         |----------------|
   19327              : */
   19328              : 
   19329       180257 : extern "C" void M2Quads_BuildProcedureCall (unsigned int tokno)
   19330              : {
   19331       180257 :   unsigned int NoOfParam;
   19332       180257 :   unsigned int ProcSym;
   19333              : 
   19334       180257 :   M2Quads_PopT (&NoOfParam);
   19335       180257 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   19336       180257 :   M2Quads_PushT (NoOfParam);  /* Compile time stack restored to entry state  */
   19337       180257 :   if ((M2Base_IsPseudoBaseProcedure (ProcSym)) || (M2System_IsPseudoSystemProcedure (ProcSym)))  /* Compile time stack restored to entry state  */
   19338              :     {
   19339        21535 :       M2Quads_DisplayStack ();
   19340        21535 :       ManipulatePseudoCallParameters ();
   19341        21535 :       M2Quads_DisplayStack ();
   19342        21535 :       BuildPseudoProcedureCall (tokno);
   19343        21535 :       M2Quads_DisplayStack ();
   19344              :     }
   19345       158722 :   else if (SymbolTable_IsUnknown (ProcSym))
   19346              :     {
   19347              :       /* avoid dangling else.  */
   19348              :       /* Spellcheck.  */
   19349           30 :       M2MetaError_MetaError1 ((const char *) "{%1Ua} is not recognised as a procedure {%1&s}", 46, ProcSym);
   19350           30 :       M2Quads_PopN (NoOfParam+2);
   19351           30 :       SymbolTable_UnknownReported (ProcSym);
   19352              :     }
   19353              :   else
   19354              :     {
   19355              :       /* avoid dangling else.  */
   19356       158692 :       M2Quads_DisplayStack ();
   19357       158692 :       BuildRealProcedureCall (tokno);
   19358       158686 :       M2Quads_DisplayStack ();
   19359              :     }
   19360       180251 : }
   19361              : 
   19362              : 
   19363              : /*
   19364              :    CheckBuildFunction - checks to see whether ProcSym is a function
   19365              :                         and if so it adds a TempSym value which will
   19366              :                         hold the return value once the function finishes.
   19367              :                         This procedure also generates an error message
   19368              :                         if the user is calling a function and ignoring
   19369              :                         the return result.  The additional TempSym
   19370              :                         is not created if ProcSym is a procedure
   19371              :                         and the stack is unaltered.
   19372              : 
   19373              :                         The Stack:
   19374              : 
   19375              : 
   19376              :                        Entry                      Exit
   19377              : 
   19378              :                 Ptr ->
   19379              : 
   19380              :                                                   +----------------+
   19381              :                                                   | ProcSym | Type |
   19382              :                        +----------------+         |----------------|
   19383              :                        | ProcSym | Type |         | TempSym | Type |
   19384              :                        |----------------|         |----------------|
   19385              : */
   19386              : 
   19387       107723 : extern "C" bool M2Quads_CheckBuildFunction (void)
   19388              : {
   19389       107723 :   unsigned int tokpos;
   19390       107723 :   unsigned int TempSym;
   19391       107723 :   unsigned int ProcSym;
   19392       107723 :   unsigned int Type;
   19393              : 
   19394       107723 :   M2Quads_PopTFtok (&ProcSym, &Type, &tokpos);
   19395       107723 :   if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (Type)))
   19396              :     {
   19397              :       /* avoid dangling else.  */
   19398          684 :       if ((SymbolTable_GetSType (Type)) != SymbolTable_NulSym)
   19399              :         {
   19400            0 :           TempSym = SymbolTable_MakeTemporary (tokpos, SymbolTable_RightValue);
   19401            0 :           SymbolTable_PutVar (TempSym, SymbolTable_GetSType (Type));
   19402            0 :           M2Quads_PushTFtok (TempSym, SymbolTable_GetSType (Type), tokpos);
   19403            0 :           M2Quads_PushTFtok (ProcSym, Type, tokpos);
   19404            0 :           if (! (SymbolTable_IsReturnOptionalAny (Type)))
   19405              :             {
   19406            0 :               M2MetaError_MetaErrorT1 (tokpos, (const char *) "function {%1Ea} is called but its return value is ignored", 57, ProcSym);
   19407              :             }
   19408            0 :           return true;
   19409              :         }
   19410              :     }
   19411       107039 :   else if ((SymbolTable_IsProcedure (ProcSym)) && (Type != SymbolTable_NulSym))
   19412              :     {
   19413              :       /* avoid dangling else.  */
   19414            0 :       TempSym = SymbolTable_MakeTemporary (tokpos, SymbolTable_RightValue);
   19415            0 :       SymbolTable_PutVar (TempSym, Type);
   19416            0 :       M2Quads_PushTFtok (TempSym, Type, tokpos);
   19417            0 :       M2Quads_PushTFtok (ProcSym, Type, tokpos);
   19418            0 :       if (! (SymbolTable_IsReturnOptionalAny (ProcSym)))
   19419              :         {
   19420            0 :           M2MetaError_MetaErrorT1 (tokpos, (const char *) "function {%1Ea} is called but its return value is ignored", 57, ProcSym);
   19421              :         }
   19422            0 :       return true;
   19423              :     }
   19424       107723 :   M2Quads_PushTFtok (ProcSym, Type, tokpos);
   19425       107723 :   return false;
   19426              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   19427              :   __builtin_unreachable ();
   19428              : }
   19429              : 
   19430              : 
   19431              : /*
   19432              :    BuildFunctionCall - builds a function call.
   19433              :                        The Stack:
   19434              : 
   19435              : 
   19436              :                        Entry                      Exit
   19437              : 
   19438              :                 Ptr ->
   19439              :                        +----------------+
   19440              :                        | NoOfParam      |
   19441              :                        |----------------|
   19442              :                        | Param 1        |
   19443              :                        |----------------|
   19444              :                        | Param 2        |
   19445              :                        |----------------|
   19446              :                        .                .
   19447              :                        .                .
   19448              :                        .                .
   19449              :                        |----------------|
   19450              :                        | Param #        |                        <- Ptr
   19451              :                        |----------------|         +------------+
   19452              :                        | ProcSym | Type |         | ReturnVar  |
   19453              :                        |----------------|         |------------|
   19454              : */
   19455              : 
   19456       107008 : extern "C" void M2Quads_BuildFunctionCall (bool ConstExpr)
   19457              : {
   19458       107008 :   unsigned int paramtok;
   19459       107008 :   unsigned int combinedtok;
   19460       107008 :   unsigned int functok;
   19461       107008 :   unsigned int NoOfParam;
   19462       107008 :   unsigned int ProcSym;
   19463              : 
   19464       107008 :   M2Quads_PopT (&NoOfParam);
   19465       107008 :   functok = OperandTtok (NoOfParam+1);
   19466       107008 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   19467       107008 :   ProcSym = PCSymBuild_SkipConst (ProcSym);
   19468       107008 :   M2Quads_PushT (NoOfParam);
   19469              :   /* Compile time stack restored to entry state.  */
   19470       107008 :   if (SymbolTable_IsUnknown (ProcSym))
   19471              :     {
   19472              :       /* Spellcheck.  */
   19473            6 :       paramtok = OperandTtok (1);
   19474            6 :       combinedtok = M2LexBuf_MakeVirtual2Tok (functok, paramtok);
   19475            6 :       M2MetaError_MetaErrorT1 (functok, (const char *) "procedure function {%1Ea} is undefined {%1&s}", 45, ProcSym);
   19476            6 :       SymbolTable_UnknownReported (ProcSym);
   19477            6 :       M2Quads_PopN (NoOfParam+2);
   19478              :       /* Fake return value to continue compiling.  */
   19479            6 :       M2Quads_PushT (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym));
   19480              :     }
   19481       107002 :   else if (SymbolTable_IsAModula2Type (ProcSym))
   19482              :     {
   19483              :       /* avoid dangling else.  */
   19484         2544 :       ManipulatePseudoCallParameters ();
   19485         2544 :       BuildTypeCoercion (ConstExpr);
   19486              :     }
   19487       104458 :   else if ((M2System_IsPseudoSystemFunction (ProcSym)) || (M2Base_IsPseudoBaseFunction (ProcSym)))
   19488              :     {
   19489              :       /* avoid dangling else.  */
   19490        42796 :       ManipulatePseudoCallParameters ();
   19491        42796 :       BuildPseudoFunctionCall (ConstExpr);
   19492              :     }
   19493              :   else
   19494              :     {
   19495              :       /* avoid dangling else.  */
   19496        61662 :       BuildRealFunctionCall (functok, ConstExpr);
   19497              :     }
   19498       106981 : }
   19499              : 
   19500              : 
   19501              : /*
   19502              :    BuildConstFunctionCall - builds a function call and checks that this function can be
   19503              :                             called inside a ConstExpression.
   19504              : 
   19505              :                             The Stack:
   19506              : 
   19507              : 
   19508              :                             Entry                      Exit
   19509              : 
   19510              :                      Ptr ->
   19511              :                             +----------------+
   19512              :                             | NoOfParam      |
   19513              :                             |----------------|
   19514              :                             | Param 1        |
   19515              :                             |----------------|
   19516              :                             | Param 2        |
   19517              :                             |----------------|
   19518              :                             .                .
   19519              :                             .                .
   19520              :                             .                .
   19521              :                             |----------------|
   19522              :                             | Param #        |                        <- Ptr
   19523              :                             |----------------|         +------------+
   19524              :                             | ProcSym | Type |         | ReturnVar  |
   19525              :                             |----------------|         |------------|
   19526              : 
   19527              : */
   19528              : 
   19529         7394 : extern "C" void M2Quads_BuildConstFunctionCall (void)
   19530              : {
   19531         7394 :   unsigned int functok;
   19532         7394 :   unsigned int combinedtok;
   19533         7394 :   unsigned int paramtok;
   19534         7394 :   unsigned int ConstExpression;
   19535         7394 :   unsigned int NoOfParam;
   19536         7394 :   unsigned int ProcSym;
   19537              : 
   19538         7394 :   M2Quads_DisplayStack ();
   19539         7394 :   M2Quads_PopT (&NoOfParam);
   19540         7394 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   19541         7394 :   functok = OperandTtok (NoOfParam+1);
   19542         7394 :   if (M2Options_CompilerDebugging)
   19543              :     {
   19544            0 :       M2Printf_printf2 ((const char *) "procsym = %d  token = %d\\n", 26, (const unsigned char *) &ProcSym, (sizeof (ProcSym)-1), (const unsigned char *) &functok, (sizeof (functok)-1));
   19545              :     }
   19546              :   /* ErrorStringAt (InitString ('constant function'), functok).  */
   19547         7394 :   M2Quads_PushT (NoOfParam);
   19548         7394 :   if ((ProcSym != M2Base_Convert) && (((M2Base_IsPseudoBaseFunction (ProcSym)) || (M2System_IsPseudoSystemFunctionConstExpression (ProcSym))) || ((SymbolTable_IsProcedure (ProcSym)) && (SymbolTable_IsProcedureBuiltin (ProcSym)))))
   19549              :     {
   19550         7262 :       M2Quads_BuildFunctionCall (true);
   19551              :     }
   19552              :   else
   19553              :     {
   19554          132 :       if (SymbolTable_IsAModula2Type (ProcSym))
   19555              :         {
   19556              :           /* Type conversion.  */
   19557          132 :           if (NoOfParam == 1)
   19558              :             {
   19559          132 :               ConstExpression = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   19560          132 :               paramtok = OperandTtok (NoOfParam+1);
   19561          132 :               M2Quads_PopN (NoOfParam+2);
   19562              :               /* Build macro: CONVERT( ProcSym, ConstExpression ).  */
   19563          132 :               M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
   19564          132 :               M2Quads_PushTtok (ProcSym, functok);
   19565          132 :               M2Quads_PushTtok (ConstExpression, paramtok);
   19566          132 :               M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters.  */
   19567          132 :               BuildConvertFunction (M2Base_Convert, true);  /* Two parameters.  */
   19568              :             }
   19569              :           else
   19570              :             {
   19571            0 :               M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}a constant type conversion can only have one argument", 57);
   19572              :             }
   19573              :         }
   19574              :       else
   19575              :         {
   19576              :           /* Error issue message and fake return stack.  */
   19577            0 :           if (M2Options_Iso)
   19578              :             {
   19579            0 :               M2MetaError_MetaErrorT0 (functok, (const char *) "the only functions permissible in a constant expression are: {%kCAP}, {%kCHR}, {%kCMPLX}, {%kFLOAT}, {%kHIGH}, {%kIM}, {%kLENGTH}, {%kMAX}, {%kMIN}, {%kODD}, {%kORD}, {%kRE}, {%kSIZE}, {%kTSIZE}, {%kTBITSIZE}, {%kTRUNC}, {%kVAL} and gcc builtins", 245);
   19580              :             }
   19581              :           else
   19582              :             {
   19583            0 :               M2MetaError_MetaErrorT0 (functok, (const char *) "the only functions permissible in a constant expression are: {%kCAP}, {%kCHR}, {%kFLOAT}, {%kHIGH}, {%kMAX}, {%kMIN}, {%kODD}, {%kORD}, {%kSIZE}, {%kTSIZE}, {%kTRUNC}, {%kTBITSIZE}, {%kVAL} and gcc builtins", 206);
   19584              :             }
   19585            0 :           if (NoOfParam > 0)
   19586              :             {
   19587            0 :               paramtok = OperandTtok (NoOfParam+1);
   19588            0 :               combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   19589              :             }
   19590              :           else
   19591              :             {
   19592            0 :               combinedtok = functok;
   19593              :             }
   19594            0 :           M2Quads_PopN (NoOfParam+2);
   19595            0 :           M2Quads_PushT (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym));  /* Fake return value to continue compiling.  */
   19596              :         }
   19597              :     }
   19598         7394 : }
   19599              : 
   19600              : 
   19601              : /*
   19602              :    BuildBooleanVariable - tests to see whether top of stack is a boolean
   19603              :                           conditional and if so it converts it into a boolean
   19604              :                           variable.
   19605              : */
   19606              : 
   19607       361118 : extern "C" void M2Quads_BuildBooleanVariable (void)
   19608              : {
   19609       361118 :   if (IsBoolean (1))
   19610              :     {
   19611         7262 :       ConvertBooleanToVariable (OperandTtok (1), 1);
   19612              :     }
   19613       361118 : }
   19614              : 
   19615              : 
   19616              : /*
   19617              :    BuildModuleStart - starts current module scope.
   19618              : */
   19619              : 
   19620        84893 : extern "C" void M2Quads_BuildModuleStart (unsigned int tok)
   19621              : {
   19622        84893 :   GenQuadO (tok, M2Quads_ModuleScopeOp, tok, (unsigned int ) (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()))), SymbolTable_GetCurrentModule (), false);
   19623        84893 : }
   19624              : 
   19625              : 
   19626              : /*
   19627              :    BuildProcedureStart - Builds start of the procedure. Generates a
   19628              :                          quadruple which indicated the start of
   19629              :                          this procedure declarations scope.
   19630              :                          The Stack is expected to contain:
   19631              : 
   19632              : 
   19633              :                          Entry                   Exit
   19634              :                          =====                   ====
   19635              : 
   19636              :                  Ptr ->                                       <- Ptr
   19637              :                         +------------+          +-----------+
   19638              :                         | ProcSym    |          | ProcSym   |
   19639              :                         |------------|          |-----------|
   19640              :                         | Name       |          | Name      |
   19641              :                         |------------|          |-----------|
   19642              : 
   19643              : 
   19644              :                         Quadruples:
   19645              : 
   19646              :                         q   ProcedureScopeOp  Line#  Scope  ProcSym
   19647              : */
   19648              : 
   19649        81810 : extern "C" void M2Quads_BuildProcedureStart (void)
   19650              : {
   19651        81810 :   unsigned int ProcSym;
   19652              : 
   19653        81810 :   M2Quads_PopT (&ProcSym);
   19654        81810 :   M2Debug_Assert (SymbolTable_IsProcedure (ProcSym));
   19655        81810 :   SymbolTable_PutProcedureScopeQuad (ProcSym, NextQuad);
   19656        81810 :   GenQuad (M2Quads_ProcedureScopeOp, M2LexBuf_GetPreviousTokenLineNo (), SymbolTable_GetScope (ProcSym), ProcSym);
   19657        81810 :   M2Quads_PushT (ProcSym);
   19658        81810 : }
   19659              : 
   19660              : 
   19661              : /*
   19662              :    BuildProcedureBegin - determines the start of the BEGIN END block of
   19663              :                          the procedure.
   19664              :                          The Stack is expected to contain:
   19665              : 
   19666              : 
   19667              :                          Entry                   Exit
   19668              :                          =====                   ====
   19669              : 
   19670              :                  Ptr ->                                       <- Ptr
   19671              :                         +------------+          +-----------+
   19672              :                         | ProcSym    |          | ProcSym   |
   19673              :                         |------------|          |-----------|
   19674              :                         | Name       |          | Name      |
   19675              :                         |------------|          |-----------|
   19676              : 
   19677              : 
   19678              :                         Quadruples:
   19679              : 
   19680              :                         q   NewLocalVarOp  TokenNo(BEGIN)  _  ProcSym
   19681              : */
   19682              : 
   19683        81798 : extern "C" void M2Quads_BuildProcedureBegin (void)
   19684              : {
   19685        81798 :   unsigned int ProcSym;
   19686              : 
   19687        81798 :   M2Quads_PopT (&ProcSym);
   19688        81798 :   M2Debug_Assert (SymbolTable_IsProcedure (ProcSym));
   19689        81798 :   SymbolTable_PutProcedureStartQuad (ProcSym, NextQuad);
   19690        81798 :   SymbolTable_PutProcedureBegin (ProcSym, M2LexBuf_GetTokenNo ());
   19691        81798 :   GenQuad (M2Quads_NewLocalVarOp, M2LexBuf_GetTokenNo (), SymbolTable_GetScope (ProcSym), ProcSym);
   19692        81798 :   CurrentProc = ProcSym;
   19693        81798 :   M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
   19694        81798 :   M2Quads_PushT (ProcSym);
   19695        81798 :   CheckVariablesAt (ProcSym);
   19696        81798 :   CheckNeedPriorityBegin (M2LexBuf_GetTokenNo (), ProcSym, SymbolTable_GetCurrentModule ());
   19697        81798 :   M2StackWord_PushWord (TryStack, NextQuad);
   19698        81798 :   M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
   19699        81798 :   if (SymbolTable_HasExceptionBlock (ProcSym))
   19700              :     {
   19701          168 :       GenQuad (M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
   19702              :     }
   19703        81798 : }
   19704              : 
   19705              : 
   19706              : /*
   19707              :    BuildProcedureEnd - Builds end of the procedure. Destroys space for
   19708              :                        the local variables.
   19709              :                        The Stack is expected to contain:
   19710              : 
   19711              : 
   19712              :                        Entry                   Exit
   19713              :                        =====                   ====
   19714              : 
   19715              :                 Ptr ->                                       <- Ptr
   19716              :                        +------------+          +-----------+
   19717              :                        | ProcSym    |          | ProcSym   |
   19718              :                        |------------|          |-----------|
   19719              :                        | Name       |          | Name      |
   19720              :                        |------------|          |-----------|
   19721              : 
   19722              : 
   19723              :                        Quadruples:
   19724              : 
   19725              :                        q   KillLocalVarOp  TokenNo(END)  _  ProcSym
   19726              : */
   19727              : 
   19728        81768 : extern "C" void M2Quads_BuildProcedureEnd (void)
   19729              : {
   19730        81768 :   unsigned int tok;
   19731        81768 :   unsigned int ProcSym;
   19732              : 
   19733        81768 :   M2Quads_PopTtok (&ProcSym, &tok);
   19734        81768 :   if (SymbolTable_HasExceptionBlock (ProcSym))
   19735              :     {
   19736          168 :       BuildRTExceptLeave (tok, true);
   19737          168 :       GenQuad (M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
   19738              :     }
   19739        81768 :   if ((SymbolTable_GetSType (ProcSym)) != SymbolTable_NulSym)
   19740              :     {
   19741        19166 :       BuildError (M2Range_InitNoReturnRangeCheck ());
   19742              :     }
   19743        81768 :   BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
   19744        81768 :   CheckNeedPriorityEnd (tok, ProcSym, SymbolTable_GetCurrentModule ());
   19745        81768 :   CurrentProc = SymbolTable_NulSym;
   19746        81768 :   SymbolTable_PutProcedureEnd (ProcSym, (M2LexBuf_GetTokenNo ())-1);  /* --fixme--  */
   19747        81768 :   GenQuad (M2Quads_KillLocalVarOp, (M2LexBuf_GetTokenNo ())-1, SymbolTable_NulSym, ProcSym);  /* --fixme--  */
   19748        81768 :   SymbolTable_PutProcedureEndQuad (ProcSym, NextQuad);
   19749        81768 :   GenQuad (M2Quads_ReturnOp, SymbolTable_NulSym, SymbolTable_NulSym, ProcSym);
   19750        81768 :   CheckFunctionReturn (ProcSym);
   19751        81768 :   CheckVariablesInBlock (ProcSym);
   19752              :   /* Call PutProcedureEndQuad so that any runtime procedure will be
   19753              :       seen as defined even if it not seen during pass 2 (which will also
   19754              :       call PutProcedureEndQuad).  */
   19755        81768 :   SymbolTable_PutProcedureParametersDefined (ProcSym, SymbolTable_ProperProcedure);
   19756        81768 :   SymbolTable_PutProcedureDefined (ProcSym, SymbolTable_ProperProcedure);
   19757        81768 :   M2StackWord_RemoveTop (CatchStack);
   19758        81768 :   M2StackWord_RemoveTop (TryStack);
   19759        81768 :   M2Quads_PushT (ProcSym);
   19760        81768 : }
   19761              : 
   19762              : 
   19763              : /*
   19764              :    BuildReturn - Builds the Return part of the procedure.
   19765              :                  tokreturn is the location of the RETURN keyword.
   19766              :                  The Stack is expected to contain:
   19767              : 
   19768              : 
   19769              :                  Entry                   Exit
   19770              :                  =====                   ====
   19771              : 
   19772              :          Ptr ->
   19773              :                  +------------+
   19774              :                  | e1         |          Empty
   19775              :                  |------------|
   19776              : */
   19777              : 
   19778        28975 : extern "C" void M2Quads_BuildReturn (unsigned int tokreturn)
   19779              : {
   19780        28975 :   unsigned int tokcombined;
   19781        28975 :   unsigned int tokexpr;
   19782        28975 :   unsigned int e1;
   19783        28975 :   unsigned int t1;
   19784        28975 :   unsigned int t;
   19785        28975 :   unsigned int f;
   19786        28975 :   unsigned int Des;
   19787              : 
   19788        28975 :   if (IsBoolean (1))
   19789              :     {
   19790         1816 :       PopBooltok (&t, &f, &tokexpr);
   19791              :       /* Des will be a boolean type  */
   19792         1816 :       Des = SymbolTable_MakeTemporary (tokexpr, SymbolTable_RightValue);
   19793         1816 :       SymbolTable_PutVar (Des, M2Base_Boolean);
   19794         1816 :       M2Quads_PushTFtok (Des, M2Base_Boolean, tokexpr);
   19795         1816 :       PushBooltok (t, f, tokexpr);
   19796         1816 :       BuildAssignmentWithoutBounds (tokreturn, false, true);
   19797         1816 :       M2Quads_PushTFtok (Des, M2Base_Boolean, tokexpr);
   19798              :     }
   19799        28975 :   M2Quads_PopTFtok (&e1, &t1, &tokexpr);
   19800        28975 :   tokcombined = M2LexBuf_MakeVirtualTok (tokreturn, tokreturn, tokexpr);
   19801        28975 :   if (e1 != SymbolTable_NulSym)
   19802              :     {
   19803              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   19804              :       /* Check we are in a procedure scope and that the procedure has a return type.  */
   19805        28123 :       if (CurrentProc == SymbolTable_NulSym)
   19806              :         {
   19807            6 :           M2MetaError_MetaErrorT0 (tokcombined, (const char *) "{%1E} attempting to return a value when not in a procedure scope", 64);
   19808              :         }
   19809        28117 :       else if ((SymbolTable_GetSType (CurrentProc)) == SymbolTable_NulSym)
   19810              :         {
   19811              :           /* avoid dangling else.  */
   19812            6 :           M2MetaError_MetaErrorT1 (tokcombined, (const char *) "attempting to return a value from procedure {%1Ea} which does not have a return type", 84, CurrentProc);
   19813              :         }
   19814              :       else
   19815              :         {
   19816              :           /* avoid dangling else.  */
   19817        28111 :           BuildReturnLower (tokcombined, tokexpr, e1, t1);
   19818              :         }
   19819              :     }
   19820        28975 :   GenQuadO (tokcombined, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PopWord (ReturnStack), false);
   19821        28975 :   M2StackWord_PushWord (ReturnStack, NextQuad-1);
   19822        28975 : }
   19823              : 
   19824              : 
   19825              : /*
   19826              :    BuildModulePriority - assigns the current module with a priority
   19827              :                          from the top of stack.
   19828              : 
   19829              :                          Entry                   Exit
   19830              :                          =====                   ====
   19831              : 
   19832              : 
   19833              :                   Ptr ->                         Empty
   19834              :                          +------------+
   19835              :                          | Priority   |
   19836              :                          |------------|
   19837              : */
   19838              : 
   19839           38 : extern "C" void M2Quads_BuildModulePriority (void)
   19840              : {
   19841           38 :   unsigned int Priority;
   19842              : 
   19843           38 :   M2Quads_PopT (&Priority);
   19844           38 :   SymbolTable_PutPriority (SymbolTable_GetCurrentModule (), Priority);
   19845           38 : }
   19846              : 
   19847              : 
   19848              : /*
   19849              :    StartBuildWith - performs the with statement.
   19850              :                     The Stack:
   19851              : 
   19852              :                     Entry                    Exit
   19853              : 
   19854              :                     +------------+
   19855              :                     | Sym | Type |           Empty
   19856              :                     |------------|
   19857              : */
   19858              : 
   19859         6196 : extern "C" void M2Quads_StartBuildWith (unsigned int withTok)
   19860              : {
   19861         6196 :   unsigned int tok;
   19862         6196 :   unsigned int Sym;
   19863         6196 :   unsigned int Type;
   19864         6196 :   unsigned int Ref;
   19865              : 
   19866         6196 :   DebugLocation (static_cast<unsigned int> (M2Reserved_withtok), (const char *) "with", 4);
   19867         6196 :   BuildStmtNoteTok (withTok);
   19868         6196 :   M2Quads_DisplayStack ();
   19869         6196 :   M2Quads_PopTFtok (&Sym, &Type, &tok);
   19870         6196 :   DebugLocation (tok, (const char *) "expression", 10);
   19871         6196 :   Type = SymbolTable_SkipType (Type);
   19872         6196 :   if (Type == SymbolTable_NulSym)
   19873              :     {
   19874            6 :       M2MetaError_MetaErrorT1 (tok, (const char *) "{%1Aa} {%1d} has a no type, the {%kWITH} statement requires a variable or parameter of a {%kRECORD} type", 104, Sym);
   19875              :     }
   19876              :   else
   19877              :     {
   19878         6190 :       Ref = SymbolTable_MakeTemporary (tok, SymbolTable_LeftValue);
   19879         6190 :       SymbolTable_PutVar (Ref, Type);
   19880         6190 :       if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
   19881              :         {
   19882              :           /* Copy LeftValue.  */
   19883         5878 :           GenQuadO (tok, M2Quads_BecomesOp, Ref, SymbolTable_NulSym, Sym, true);
   19884              :         }
   19885              :       else
   19886              :         {
   19887              :           /* Calculate the address of Sym.  */
   19888          312 :           GenQuadO (tok, M2Quads_AddrOp, Ref, SymbolTable_NulSym, Sym, true);
   19889              :         }
   19890         6190 :       PushWith (Sym, Type, Ref, tok);
   19891         6190 :       DebugLocation (tok, (const char *) "with ref", 8);
   19892         6190 :       if (! (SymbolTable_IsRecord (Type)))
   19893              :         {
   19894            0 :           M2MetaError_MetaErrorT1 (tok, (const char *) "the {%kWITH} statement requires that {%1Ea} {%1d} be of a {%kRECORD} {%1tsa:type rather than {%1tsa}}", 101, Sym);
   19895              :         }
   19896         6190 :       SymbolTable_StartScope (Type);
   19897              :     }
   19898         6190 :   M2StackSpell_Push (Type);
   19899         6190 :   M2Quads_DisplayStack ();
   19900         6190 : }
   19901              : 
   19902              : 
   19903              : /*
   19904              :    EndBuildWith - terminates the innermost with scope.
   19905              : */
   19906              : 
   19907         6190 : extern "C" void M2Quads_EndBuildWith (void)
   19908              : {
   19909         6190 :   M2Quads_DisplayStack ();
   19910         6190 :   SymbolTable_EndScope ();
   19911         6190 :   PopWith ();
   19912         6190 :   M2StackSpell_Pop ();
   19913         6190 :   M2Quads_DisplayStack ();
   19914         6190 : }
   19915              : 
   19916              : 
   19917              : /*
   19918              :    CheckWithReference - performs the with statement.
   19919              :                         The Stack:
   19920              : 
   19921              :                         Entry                    Exit
   19922              : 
   19923              :                         +------------+           +------------+
   19924              :                         | Sym | Type |           | Sym | Type |
   19925              :                         |------------|           |------------|
   19926              : */
   19927              : 
   19928       697255 : extern "C" void M2Quads_CheckWithReference (void)
   19929              : {
   19930       697255 :   M2Quads_WithFrame f;
   19931       697255 :   unsigned int tokpos;
   19932       697255 :   unsigned int i;
   19933       697255 :   unsigned int n;
   19934       697255 :   unsigned int rw;
   19935       697255 :   unsigned int Sym;
   19936       697255 :   unsigned int Type;
   19937              : 
   19938       697255 :   n = M2StackAddress_NoOfItemsInStackAddress (WithStack);
   19939       697255 :   if ((n > 0) && ! SuppressWith)
   19940              :     {
   19941       107206 :       PopTFrwtok (&Sym, &Type, &rw, &tokpos);
   19942       107206 :       M2Debug_Assert (tokpos != M2LexBuf_UnknownTokenNo);
   19943       107206 :       if (SymbolTable_IsUnknown (Sym))
   19944              :         {
   19945            6 :           M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1ad} is unknown {%1&s}", 24, Sym);
   19946            6 :           SymbolTable_UnknownReported (Sym);
   19947              :         }
   19948              :       else
   19949              :         {
   19950              :           /* Inner WITH always has precedence.  */
   19951              :           i = 1;  /* top of stack  */
   19952              :           /* WriteString('Checking for a with') ;  */
   19953       227600 :           while (i <= n)
   19954              :             {
   19955       120400 :               f = static_cast<M2Quads_WithFrame> (M2StackAddress_PeepAddress (WithStack, i));
   19956       120400 :               if ((SymbolTable_IsRecordField (Sym)) && ((SymbolTable_GetRecord (SymbolTable_GetParent (Sym))) == f->RecordType))
   19957              :                 {
   19958        31040 :                   if (SymbolTable_IsUnused (Sym))
   19959              :                     {
   19960            0 :                       M2MetaError_MetaError1 ((const char *) "record field {%1Dad} was declared as unused by a pragma", 55, Sym);
   19961              :                     }
   19962              :                   /* Fake a RecordSym.op  */
   19963        31040 :                   PushTFrwtok (f->RecordRef, f->RecordType, f->rw, f->RecordTokPos);
   19964        31040 :                   M2Quads_PushTFtok (Sym, Type, tokpos);
   19965        31040 :                   BuildAccessWithField ();
   19966        31040 :                   PopTFrw (&Sym, &Type, &f->rw);
   19967        31040 :                   i = n+1;  /* Finish loop.  */
   19968              :                 }
   19969              :               else
   19970              :                 {
   19971        89360 :                   i += 1;
   19972              :                 }
   19973              :             }
   19974              :         }
   19975       107206 :       PushTFrwtok (Sym, Type, rw, tokpos);
   19976              :     }
   19977       697255 : }
   19978              : 
   19979              : 
   19980              : /*
   19981              :    BuildDesignatorRecord - Builds the record referencing.
   19982              :                            The Stack is expected to contain:
   19983              : 
   19984              : 
   19985              :                            Entry                   Exit
   19986              :                            =====                   ====
   19987              : 
   19988              :                    Ptr ->
   19989              :                            +--------------+
   19990              :                            | n            |
   19991              :                            |--------------|
   19992              :                            | fld1 | type1 |
   19993              :                            |--------------|
   19994              :                            .              .
   19995              :                            .              .
   19996              :                            .              .
   19997              :                            |--------------|
   19998              :                            | fldn | typen |                        <- Ptr
   19999              :                            |--------------|        +-------------+
   20000              :                            | Sym  | Type  |        | S    | type1|
   20001              :                            |--------------|        |-------------|
   20002              : */
   20003              : 
   20004       117234 : extern "C" void M2Quads_BuildDesignatorRecord (unsigned int dottok)
   20005              : {
   20006       117234 :   unsigned int RecordTok;
   20007       117234 :   unsigned int FieldTok;
   20008       117234 :   unsigned int combinedtok;
   20009       117234 :   unsigned int n;
   20010       117234 :   unsigned int rw;
   20011       117234 :   unsigned int Field;
   20012       117234 :   unsigned int FieldType;
   20013       117234 :   unsigned int RecordSym;
   20014       117234 :   unsigned int Res;
   20015              : 
   20016       117234 :   M2Quads_PopT (&n);
   20017       117234 :   RecordSym = static_cast<unsigned int> (M2Quads_OperandT (n+1));
   20018              :   /* RecordType could be found by:  SkipType (OperandF (n+1)).  */
   20019       117234 :   RecordTok = static_cast<unsigned int> (M2Quads_OperandTok (n+1));
   20020       117234 :   rw = static_cast<unsigned int> (OperandMergeRW (n+1));
   20021       117234 :   M2Debug_Assert (SymbolTable_IsLegal (rw));
   20022       117234 :   Field = static_cast<unsigned int> (M2Quads_OperandT (n));
   20023       117234 :   FieldType = SymbolTable_SkipType (M2Quads_OperandF (n));
   20024       117234 :   FieldTok = static_cast<unsigned int> (M2Quads_OperandTok (n));
   20025       117234 :   combinedtok = M2LexBuf_MakeVirtualTok (dottok, RecordTok, FieldTok);
   20026       117234 :   if (n > 1)
   20027              :     {
   20028            0 :       M2Error_InternalError ((const char *) "not expecting to see n>1", 24);
   20029              :     }
   20030       117234 :   if (SymbolTable_IsUnused (Field))
   20031              :     {
   20032            0 :       M2MetaError_MetaErrors1 ((const char *) "record field {%1Dad} was declared as unused by a pragma", 55, (const char *) "record field {%1ad} is being used after being declared as unused by a pragma", 76, Field);
   20033              :     }
   20034       117234 :   Res = SymbolTable_MakeComponentRef (SymbolTable_MakeComponentRecord (combinedtok, SymbolTable_RightValue, RecordSym), Field);
   20035       117234 :   SymbolTable_PutVarConst (Res, IsReadOnly (RecordSym));
   20036       117234 :   GenQuadO (combinedtok, M2Quads_RecordFieldOp, Res, RecordSym, Field, false);
   20037       117234 :   M2Quads_PopN (n+1);
   20038       117234 :   PushTFrwtok (Res, FieldType, rw, combinedtok);
   20039       117234 : }
   20040              : 
   20041              : 
   20042              : /*
   20043              :    BuildDesignatorArray - Builds the array referencing.
   20044              :                           The purpose of this procedure is to work out
   20045              :                           whether the DesignatorArray is a constant string or
   20046              :                           dynamic array/static array and to call the appropriate
   20047              :                           BuildRoutine.
   20048              : 
   20049              :                           The Stack is expected to contain:
   20050              : 
   20051              :                           Entry                   Exit
   20052              :                           =====                   ====
   20053              : 
   20054              :                   Ptr ->
   20055              :                           +--------------+
   20056              :                           | e            |                        <- Ptr
   20057              :                           |--------------|        +------------+
   20058              :                           | Sym  | Type  |        | S    | T   |
   20059              :                           |--------------|        |------------|
   20060              : */
   20061              : 
   20062        57026 : extern "C" void M2Quads_BuildDesignatorArray (void)
   20063              : {
   20064        57026 :   if ((SymbolTable_IsConst (M2Quads_OperandT (2))) && (SymbolTable_IsConstString (M2Quads_OperandT (2))))
   20065              :     {
   20066            6 :       M2MetaError_MetaErrorT1 (OperandTtok (2), (const char *) "{%1Ead} is not an array, but a constant string.  Hint use a string constant created with an array constructor", 109, M2Quads_OperandT (2));
   20067            6 :       BuildDesignatorError ((const char *) "bad array access", 16);
   20068              :     }
   20069              :   else
   20070              :     {
   20071        57020 :       BuildDesignatorArrayStaticDynamic ();
   20072              :     }
   20073        57020 : }
   20074              : 
   20075              : 
   20076              : /*
   20077              :    BuildDesignatorPointer - Builds a pointer reference.
   20078              :                             The Stack is expected to contain:
   20079              : 
   20080              : 
   20081              :                             Entry                   Exit
   20082              :                             =====                   ====
   20083              : 
   20084              :                     Ptr ->                                           <- Ptr
   20085              :                             +--------------+        +--------------+
   20086              :                             | Sym1  | Type1|        | Sym2  | Type2|
   20087              :                             |--------------|        |--------------|
   20088              : */
   20089              : 
   20090        20106 : extern "C" void M2Quads_BuildDesignatorPointer (unsigned int ptrtok)
   20091              : {
   20092        20106 :   unsigned int combinedtok;
   20093        20106 :   unsigned int destok;
   20094        20106 :   unsigned int rw;
   20095        20106 :   unsigned int Sym1;
   20096        20106 :   unsigned int Type1;
   20097        20106 :   unsigned int Sym2;
   20098        20106 :   unsigned int Type2;
   20099              : 
   20100        20106 :   PopTFrwtok (&Sym1, &Type1, &rw, &destok);
   20101        20106 :   DebugLocation (destok, (const char *) "des ptr expression", 18);
   20102        20106 :   Type1 = SymbolTable_SkipType (Type1);
   20103        20106 :   if (Type1 == SymbolTable_NulSym)
   20104              :     {
   20105            0 :       M2MetaError_MetaErrorT1 (ptrtok, (const char *) "{%1ad} has no type and therefore cannot be dereferenced by ^", 60, Sym1);
   20106              :     }
   20107        20106 :   else if (SymbolTable_IsUnknown (Sym1))
   20108              :     {
   20109              :       /* avoid dangling else.  */
   20110              :       /* Spellcheck.  */
   20111            0 :       M2MetaError_MetaError1 ((const char *) "{%1EMad} is undefined and therefore {%1ad}^ cannot be resolved {%1&s}", 69, Sym1);
   20112            0 :       SymbolTable_UnknownReported (Sym1);
   20113              :     }
   20114              :   else
   20115              :     {
   20116              :       /* avoid dangling else.  */
   20117        20106 :       combinedtok = M2LexBuf_MakeVirtual2Tok (destok, ptrtok);
   20118        20106 :       if (SymbolTable_IsPointer (Type1))
   20119              :         {
   20120        20104 :           Type2 = SymbolTable_GetSType (Type1);
   20121        20104 :           Sym2 = SymbolTable_MakeTemporary (ptrtok, SymbolTable_LeftValue);
   20122              :           /* 
   20123              :           Ok must reference by address
   20124              :           - but we contain the type of the referenced entity
   20125              :   */
   20126        20104 :           MarkAsRead (rw);
   20127        20104 :           SymbolTable_PutVarPointerCheck (Sym1, true);
   20128        20104 :           CheckPointerThroughNil (ptrtok, Sym1);
   20129        20104 :           if ((SymbolTable_GetMode (Sym1)) == SymbolTable_LeftValue)
   20130              :             {
   20131          510 :               rw = SymbolTable_NulSym;
   20132          510 :               SymbolTable_PutLeftValueFrontBackType (Sym2, Type2, Type1);
   20133          510 :               GenQuadO (ptrtok, M2Quads_IndrXOp, Sym2, Type1, Sym1, false);  /* Sym2 := *Sym1.  */
   20134              :             }
   20135              :           else
   20136              :             {
   20137        19594 :               SymbolTable_PutLeftValueFrontBackType (Sym2, Type2, SymbolTable_NulSym);
   20138        19594 :               GenQuadO (ptrtok, M2Quads_BecomesOp, Sym2, SymbolTable_NulSym, Sym1, false);  /* Sym2 :=  Sym1.  */
   20139              :             }
   20140              :           /* We should check this for Sym2 later on (pointer via NIL).  */
   20141        20104 :           SymbolTable_PutVarPointerCheck (Sym2, true);
   20142        20104 :           PushTFrwtok (Sym2, Type2, rw, combinedtok);
   20143        20104 :           DebugLocation (combinedtok, (const char *) "pointer expression", 18);
   20144              :         }
   20145            2 :       else if ((SymbolTable_IsHiddenType (Type1)) && ((SymbolTable_GetModuleScope (Type1)) != (SymbolTable_GetCurrentModuleScope ())))
   20146              :         {
   20147              :           /* avoid dangling else.  */
   20148            2 :           M2MetaError_MetaErrorT1 (ptrtok, (const char *) "{%1Ead} is declared with an opaque type from a different module and cannot be dereferenced", 90, Sym1);
   20149            2 :           MarkAsRead (rw);
   20150            2 :           BuildDesignatorPointerError (Type1, rw, combinedtok, (const char *) "bad opaque pointer dereference", 30);
   20151              :         }
   20152              :       else
   20153              :         {
   20154              :           /* avoid dangling else.  */
   20155            0 :           M2MetaError_MetaError2 ((const char *) "{%1Ead} is not a pointer type but a {%2dv}", 42, Sym1, Type1);
   20156            0 :           MarkAsRead (rw);
   20157            0 :           BuildDesignatorPointerError (Type1, rw, combinedtok, (const char *) "bad pointer dereference", 23);
   20158              :         }
   20159              :     }
   20160        20106 : }
   20161              : 
   20162              : 
   20163              : /*
   20164              :    BuildNulExpression - Builds a nul expression on the stack.
   20165              :                         The Stack:
   20166              : 
   20167              :                         Entry             Exit
   20168              : 
   20169              :                                                          <- Ptr
   20170              :                         Empty             +------------+
   20171              :                                           | NulSym     |
   20172              :                                           |------------|
   20173              :    tokpos is the position of the RETURN token.
   20174              : */
   20175              : 
   20176          852 : extern "C" void M2Quads_BuildNulExpression (unsigned int tokpos)
   20177              : {
   20178          852 :   M2Quads_PushTtok (static_cast<unsigned int> (SymbolTable_NulSym), tokpos);
   20179          852 : }
   20180              : 
   20181              : 
   20182              : /*
   20183              :    BuildSetStart - Pushes a Bitset type on the stack.
   20184              : 
   20185              :                       The Stack:
   20186              : 
   20187              :                       Entry             Exit
   20188              : 
   20189              :                Ptr ->                                        <- Ptr
   20190              : 
   20191              :                       Empty             +--------------+
   20192              :                                         | Bitset       |
   20193              :                                         |--------------|
   20194              : */
   20195              : 
   20196            0 : extern "C" void M2Quads_BuildSetStart (unsigned int tokpos)
   20197              : {
   20198            0 :   M2Quads_PushTtok (M2Bitset_Bitset, tokpos);
   20199            0 : }
   20200              : 
   20201              : 
   20202              : /*
   20203              :    BuildSetEnd - pops the set value and type from the stack
   20204              :                  and pushes the value,type pair.
   20205              : 
   20206              :                     Entry                   Exit
   20207              : 
   20208              :              Ptr ->
   20209              :                     +--------------+
   20210              :                     | Set Value    |                         <- Ptr
   20211              :                     |--------------|        +--------------+
   20212              :                     | Set Type     |        | Value | Type |
   20213              :                     |--------------|        |--------------|
   20214              : */
   20215              : 
   20216            0 : extern "C" void M2Quads_BuildSetEnd (void)
   20217              : {
   20218            0 :   unsigned int valuepos;
   20219            0 :   unsigned int typepos;
   20220            0 :   unsigned int combined;
   20221            0 :   unsigned int value;
   20222            0 :   unsigned int type;
   20223              : 
   20224            0 :   M2Quads_PopTtok (&value, &valuepos);
   20225            0 :   M2Quads_PopTtok (&type, &typepos);
   20226            0 :   combined = M2LexBuf_MakeVirtual2Tok (typepos, valuepos);
   20227            0 :   M2Quads_PushTFtok (value, type, combined);
   20228            0 :   M2Debug_Assert (SymbolTable_IsSet (type));
   20229            0 : }
   20230              : 
   20231              : 
   20232              : /*
   20233              :    BuildEmptySet - Builds an empty set on the stack.
   20234              :                    The Stack:
   20235              : 
   20236              :                    Entry             Exit
   20237              : 
   20238              :                                                      <- Ptr
   20239              :                                      +-------------+
   20240              :             Ptr ->                   | Value       |
   20241              :                    +-----------+     |-------------|
   20242              :                    | SetType   |     | SetType     |
   20243              :                    |-----------|     |-------------|
   20244              : 
   20245              :    tokpos points to the opening '{'.
   20246              : */
   20247              : 
   20248            0 : extern "C" void M2Quads_BuildEmptySet (unsigned int tokpos)
   20249              : {
   20250            0 :   NameKey_Name n;
   20251            0 :   unsigned int typepos;
   20252            0 :   unsigned int Type;
   20253            0 :   unsigned int NulSet;
   20254              : 
   20255            0 :   M2Quads_PopTtok (&Type, &typepos);  /* type of set we are building  */
   20256            0 :   if ((Type == SymbolTable_NulSym) && M2Options_Pim)
   20257              :     {
   20258              :       /* allowed generic {} in PIM Modula-2  */
   20259            0 :       typepos = tokpos;
   20260              :     }
   20261            0 :   else if (SymbolTable_IsUnknown (Type))
   20262              :     {
   20263              :       /* avoid dangling else.  */
   20264              :       /* Spellcheck.  */
   20265            0 :       M2MetaError_MetaError1 ((const char *) "set type {%1a} is undefined {%1&s}", 34, Type);
   20266            0 :       SymbolTable_UnknownReported (Type);
   20267            0 :       Type = M2Bitset_Bitset;
   20268              :     }
   20269            0 :   else if (! (SymbolTable_IsSet (SymbolTable_SkipType (Type))))
   20270              :     {
   20271              :       /* avoid dangling else.  */
   20272            0 :       M2MetaError_MetaError1 ((const char *) "expecting a set type {%1a} and not a {%1d}", 42, Type);
   20273            0 :       Type = M2Bitset_Bitset;
   20274              :     }
   20275              :   else
   20276              :     {
   20277              :       /* avoid dangling else.  */
   20278            0 :       Type = SymbolTable_SkipType (Type);
   20279            0 :       M2Debug_Assert (Type != SymbolTable_NulSym);
   20280              :     }
   20281            0 :   NulSet = SymbolTable_MakeTemporary (typepos, SymbolTable_ImmediateValue);
   20282            0 :   SymbolTable_PutVar (NulSet, Type);
   20283            0 :   SymbolTable_PutConstSet (NulSet);
   20284            0 :   if (M2Options_CompilerDebugging)
   20285              :     {
   20286            0 :       n = SymbolTable_GetSymName (Type);
   20287            0 :       M2Printf_printf1 ((const char *) "set type = %a\\n", 15, (const unsigned char *) &n, (sizeof (n)-1));
   20288              :     }
   20289            0 :   M2ALU_PushNulSet (Type);  /* onto the ALU stack  */
   20290            0 :   SymbolTable_PopValue (NulSet);  /* ALU -> symbol table  */
   20291              :   /* and now construct the M2Quads stack as defined by the comments above  */
   20292            0 :   M2Quads_PushTtok (Type, typepos);
   20293            0 :   M2Quads_PushTtok (NulSet, typepos);
   20294            0 :   if (M2Options_CompilerDebugging)
   20295              :     {
   20296            0 :       n = SymbolTable_GetSymName (Type);
   20297            0 :       M2Printf_printf2 ((const char *) "Type = %a  (%d)  built empty set\\n", 34, (const unsigned char *) &n, (sizeof (n)-1), (const unsigned char *) &Type, (sizeof (Type)-1));
   20298            0 :       M2Quads_DisplayStack ();  /* Debugging info  */
   20299              :     }
   20300            0 : }
   20301              : 
   20302              : 
   20303              : /*
   20304              :    BuildInclRange - includes a set range with a set.
   20305              : 
   20306              : 
   20307              :                           Entry                   Exit
   20308              :                           =====                   ====
   20309              : 
   20310              : 
   20311              :                    Ptr ->
   20312              :                           +------------+
   20313              :                           | El2        |
   20314              :                           |------------|
   20315              :                           | El1        |                                 <- Ptr
   20316              :                           |------------|           +-------------------+
   20317              :                           | Set Value  |           | Value + {El1..El2}|
   20318              :                           |------------|           |-------------------|
   20319              : 
   20320              :                    No quadruples produced as the range info is contained within
   20321              :                    the set value.
   20322              : */
   20323              : 
   20324            0 : extern "C" void M2Quads_BuildInclRange (void)
   20325              : {
   20326            0 :   NameKey_Name n;
   20327            0 :   unsigned int el1;
   20328            0 :   unsigned int el2;
   20329            0 :   unsigned int value;
   20330              : 
   20331            0 :   M2Quads_PopT (&el2);
   20332            0 :   SafeCheckWithField ();
   20333            0 :   M2Quads_PopT (&el1);
   20334            0 :   SafeCheckWithField ();
   20335            0 :   M2Quads_PopT (&value);
   20336            0 :   if (! (SymbolTable_IsConstSet (value)))
   20337              :     {
   20338            0 :       n = SymbolTable_GetSymName (el1);
   20339            0 :       M2Error_WriteFormat1 ((const char *) "can only add bit ranges to a constant set, %a is not a constant set", 67, (const unsigned char *) &n, (sizeof (n)-1));
   20340              :     }
   20341            0 :   if ((SymbolTable_IsConst (el1)) && (SymbolTable_IsConst (el2)))
   20342              :     {
   20343            0 :       SymbolTable_PushValue (value);  /* onto ALU stack  */
   20344            0 :       M2ALU_AddBitRange (M2LexBuf_GetTokenNo (), el1, el2);  /* onto ALU stack  */
   20345            0 :       SymbolTable_PopValue (value);  /* ALU -> symboltable  */
   20346              :     }
   20347              :   else
   20348              :     {
   20349            0 :       if (! (SymbolTable_IsConst (el1)))
   20350              :         {
   20351            0 :           n = SymbolTable_GetSymName (el1);
   20352            0 :           M2Error_WriteFormat1 ((const char *) "must use constants as ranges when defining a set constant, problem with the low value %a", 88, (const unsigned char *) &n, (sizeof (n)-1));
   20353              :         }
   20354            0 :       if (! (SymbolTable_IsConst (el2)))
   20355              :         {
   20356            0 :           n = SymbolTable_GetSymName (el2);
   20357            0 :           M2Error_WriteFormat1 ((const char *) "must use constants as ranges when defining a set constant, problem with the high value %a", 89, (const unsigned char *) &n, (sizeof (n)-1));
   20358              :         }
   20359              :     }
   20360            0 :   M2Quads_PushT (value);
   20361            0 : }
   20362              : 
   20363              : 
   20364              : /*
   20365              :    BuildInclBit - includes a bit into the set.
   20366              : 
   20367              :                          Entry                   Exit
   20368              :                          =====                   ====
   20369              : 
   20370              : 
   20371              :                   Ptr ->
   20372              :                          +------------+
   20373              :                          | Element    |                         <- Ptr
   20374              :                          |------------|          +------------+
   20375              :                          | Value      |          | Value      |
   20376              :                          |------------|          |------------|
   20377              : 
   20378              : */
   20379              : 
   20380        12100 : extern "C" void M2Quads_BuildInclBit (void)
   20381              : {
   20382        12100 :   unsigned int tok;
   20383        12100 :   unsigned int el;
   20384        12100 :   unsigned int value;
   20385        12100 :   unsigned int t;
   20386              : 
   20387        12100 :   SafeCheckWithField ();
   20388        12100 :   M2Quads_PopT (&el);
   20389        12100 :   M2Quads_PopT (&value);
   20390        12100 :   tok = M2LexBuf_GetTokenNo ();
   20391        12100 :   if (SymbolTable_IsConst (el))
   20392              :     {
   20393        11966 :       SymbolTable_PushValue (value);  /* onto ALU stack  */
   20394        11966 :       M2ALU_AddBit (tok, el);  /* onto ALU stack  */
   20395        11966 :       SymbolTable_PopValue (value);  /* ALU -> symboltable  */
   20396              :     }
   20397              :   else
   20398              :     {
   20399          134 :       if ((SymbolTable_GetMode (el)) == SymbolTable_LeftValue)
   20400              :         {
   20401            0 :           t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
   20402            0 :           SymbolTable_PutVar (t, SymbolTable_GetSType (el));
   20403            0 :           CheckPointerThroughNil (tok, el);
   20404            0 :           doIndrX (tok, t, el);
   20405            0 :           el = t;
   20406              :         }
   20407          134 :       if (SymbolTable_IsConst (value))
   20408              :         {
   20409              :           /* Move constant or record field into a variable to achieve the include.  */
   20410          134 :           t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
   20411          134 :           SymbolTable_PutVar (t, SymbolTable_GetSType (value));
   20412          134 :           GenQuad (M2Quads_BecomesOp, t, SymbolTable_NulSym, value);
   20413          134 :           value = t;
   20414              :         }
   20415          134 :       GenQuad (M2Quads_InclOp, value, SymbolTable_NulSym, el);
   20416              :     }
   20417        12100 :   M2Quads_PushT (value);
   20418        12100 : }
   20419              : 
   20420              : 
   20421              : /*
   20422              :    SilentBuildConstructor - places NulSym into the constructor fifo queue.
   20423              : */
   20424              : 
   20425            0 : extern "C" void M2Quads_SilentBuildConstructor (void)
   20426              : {
   20427            0 :   FifoQueue_PutConstructorIntoFifoQueue (SymbolTable_NulSym);
   20428            0 : }
   20429              : 
   20430              : 
   20431              : /*
   20432              :    SilentBuildConstructorStart - removes an entry from the constructor fifo queue.
   20433              : */
   20434              : 
   20435        25984 : extern "C" void M2Quads_SilentBuildConstructorStart (void)
   20436              : {
   20437        25984 :   unsigned int constValue;
   20438              : 
   20439        25984 :   FifoQueue_GetConstructorFromFifoQueue (&constValue);
   20440        25984 : }
   20441              : 
   20442              : 
   20443              : /*
   20444              :    BuildConstructor - builds a constructor.
   20445              :                       Stack
   20446              : 
   20447              :                       Entry                 Exit
   20448              : 
   20449              :                Ptr ->
   20450              :                       +------------+
   20451              :                       | Type       |                <- Ptr
   20452              :                       |------------+
   20453              : */
   20454              : 
   20455        37178 : extern "C" void M2Quads_BuildConstructor (unsigned int tokcbrpos)
   20456              : {
   20457        37178 :   unsigned int tok;
   20458        37178 :   unsigned int constValue;
   20459        37178 :   unsigned int type;
   20460              : 
   20461        37178 :   M2Quads_PopTtok (&type, &tok);
   20462        37178 :   constValue = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
   20463        37178 :   SymbolTable_PutVar (constValue, type);
   20464        37178 :   SymbolTable_PutConstructor (constValue);
   20465        37178 :   SymbolTable_PushValue (constValue);
   20466        37178 :   if (type == SymbolTable_NulSym)
   20467              :     {
   20468            6 :       M2MetaError_MetaErrorT0 (tokcbrpos, (const char *) "{%E}constructor requires a type before the opening %{", 53);
   20469              :     }
   20470              :   else
   20471              :     {
   20472        37172 :       M2ALU_ChangeToConstructor (tok, type);
   20473        37172 :       SymbolTable_PutConstructorFrom (constValue, type);
   20474        37172 :       SymbolTable_PopValue (constValue);
   20475        37172 :       FifoQueue_PutConstructorIntoFifoQueue (constValue);
   20476              :     }
   20477        37178 :   PushConstructor (type);
   20478        37178 : }
   20479              : 
   20480              : 
   20481              : /*
   20482              :    BuildConstructorStart - builds a constructor.
   20483              :                            Stack
   20484              : 
   20485              :                            Entry                 Exit
   20486              : 
   20487              :                     Ptr ->                                          <- Ptr
   20488              :                            +------------+        +----------------+
   20489              :                            | Type       |        | ConstructorSym |
   20490              :                            |------------+        |----------------|
   20491              : */
   20492              : 
   20493        11182 : extern "C" void M2Quads_BuildConstructorStart (unsigned int cbratokpos)
   20494              : {
   20495        11182 :   unsigned int typepos;
   20496        11182 :   unsigned int constValue;
   20497        11182 :   unsigned int type;
   20498              : 
   20499        11182 :   M2Quads_PopTtok (&type, &typepos);  /* we ignore the type as we already have the constructor symbol from pass C  */
   20500        11182 :   FifoQueue_GetConstructorFromFifoQueue (&constValue);  /* we ignore the type as we already have the constructor symbol from pass C  */
   20501        11182 :   if (type != (SymbolTable_GetSType (constValue)))
   20502              :     {
   20503            0 :       M2MetaError_MetaErrorT3 (cbratokpos, (const char *) "{%E}the constructor type is {%1ad} and this is different from the constant {%2ad} which has a type {%2tad}", 106, type, constValue, constValue);
   20504              :     }
   20505        11182 :   M2Quads_PushTtok (constValue, cbratokpos);
   20506        11182 :   PushConstructor (type);
   20507        11182 : }
   20508              : 
   20509              : 
   20510              : /*
   20511              :    BuildConstructorEnd - removes the current constructor frame from the
   20512              :                          constructor stack (it does not effect the quad
   20513              :                          stack)
   20514              : 
   20515              :                          Entry                 Exit
   20516              : 
   20517              :                   Ptr ->                                      <- Ptr
   20518              :                          +------------+        +------------+
   20519              :                          | const      |        | const      |
   20520              :                          |------------|        |------------|
   20521              : 
   20522              :    startpos is the start of the constructor, either the typename or '{'
   20523              :    cbratokpos is the '}'.
   20524              : */
   20525              : 
   20526        11182 : extern "C" void M2Quads_BuildConstructorEnd (unsigned int startpos, unsigned int cbratokpos)
   20527              : {
   20528        11182 :   unsigned int value;
   20529        11182 :   unsigned int valtok;
   20530              : 
   20531        11182 :   if (DebugTokPos)
   20532              :     {
   20533              :       M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "startpos", 8), startpos);
   20534              :       M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "cbratokpos", 10), cbratokpos);
   20535              :     }
   20536        11182 :   M2Quads_PopTtok (&value, &valtok);
   20537        11182 :   if (DebugTokPos)
   20538              :     {
   20539              :       M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "value valtok", 12), valtok);
   20540              :     }
   20541        11182 :   valtok = M2LexBuf_MakeVirtual2Tok (startpos, cbratokpos);
   20542        11182 :   SymbolTable_PutDeclared (valtok, value);
   20543        11182 :   M2Quads_PushTtok (value, valtok);  /* Use valtok as we now know it was a constructor.  */
   20544        11182 :   M2Quads_PopConstructor ();  /* Use valtok as we now know it was a constructor.  */
   20545        11182 :   if (DebugTokPos)
   20546              :     {
   20547              :       M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "aggregate constant", 18), valtok);
   20548              :     }
   20549        11182 : }
   20550              : 
   20551              : 
   20552              : /*
   20553              :    NextConstructorField - increments the top of constructor stacks index by one.
   20554              : */
   20555              : 
   20556        35164 : extern "C" void M2Quads_NextConstructorField (void)
   20557              : {
   20558        35164 :   M2Quads_ConstructorFrame c;
   20559              : 
   20560        35164 :   c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PeepAddress (ConstructorStack, 1));
   20561        35164 :   c->index += 1;
   20562        35164 : }
   20563              : 
   20564              : 
   20565              : /*
   20566              :    BuildTypeForConstructor - pushes the type implied by the current constructor.
   20567              :                              If no constructor is currently being built then
   20568              :                              it Pushes a Bitset type.
   20569              : */
   20570              : 
   20571         1728 : extern "C" void M2Quads_BuildTypeForConstructor (unsigned int tokpos)
   20572              : {
   20573         1728 :   M2Quads_ConstructorFrame c;
   20574              : 
   20575         1728 :   if ((M2StackAddress_NoOfItemsInStackAddress (ConstructorStack)) == 0)
   20576              :     {
   20577          660 :       M2Quads_PushTtok (M2Bitset_Bitset, tokpos);
   20578              :     }
   20579              :   else
   20580              :     {
   20581         1068 :       c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PeepAddress (ConstructorStack, 1));
   20582         1068 :       if ((SymbolTable_IsArray (c->type)) || (SymbolTable_IsSet (c->type)))
   20583              :         {
   20584          972 :           M2Quads_PushTtok (SymbolTable_GetSType (c->type), tokpos);
   20585              :         }
   20586           96 :       else if (SymbolTable_IsRecord (c->type))
   20587              :         {
   20588              :           /* avoid dangling else.  */
   20589           96 :           M2Quads_PushTtok (SymbolTable_GetSType (SymbolTable_GetNth (c->type, c->index)), tokpos);
   20590              :         }
   20591              :       else
   20592              :         {
   20593              :           /* avoid dangling else.  */
   20594            0 :           M2MetaError_MetaError1 ((const char *) "{%1ad} is not a set, record or array type which is expected when constructing an aggregate entity", 97, c->type);
   20595              :         }
   20596              :     }
   20597         1728 : }
   20598              : 
   20599              : 
   20600              : /*
   20601              :    BuildComponentValue -  builds a component value.
   20602              : 
   20603              :                           Entry                 Exit
   20604              : 
   20605              :                    Ptr ->                                      <- Ptr
   20606              : 
   20607              : 
   20608              :                           +------------+        +------------+
   20609              :                           | const      |        | const      |
   20610              :                           |------------|        |------------|
   20611              : */
   20612              : 
   20613        26114 : extern "C" void M2Quads_BuildComponentValue (void)
   20614              : {
   20615        26114 :   unsigned int e1tok;
   20616        26114 :   unsigned int e2tok;
   20617        26114 :   unsigned int consttok;
   20618        26114 :   unsigned int virtpos;
   20619        26114 :   unsigned int const_;
   20620        26114 :   unsigned int e1;
   20621        26114 :   unsigned int e2;
   20622        26114 :   NameKey_Name nuldotdot;
   20623        26114 :   NameKey_Name nulby;
   20624              : 
   20625        26114 :   M2Quads_PopT (&nulby);
   20626        26114 :   if (nulby == M2Reserved_NulTok)
   20627              :     {
   20628        26084 :       M2Quads_PopT (&nuldotdot);
   20629        26084 :       if (nuldotdot == M2Reserved_NulTok)
   20630              :         {
   20631        25842 :           M2Quads_PopTtok (&e1, &e1tok);
   20632        25842 :           M2Quads_PopTtok (&const_, &consttok);
   20633        25842 :           const_ = AddFieldTo (const_, e1, consttok, e1tok);
   20634        25842 :           PushTFrwtok (const_, SymbolTable_GetSType (const_), static_cast<unsigned int> (SymbolTable_NulSym), M2LexBuf_MakeVirtual2Tok (consttok, e1tok));
   20635              :         }
   20636              :       else
   20637              :         {
   20638          242 :           M2Quads_PopTtok (&e2, &e2tok);
   20639          242 :           M2Quads_PopTtok (&e1, &e1tok);
   20640          242 :           M2Quads_PopTtok (&const_, &consttok);
   20641          242 :           SymbolTable_PushValue (const_);
   20642          242 :           M2ALU_AddBitRange (M2LexBuf_MakeVirtual2Tok (e1tok, e2tok), e1, e2);
   20643          242 :           SymbolTable_PopValue (const_);
   20644          242 :           PushTFrwtok (const_, SymbolTable_GetSType (const_), static_cast<unsigned int> (SymbolTable_NulSym), M2LexBuf_MakeVirtual2Tok (consttok, e2tok));
   20645              :         }
   20646              :     }
   20647              :   else
   20648              :     {
   20649           30 :       M2Quads_PopTtok (&e1, &e1tok);
   20650           30 :       M2Quads_PopT (&nuldotdot);
   20651           30 :       if (nuldotdot == M2Reserved_NulTok)
   20652              :         {
   20653           30 :           M2Quads_PopTtok (&e2, &e2tok);
   20654           30 :           M2Quads_PopTtok (&const_, &consttok);
   20655           30 :           SymbolTable_PushValue (const_);
   20656           30 :           M2ALU_AddElements (M2LexBuf_MakeVirtual2Tok (e1tok, e2tok), e2, e1);
   20657           30 :           SymbolTable_PopValue (const_);
   20658           30 :           PushTFrwtok (const_, SymbolTable_GetSType (const_), static_cast<unsigned int> (SymbolTable_NulSym), M2LexBuf_MakeVirtual2Tok (consttok, e2tok));
   20659              :         }
   20660              :       else
   20661              :         {
   20662            0 :           M2Quads_PopTtok (&e2, &e2tok);
   20663            0 :           M2Quads_PopTtok (&e1, &e1tok);
   20664            0 :           M2Quads_PopTtok (&const_, &consttok);
   20665            0 :           consttok = M2LexBuf_MakeVirtual2Tok (consttok, e2tok);
   20666            0 :           M2MetaError_MetaErrorT1 (consttok, (const char *) "the constant {%E1a} must be either an array constructor or a set constructor", 76, const_);
   20667            0 :           PushTFrwtok (const_, SymbolTable_GetSType (const_), static_cast<unsigned int> (SymbolTable_NulSym), consttok);
   20668              :         }
   20669              :     }
   20670        26114 : }
   20671              : 
   20672              : 
   20673              : /*
   20674              :    PopConstructor - removes the top constructor from the top of stack.
   20675              : */
   20676              : 
   20677        48360 : extern "C" void M2Quads_PopConstructor (void)
   20678              : {
   20679        48360 :   M2Quads_ConstructorFrame c;
   20680              : 
   20681        48360 :   c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PopAddress (ConstructorStack));
   20682        48360 :   Storage_DEALLOCATE ((void **) &c, sizeof (M2Quads__T1));
   20683        48360 : }
   20684              : 
   20685              : 
   20686              : /*
   20687              :    BuildNot   - Builds a NOT operation from the quad stack.
   20688              :                 The Stack is expected to contain:
   20689              : 
   20690              : 
   20691              :                   Entry                   Exit
   20692              :                   =====                   ====
   20693              : 
   20694              :            Ptr ->                                        <- Ptr
   20695              :                   +------------+          +------------+
   20696              :                   | t    | f   |          | f    | t   |
   20697              :                   |------------|          |------------|
   20698              : */
   20699              : 
   20700         4980 : extern "C" void M2Quads_BuildNot (unsigned int notTokPos)
   20701              : {
   20702         4980 :   unsigned int combinedTok;
   20703         4980 :   unsigned int exprTokPos;
   20704         4980 :   unsigned int t;
   20705         4980 :   unsigned int f;
   20706              : 
   20707         4980 :   CheckBooleanId ();
   20708         4980 :   PopBooltok (&t, &f, &exprTokPos);
   20709         4980 :   combinedTok = M2LexBuf_MakeVirtualTok (notTokPos, notTokPos, exprTokPos);
   20710         4980 :   PushBooltok (f, t, combinedTok);
   20711         4980 : }
   20712              : 
   20713              : 
   20714              : /*
   20715              :    RecordOp - Records the operator passed on the stack.
   20716              :               This is called when a boolean operator is found in an
   20717              :               expression.  It is called just after the lhs has been built
   20718              :               and pushed to the quad stack and prior to the rhs build.
   20719              :               It checks to see if AND OR or equality tests are required.
   20720              :               It will short circuit AND and OR expressions.  It also
   20721              :               converts a lhs to a boolean variable if an xor comparison
   20722              :               is about to be performed.
   20723              : 
   20724              :               Checks for AND operator or OR operator
   20725              :               if either of these operators are found then BackPatching
   20726              :               takes place.
   20727              :               The Expected Stack:
   20728              : 
   20729              :               Entry                        Exit
   20730              : 
   20731              :        Ptr ->                                               <- Ptr
   20732              :               +-------------+               +-------------+
   20733              :               | OperatorTok |               | OperatorTok |
   20734              :               |-------------|               |-------------|
   20735              :               | t    | f    |               | t    | f    |
   20736              :               |-------------|               |-------------|
   20737              : 
   20738              : 
   20739              :               If OperatorTok=AndTok
   20740              :               Then
   20741              :                  BackPatch(f, NextQuad)
   20742              :               Elsif OperatorTok=OrTok
   20743              :               Then
   20744              :                  BackPatch(t, NextQuad)
   20745              :               End
   20746              : */
   20747              : 
   20748       106143 : extern "C" void M2Quads_RecordOp (void)
   20749              : {
   20750       106143 :   NameKey_Name Op;
   20751       106143 :   unsigned int tokno;
   20752       106143 :   unsigned int t;
   20753       106143 :   unsigned int f;
   20754              : 
   20755       106143 :   M2Quads_PopTtok (&Op, &tokno);
   20756       106143 :   if ((Op == M2Reserved_AndTok) || (Op == M2Reserved_AmbersandTok))
   20757              :     {
   20758         9808 :       CheckBooleanId ();
   20759         9808 :       PopBool (&t, &f);
   20760         9808 :       BackPatch (t, NextQuad);
   20761         9808 :       PushBool (0, f);
   20762              :     }
   20763        96335 :   else if (Op == M2Reserved_OrTok)
   20764              :     {
   20765              :       /* avoid dangling else.  */
   20766         3630 :       CheckBooleanId ();
   20767         3630 :       PopBool (&t, &f);
   20768         3630 :       BackPatch (f, NextQuad);
   20769         3630 :       PushBool (t, 0);
   20770              :     }
   20771        92705 :   else if ((IsBoolean (1)) && ((((Op == M2Reserved_EqualTok) || (Op == M2Reserved_LessGreaterTok)) || (Op == M2Reserved_HashTok)) || (Op == M2Reserved_InTok)))
   20772              :     {
   20773              :       /* avoid dangling else.  */
   20774           52 :       ConvertBooleanToVariable (tokno, 1);
   20775              :     }
   20776       106143 :   M2Quads_PushTtok (Op, tokno);
   20777       106143 : }
   20778              : 
   20779              : 
   20780              : /*
   20781              :    BuildRelOp   - Builds a relative operation from the quad stack.
   20782              :                   The Stack is expected to contain:
   20783              : 
   20784              : 
   20785              :                   Entry                   Exit
   20786              :                   =====                   ====
   20787              : 
   20788              :            Ptr ->
   20789              :                   +------------+
   20790              :                   | e1         |
   20791              :                   |------------|                          <- Ptr
   20792              :                   | Operator   |
   20793              :                   |------------|          +------------+
   20794              :                   | e2         |          | t    | f   |
   20795              :                   |------------|          |------------|
   20796              : 
   20797              : 
   20798              :                     Quadruples Produced
   20799              : 
   20800              :                     q     IFOperator  e2  e1  TrueExit    ; e2  e1 since
   20801              :                     q+1   GotoOp              FalseExit   ; relation > etc
   20802              :                                                           ; requires order.
   20803              : */
   20804              : 
   20805        92296 : extern "C" void M2Quads_BuildRelOp (unsigned int optokpos)
   20806              : {
   20807        92296 :   unsigned int combinedTok;
   20808        92296 :   unsigned int rightpos;
   20809        92296 :   unsigned int leftpos;
   20810        92296 :   NameKey_Name Op;
   20811        92296 :   unsigned int t;
   20812        92296 :   unsigned int rightType;
   20813        92296 :   unsigned int leftType;
   20814        92296 :   unsigned int right;
   20815        92296 :   unsigned int left;
   20816        92296 :   DynamicStrings_String s;
   20817              : 
   20818        92296 :   if (M2Options_CompilerDebugging)
   20819              :     {
   20820            0 :       M2Quads_DisplayStack ();  /* Debugging info  */
   20821              :     }
   20822        92296 :   if (((M2Quads_IsInConstExpression ()) && (IsBoolean (1))) && (IsBoolean (3)))
   20823              :     {
   20824              :       /* 
   20825              :          we allow # and = to be used with Boolean expressions.
   20826              :          we do not allow >  <  >=  <=  though.  We only examine
   20827              :          this case if we are in a const expression as there will be
   20828              :          no dereferencing of operands.
   20829              :   */
   20830            0 :       BuildRelOpFromBoolean (optokpos);
   20831              :     }
   20832              :   else
   20833              :     {
   20834        92296 :       if (IsBoolean (1))
   20835              :         {
   20836           64 :           ConvertBooleanToVariable (OperandTtok (1), 1);
   20837              :         }
   20838        92296 :       if (IsBoolean (3))
   20839              :         {
   20840            0 :           ConvertBooleanToVariable (OperandTtok (3), 3);
   20841              :         }
   20842        92296 :       M2Quads_PopTFtok (&right, &rightType, &rightpos);
   20843        92296 :       M2Quads_PopT (&Op);
   20844        92296 :       M2Quads_PopTFtok (&left, &leftType, &leftpos);
   20845        92296 :       CheckVariableOrConstantOrProcedure (rightpos, right);
   20846        92296 :       CheckVariableOrConstantOrProcedure (leftpos, left);
   20847        92296 :       combinedTok = M2LexBuf_MakeVirtualTok (optokpos, leftpos, rightpos);
   20848        92296 :       if ((left != SymbolTable_NulSym) && (right != SymbolTable_NulSym))
   20849              :         {
   20850              :           /* BuildRange will check the expression later on once gcc knows about all data types.  */
   20851        92296 :           BuildRange (M2Range_InitTypesExpressionCheck (combinedTok, left, right, true, Op == M2Reserved_InTok));
   20852              :         }
   20853              :       /* Must dereference LeftValue operands.  */
   20854        92296 :       if ((SymbolTable_GetMode (right)) == SymbolTable_LeftValue)
   20855              :         {
   20856         1936 :           t = SymbolTable_MakeTemporary (rightpos, SymbolTable_RightValue);
   20857         1936 :           SymbolTable_PutVar (t, SymbolTable_GetSType (right));
   20858         1936 :           CheckPointerThroughNil (rightpos, right);
   20859         1936 :           doIndrX (rightpos, t, right);
   20860         1936 :           right = t;
   20861              :         }
   20862        92296 :       if ((SymbolTable_GetMode (left)) == SymbolTable_LeftValue)
   20863              :         {
   20864         6401 :           t = SymbolTable_MakeTemporary (leftpos, SymbolTable_RightValue);
   20865         6401 :           SymbolTable_PutVar (t, SymbolTable_GetSType (left));
   20866         6401 :           CheckPointerThroughNil (leftpos, left);
   20867         6401 :           doIndrX (leftpos, t, left);
   20868         6401 :           left = t;
   20869              :         }
   20870        92296 :       if (DebugTokPos)
   20871              :         {
   20872              :           s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (M2LexBuf_GetTokenName (Op)));
   20873              :           M2Error_WarnStringAt (s, optokpos);
   20874              :           s = DynamicStrings_InitString ((const char *) "left", 4);
   20875              :           M2Error_WarnStringAt (s, leftpos);
   20876              :           s = DynamicStrings_InitString ((const char *) "right", 5);
   20877              :           M2Error_WarnStringAt (s, rightpos);
   20878              :           s = DynamicStrings_InitString ((const char *) "caret", 5);
   20879              :           M2Error_WarnStringAt (s, optokpos);
   20880              :           s = DynamicStrings_InitString ((const char *) "combined", 8);
   20881              :           M2Error_WarnStringAt (s, combinedTok);
   20882              :         }
   20883        92296 :       GenQuadOtok (combinedTok, MakeOp (Op), left, right, 0, false, leftpos, rightpos, M2LexBuf_UnknownTokenNo);  /* True  Exit  */
   20884        92296 :       GenQuadO (combinedTok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);  /* False Exit  */
   20885        92296 :       PushBooltok (NextQuad-2, NextQuad-1, combinedTok);  /* False Exit  */
   20886              :     }
   20887        92296 : }
   20888              : 
   20889              : 
   20890              : /*
   20891              :    BuildBinaryOp   - Builds a binary operation from the quad stack.
   20892              :                      Be aware that this procedure will check for
   20893              :                      the overloading of the bitset operators + - \ *.
   20894              :                      So do NOT call this procedure if you are building
   20895              :                      a reference to an array which has a bitset type or
   20896              :                      the address arithmetic will be wrongly coersed into
   20897              :                      logical ORs.
   20898              : 
   20899              :                      The Stack is expected to contain:
   20900              : 
   20901              : 
   20902              :                      Entry                   Exit
   20903              :                      =====                   ====
   20904              : 
   20905              :               Ptr ->
   20906              :                      +------------+
   20907              :                      | Sym1       |
   20908              :                      |------------|
   20909              :                      | Operator   |                          <- Ptr
   20910              :                      |------------|          +------------+
   20911              :                      | Sym2       |          | Temporary  |
   20912              :                      |------------|          |------------|
   20913              : 
   20914              : 
   20915              :                      Quadruples Produced
   20916              : 
   20917              :                      q     Operator  Temporary  Sym1  Sym2
   20918              : 
   20919              : 
   20920              :                 OR
   20921              : 
   20922              : 
   20923              :                      Entry                   Exit
   20924              :                      =====                   ====
   20925              : 
   20926              :               Ptr ->
   20927              :                      +------------+
   20928              :                      | T1   | F1  |
   20929              :                      |------------|
   20930              :                      | OrTok      |                          <- Ptr
   20931              :                      |------------|          +------------+
   20932              :                      | T2   | F2  |          | T1+T2| F1  |
   20933              :                      |------------|          |------------|
   20934              : 
   20935              : 
   20936              :                      Quadruples Produced
   20937              : 
   20938              : */
   20939              : 
   20940        74142 : extern "C" void M2Quads_BuildBinaryOp (void)
   20941              : {
   20942        74142 :   doBuildBinaryOp (true, true);
   20943        74034 : }
   20944              : 
   20945              : 
   20946              : /*
   20947              :    BuildUnaryOp   - Builds a unary operation from the quad stack.
   20948              :                     The Stack is expected to contain:
   20949              : 
   20950              : 
   20951              :                     Entry                   Exit
   20952              :                     =====                   ====
   20953              : 
   20954              :              Ptr ->
   20955              :                     +------------+
   20956              :                     | Sym        |
   20957              :                     |------------|          +------------+
   20958              :                     | Operator   |          | Temporary  | <- Ptr
   20959              :                     |------------|          |------------|
   20960              : 
   20961              : 
   20962              :                     Quadruples Produced
   20963              : 
   20964              :                     q     Operator  Temporary  _ Sym
   20965              : 
   20966              : */
   20967              : 
   20968        21408 : extern "C" void M2Quads_BuildUnaryOp (void)
   20969              : {
   20970        21408 :   unsigned int sympos;
   20971        21408 :   unsigned int tokpos;
   20972        21408 :   NameKey_Name Tok;
   20973        21408 :   unsigned int type;
   20974        21408 :   unsigned int Sym;
   20975        21408 :   unsigned int SymT;
   20976        21408 :   unsigned int r;
   20977        21408 :   unsigned int t;
   20978              : 
   20979        21408 :   PopTrwtok (&Sym, &r, &sympos);
   20980        21408 :   M2Quads_PopTtok (&Tok, &tokpos);
   20981        21408 :   if (Tok == M2Reserved_MinusTok)
   20982              :     {
   20983        21252 :       MarkAsRead (r);
   20984        21252 :       type = M2Base_NegateType (SymbolTable_GetSType (Sym));  /* , sympos  */
   20985        21252 :       tokpos = M2LexBuf_MakeVirtualTok (tokpos, tokpos, sympos);
   20986        42504 :       t = SymbolTable_MakeTemporary (tokpos, AreConstant (SymbolTable_IsConst (Sym)));
   20987        21252 :       SymbolTable_PutVar (t, type);
   20988              :       /* 
   20989              :          variables must have a type and REAL/LONGREAL constants must
   20990              :          be typed
   20991              :   */
   20992        21252 :       if (! (SymbolTable_IsConst (Sym)))
   20993              :         {
   20994              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   20995         1002 :           if ((type != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_SkipType (type))))
   20996              :             {}  /* empty.  */
   20997              :           /* do not dereference set variables  */
   20998          924 :           else if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
   20999              :             {
   21000              :               /* avoid dangling else.  */
   21001              :               /* dereference symbols which are not sets and which are variables  */
   21002            0 :               SymT = SymbolTable_MakeTemporary (sympos, SymbolTable_RightValue);
   21003            0 :               SymbolTable_PutVar (SymT, SymbolTable_GetSType (Sym));
   21004            0 :               CheckPointerThroughNil (sympos, Sym);
   21005            0 :               doIndrX (sympos, SymT, Sym);
   21006            0 :               Sym = SymT;
   21007              :             }
   21008              :         }
   21009        21252 :       GenQuadO (tokpos, M2Quads_NegateOp, t, SymbolTable_NulSym, Sym, true);
   21010        21252 :       M2Quads_PushTtok (t, tokpos);
   21011              :     }
   21012          156 :   else if (Tok == M2Reserved_PlusTok)
   21013              :     {
   21014              :       /* avoid dangling else.  */
   21015          156 :       tokpos = M2LexBuf_MakeVirtualTok (tokpos, tokpos, sympos);
   21016          156 :       PushTrwtok (Sym, r, tokpos);
   21017              :     }
   21018              :   else
   21019              :     {
   21020              :       /* avoid dangling else.  */
   21021            0 :       M2MetaError_MetaErrorNT1 (tokpos, (const char *) "expecting an unary operator, seen {%Ek%a}", 41, Tok);
   21022              :     }
   21023        21408 : }
   21024              : 
   21025              : 
   21026              : /*
   21027              :    OperandT - returns the ident operand stored in the true position on the boolean stack.
   21028              : */
   21029              : 
   21030    214541580 : extern "C" unsigned int M2Quads_OperandT (unsigned int pos)
   21031              : {
   21032    214541580 :   M2Debug_Assert (! (IsBoolean (pos)));
   21033    214541580 :   return OperandTno (pos);
   21034              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   21035              :   __builtin_unreachable ();
   21036              : }
   21037              : 
   21038              : 
   21039              : /*
   21040              :    OperandF - returns the ident operand stored in the false position on the boolean stack.
   21041              : */
   21042              : 
   21043       178228 : extern "C" unsigned int M2Quads_OperandF (unsigned int pos)
   21044              : {
   21045       178228 :   M2Debug_Assert (! (IsBoolean (pos)));
   21046       178228 :   return OperandFno (pos);
   21047              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   21048              :   __builtin_unreachable ();
   21049              : }
   21050              : 
   21051              : 
   21052              : /*
   21053              :    PushTF - Push a True and False numbers onto the True/False stack.
   21054              :             True and False are assumed to contain Symbols or Ident etc.
   21055              : */
   21056              : 
   21057     15994640 : extern "C" void M2Quads_PushTF (unsigned int True, unsigned int False)
   21058              : {
   21059     15994640 :   M2Quads_BoolFrame f;
   21060              : 
   21061     15994640 :   f = newBoolFrame ();
   21062     15994640 :   f->TrueExit = static_cast<unsigned int> (True);
   21063     15994640 :   f->FalseExit = static_cast<unsigned int> (False);
   21064     15994640 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21065     15994640 : }
   21066              : 
   21067              : 
   21068              : /*
   21069              :    PopTF - Pop a True and False number from the True/False stack.
   21070              :            True and False are assumed to contain Symbols or Ident etc.
   21071              : */
   21072              : 
   21073     10767703 : extern "C" void M2Quads_PopTF (unsigned int *True, unsigned int *False)
   21074              : {
   21075     10767703 :   M2Quads_BoolFrame f;
   21076              : 
   21077     10767703 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   21078     10767703 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   21079     10767703 :   (*False) = static_cast<unsigned int> (f->FalseExit);
   21080     10767703 :   M2Debug_Assert (! f->BooleanOp);
   21081     10767703 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   21082     10767703 : }
   21083              : 
   21084              : 
   21085              : /*
   21086              :    PushT - Push an item onto the stack in the T (true) position.
   21087              : */
   21088              : 
   21089     99242185 : extern "C" void M2Quads_PushT (unsigned int True)
   21090              : {
   21091     99242185 :   M2Quads_BoolFrame f;
   21092              : 
   21093     99242185 :   f = newBoolFrame ();
   21094     99242185 :   f->TrueExit = static_cast<unsigned int> (True);
   21095     99242185 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21096     99242185 : }
   21097              : 
   21098              : 
   21099              : /*
   21100              :    PopT - Pops the T value from the stack.
   21101              : */
   21102              : 
   21103    146412772 : extern "C" void M2Quads_PopT (unsigned int *True)
   21104              : {
   21105    146412772 :   M2Quads_BoolFrame f;
   21106              : 
   21107    146412772 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   21108    146412766 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   21109    146412766 :   M2Debug_Assert (! f->BooleanOp);
   21110    146412766 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   21111    146412766 : }
   21112              : 
   21113              : 
   21114              : /*
   21115              :    PushTtok - Push an item onto the stack in the T (true) position,
   21116              :               it is assummed to be a token and its token location is recorded.
   21117              : */
   21118              : 
   21119     78853375 : extern "C" void M2Quads_PushTtok (unsigned int True, unsigned int tokno)
   21120              : {
   21121     78853375 :   M2Quads_BoolFrame f;
   21122              : 
   21123              :   /* PrintTokenNo (tokno) ;  */
   21124     78853375 :   f = newBoolFrame ();
   21125     78853375 :   f->TrueExit = static_cast<unsigned int> (True);
   21126     78853375 :   f->tokenno = tokno;
   21127     78853375 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21128     78853375 : }
   21129              : 
   21130              : 
   21131              : /*
   21132              :    PushTFtok - Push an item onto the stack in the T (true) position,
   21133              :                it is assummed to be a token and its token location is recorded.
   21134              : */
   21135              : 
   21136    157509383 : extern "C" void M2Quads_PushTFtok (unsigned int True, unsigned int False, unsigned int tokno)
   21137              : {
   21138    157509383 :   M2Quads_BoolFrame f;
   21139              : 
   21140    157509383 :   f = newBoolFrame ();
   21141    157509383 :   f->TrueExit = static_cast<unsigned int> (True);
   21142    157509383 :   f->FalseExit = static_cast<unsigned int> (False);
   21143    157509383 :   f->tokenno = tokno;
   21144    157509383 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21145    157509383 : }
   21146              : 
   21147              : 
   21148              : /*
   21149              :    PopTFtok - Pop T/F/tok from the stack.
   21150              : */
   21151              : 
   21152      9521079 : extern "C" void M2Quads_PopTFtok (unsigned int *True, unsigned int *False, unsigned int *tokno)
   21153              : {
   21154      9521079 :   M2Quads_BoolFrame f;
   21155              : 
   21156      9521079 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   21157      9521079 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   21158      9521079 :   (*False) = static_cast<unsigned int> (f->FalseExit);
   21159      9521079 :   (*tokno) = f->tokenno;
   21160      9521079 : }
   21161              : 
   21162              : 
   21163              : /*
   21164              :    PushTFAtok - Push T/F/A/tok to the stack.
   21165              : */
   21166              : 
   21167           54 : extern "C" void M2Quads_PushTFAtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int tokno)
   21168              : {
   21169           54 :   M2Quads_BoolFrame f;
   21170              : 
   21171           54 :   f = newBoolFrame ();
   21172           54 :   f->TrueExit = static_cast<unsigned int> (True);
   21173           54 :   f->FalseExit = static_cast<unsigned int> (False);
   21174           54 :   f->Unbounded = static_cast<unsigned int> (Array);
   21175           54 :   f->tokenno = tokno;
   21176           54 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21177           54 : }
   21178              : 
   21179              : 
   21180              : /*
   21181              :    PopTtok - Pops the T value from the stack and token position.
   21182              : */
   21183              : 
   21184    117890707 : extern "C" void M2Quads_PopTtok (unsigned int *True, unsigned int *tok)
   21185              : {
   21186    117890707 :   M2Quads_BoolFrame f;
   21187              : 
   21188    117890707 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   21189    117890707 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   21190    117890707 :   (*tok) = f->tokenno;
   21191    117890707 :   M2Debug_Assert (! f->BooleanOp);
   21192    117890707 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   21193    117890707 : }
   21194              : 
   21195              : 
   21196              : /*
   21197              :    PushTFn - Push a True and False numbers onto the True/False stack.
   21198              :              True and False are assumed to contain Symbols or Ident etc.
   21199              : */
   21200              : 
   21201            0 : extern "C" void M2Quads_PushTFn (unsigned int True, unsigned int False, unsigned int n)
   21202              : {
   21203            0 :   M2Quads_BoolFrame f;
   21204              : 
   21205            0 :   f = newBoolFrame ();
   21206            0 :   f->TrueExit = static_cast<unsigned int> (True);
   21207            0 :   f->FalseExit = static_cast<unsigned int> (False);
   21208            0 :   f->name = static_cast<unsigned int> (n);
   21209            0 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21210            0 : }
   21211              : 
   21212              : 
   21213              : /*
   21214              :    PushTFntok - Push a True and False numbers onto the True/False stack.
   21215              :                 True and False are assumed to contain Symbols or Ident etc.
   21216              : */
   21217              : 
   21218       666251 : extern "C" void M2Quads_PushTFntok (unsigned int True, unsigned int False, unsigned int n, unsigned int tokno)
   21219              : {
   21220       666251 :   M2Quads_BoolFrame f;
   21221              : 
   21222       666251 :   f = newBoolFrame ();
   21223       666251 :   f->TrueExit = static_cast<unsigned int> (True);
   21224       666251 :   f->FalseExit = static_cast<unsigned int> (False);
   21225       666251 :   f->name = static_cast<unsigned int> (n);
   21226       666251 :   f->tokenno = tokno;
   21227       666251 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21228       666251 : }
   21229              : 
   21230              : 
   21231              : /*
   21232              :    PopTFn - Pop a True and False number from the True/False stack.
   21233              :             True and False are assumed to contain Symbols or Ident etc.
   21234              : */
   21235              : 
   21236            0 : extern "C" void M2Quads_PopTFn (unsigned int *True, unsigned int *False, unsigned int *n)
   21237              : {
   21238            0 :   M2Quads_BoolFrame f;
   21239              : 
   21240            0 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   21241            0 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   21242            0 :   (*False) = static_cast<unsigned int> (f->FalseExit);
   21243            0 :   (*n) = static_cast<unsigned int> (f->name);
   21244            0 :   M2Debug_Assert (! f->BooleanOp);
   21245            0 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   21246            0 : }
   21247              : 
   21248              : 
   21249              : /*
   21250              :    PopNothing - pops the top element on the boolean stack.
   21251              : */
   21252              : 
   21253     66611387 : extern "C" void M2Quads_PopNothing (void)
   21254              : {
   21255     66611387 :   M2Quads_BoolFrame f;
   21256              : 
   21257     66611387 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   21258     66611387 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   21259     66611387 : }
   21260              : 
   21261              : 
   21262              : /*
   21263              :    PopN - pops multiple elements from the BoolStack.
   21264              : */
   21265              : 
   21266     12788262 : extern "C" void M2Quads_PopN (unsigned int n)
   21267              : {
   21268     48464878 :   while (n > 0)
   21269              :     {
   21270     35676616 :       M2Quads_PopNothing ();
   21271     35676616 :       n -= 1;
   21272              :     }
   21273     12788262 : }
   21274              : 
   21275              : 
   21276              : /*
   21277              :    PushTFA - Push True, False, Array, numbers onto the
   21278              :              True/False stack.  True and False are assumed to
   21279              :              contain Symbols or Ident etc.
   21280              : */
   21281              : 
   21282            0 : extern "C" void M2Quads_PushTFA (unsigned int True, unsigned int False, unsigned int Array)
   21283              : {
   21284            0 :   M2Quads_BoolFrame f;
   21285              : 
   21286            0 :   f = newBoolFrame ();
   21287            0 :   f->TrueExit = static_cast<unsigned int> (True);
   21288            0 :   f->FalseExit = static_cast<unsigned int> (False);
   21289            0 :   f->Unbounded = static_cast<unsigned int> (Array);
   21290            0 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21291            0 : }
   21292              : 
   21293              : 
   21294              : /*
   21295              :    OperandTok - returns the token associated with pos, on the stack.
   21296              : */
   21297              : 
   21298     57053235 : extern "C" unsigned int M2Quads_OperandTok (unsigned int pos)
   21299              : {
   21300     57053235 :   M2Debug_Assert (! (IsBoolean (pos)));
   21301     57053235 :   return static_cast<unsigned int> (OperandTtok (pos));
   21302              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   21303              :   __builtin_unreachable ();
   21304              : }
   21305              : 
   21306              : 
   21307              : /*
   21308              :    OperandA - returns possible array symbol associated with the ident
   21309              :               operand stored on the boolean stack.
   21310              : */
   21311              : 
   21312      2266341 : extern "C" unsigned int M2Quads_OperandA (unsigned int pos)
   21313              : {
   21314      2266341 :   M2Quads_BoolFrame f;
   21315              : 
   21316      2266341 :   M2Debug_Assert (pos > 0);
   21317      2266341 :   M2Debug_Assert (! (IsBoolean (pos)));
   21318      2266341 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   21319      2266341 :   return static_cast<unsigned int> (f->Unbounded);
   21320              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   21321              :   __builtin_unreachable ();
   21322              : }
   21323              : 
   21324              : 
   21325              : /*
   21326              :    OperandAnno - returns the annotation string associated with the
   21327              :                  position, n, on the stack.
   21328              : */
   21329              : 
   21330            0 : extern "C" DynamicStrings_String M2Quads_OperandAnno (unsigned int n)
   21331              : {
   21332            0 :   M2Quads_BoolFrame f;
   21333              : 
   21334            0 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, n));
   21335            0 :   return f->Annotation;
   21336              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   21337              :   __builtin_unreachable ();
   21338              : }
   21339              : 
   21340              : 
   21341              : /*
   21342              :    Annotate - annotate the top of stack.
   21343              : */
   21344              : 
   21345    126176844 : extern "C" void M2Quads_Annotate (const char *a_, unsigned int _a_high)
   21346              : {
   21347    126176844 :   M2Quads_BoolFrame f;
   21348    126176844 :   char a[_a_high+1];
   21349              : 
   21350              :   /* make a local copy of each unbounded array.  */
   21351    126176844 :   memcpy (a, a_, _a_high+1);
   21352              : 
   21353            0 :   if ((DebugStackOn && M2Options_CompilerDebugging) && ((M2StackAddress_NoOfItemsInStackAddress (BoolStack)) > 0))
   21354              :     {
   21355            0 :       f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, 1));  /* top of stack  */
   21356            0 :       if (f->Annotation != NULL)  /* top of stack  */
   21357              :         {
   21358            0 :           f->Annotation = DynamicStrings_KillString (f->Annotation);
   21359              :         }
   21360            0 :       f->Annotation = DynamicStrings_InitString ((const char *) a, _a_high);
   21361              :     }
   21362    126176844 : }
   21363              : 
   21364              : 
   21365              : /*
   21366              :    DisplayStack - displays the compile time symbol stack.
   21367              : */
   21368              : 
   21369     20562167 : extern "C" void M2Quads_DisplayStack (void)
   21370              : {
   21371     20562167 :   if (DebugStackOn && M2Options_CompilerDebugging)
   21372              :     {
   21373            0 :       M2DebugStack_DebugStack (M2StackAddress_NoOfItemsInStackAddress (BoolStack), (M2DebugStack_ProcedureWord) {(M2DebugStack_ProcedureWord_t) OperandTno}, (M2DebugStack_ProcedureWord) {(M2DebugStack_ProcedureWord_t) OperandFno}, (M2DebugStack_ProcedureWord) {(M2DebugStack_ProcedureWord_t) M2Quads_OperandA}, (M2DebugStack_ProcedureWord) {(M2DebugStack_ProcedureWord_t) OperandD}, (M2DebugStack_ProcedureWord) {(M2DebugStack_ProcedureWord_t) OperandRW}, (M2DebugStack_ProcedureWord) {(M2DebugStack_ProcedureWord_t) M2Quads_OperandTok}, (M2DebugStack_ProcedureString) {(M2DebugStack_ProcedureString_t) M2Quads_OperandAnno});
   21374              :     }
   21375     20562167 : }
   21376              : 
   21377              : 
   21378              : /*
   21379              :    Top - returns the no of items held in the stack.
   21380              : */
   21381              : 
   21382     91630811 : extern "C" unsigned int M2Quads_Top (void)
   21383              : {
   21384     91630811 :   return M2StackAddress_NoOfItemsInStackAddress (BoolStack);
   21385              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   21386              :   __builtin_unreachable ();
   21387              : }
   21388              : 
   21389              : 
   21390              : /*
   21391              :    DupFrame - duplicate the top of stack and push the new frame.
   21392              : */
   21393              : 
   21394            0 : extern "C" void M2Quads_DupFrame (void)
   21395              : {
   21396            0 :   M2Quads_BoolFrame f;
   21397            0 :   M2Quads_BoolFrame newf;
   21398              : 
   21399            0 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   21400            0 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21401            0 :   newf = newBoolFrame ();
   21402            0 :   (*newf) = (*f);
   21403            0 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (newf));
   21404            0 : }
   21405              : 
   21406              : 
   21407              : /*
   21408              :    WriteOperand - displays the operands name, symbol id and mode of addressing.
   21409              : */
   21410              : 
   21411            0 : extern "C" void M2Quads_WriteOperand (unsigned int Sym)
   21412              : {
   21413            0 :   NameKey_Name n;
   21414              : 
   21415            0 :   if (Sym == SymbolTable_NulSym)
   21416              :     {
   21417            0 :       M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "<nulsym>", 8);
   21418              :     }
   21419              :   else
   21420              :     {
   21421            0 :       n = SymbolTable_GetSymName (Sym);
   21422            0 :       M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%a", 2, (const unsigned char *) &n, (sizeof (n)-1));
   21423            0 :       if ((SymbolTable_IsVar (Sym)) || (SymbolTable_IsConst (Sym)))
   21424              :         {
   21425            0 :           M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "[", 1);
   21426            0 :           WriteMode (SymbolTable_GetMode (Sym));
   21427            0 :           M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "]", 1);
   21428              :         }
   21429            0 :       M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "(%d)", 4, (const unsigned char *) &Sym, (sizeof (Sym)-1));
   21430            0 :       if (SymbolConversion_GccKnowsAbout (Sym))
   21431              :         {
   21432            0 :           M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "[gcc]", 5);
   21433              :         }
   21434              :     }
   21435            0 : }
   21436              : 
   21437              : 
   21438              : /*
   21439              :    BeginVarient - begin a varient record.
   21440              : */
   21441              : 
   21442         3048 : extern "C" void M2Quads_BeginVarient (void)
   21443              : {
   21444         3048 :   unsigned int r;
   21445         3048 :   unsigned int v;
   21446              : 
   21447         3048 :   r = GetRecordOrField ();
   21448         6096 :   M2Debug_Assert ((SymbolTable_IsRecord (r)) || (SymbolTable_IsFieldVarient (r)));
   21449         3048 :   v = GetRecordOrField ();
   21450         3048 :   M2Debug_Assert (SymbolTable_IsVarient (v));
   21451         3048 :   BuildRange (M2Range_InitCaseBounds (M2CaseList_PushCase (r, v, SymbolTable_NulSym)));
   21452         3048 : }
   21453              : 
   21454              : 
   21455              : /*
   21456              :    EndVarient - end a varient record.
   21457              : */
   21458              : 
   21459         3048 : extern "C" void M2Quads_EndVarient (void)
   21460              : {
   21461         3048 :   M2CaseList_PopCase ();
   21462         3048 : }
   21463              : 
   21464              : 
   21465              : /*
   21466              :    ElseVarient - associate an ELSE clause with a varient record.
   21467              : */
   21468              : 
   21469          114 : extern "C" void M2Quads_ElseVarient (void)
   21470              : {
   21471          114 :   unsigned int f;
   21472              : 
   21473          114 :   f = GetRecordOrField ();
   21474          114 :   M2Debug_Assert (SymbolTable_IsFieldVarient (f));
   21475          114 :   M2CaseList_ElseCase (f);
   21476          114 : }
   21477              : 
   21478              : 
   21479              : /*
   21480              :    BeginVarientList - begin an ident list containing ranges belonging to a
   21481              :                       varient list.
   21482              : */
   21483              : 
   21484         6096 : extern "C" void M2Quads_BeginVarientList (void)
   21485              : {
   21486         6096 :   unsigned int f;
   21487              : 
   21488         6096 :   f = GetRecordOrField ();
   21489         6096 :   M2Debug_Assert (SymbolTable_IsFieldVarient (f));
   21490         6096 :   M2CaseList_BeginCaseList (f);
   21491         6096 : }
   21492              : 
   21493              : 
   21494              : /*
   21495              :    EndVarientList - end a range list for a varient field.
   21496              : */
   21497              : 
   21498         6096 : extern "C" void M2Quads_EndVarientList (void)
   21499              : {
   21500         6096 :   M2CaseList_EndCaseList ();
   21501         6096 : }
   21502              : 
   21503              : 
   21504              : /*
   21505              :    AddRecordToList - adds the record held on the top of stack to the
   21506              :                      list of records and varient fields.
   21507              : */
   21508              : 
   21509         3048 : extern "C" void M2Quads_AddRecordToList (void)
   21510              : {
   21511         3048 :   unsigned int r;
   21512         3048 :   unsigned int n;
   21513              : 
   21514         3048 :   r = static_cast<unsigned int> (M2Quads_OperandT (1));
   21515         6096 :   M2Debug_Assert ((SymbolTable_IsRecord (r)) || (SymbolTable_IsFieldVarient (r)));
   21516              :   /* 
   21517              :       r might be a field varient if the declaration consists of nested
   21518              :       varients.  However ISO TSIZE can only utilise record types, we store
   21519              :       a varient field anyway as the next pass would not know whether to
   21520              :       ignore a varient field.
   21521              :   */
   21522         3048 :   Lists_PutItemIntoList (VarientFields, r);
   21523         3048 :   if (DebugVarients)
   21524              :     {
   21525              :       n = Lists_NoOfItemsInList (VarientFields);
   21526              :       if (SymbolTable_IsRecord (r))
   21527              :         {
   21528              :           M2Printf_printf2 ((const char *) "in list: record %d is %d\\n", 26, (const unsigned char *) &n, (sizeof (n)-1), (const unsigned char *) &r, (sizeof (r)-1));
   21529              :         }
   21530              :       else
   21531              :         {
   21532              :           M2Printf_printf2 ((const char *) "in list: varient field %d is %d\\n", 33, (const unsigned char *) &n, (sizeof (n)-1), (const unsigned char *) &r, (sizeof (r)-1));
   21533              :         }
   21534              :     }
   21535         3048 : }
   21536              : 
   21537              : 
   21538              : /*
   21539              :    AddVarientToList - adds varient held on the top of stack to the list.
   21540              : */
   21541              : 
   21542         3048 : extern "C" void M2Quads_AddVarientToList (void)
   21543              : {
   21544         3048 :   unsigned int v;
   21545         3048 :   unsigned int n;
   21546              : 
   21547         3048 :   v = static_cast<unsigned int> (M2Quads_OperandT (1));
   21548         3048 :   M2Debug_Assert (SymbolTable_IsVarient (v));
   21549         3048 :   Lists_PutItemIntoList (VarientFields, v);
   21550         3048 :   if (DebugVarients)
   21551              :     {
   21552              :       n = Lists_NoOfItemsInList (VarientFields);
   21553              :       M2Printf_printf2 ((const char *) "in list: varient %d is %d\\n", 27, (const unsigned char *) &n, (sizeof (n)-1), (const unsigned char *) &v, (sizeof (v)-1));
   21554              :     }
   21555         3048 : }
   21556              : 
   21557              : 
   21558              : /*
   21559              :    AddVarientFieldToList - adds varient field, f, to the list of all varient
   21560              :                            fields created.
   21561              : */
   21562              : 
   21563         6210 : extern "C" void M2Quads_AddVarientFieldToList (unsigned int f)
   21564              : {
   21565         6210 :   unsigned int n;
   21566              : 
   21567         6210 :   M2Debug_Assert (SymbolTable_IsFieldVarient (f));
   21568         6210 :   Lists_PutItemIntoList (VarientFields, f);
   21569         6210 :   if (DebugVarients)
   21570              :     {
   21571              :       n = Lists_NoOfItemsInList (VarientFields);
   21572              :       M2Printf_printf2 ((const char *) "in list: varient field %d is %d\\n", 33, (const unsigned char *) &n, (sizeof (n)-1), (const unsigned char *) &f, (sizeof (f)-1));
   21573              :     }
   21574         6210 : }
   21575              : 
   21576              : 
   21577              : /*
   21578              :    AddVarientRange - creates a range from the top two contant expressions
   21579              :                      on the stack which are recorded with the current
   21580              :                      varient field.  The stack is unaltered.
   21581              : */
   21582              : 
   21583            0 : extern "C" void M2Quads_AddVarientRange (void)
   21584              : {
   21585            0 :   unsigned int r1;
   21586            0 :   unsigned int r2;
   21587              : 
   21588            0 :   M2Quads_PopT (&r2);
   21589            0 :   M2Quads_PopT (&r1);
   21590            0 :   M2CaseList_AddRange (r1, r2, M2LexBuf_GetTokenNo ());
   21591            0 : }
   21592              : 
   21593              : 
   21594              : /*
   21595              :    AddVarientEquality - adds the contant expression on the top of the stack
   21596              :                         to the current varient field being recorded.
   21597              :                         The stack is unaltered.
   21598              : */
   21599              : 
   21600         6138 : extern "C" void M2Quads_AddVarientEquality (void)
   21601              : {
   21602         6138 :   unsigned int r1;
   21603              : 
   21604         6138 :   M2Quads_PopT (&r1);
   21605         6138 :   M2CaseList_AddRange (r1, SymbolTable_NulSym, M2LexBuf_GetTokenNo ());
   21606         6138 : }
   21607              : 
   21608              : 
   21609              : /*
   21610              :    BuildCodeOn - generates a quadruple declaring that code should be
   21611              :                  emmitted from henceforth.
   21612              : 
   21613              :                  The Stack is unnaffected.
   21614              : */
   21615              : 
   21616            0 : extern "C" void M2Quads_BuildCodeOn (void)
   21617              : {
   21618            0 :   GenQuad (M2Quads_CodeOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
   21619            0 : }
   21620              : 
   21621              : 
   21622              : /*
   21623              :    BuildCodeOff - generates a quadruple declaring that code should not be
   21624              :                   emmitted from henceforth.
   21625              : 
   21626              :                   The Stack is unnaffected.
   21627              : */
   21628              : 
   21629            0 : extern "C" void M2Quads_BuildCodeOff (void)
   21630              : {
   21631            0 :   GenQuad (M2Quads_CodeOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
   21632            0 : }
   21633              : 
   21634              : 
   21635              : /*
   21636              :    BuildProfileOn - generates a quadruple declaring that profile timings
   21637              :                     should be emmitted from henceforth.
   21638              : 
   21639              :                     The Stack is unnaffected.
   21640              : */
   21641              : 
   21642            0 : extern "C" void M2Quads_BuildProfileOn (void)
   21643              : {
   21644            0 :   GenQuad (M2Quads_ProfileOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
   21645            0 : }
   21646              : 
   21647            0 : extern "C" void M2Quads_BuildProfileOff (void)
   21648              : {
   21649              :   /* 
   21650              :    BuildProfileOn - generates a quadruple declaring that profile timings
   21651              :                     should be emmitted from henceforth.
   21652              : 
   21653              :                     The Stack is unnaffected.
   21654              :   */
   21655            0 :   GenQuad (M2Quads_ProfileOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
   21656            0 : }
   21657              : 
   21658              : 
   21659              : /*
   21660              :    BuildOptimizeOn - generates a quadruple declaring that optimization
   21661              :                      should occur from henceforth.
   21662              : 
   21663              :                      The Stack is unnaffected.
   21664              : */
   21665              : 
   21666            0 : extern "C" void M2Quads_BuildOptimizeOn (void)
   21667              : {
   21668            0 :   GenQuad (M2Quads_OptimizeOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
   21669            0 : }
   21670              : 
   21671              : 
   21672              : /*
   21673              :    BuildOptimizeOff - generates a quadruple declaring that optimization
   21674              :                       should not occur from henceforth.
   21675              : 
   21676              :                       The Stack is unnaffected.
   21677              : */
   21678              : 
   21679            0 : extern "C" void M2Quads_BuildOptimizeOff (void)
   21680              : {
   21681            0 :   GenQuad (M2Quads_OptimizeOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
   21682            0 : }
   21683              : 
   21684              : 
   21685              : /*
   21686              :    BuildAsm - builds an Inline pseudo quadruple operator.
   21687              :               The inline interface, Sym, is stored as the operand
   21688              :               to the operator InlineOp.
   21689              : 
   21690              :               The stack is expected to contain:
   21691              : 
   21692              : 
   21693              :                         Entry                   Exit
   21694              :                         =====                   ====
   21695              : 
   21696              :               Ptr ->
   21697              :                      +--------------+
   21698              :                      | Sym          |        Empty
   21699              :                      |--------------|
   21700              : */
   21701              : 
   21702           27 : extern "C" void M2Quads_BuildAsm (unsigned int tok)
   21703              : {
   21704           27 :   unsigned int Sym;
   21705              : 
   21706           27 :   M2Quads_PopT (&Sym);
   21707           27 :   GenQuadO (tok, M2Quads_InlineOp, SymbolTable_NulSym, SymbolTable_NulSym, Sym, false);
   21708           27 : }
   21709              : 
   21710              : 
   21711              : /*
   21712              :    BuildLineNo - builds a LineNumberOp pseudo quadruple operator.
   21713              :                  This quadruple indicates which source line has been
   21714              :                  processed, these quadruples are only generated if we
   21715              :                  are producing runtime debugging information.
   21716              : 
   21717              :                  The stack is not affected, read or altered in any way.
   21718              : 
   21719              : 
   21720              :                         Entry                   Exit
   21721              :                         =====                   ====
   21722              : 
   21723              :                  Ptr ->                              <- Ptr
   21724              : */
   21725              : 
   21726            0 : extern "C" void M2Quads_BuildLineNo (void)
   21727              : {
   21728            0 :   NameKey_Name filename;
   21729            0 :   M2Quads_QuadFrame f;
   21730              : 
   21731            0 :   if (((NextQuad != Head) && (M2Options_GenerateLineDebug || M2Options_GenerateDebugging)) && false)
   21732              :     {
   21733              :       filename = NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()));
   21734              :       f = GetQF (NextQuad-1);
   21735              :       if (! ((f->Operator == M2Quads_LineNumberOp) && (f->Operand1 == ((unsigned int ) (filename)))))
   21736              :         {
   21737              :           GenQuad (M2Quads_LineNumberOp, (unsigned int ) (filename), SymbolTable_NulSym, (unsigned int ) (M2LexBuf_GetLineNo ()));
   21738              :         }
   21739              :     }
   21740            0 : }
   21741              : 
   21742              : 
   21743              : /*
   21744              :    PushLineNo - pushes the current file and line number to the stack.
   21745              : */
   21746              : 
   21747         5220 : extern "C" void M2Quads_PushLineNo (void)
   21748              : {
   21749         5220 :   PushLineNote (InitLineNote (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ())), M2LexBuf_GetLineNo ()));
   21750         5220 : }
   21751              : 
   21752              : 
   21753              : /*
   21754              :    BuildStmtNote - builds a StatementNoteOp pseudo quadruple operator.
   21755              :                    This quadruple indicates which source line has been
   21756              :                    processed and it represents the start of a statement
   21757              :                    sequence.
   21758              :                    It differs from LineNumberOp in that multiple successive
   21759              :                    LineNumberOps will be removed and the final one is attached to
   21760              :                    the next real GCC tree.  Whereas a StatementNoteOp is always left
   21761              :                    alone.  Depending upon the debugging level it will issue a nop
   21762              :                    instruction to ensure that the gdb single step will step into
   21763              :                    this line.  Practically it allows pedalogical debugging to
   21764              :                    occur when there is syntax sugar such as:
   21765              : 
   21766              : 
   21767              :                          END   step 
   21768              :                       END   step 
   21769              :                    END ;  step 
   21770              :                    a := 1 ;  step 
   21771              : 
   21772              :                    REPEAT  step 
   21773              :                       i := 1   step 
   21774              : 
   21775              :                    The stack is not affected, read or altered in any way.
   21776              : 
   21777              : 
   21778              :                         Entry                   Exit
   21779              :                         =====                   ====
   21780              : 
   21781              :                  Ptr ->                              <- Ptr
   21782              : */
   21783              : 
   21784       545218 : extern "C" void M2Quads_BuildStmtNote (int offset)
   21785              : {
   21786       545218 :   int tokenno;
   21787              : 
   21788       545218 :   if (NextQuad != Head)
   21789              :     {
   21790       545218 :       tokenno = offset;
   21791       545218 :       tokenno += M2LexBuf_GetTokenNo ();
   21792       545218 :       BuildStmtNoteTok ((unsigned int ) (tokenno));
   21793              :     }
   21794       545218 : }
   21795              : 
   21796              : 
   21797              : /*
   21798              :    LoopAnalysis - checks whether an infinite loop exists.
   21799              : */
   21800              : 
   21801       410599 : extern "C" void M2Quads_LoopAnalysis (unsigned int Scope, unsigned int Current, unsigned int End)
   21802              : {
   21803       410599 :   M2Quads_QuadOperator op;
   21804       410599 :   unsigned int op1;
   21805       410599 :   unsigned int op2;
   21806       410599 :   unsigned int op3;
   21807              : 
   21808       410599 :   if (M2Options_Pedantic)
   21809              :     {
   21810        11442 :       while ((Current <= End) && (Current != 0))
   21811              :         {
   21812         9990 :           M2Quads_GetQuad (Current, &op, &op1, &op2, &op3);
   21813         9990 :           if ((op == M2Quads_GotoOp) || (M2Quads_IsConditional (Current)))
   21814              :             {
   21815          114 :               if (op3 <= Current)
   21816              :                 {
   21817              :                   /* found a loop - ie a branch which goes back in quadruple numbers  */
   21818           24 :                   if (IsInfiniteLoop (Current))
   21819              :                     {
   21820            0 :                       M2MetaError_MetaErrorT1 (M2Quads_QuadToTokenNo (op3), (const char *) "it is very likely (although not absolutely certain) that the top of an infinite loop exists here in {%1Wad}", 107, Scope);
   21821            0 :                       M2MetaError_MetaErrorT1 (M2Quads_QuadToTokenNo (Current), (const char *) "and the bottom of the infinite loop is ends here in {%1Wad} or alternatively a component of this loop is never executed", 119, Scope);
   21822              :                     }
   21823              :                   /* 
   21824              :                   WarnStringAt(InitString('it is very likely (although not absolutely certain) that the top of an infinite loop is here'),
   21825              :                                QuadToTokenNo(op3)) ;
   21826              :                   WarnStringAt(InitString('and the bottom of the infinite loop is ends here or alternatively a component of this loop is never executed'),
   21827              :                                QuadToTokenNo(Current))
   21828              :   */
   21829              :                 }
   21830              :             }
   21831         9990 :           Current = M2Quads_GetNextQuad (Current);
   21832              :         }
   21833              :     }
   21834       410599 : }
   21835              : 
   21836              : 
   21837              : /*
   21838              :    ForLoopAnalysis - checks all the FOR loops for index variable manipulation
   21839              :                      and dangerous usage outside the loop.
   21840              : */
   21841              : 
   21842        14662 : extern "C" void M2Quads_ForLoopAnalysis (void)
   21843              : {
   21844        14662 :   unsigned int i;
   21845        14662 :   unsigned int n;
   21846        14662 :   M2Quads_ForLoopInfo forDesc;
   21847              : 
   21848        14662 :   if (M2Options_Pedantic)
   21849              :     {
   21850          108 :       n = Indexing_HighIndice (ForInfo);
   21851          108 :       i = 1;
   21852          216 :       while (i <= n)
   21853              :         {
   21854            0 :           forDesc = static_cast<M2Quads_ForLoopInfo> (Indexing_GetIndice (ForInfo, i));
   21855            0 :           CheckForIndex (forDesc);
   21856            0 :           i += 1;
   21857              :         }
   21858              :     }
   21859        14662 : }
   21860              : 
   21861              : 
   21862              : /*
   21863              :    BuildSizeCheckStart - switches off all quadruple generation if the function SIZE or HIGH
   21864              :                          is being "called".  This should be done as SIZE only requires the
   21865              :                          actual type of the expression, not its value.  Consider the problem of
   21866              :                          SIZE(UninitializedPointer^) which is quite legal and it must
   21867              :                          also be safe!
   21868              :                          ISO Modula-2 also allows HIGH(a[0]) for a two dimensional array
   21869              :                          and there is no need to compute a[0], we just need to follow the
   21870              :                          type and count dimensions.  However if SIZE(a) or HIGH(a) occurs
   21871              :                          and, a, is an unbounded array then we turn on quadruple generation.
   21872              : 
   21873              :                          The Stack is expected to contain:
   21874              : 
   21875              : 
   21876              :                          Entry                       Exit
   21877              :                          =====                       ====
   21878              : 
   21879              :                  Ptr ->                                                       <- Ptr
   21880              :                         +----------------------+     +----------------------+
   21881              :                         | ProcSym | Type | tok |     | ProcSym | Type | tok |
   21882              :                         |----------------------|     |----------------------|
   21883              : */
   21884              : 
   21885       192720 : extern "C" void M2Quads_BuildSizeCheckStart (void)
   21886              : {
   21887       192720 :   unsigned int ProcSym;
   21888       192720 :   unsigned int Type;
   21889       192720 :   unsigned int tok;
   21890              : 
   21891       192720 :   M2Quads_PopTFtok (&ProcSym, &Type, &tok);
   21892       192720 :   if (((ProcSym == M2Size_Size) || (ProcSym == M2System_TSize)) || (ProcSym == M2System_TBitSize))
   21893              :     {
   21894         9235 :       QuadrupleGeneration = false;
   21895         9235 :       BuildingSize = true;
   21896              :     }
   21897       183485 :   else if (ProcSym == M2Base_High)
   21898              :     {
   21899              :       /* avoid dangling else.  */
   21900         2978 :       QuadrupleGeneration = false;
   21901         2978 :       BuildingHigh = true;
   21902              :     }
   21903       192720 :   M2Quads_PushTFtok (ProcSym, Type, tok);
   21904       192720 : }
   21905              : 
   21906              : 
   21907              : /*
   21908              :    BackPatchSubrangesAndOptParam - runs through all the quadruples and finds SubrangeLow or SubrangeHigh
   21909              :                                    quadruples and replaces it by an assignment to the Low or High component
   21910              :                                    of the subrange type.
   21911              : 
   21912              :                                    Input:
   21913              :                                    SubrangeLow    op1     op3          op3 is a subrange 
   21914              : 
   21915              :                                    Output:
   21916              :                                    Becomes        op1     low
   21917              : 
   21918              :                                    Input:
   21919              :                                    SubrangeHigh   op1     op3          op3 is a subrange 
   21920              : 
   21921              :                                    Output:
   21922              :                                    Becomes        op1     high
   21923              : 
   21924              :                                    Input:
   21925              :                                    OptParam       op1     op2    op3
   21926              : 
   21927              :                                    Output:
   21928              :                                    Param          op1     op2    GetOptArgInit(op3)
   21929              : */
   21930              : 
   21931        14662 : extern "C" void M2Quads_BackPatchSubrangesAndOptParam (void)
   21932              : {
   21933        14662 :   M2Quads_QuadFrame f;
   21934        14662 :   unsigned int q;
   21935              : 
   21936        14662 :   q = M2Quads_GetFirstQuad ();
   21937        14662 :   if (q != 0)
   21938              :     {
   21939      6259579 :       do {
   21940      6259579 :         f = GetQF (q);
   21941      6259579 :         switch (f->Operator)
   21942              :           {
   21943          306 :             case M2Quads_SubrangeLowOp:
   21944          306 :               f->Operand3 = CollectLow (f->Operand3);
   21945          306 :               f->Operator = M2Quads_BecomesOp;
   21946          306 :               f->ConstExpr = false;
   21947          306 :               break;
   21948              : 
   21949          562 :             case M2Quads_SubrangeHighOp:
   21950          562 :               f->Operand3 = CollectHigh (f->Operand3);
   21951          562 :               f->Operator = M2Quads_BecomesOp;
   21952          562 :               f->ConstExpr = false;
   21953          562 :               break;
   21954              : 
   21955         3626 :             case M2Quads_OptParamOp:
   21956         3626 :               f->Operand3 = SymbolTable_GetOptArgInit (f->Operand3);
   21957         3626 :               f->Operator = M2Quads_ParamOp;
   21958         3626 :               break;
   21959              : 
   21960              : 
   21961              :             default:
   21962              :               break;
   21963              :           }
   21964      6259579 :         q = f->Next;
   21965      6259579 :       } while (! (q == 0));
   21966              :     }
   21967        14662 : }
   21968              : 
   21969              : 
   21970              : /*
   21971              :    WriteOperator - writes the name of the quadruple operator.
   21972              : */
   21973              : 
   21974            0 : extern "C" void M2Quads_WriteOperator (M2Quads_QuadOperator Operator)
   21975              : {
   21976            0 :   switch (Operator)
   21977              :     {
   21978            0 :       case M2Quads_ArithAddOp:
   21979            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Arith +           ", 18);
   21980            0 :         break;
   21981              : 
   21982            0 :       case M2Quads_InitAddressOp:
   21983            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitAddress       ", 18);
   21984            0 :         break;
   21985              : 
   21986            0 :       case M2Quads_LastForIteratorOp:
   21987            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "LastForIterator   ", 18);
   21988            0 :         break;
   21989              : 
   21990            0 :       case M2Quads_LogicalOrOp:
   21991            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Or                ", 18);
   21992            0 :         break;
   21993              : 
   21994            0 :       case M2Quads_LogicalAndOp:
   21995            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "And               ", 18);
   21996            0 :         break;
   21997              : 
   21998            0 :       case M2Quads_LogicalXorOp:
   21999            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Xor               ", 18);
   22000            0 :         break;
   22001              : 
   22002            0 :       case M2Quads_LogicalDiffOp:
   22003            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Ldiff             ", 18);
   22004            0 :         break;
   22005              : 
   22006            0 :       case M2Quads_LogicalShiftOp:
   22007            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Shift             ", 18);
   22008            0 :         break;
   22009              : 
   22010            0 :       case M2Quads_LogicalRotateOp:
   22011            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Rotate            ", 18);
   22012            0 :         break;
   22013              : 
   22014            0 :       case M2Quads_BecomesOp:
   22015            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Becomes           ", 18);
   22016            0 :         break;
   22017              : 
   22018            0 :       case M2Quads_IndrXOp:
   22019            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "IndrX             ", 18);
   22020            0 :         break;
   22021              : 
   22022            0 :       case M2Quads_XIndrOp:
   22023            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "XIndr             ", 18);
   22024            0 :         break;
   22025              : 
   22026            0 :       case M2Quads_ArrayOp:
   22027            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Array             ", 18);
   22028            0 :         break;
   22029              : 
   22030            0 :       case M2Quads_ElementSizeOp:
   22031            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ElementSize       ", 18);
   22032            0 :         break;
   22033              : 
   22034            0 :       case M2Quads_RecordFieldOp:
   22035            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RecordField       ", 18);
   22036            0 :         break;
   22037              : 
   22038            0 :       case M2Quads_AddrOp:
   22039            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Addr              ", 18);
   22040            0 :         break;
   22041              : 
   22042            0 :       case M2Quads_SizeOp:
   22043            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Size              ", 18);
   22044            0 :         break;
   22045              : 
   22046            0 :       case M2Quads_IfInOp:
   22047            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If IN             ", 18);
   22048            0 :         break;
   22049              : 
   22050            0 :       case M2Quads_IfNotInOp:
   22051            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If NOT IN         ", 18);
   22052            0 :         break;
   22053              : 
   22054            0 :       case M2Quads_IfNotEquOp:
   22055            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If <>             ", 18);
   22056            0 :         break;
   22057              : 
   22058            0 :       case M2Quads_IfEquOp:
   22059            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If =              ", 18);
   22060            0 :         break;
   22061              : 
   22062            0 :       case M2Quads_IfLessEquOp:
   22063            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If <=             ", 18);
   22064            0 :         break;
   22065              : 
   22066            0 :       case M2Quads_IfGreEquOp:
   22067            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If >=             ", 18);
   22068            0 :         break;
   22069              : 
   22070            0 :       case M2Quads_IfGreOp:
   22071            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If >              ", 18);
   22072            0 :         break;
   22073              : 
   22074            0 :       case M2Quads_IfLessOp:
   22075            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If <              ", 18);
   22076            0 :         break;
   22077              : 
   22078            0 :       case M2Quads_GotoOp:
   22079            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Goto              ", 18);
   22080            0 :         break;
   22081              : 
   22082            0 :       case M2Quads_DummyOp:
   22083            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Dummy             ", 18);
   22084            0 :         break;
   22085              : 
   22086            0 :       case M2Quads_ModuleScopeOp:
   22087            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ModuleScopeOp     ", 18);
   22088            0 :         break;
   22089              : 
   22090            0 :       case M2Quads_StartDefFileOp:
   22091            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StartDefFile      ", 18);
   22092            0 :         break;
   22093              : 
   22094            0 :       case M2Quads_StartModFileOp:
   22095            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StartModFile      ", 18);
   22096            0 :         break;
   22097              : 
   22098            0 :       case M2Quads_EndFileOp:
   22099            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "EndFileOp         ", 18);
   22100            0 :         break;
   22101              : 
   22102            0 :       case M2Quads_InitStartOp:
   22103            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitStart         ", 18);
   22104            0 :         break;
   22105              : 
   22106            0 :       case M2Quads_InitEndOp:
   22107            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitEnd           ", 18);
   22108            0 :         break;
   22109              : 
   22110            0 :       case M2Quads_FinallyStartOp:
   22111            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FinallyStart      ", 18);
   22112            0 :         break;
   22113              : 
   22114            0 :       case M2Quads_FinallyEndOp:
   22115            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FinallyEnd        ", 18);
   22116            0 :         break;
   22117              : 
   22118            0 :       case M2Quads_RetryOp:
   22119            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Retry             ", 18);
   22120            0 :         break;
   22121              : 
   22122            0 :       case M2Quads_TryOp:
   22123            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Try               ", 18);
   22124            0 :         break;
   22125              : 
   22126            0 :       case M2Quads_ThrowOp:
   22127            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Throw             ", 18);
   22128            0 :         break;
   22129              : 
   22130            0 :       case M2Quads_CatchBeginOp:
   22131            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CatchBegin        ", 18);
   22132            0 :         break;
   22133              : 
   22134            0 :       case M2Quads_CatchEndOp:
   22135            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CatchEnd          ", 18);
   22136            0 :         break;
   22137              : 
   22138            0 :       case M2Quads_AddOp:
   22139            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "+                 ", 18);
   22140            0 :         break;
   22141              : 
   22142            0 :       case M2Quads_SubOp:
   22143            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "-                 ", 18);
   22144            0 :         break;
   22145              : 
   22146            0 :       case M2Quads_DivM2Op:
   22147            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV M2            ", 18);
   22148            0 :         break;
   22149              : 
   22150            0 :       case M2Quads_ModM2Op:
   22151            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD M2            ", 18);
   22152            0 :         break;
   22153              : 
   22154            0 :       case M2Quads_DivCeilOp:
   22155            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV ceil          ", 18);
   22156            0 :         break;
   22157              : 
   22158            0 :       case M2Quads_ModCeilOp:
   22159            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD ceil          ", 18);
   22160            0 :         break;
   22161              : 
   22162            0 :       case M2Quads_DivFloorOp:
   22163            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV floor         ", 18);
   22164            0 :         break;
   22165              : 
   22166            0 :       case M2Quads_ModFloorOp:
   22167            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD floor         ", 18);
   22168            0 :         break;
   22169              : 
   22170            0 :       case M2Quads_DivTruncOp:
   22171            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV trunc         ", 18);
   22172            0 :         break;
   22173              : 
   22174            0 :       case M2Quads_ModTruncOp:
   22175            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD trunc         ", 18);
   22176            0 :         break;
   22177              : 
   22178            0 :       case M2Quads_MultOp:
   22179            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "*                 ", 18);
   22180            0 :         break;
   22181              : 
   22182            0 :       case M2Quads_NegateOp:
   22183            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Negate            ", 18);
   22184            0 :         break;
   22185              : 
   22186            0 :       case M2Quads_InclOp:
   22187            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Incl              ", 18);
   22188            0 :         break;
   22189              : 
   22190            0 :       case M2Quads_ExclOp:
   22191            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Excl              ", 18);
   22192            0 :         break;
   22193              : 
   22194            0 :       case M2Quads_ReturnOp:
   22195            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Return            ", 18);
   22196            0 :         break;
   22197              : 
   22198            0 :       case M2Quads_ReturnValueOp:
   22199            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ReturnValue       ", 18);
   22200            0 :         break;
   22201              : 
   22202            0 :       case M2Quads_FunctValueOp:
   22203            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FunctValue        ", 18);
   22204            0 :         break;
   22205              : 
   22206            0 :       case M2Quads_CallOp:
   22207            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Call              ", 18);
   22208            0 :         break;
   22209              : 
   22210            0 :       case M2Quads_ParamOp:
   22211            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Param             ", 18);
   22212            0 :         break;
   22213              : 
   22214            0 :       case M2Quads_OptParamOp:
   22215            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptParam          ", 18);
   22216            0 :         break;
   22217              : 
   22218            0 :       case M2Quads_NewLocalVarOp:
   22219            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "NewLocalVar       ", 18);
   22220            0 :         break;
   22221              : 
   22222            0 :       case M2Quads_KillLocalVarOp:
   22223            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "KillLocalVar      ", 18);
   22224            0 :         break;
   22225              : 
   22226            0 :       case M2Quads_ProcedureScopeOp:
   22227            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProcedureScope    ", 18);
   22228            0 :         break;
   22229              : 
   22230            0 :       case M2Quads_UnboundedOp:
   22231            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Unbounded         ", 18);
   22232            0 :         break;
   22233              : 
   22234            0 :       case M2Quads_CoerceOp:
   22235            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Coerce            ", 18);
   22236            0 :         break;
   22237              : 
   22238            0 :       case M2Quads_ConvertOp:
   22239            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Convert           ", 18);
   22240            0 :         break;
   22241              : 
   22242            0 :       case M2Quads_CastOp:
   22243            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Cast              ", 18);
   22244            0 :         break;
   22245              : 
   22246            0 :       case M2Quads_HighOp:
   22247            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "High              ", 18);
   22248            0 :         break;
   22249              : 
   22250            0 :       case M2Quads_CodeOnOp:
   22251            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CodeOn            ", 18);
   22252            0 :         break;
   22253              : 
   22254            0 :       case M2Quads_CodeOffOp:
   22255            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CodeOff           ", 18);
   22256            0 :         break;
   22257              : 
   22258            0 :       case M2Quads_ProfileOnOp:
   22259            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProfileOn         ", 18);
   22260            0 :         break;
   22261              : 
   22262            0 :       case M2Quads_ProfileOffOp:
   22263            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProfileOff        ", 18);
   22264            0 :         break;
   22265              : 
   22266            0 :       case M2Quads_OptimizeOnOp:
   22267            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptimizeOn        ", 18);
   22268            0 :         break;
   22269              : 
   22270            0 :       case M2Quads_OptimizeOffOp:
   22271            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptimizeOff       ", 18);
   22272            0 :         break;
   22273              : 
   22274            0 :       case M2Quads_InlineOp:
   22275            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Inline            ", 18);
   22276            0 :         break;
   22277              : 
   22278            0 :       case M2Quads_StatementNoteOp:
   22279            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StatementNote     ", 18);
   22280            0 :         break;
   22281              : 
   22282            0 :       case M2Quads_LineNumberOp:
   22283            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "LineNumber        ", 18);
   22284            0 :         break;
   22285              : 
   22286            0 :       case M2Quads_BuiltinConstOp:
   22287            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "BuiltinConst      ", 18);
   22288            0 :         break;
   22289              : 
   22290            0 :       case M2Quads_BuiltinTypeInfoOp:
   22291            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "BuiltinTypeInfo   ", 18);
   22292            0 :         break;
   22293              : 
   22294            0 :       case M2Quads_StandardFunctionOp:
   22295            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StandardFunction  ", 18);
   22296            0 :         break;
   22297              : 
   22298            0 :       case M2Quads_SavePriorityOp:
   22299            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SavePriority      ", 18);
   22300            0 :         break;
   22301              : 
   22302            0 :       case M2Quads_RestorePriorityOp:
   22303            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RestorePriority   ", 18);
   22304            0 :         break;
   22305              : 
   22306            0 :       case M2Quads_RangeCheckOp:
   22307            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RangeCheck        ", 18);
   22308            0 :         break;
   22309              : 
   22310            0 :       case M2Quads_ErrorOp:
   22311            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Error             ", 18);
   22312            0 :         break;
   22313              : 
   22314            0 :       case M2Quads_SaveExceptionOp:
   22315            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SaveException     ", 18);
   22316            0 :         break;
   22317              : 
   22318            0 :       case M2Quads_RestoreExceptionOp:
   22319            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RestoreException  ", 18);
   22320            0 :         break;
   22321              : 
   22322            0 :       case M2Quads_StringConvertCnulOp:
   22323            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringConvertCnul ", 18);
   22324            0 :         break;
   22325              : 
   22326            0 :       case M2Quads_StringConvertM2nulOp:
   22327            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringConvertM2nul", 18);
   22328            0 :         break;
   22329              : 
   22330            0 :       case M2Quads_StringLengthOp:
   22331            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringLength      ", 18);
   22332            0 :         break;
   22333              : 
   22334            0 :       case M2Quads_SubrangeHighOp:
   22335            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SubrangeHigh      ", 18);
   22336            0 :         break;
   22337              : 
   22338            0 :       case M2Quads_SubrangeLowOp:
   22339            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SubrangeLow       ", 18);
   22340            0 :         break;
   22341              : 
   22342              : 
   22343            0 :       default:
   22344            0 :         M2Error_InternalError ((const char *) "operator not expected", 21);
   22345            0 :         break;
   22346              :     }
   22347            0 : }
   22348              : 
   22349              : 
   22350              : /*
   22351              :    PushAutoOn - push the auto flag and then set it to TRUE.
   22352              :                 Any call to ident in the parser will result in the token being pushed.
   22353              : */
   22354              : 
   22355     64160209 : extern "C" void M2Quads_PushAutoOn (void)
   22356              : {
   22357     64160209 :   M2StackWord_PushWord (AutoStack, static_cast<unsigned int> (IsAutoOn));
   22358     64160209 :   IsAutoOn = true;
   22359     64160209 : }
   22360              : 
   22361              : 
   22362              : /*
   22363              :    PushAutoOff - push the auto flag and then set it to FALSE.
   22364              : */
   22365              : 
   22366    120049063 : extern "C" void M2Quads_PushAutoOff (void)
   22367              : {
   22368    120049063 :   M2StackWord_PushWord (AutoStack, static_cast<unsigned int> (IsAutoOn));
   22369    120049063 :   IsAutoOn = false;
   22370    120049063 : }
   22371              : 
   22372              : 
   22373              : /*
   22374              :    IsAutoPushOn - returns the value of the current Auto ident push flag.
   22375              : */
   22376              : 
   22377    574374050 : extern "C" bool M2Quads_IsAutoPushOn (void)
   22378              : {
   22379    574374050 :   return IsAutoOn;
   22380              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   22381              :   __builtin_unreachable ();
   22382              : }
   22383              : 
   22384              : 
   22385              : /*
   22386              :    PopAuto - restores the previous value of the Auto flag.
   22387              : */
   22388              : 
   22389    184184494 : extern "C" void M2Quads_PopAuto (void)
   22390              : {
   22391    184184494 :   IsAutoOn = static_cast<bool> (M2StackWord_PopWord (AutoStack));
   22392    184184494 : }
   22393              : 
   22394              : 
   22395              : /*
   22396              :    MustCheckOverflow - returns TRUE if the quadruple should test for overflow.
   22397              : */
   22398              : 
   22399       544051 : extern "C" bool M2Quads_MustCheckOverflow (unsigned int q)
   22400              : {
   22401       544051 :   M2Quads_QuadFrame f;
   22402              : 
   22403       544051 :   f = GetQF (q);
   22404       544051 :   return f->CheckOverflow;
   22405              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   22406              :   __builtin_unreachable ();
   22407              : }
   22408              : 
   22409              : 
   22410              : /*
   22411              :    PushInConstExpression - push the InConstExpression flag and then set it to TRUE.
   22412              : */
   22413              : 
   22414      1253896 : extern "C" void M2Quads_PushInConstExpression (void)
   22415              : {
   22416      1253896 :   M2StackWord_PushWord (ConstExprStack, static_cast<unsigned int> (InConstExpression));
   22417      1253896 :   InConstExpression = true;
   22418      1253896 : }
   22419              : 
   22420              : 
   22421              : /*
   22422              :    PopInConstExpression - restores the previous value of the InConstExpression.
   22423              : */
   22424              : 
   22425      1253872 : extern "C" void M2Quads_PopInConstExpression (void)
   22426              : {
   22427      1253872 :   InConstExpression = static_cast<bool> (M2StackWord_PopWord (ConstExprStack));
   22428      1253872 : }
   22429              : 
   22430              : 
   22431              : /*
   22432              :    IsInConstExpression - returns the value of the InConstExpression.
   22433              : */
   22434              : 
   22435        99674 : extern "C" bool M2Quads_IsInConstExpression (void)
   22436              : {
   22437        99674 :   return InConstExpression;
   22438              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   22439              :   __builtin_unreachable ();
   22440              : }
   22441              : 
   22442              : 
   22443              : /*
   22444              :    PushInConstParameters - push the InConstParameters flag and then set it to TRUE.
   22445              : */
   22446              : 
   22447         1726 : extern "C" void M2Quads_PushInConstParameters (void)
   22448              : {
   22449         1726 :   M2StackWord_PushWord (ConstParamStack, static_cast<unsigned int> (InConstParameters));
   22450         1726 :   InConstParameters = true;
   22451         1726 : }
   22452              : 
   22453              : 
   22454              : /*
   22455              :    PopInConstParameters - restores the previous value of the InConstParameters.
   22456              : */
   22457              : 
   22458         1726 : extern "C" void M2Quads_PopInConstParameters (void)
   22459              : {
   22460         1726 :   InConstParameters = static_cast<bool> (M2StackWord_PopWord (ConstParamStack));
   22461         1726 : }
   22462              : 
   22463              : 
   22464              : /*
   22465              :    IsInConstParameters - returns the value of the InConstParameters.
   22466              : */
   22467              : 
   22468        92636 : extern "C" bool M2Quads_IsInConstParameters (void)
   22469              : {
   22470        92636 :   return InConstParameters;
   22471              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   22472              :   __builtin_unreachable ();
   22473              : }
   22474              : 
   22475              : 
   22476              : /*
   22477              :    BuildAsmElement - the stack is expected to contain:
   22478              : 
   22479              : 
   22480              :                         Entry                      Exit
   22481              :                         =====                      ====
   22482              : 
   22483              :                  Ptr ->
   22484              :                         +------------------+
   22485              :                         | expr | tokpos    |
   22486              :                         |------------------|
   22487              :                         | str              |
   22488              :                         |------------------|
   22489              :                         | name             |
   22490              :                         |------------------|       +------------------+
   22491              :                         | CurrentInterface |       | CurrentInterface |
   22492              :                         |------------------|       |------------------|
   22493              :                         | CurrentAsm       |       | CurrentAsm       |
   22494              :                         |------------------|       |------------------|
   22495              :                         | n                |       | n                |
   22496              :                         |------------------|       |------------------|
   22497              : */
   22498              : 
   22499           33 : extern "C" void M2Quads_BuildAsmElement (bool input, bool output)
   22500              : {
   22501           33 :   DynamicStrings_String s;
   22502           33 :   unsigned int n;
   22503           33 :   unsigned int str;
   22504           33 :   unsigned int expr;
   22505           33 :   unsigned int tokpos;
   22506           33 :   unsigned int CurrentInterface;
   22507           33 :   unsigned int CurrentAsm;
   22508           33 :   unsigned int name;
   22509              : 
   22510           33 :   M2Quads_PopTtok (&expr, &tokpos);
   22511           33 :   M2Quads_PopT (&str);
   22512           33 :   M2Quads_PopT (&name);
   22513           33 :   M2Quads_PopT (&CurrentInterface);
   22514           33 :   M2Quads_PopT (&CurrentAsm);
   22515           66 :   M2Debug_Assert ((SymbolTable_IsGnuAsm (CurrentAsm)) || (SymbolTable_IsGnuAsmVolatile (CurrentAsm)));
   22516           33 :   M2Quads_PopT (&n);
   22517           33 :   n += 1;
   22518           33 :   if (CurrentInterface == SymbolTable_NulSym)
   22519              :     {
   22520           30 :       CurrentInterface = SymbolTable_MakeRegInterface ();
   22521              :     }
   22522           33 :   if (input)
   22523              :     {
   22524           18 :       SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, name, str, expr, NextQuad, 0);
   22525           18 :       if (DebugAsmTokPos)
   22526              :         {
   22527              :           s = DynamicStrings_InitString ((const char *) "input expression", 16);
   22528              :           M2Error_WarnStringAt (s, tokpos);
   22529              :         }
   22530              :     }
   22531           33 :   if (output)
   22532              :     {
   22533           15 :       SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, name, str, expr, 0, NextQuad);
   22534           15 :       if (DebugAsmTokPos)
   22535              :         {
   22536              :           s = DynamicStrings_InitString ((const char *) "output expression", 17);
   22537              :           M2Error_WarnStringAt (s, tokpos);
   22538              :         }
   22539              :     }
   22540           33 :   M2Quads_PushT (n);
   22541           33 :   M2Quads_PushT (CurrentAsm);
   22542           33 :   M2Quads_PushT (CurrentInterface);
   22543           33 : }
   22544              : 
   22545              : 
   22546              : /*
   22547              :    BuildAsmTrash - the stack is expected to contain:
   22548              : 
   22549              : 
   22550              :                         Entry                      Exit
   22551              :                         =====                      ====
   22552              : 
   22553              :                  Ptr ->
   22554              :                         +------------------+
   22555              :                         | expr | tokpos    |
   22556              :                         |------------------|       +------------------+
   22557              :                         | CurrentInterface |       | CurrentInterface |
   22558              :                         |------------------|       |------------------|
   22559              :                         | CurrentAsm       |       | CurrentAsm       |
   22560              :                         |------------------|       |------------------|
   22561              :                         | n                |       | n                |
   22562              :                         |------------------|       |------------------|
   22563              : */
   22564              : 
   22565            3 : extern "C" void M2Quads_BuildAsmTrash (void)
   22566              : {
   22567            3 :   unsigned int n;
   22568            3 :   unsigned int expr;
   22569            3 :   unsigned int tokpos;
   22570            3 :   unsigned int CurrentInterface;
   22571            3 :   unsigned int CurrentAsm;
   22572              : 
   22573            3 :   M2Quads_PopTtok (&expr, &tokpos);
   22574            3 :   M2Quads_PopT (&CurrentInterface);
   22575            3 :   M2Quads_PopT (&CurrentAsm);
   22576            6 :   M2Debug_Assert ((SymbolTable_IsGnuAsm (CurrentAsm)) || (SymbolTable_IsGnuAsmVolatile (CurrentAsm)));
   22577            3 :   M2Quads_PopT (&n);
   22578            3 :   n += 1;
   22579            3 :   if (CurrentInterface == SymbolTable_NulSym)
   22580              :     {
   22581            3 :       CurrentInterface = SymbolTable_MakeRegInterface ();
   22582              :     }
   22583            3 :   SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, NameKey_NulName, SymbolTable_NulSym, expr, 0, NextQuad);
   22584            3 :   M2Quads_PushT (n);
   22585            3 :   M2Quads_PushT (CurrentAsm);
   22586            3 :   M2Quads_PushT (CurrentInterface);
   22587            3 : }
   22588              : 
   22589              : 
   22590              : /*
   22591              :    GetQuadTrash - return the symbol associated with the trashed operand.
   22592              : */
   22593              : 
   22594          260 : extern "C" unsigned int M2Quads_GetQuadTrash (unsigned int quad)
   22595              : {
   22596          260 :   M2Quads_QuadFrame f;
   22597              : 
   22598          260 :   f = GetQF (quad);
   22599          260 :   LastQuadNo = quad;
   22600          260 :   return f->Trash;
   22601              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   22602              :   __builtin_unreachable ();
   22603              : }
   22604              : 
   22605        15674 : extern "C" void _M2_M2Quads_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
   22606              : {
   22607        15674 :   Init ();
   22608        15674 : }
   22609              : 
   22610            0 : extern "C" void _M2_M2Quads_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
   22611              : {
   22612            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.