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 % 6836 5215
Test Date: 2026-10-17 16:30:31 Functions: 85.2 % 446 380
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              :    PopTntok - Pop a True/number/tok from the True/False stack.
    5647              :               True and False are assumed to contain Symbols.
    5648              :               The number is word sized.
    5649              : */
    5650              : 
    5651              : static void PopTntok (unsigned int *True, unsigned int *n, unsigned int *tokno);
    5652              : 
    5653              : /*
    5654              :    gdbhook - a debugger convenience hook.
    5655              : */
    5656              : 
    5657              : static void gdbhook (void);
    5658              : 
    5659              : /*
    5660              :    BreakWhenQuadCreated - to be called interactively by gdb.
    5661              : */
    5662              : 
    5663              : static void BreakWhenQuadCreated (unsigned int quad);
    5664              : 
    5665              : /*
    5666              :    CheckBreak - if quad = BreakQuad then call gdbhook.
    5667              : */
    5668              : 
    5669              : static void CheckBreak (unsigned int quad);
    5670              : 
    5671              : /*
    5672              :    Init - initialize the M2Quads module, all the stacks, all the lists
    5673              :           and the quads list.
    5674              : */
    5675              : 
    5676              : static void Init (void);
    5677              : 
    5678              : 
    5679              : /*
    5680              :    DSdbEnter -
    5681              : */
    5682              : 
    5683            0 : static void DSdbEnter (void)
    5684              : {
    5685            0 : }
    5686              : 
    5687              : 
    5688              : /*
    5689              :    DSdbExit -
    5690              : */
    5691              : 
    5692            0 : static void DSdbExit (void)
    5693              : {
    5694            0 : }
    5695              : 
    5696              : 
    5697              : /*
    5698              :    GetQF - returns the QuadFrame associated with, q.
    5699              : */
    5700              : 
    5701  14299951610 : static M2Quads_QuadFrame GetQF (unsigned int q)
    5702              : {
    5703            0 :   return (M2Quads_QuadFrame) (Indexing_GetIndice (QuadArray, q));
    5704              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5705              :   __builtin_unreachable ();
    5706              : }
    5707              : 
    5708              : 
    5709              : /*
    5710              :    IsQuadA - returns true if QuadNo is a op.
    5711              : */
    5712              : 
    5713   1058457771 : static bool IsQuadA (unsigned int QuadNo, M2Quads_QuadOperator op)
    5714              : {
    5715   1058457771 :   M2Quads_QuadFrame f;
    5716              : 
    5717            0 :   f = GetQF (QuadNo);
    5718   1058457771 :   return f->Operator == op;
    5719              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5720              :   __builtin_unreachable ();
    5721              : }
    5722              : 
    5723              : 
    5724              : /*
    5725              :    OpUsesOp1 - return TRUE if op allows op1.
    5726              : */
    5727              : 
    5728       428763 : static bool OpUsesOp1 (M2Quads_QuadOperator op)
    5729              : {
    5730       428763 :   switch (op)
    5731              :     {
    5732              :       case M2Quads_StringConvertCnulOp:
    5733              :       case M2Quads_StringConvertM2nulOp:
    5734              :       case M2Quads_StringLengthOp:
    5735              :       case M2Quads_InclOp:
    5736              :       case M2Quads_ExclOp:
    5737              :       case M2Quads_UnboundedOp:
    5738              :       case M2Quads_FunctValueOp:
    5739              :       case M2Quads_NegateOp:
    5740              :       case M2Quads_BecomesOp:
    5741              :       case M2Quads_HighOp:
    5742              :       case M2Quads_SizeOp:
    5743              :       case M2Quads_AddrOp:
    5744              :       case M2Quads_RecordFieldOp:
    5745              :       case M2Quads_ArrayOp:
    5746              :       case M2Quads_LogicalShiftOp:
    5747              :       case M2Quads_LogicalRotateOp:
    5748              :       case M2Quads_LogicalOrOp:
    5749              :       case M2Quads_LogicalAndOp:
    5750              :       case M2Quads_LogicalXorOp:
    5751              :       case M2Quads_CoerceOp:
    5752              :       case M2Quads_ConvertOp:
    5753              :       case M2Quads_CastOp:
    5754              :       case M2Quads_AddOp:
    5755              :       case M2Quads_SubOp:
    5756              :       case M2Quads_MultOp:
    5757              :       case M2Quads_ModFloorOp:
    5758              :       case M2Quads_DivCeilOp:
    5759              :       case M2Quads_ModCeilOp:
    5760              :       case M2Quads_DivFloorOp:
    5761              :       case M2Quads_ModTruncOp:
    5762              :       case M2Quads_DivTruncOp:
    5763              :       case M2Quads_DivM2Op:
    5764              :       case M2Quads_ModM2Op:
    5765              :       case M2Quads_XIndrOp:
    5766              :       case M2Quads_IndrXOp:
    5767              :       case M2Quads_SaveExceptionOp:
    5768              :       case M2Quads_RestoreExceptionOp:
    5769              :         return true;
    5770       104344 :         break;
    5771              : 
    5772              : 
    5773       104344 :       default:
    5774       104344 :         return false;
    5775              :         break;
    5776              :     }
    5777              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    5778              :   __builtin_unreachable ();
    5779              : }
    5780              : 
    5781              : 
    5782              : /*
    5783              :    AddQuadInformation - adds variable analysis and jump analysis to the new quadruple.
    5784              : */
    5785              : 
    5786      6377484 : static void AddQuadInformation (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
    5787              : {
    5788      6377484 :   switch (Op)
    5789              :     {
    5790       175078 :       case M2Quads_IfInOp:
    5791       175078 :       case M2Quads_IfNotInOp:
    5792       175078 :       case M2Quads_IfEquOp:
    5793       175078 :       case M2Quads_IfNotEquOp:
    5794       175078 :       case M2Quads_IfLessOp:
    5795       175078 :       case M2Quads_IfLessEquOp:
    5796       175078 :       case M2Quads_IfGreOp:
    5797       175078 :       case M2Quads_IfGreEquOp:
    5798       175078 :         ManipulateReference (QuadNo, Oper3);
    5799       175078 :         CheckAddVariableRead (Oper1, false, QuadNo);
    5800       175078 :         CheckAddVariableRead (Oper2, false, QuadNo);
    5801       175078 :         break;
    5802              : 
    5803         2552 :       case M2Quads_LastForIteratorOp:
    5804         2552 :         CheckAddVariableWrite (Oper1, false, QuadNo);
    5805         2552 :         CheckAddTuple2Read (Oper2, false, QuadNo);
    5806         2552 :         CheckAddVariableRead (Oper3, false, QuadNo);
    5807         2552 :         break;
    5808              : 
    5809       186539 :       case M2Quads_TryOp:
    5810       186539 :       case M2Quads_RetryOp:
    5811       186539 :       case M2Quads_GotoOp:
    5812       186539 :         ManipulateReference (QuadNo, Oper3);
    5813       186539 :         break;
    5814              : 
    5815         2003 :       case M2Quads_InclOp:
    5816         2003 :       case M2Quads_ExclOp:
    5817              :         /* variable references  */
    5818         2003 :         CheckConst (Oper1);
    5819         2003 :         CheckAddVariableRead (Oper3, false, QuadNo);
    5820         2003 :         CheckAddVariableWrite (Oper1, true, QuadNo);
    5821         2003 :         break;
    5822              : 
    5823       675188 :       case M2Quads_UnboundedOp:
    5824       675188 :       case M2Quads_FunctValueOp:
    5825       675188 :       case M2Quads_NegateOp:
    5826       675188 :       case M2Quads_BecomesOp:
    5827       675188 :       case M2Quads_HighOp:
    5828       675188 :       case M2Quads_SizeOp:
    5829       675188 :         CheckConst (Oper1);
    5830       675188 :         CheckAddVariableWrite (Oper1, false, QuadNo);
    5831       675188 :         CheckAddVariableRead (Oper3, false, QuadNo);
    5832       675188 :         break;
    5833              : 
    5834       196064 :       case M2Quads_AddrOp:
    5835       196064 :         CheckConst (Oper1);
    5836       196064 :         CheckAddVariableWrite (Oper1, false, QuadNo);
    5837              :         /* the next line is a kludge and assumes we _will_
    5838              :                           write to the variable as we have taken its address  */
    5839       196064 :         CheckRemoveVariableWrite (Oper1, true, QuadNo);
    5840       196064 :         break;
    5841              : 
    5842        29799 :       case M2Quads_ReturnValueOp:
    5843        29799 :         CheckAddVariableRead (Oper1, false, QuadNo);
    5844        29799 :         break;
    5845              : 
    5846              :       case M2Quads_ReturnOp:
    5847              :       case M2Quads_NewLocalVarOp:
    5848              :       case M2Quads_KillLocalVarOp:
    5849              :         break;
    5850              : 
    5851       218988 :       case M2Quads_CallOp:
    5852       218988 :         CheckAddVariableRead (Oper3, true, QuadNo);
    5853       218988 :         break;
    5854              : 
    5855       614714 :       case M2Quads_ParamOp:
    5856       614714 :         CheckAddVariableRead (Oper2, false, QuadNo);
    5857       614714 :         CheckAddVariableRead (Oper3, false, QuadNo);
    5858       614714 :         if (((Oper1 > 0) && (Oper1 <= (SymbolTable_NoOfParamAny (Oper2)))) && (SymbolTable_IsVarParamAny (Oper2, Oper1)))
    5859              :           {
    5860              :             /* _may_ also write to a var parameter, although we dont know  */
    5861        20206 :             CheckAddVariableWrite (Oper3, true, QuadNo);
    5862              :           }
    5863              :         break;
    5864              : 
    5865       357406 :       case M2Quads_RecordFieldOp:
    5866       357406 :       case M2Quads_ArrayOp:
    5867       357406 :       case M2Quads_LogicalShiftOp:
    5868       357406 :       case M2Quads_LogicalRotateOp:
    5869       357406 :       case M2Quads_LogicalOrOp:
    5870       357406 :       case M2Quads_LogicalAndOp:
    5871       357406 :       case M2Quads_LogicalXorOp:
    5872       357406 :       case M2Quads_CoerceOp:
    5873       357406 :       case M2Quads_ConvertOp:
    5874       357406 :       case M2Quads_CastOp:
    5875       357406 :       case M2Quads_AddOp:
    5876       357406 :       case M2Quads_SubOp:
    5877       357406 :       case M2Quads_MultOp:
    5878       357406 :       case M2Quads_DivM2Op:
    5879       357406 :       case M2Quads_ModM2Op:
    5880       357406 :       case M2Quads_ModFloorOp:
    5881       357406 :       case M2Quads_DivCeilOp:
    5882       357406 :       case M2Quads_ModCeilOp:
    5883       357406 :       case M2Quads_DivFloorOp:
    5884       357406 :       case M2Quads_ModTruncOp:
    5885       357406 :       case M2Quads_DivTruncOp:
    5886       357406 :         CheckConst (Oper1);
    5887       357406 :         CheckAddVariableWrite (Oper1, false, QuadNo);
    5888       357406 :         CheckAddVariableRead (Oper2, false, QuadNo);
    5889       357406 :         CheckAddVariableRead (Oper3, false, QuadNo);
    5890       357406 :         break;
    5891              : 
    5892        43526 :       case M2Quads_XIndrOp:
    5893        43526 :         CheckConst (Oper1);
    5894        43526 :         CheckAddVariableWrite (Oper1, true, QuadNo);
    5895        43526 :         CheckAddVariableRead (Oper3, false, QuadNo);
    5896        43526 :         break;
    5897              : 
    5898        17249 :       case M2Quads_IndrXOp:
    5899        17249 :         CheckConst (Oper1);
    5900        17249 :         CheckAddVariableWrite (Oper1, false, QuadNo);
    5901        17249 :         CheckAddVariableRead (Oper3, true, QuadNo);
    5902        17249 :         break;
    5903              : 
    5904         2977 :       case M2Quads_SaveExceptionOp:
    5905              :         /* RangeCheckOp      : CheckRangeAddVariableRead(Oper3, QuadNo) |  */
    5906         2977 :         CheckConst (Oper1);
    5907         2977 :         CheckAddVariableWrite (Oper1, false, QuadNo);
    5908         2977 :         break;
    5909              : 
    5910         3139 :       case M2Quads_RestoreExceptionOp:
    5911         3139 :         CheckAddVariableRead (Oper1, false, QuadNo);
    5912         3139 :         break;
    5913              : 
    5914              : 
    5915              :       default:
    5916              :         break;
    5917              :     }
    5918      6377484 : }
    5919              : 
    5920              : 
    5921              : /*
    5922              :    PutQuadO - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
    5923              :               sets a boolean to determinine whether overflow should be checked.
    5924              : */
    5925              : 
    5926      5421234 : static void PutQuadO (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow)
    5927              : {
    5928            0 :   PutQuadOType (QuadNo, Op, Oper1, Oper2, Oper3, overflow, true);
    5929            0 : }
    5930              : 
    5931              : 
    5932              : /*
    5933              :    PutQuadOType -
    5934              : */
    5935              : 
    5936      6296630 : static void PutQuadOType (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow, bool checktype)
    5937              : {
    5938      6296630 :   M2Quads_QuadFrame f;
    5939              : 
    5940      6296630 :   if (QuadrupleGeneration)
    5941              :     {
    5942      6296630 :       M2Quads_EraseQuad (QuadNo);
    5943      6296630 :       AddQuadInformation (QuadNo, Op, Oper1, Oper2, Oper3);
    5944      6296630 :       f = GetQF (QuadNo);
    5945      6296630 :       f->Operator = Op;
    5946      6296630 :       f->Operand1 = Oper1;
    5947      6296630 :       f->Operand2 = Oper2;
    5948      6296630 :       f->Operand3 = Oper3;
    5949      6296630 :       f->CheckOverflow = overflow;
    5950      6296630 :       f->CheckType = checktype;
    5951      6296630 :       f->ConstExpr = false;  /* IsInConstExpression ()  */
    5952              :     }
    5953              :    /* IsInConstExpression ()  */
    5954      6296630 : }
    5955              : 
    5956              : 
    5957              : /*
    5958              :    UndoReadWriteInfo -
    5959              : */
    5960              : 
    5961      8303601 : static void UndoReadWriteInfo (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
    5962              : {
    5963      8303601 :   switch (Op)
    5964              :     {
    5965        96712 :       case M2Quads_IfInOp:
    5966        96712 :       case M2Quads_IfNotInOp:
    5967        96712 :       case M2Quads_IfEquOp:
    5968        96712 :       case M2Quads_IfNotEquOp:
    5969        96712 :       case M2Quads_IfLessOp:
    5970        96712 :       case M2Quads_IfLessEquOp:
    5971        96712 :       case M2Quads_IfGreOp:
    5972        96712 :       case M2Quads_IfGreEquOp:
    5973              :         /* jumps, calls and branches  */
    5974        96712 :         RemoveReference (QuadNo);
    5975        96712 :         CheckRemoveVariableRead (Oper1, false, QuadNo);
    5976        96712 :         CheckRemoveVariableRead (Oper2, false, QuadNo);
    5977        96712 :         break;
    5978              : 
    5979       137303 :       case M2Quads_TryOp:
    5980       137303 :       case M2Quads_RetryOp:
    5981       137303 :       case M2Quads_GotoOp:
    5982       137303 :         RemoveReference (QuadNo);
    5983       137303 :         break;
    5984              : 
    5985            0 :       case M2Quads_InclOp:
    5986            0 :       case M2Quads_ExclOp:
    5987              :         /* variable references  */
    5988            0 :         CheckRemoveVariableRead (Oper1, false, QuadNo);
    5989            0 :         CheckRemoveVariableWrite (Oper1, true, QuadNo);
    5990            0 :         break;
    5991              : 
    5992       335930 :       case M2Quads_UnboundedOp:
    5993       335930 :       case M2Quads_FunctValueOp:
    5994       335930 :       case M2Quads_NegateOp:
    5995       335930 :       case M2Quads_BecomesOp:
    5996       335930 :       case M2Quads_HighOp:
    5997       335930 :       case M2Quads_SizeOp:
    5998       335930 :         CheckRemoveVariableWrite (Oper1, false, QuadNo);
    5999       335930 :         CheckRemoveVariableRead (Oper3, false, QuadNo);
    6000       335930 :         break;
    6001              : 
    6002         1690 :       case M2Quads_AddrOp:
    6003         1690 :         CheckRemoveVariableWrite (Oper1, false, QuadNo);
    6004              :         /* the next line is a kludge and assumes we _will_
    6005              :                           write to the variable as we have taken its address  */
    6006         1690 :         CheckRemoveVariableWrite (Oper1, true, QuadNo);
    6007         1690 :         break;
    6008              : 
    6009          184 :       case M2Quads_ReturnValueOp:
    6010          184 :         CheckRemoveVariableRead (Oper1, false, QuadNo);
    6011          184 :         break;
    6012              : 
    6013              :       case M2Quads_ReturnOp:
    6014              :       case M2Quads_CallOp:
    6015              :       case M2Quads_NewLocalVarOp:
    6016              :       case M2Quads_KillLocalVarOp:
    6017              :         break;
    6018              : 
    6019        11482 :       case M2Quads_ParamOp:
    6020        11482 :         CheckRemoveVariableRead (Oper2, false, QuadNo);
    6021        11482 :         CheckRemoveVariableRead (Oper3, false, QuadNo);
    6022        11482 :         if (((Oper1 > 0) && (Oper1 <= (SymbolTable_NoOfParamAny (Oper2)))) && (SymbolTable_IsVarParamAny (Oper2, Oper1)))
    6023              :           {
    6024              :             /* _may_ also write to a var parameter, although we dont know  */
    6025          112 :             CheckRemoveVariableWrite (Oper3, true, QuadNo);
    6026              :           }
    6027              :         break;
    6028              : 
    6029        50671 :       case M2Quads_RecordFieldOp:
    6030        50671 :       case M2Quads_ArrayOp:
    6031        50671 :       case M2Quads_LogicalShiftOp:
    6032        50671 :       case M2Quads_LogicalRotateOp:
    6033        50671 :       case M2Quads_LogicalOrOp:
    6034        50671 :       case M2Quads_LogicalAndOp:
    6035        50671 :       case M2Quads_LogicalXorOp:
    6036        50671 :       case M2Quads_CoerceOp:
    6037        50671 :       case M2Quads_ConvertOp:
    6038        50671 :       case M2Quads_CastOp:
    6039        50671 :       case M2Quads_AddOp:
    6040        50671 :       case M2Quads_SubOp:
    6041        50671 :       case M2Quads_MultOp:
    6042        50671 :       case M2Quads_DivM2Op:
    6043        50671 :       case M2Quads_ModM2Op:
    6044        50671 :       case M2Quads_ModFloorOp:
    6045        50671 :       case M2Quads_DivCeilOp:
    6046        50671 :       case M2Quads_ModCeilOp:
    6047        50671 :       case M2Quads_DivFloorOp:
    6048        50671 :       case M2Quads_ModTruncOp:
    6049        50671 :       case M2Quads_DivTruncOp:
    6050        50671 :         CheckRemoveVariableWrite (Oper1, false, QuadNo);
    6051        50671 :         CheckRemoveVariableRead (Oper2, false, QuadNo);
    6052        50671 :         CheckRemoveVariableRead (Oper3, false, QuadNo);
    6053        50671 :         break;
    6054              : 
    6055            4 :       case M2Quads_XIndrOp:
    6056            4 :         CheckRemoveVariableWrite (Oper1, true, QuadNo);
    6057            4 :         CheckRemoveVariableRead (Oper3, false, QuadNo);
    6058            4 :         break;
    6059              : 
    6060          494 :       case M2Quads_IndrXOp:
    6061          494 :         CheckRemoveVariableWrite (Oper1, false, QuadNo);
    6062          494 :         CheckRemoveVariableRead (Oper3, true, QuadNo);
    6063          494 :         break;
    6064              : 
    6065            0 :       case M2Quads_SaveExceptionOp:
    6066              :         /* RangeCheckOp      : CheckRangeRemoveVariableRead(Oper3, QuadNo) |  */
    6067            0 :         CheckRemoveVariableWrite (Oper1, false, QuadNo);
    6068            0 :         break;
    6069              : 
    6070          216 :       case M2Quads_RestoreExceptionOp:
    6071          216 :         CheckRemoveVariableRead (Oper1, false, QuadNo);
    6072          216 :         break;
    6073              : 
    6074              : 
    6075              :       default:
    6076              :         break;
    6077              :     }
    6078      8303601 : }
    6079              : 
    6080              : 
    6081              : /*
    6082              :    CheckAddTuple2Read - checks to see whether symbol tuple contains variables or
    6083              :                         parameters and if so it then adds them to the quadruple
    6084              :                         variable list.
    6085              : */
    6086              : 
    6087         2552 : static void CheckAddTuple2Read (unsigned int tuple, bool canDereference, unsigned int Quad)
    6088              : {
    6089         2552 :   if (SymbolTable_IsTuple (tuple))
    6090              :     {
    6091         2552 :       CheckAddVariableRead (SymbolTable_GetNth (tuple, 1), canDereference, Quad);
    6092         2552 :       CheckAddVariableRead (SymbolTable_GetNth (tuple, 2), canDereference, Quad);
    6093              :     }
    6094         2552 : }
    6095              : 
    6096              : 
    6097              : /*
    6098              :    CheckAddVariableRead - checks to see whether symbol, Sym, is a variable or
    6099              :                           a parameter and if so it then adds this quadruple
    6100              :                           to the variable list.
    6101              : */
    6102              : 
    6103      3291944 : static void CheckAddVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad)
    6104              : {
    6105      3291944 :   if (SymbolTable_IsVar (Sym))
    6106              :     {
    6107      1169259 :       SymbolTable_PutReadQuad (Sym, SymbolTable_GetMode (Sym), Quad);
    6108      1169259 :       if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
    6109              :         {
    6110        17317 :           SymbolTable_PutReadQuad (Sym, SymbolTable_RightValue, Quad);
    6111              :         }
    6112              :     }
    6113      3291944 : }
    6114              : 
    6115              : 
    6116              : /*
    6117              :    CheckRemoveVariableRead - checks to see whether, Sym, is a variable or
    6118              :                              a parameter and if so then it removes the
    6119              :                              quadruple from the variable list.
    6120              : */
    6121              : 
    6122       654558 : static void CheckRemoveVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad)
    6123              : {
    6124       654558 :   if (SymbolTable_IsVar (Sym))
    6125              :     {
    6126       122598 :       SymbolTable_RemoveReadQuad (Sym, SymbolTable_GetMode (Sym), Quad);
    6127       122598 :       if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
    6128              :         {
    6129          494 :           SymbolTable_RemoveReadQuad (Sym, SymbolTable_RightValue, Quad);
    6130              :         }
    6131              :     }
    6132       654558 : }
    6133              : 
    6134              : 
    6135              : /*
    6136              :    CheckAddVariableWrite - checks to see whether symbol, Sym, is a variable and
    6137              :                            if so it then adds this quadruple to the variable list.
    6138              : */
    6139              : 
    6140      1317171 : static void CheckAddVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad)
    6141              : {
    6142      1317171 :   if (SymbolTable_IsVar (Sym))
    6143              :     {
    6144              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6145       944056 :       if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
    6146              :         {
    6147        59694 :           SymbolTable_PutReadQuad (Sym, SymbolTable_LeftValue, Quad);
    6148        59694 :           SymbolTable_PutWriteQuad (Sym, SymbolTable_RightValue, Quad);
    6149              :         }
    6150              :       else
    6151              :         {
    6152       884362 :           SymbolTable_PutWriteQuad (Sym, SymbolTable_GetMode (Sym), Quad);
    6153              :         }
    6154              :     }
    6155      1317171 : }
    6156              : 
    6157              : 
    6158              : /*
    6159              :    CheckRemoveVariableWrite - checks to see whether, Sym, is a variable and
    6160              :                               if so then it removes the quadruple from the
    6161              :                               variable list.
    6162              : */
    6163              : 
    6164       586655 : static void CheckRemoveVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad)
    6165              : {
    6166       586655 :   if (SymbolTable_IsVar (Sym))
    6167              :     {
    6168              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6169       217709 :       if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
    6170              :         {
    6171        11115 :           SymbolTable_RemoveReadQuad (Sym, SymbolTable_LeftValue, Quad);
    6172        11115 :           SymbolTable_RemoveWriteQuad (Sym, SymbolTable_RightValue, Quad);
    6173              :         }
    6174              :       else
    6175              :         {
    6176       206594 :           SymbolTable_RemoveWriteQuad (Sym, SymbolTable_GetMode (Sym), Quad);
    6177              :         }
    6178              :     }
    6179       586655 : }
    6180              : 
    6181              : 
    6182              : /*
    6183              :    CheckConst -
    6184              : */
    6185              : 
    6186      1294413 : static void CheckConst (unsigned int sym)
    6187              : {
    6188      1294413 :   if (SymbolTable_IsConst (sym))
    6189              :     {
    6190       371343 :       M2GCCDeclare_PutToBeSolvedByQuads (sym);
    6191              :     }
    6192      1294413 : }
    6193              : 
    6194              : 
    6195              : /*
    6196              :    AlterReference - alters all references from OldQuad, to NewQuad in a
    6197              :                     quadruple list Head.
    6198              : */
    6199              : 
    6200      1926117 : static void AlterReference (unsigned int Head, unsigned int OldQuad, unsigned int NewQuad)
    6201              : {
    6202      1926117 :   M2Quads_QuadFrame f;
    6203      1926117 :   M2Quads_QuadFrame g;
    6204      1926117 :   unsigned int i;
    6205              : 
    6206      1926117 :   f = GetQF (OldQuad);
    6207     12852849 :   while ((f->NoOfTimesReferenced > 0) && (Head != 0))
    6208              :     {
    6209      9000615 :       g = GetQF (Head);
    6210      9000615 :       switch (g->Operator)
    6211              :         {
    6212       397833 :           case M2Quads_IfInOp:
    6213       397833 :           case M2Quads_IfNotInOp:
    6214       397833 :           case M2Quads_IfEquOp:
    6215       397833 :           case M2Quads_IfNotEquOp:
    6216       397833 :           case M2Quads_IfLessOp:
    6217       397833 :           case M2Quads_IfLessEquOp:
    6218       397833 :           case M2Quads_IfGreOp:
    6219       397833 :           case M2Quads_IfGreEquOp:
    6220       397833 :           case M2Quads_TryOp:
    6221       397833 :           case M2Quads_RetryOp:
    6222       397833 :           case M2Quads_GotoOp:
    6223       397833 :             if (g->Operand3 == OldQuad)
    6224              :               {
    6225         8959 :                 ManipulateReference (Head, NewQuad);
    6226              :               }
    6227              :             break;
    6228              : 
    6229              : 
    6230              :           default:
    6231              :             break;
    6232              :         }
    6233      9000615 :       i = g->Next;
    6234      9000615 :       Head = i;
    6235              :     }
    6236      1926117 : }
    6237              : 
    6238              : 
    6239              : /*
    6240              :    GrowQuads - grows the list of quadruples to the quadruple, to.
    6241              : */
    6242              : 
    6243       639229 : static void GrowQuads (unsigned int to)
    6244              : {
    6245       639229 :   unsigned int i;
    6246       639229 :   M2Quads_QuadFrame f;
    6247              : 
    6248       639229 :   if ((to != 0) && (to > GrowInitialization))
    6249              :     {
    6250         9963 :       i = GrowInitialization+1;
    6251        19926 :       while (i <= to)
    6252              :         {
    6253         9963 :           if (Indexing_InBounds (QuadArray, i))
    6254              :             {
    6255            0 :               M2Debug_Assert ((Indexing_GetIndice (QuadArray, i)) != NULL);
    6256              :             }
    6257              :           else
    6258              :             {
    6259         9963 :               Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T3));
    6260         9963 :               if (f == NULL)
    6261              :                 {
    6262            0 :                   M2Error_InternalError ((const char *) "out of memory error when trying to allocate a quadruple", 55);
    6263              :                 }
    6264         9963 :               Indexing_PutIndice (QuadArray, i, reinterpret_cast <void *> (f));
    6265         9963 :               f->NoOfTimesReferenced = 0;
    6266              :             }
    6267         9963 :           i += 1;
    6268              :         }
    6269         9963 :       GrowInitialization = to;
    6270              :     }
    6271       639229 : }
    6272              : 
    6273              : 
    6274              : /*
    6275              :    ManipulateReference - manipulates the quadruple, q, so that it now points to quad, to.
    6276              : */
    6277              : 
    6278       639229 : static void ManipulateReference (unsigned int q, unsigned int to)
    6279              : {
    6280       639229 :   M2Quads_QuadFrame f;
    6281              : 
    6282      1278458 :   M2Debug_Assert ((GrowInitialization >= q) || (to == 0));
    6283       639229 :   GrowQuads (to);
    6284       639229 :   RemoveReference (q);
    6285       639229 :   f = GetQF (q);
    6286       639229 :   f->Operand3 = to;
    6287       639229 :   if (to != 0)
    6288              :     {
    6289       405791 :       f = GetQF (to);
    6290       405791 :       f->NoOfTimesReferenced += 1;
    6291              :     }
    6292       639229 : }
    6293              : 
    6294              : 
    6295              : /*
    6296              :    RemoveReference - remove the reference by quadruple q to wherever
    6297              :                      it was pointing.
    6298              : */
    6299              : 
    6300       873244 : static void RemoveReference (unsigned int q)
    6301              : {
    6302       873244 :   M2Quads_QuadFrame f;
    6303       873244 :   M2Quads_QuadFrame g;
    6304              : 
    6305       873244 :   f = GetQF (q);
    6306       873244 :   if ((f->Operand3 != 0) && (f->Operand3 < NextQuad))
    6307              :     {
    6308       278189 :       CheckBreak (f->Operand3);
    6309       278189 :       g = GetQF (f->Operand3);
    6310       278189 :       M2Debug_Assert (g->NoOfTimesReferenced != 0);
    6311       278189 :       g->NoOfTimesReferenced -= 1;
    6312              :     }
    6313       873244 : }
    6314              : 
    6315              : 
    6316              : /*
    6317              :    NewQuad - sets QuadNo to a new quadruple.
    6318              : */
    6319              : 
    6320      6297428 : static void NewQuad (unsigned int *QuadNo)
    6321              : {
    6322      6297428 :   M2Quads_QuadFrame f;
    6323              : 
    6324      6297428 :   (*QuadNo) = FreeList;
    6325      6297428 :   if ((Indexing_InBounds (QuadArray, (*QuadNo))) && ((Indexing_GetIndice (QuadArray, (*QuadNo))) != NULL))
    6326              :     {
    6327         9963 :       f = static_cast<M2Quads_QuadFrame> (Indexing_GetIndice (QuadArray, (*QuadNo)));
    6328              :     }
    6329              :   else
    6330              :     {
    6331      6287465 :       Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T3));
    6332      6287465 :       if (f == NULL)
    6333              :         {
    6334            0 :           M2Error_InternalError ((const char *) "out of memory error trying to allocate a quadruple", 50);
    6335              :         }
    6336              :       else
    6337              :         {
    6338      6287465 :           NoOfQuads += 1;
    6339      6287465 :           Indexing_PutIndice (QuadArray, (*QuadNo), reinterpret_cast <void *> (f));
    6340      6287465 :           f->NoOfTimesReferenced = 0;
    6341      6287465 :           M2Diagnostic_MemSet (QuadMemDiag, 1, NoOfQuads);
    6342      6287465 :           M2Diagnostic_MemIncr (QuadMemDiag, 2, sizeof ((*f)));
    6343              :         }
    6344              :     }
    6345      6297428 :   f->Operator = M2Quads_DummyOp;
    6346      6297428 :   f->Operand3 = 0;
    6347      6297428 :   f->Next = 0;
    6348      6297428 :   FreeList += 1;
    6349      6297428 :   if (GrowInitialization < FreeList)
    6350              :     {
    6351      6287465 :       GrowInitialization = FreeList;
    6352              :     }
    6353      6297428 : }
    6354              : 
    6355              : 
    6356              : /*
    6357              :    CheckVariableAt - checks to see whether, sym, was declared at a particular address.
    6358              : */
    6359              : 
    6360      4163320 : static void CheckVariableAt (unsigned int sym)
    6361              : {
    6362      4163320 :   if ((SymbolTable_IsVar (sym)) && (SymbolTable_IsVariableAtAddress (sym)))
    6363              :     {
    6364              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6365           54 :       if ((SymbolTable_GetMode (sym)) == SymbolTable_LeftValue)
    6366              :         {
    6367           54 :           GenQuad (M2Quads_InitAddressOp, sym, SymbolTable_NulSym, SymbolTable_GetVariableAtAddress (sym));
    6368              :         }
    6369              :       else
    6370              :         {
    6371            0 :           M2Error_InternalError ((const char *) "expecting lvalue for this variable which is declared at an explicit address", 75);
    6372              :         }
    6373              :     }
    6374      4163320 : }
    6375              : 
    6376              : 
    6377              : /*
    6378              :    CheckVariablesAt - checks to see whether we need to initialize any pointers
    6379              :                       which point to variable declared at addresses.
    6380              : */
    6381              : 
    6382       167505 : static void CheckVariablesAt (unsigned int scope)
    6383              : {
    6384            0 :   SymbolTable_ForeachLocalSymDo (scope, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) CheckVariableAt});
    6385            0 : }
    6386              : 
    6387              : 
    6388              : /*
    6389              :    GetTurnInterrupts - returns the TurnInterrupts procedure function.
    6390              : */
    6391              : 
    6392          840 : static unsigned int GetTurnInterrupts (unsigned int tok)
    6393              : {
    6394          840 :   if (M2Options_Iso)
    6395              :     {
    6396            0 :       return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "TurnInterrupts", 14), NameKey_MakeKey ((const char *) "COROUTINES", 10));
    6397              :     }
    6398              :   else
    6399              :     {
    6400          840 :       return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "TurnInterrupts", 14), NameKey_MakeKey ((const char *) "SYSTEM", 6));
    6401              :     }
    6402              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6403              :   __builtin_unreachable ();
    6404              : }
    6405              : 
    6406              : 
    6407              : /*
    6408              :    GetProtection - returns the PROTECTION data type.
    6409              : */
    6410              : 
    6411          420 : static unsigned int GetProtection (unsigned int tok)
    6412              : {
    6413          420 :   if (M2Options_Iso)
    6414              :     {
    6415            0 :       return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "PROTECTION", 10), NameKey_MakeKey ((const char *) "COROUTINES", 10));
    6416              :     }
    6417              :   else
    6418              :     {
    6419          420 :       return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "PROTECTION", 10), NameKey_MakeKey ((const char *) "SYSTEM", 6));
    6420              :     }
    6421              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6422              :   __builtin_unreachable ();
    6423              : }
    6424              : 
    6425              : 
    6426              : /*
    6427              :    CheckNeedPriorityBegin - checks to see whether we need to save the old
    6428              :                             module priority and change to another module
    6429              :                             priority.
    6430              :                             The current module initialization or procedure
    6431              :                             being built is defined by, scope. The module whose
    6432              :                             priority will be used is defined by, module.
    6433              : */
    6434              : 
    6435       183313 : static void CheckNeedPriorityBegin (unsigned int tok, unsigned int scope, unsigned int module)
    6436              : {
    6437       183313 :   unsigned int ProcSym;
    6438       183313 :   unsigned int old;
    6439              : 
    6440       183313 :   if ((SymbolTable_GetPriority (module)) != SymbolTable_NulSym)
    6441              :     {
    6442              :       /* module has been given a priority  */
    6443          420 :       ProcSym = GetTurnInterrupts (tok);
    6444          420 :       if (ProcSym != SymbolTable_NulSym)
    6445              :         {
    6446          420 :           old = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
    6447          420 :           SymbolTable_PutVar (old, GetProtection (tok));
    6448          840 :           GenQuadO (tok, M2Quads_SavePriorityOp, old, scope, ProcSym, false);
    6449          420 :           M2StackWord_PushWord (PriorityStack, old);
    6450              :         }
    6451              :     }
    6452       183313 : }
    6453              : 
    6454              : 
    6455              : /*
    6456              :    CheckNeedPriorityEnd - checks to see whether we need to restore the old
    6457              :                           module priority.
    6458              :                           The current module initialization or procedure
    6459              :                           being built is defined by, scope.
    6460              : */
    6461              : 
    6462       183130 : static void CheckNeedPriorityEnd (unsigned int tok, unsigned int scope, unsigned int module)
    6463              : {
    6464       183130 :   unsigned int ProcSym;
    6465       183130 :   unsigned int old;
    6466              : 
    6467       183130 :   if ((SymbolTable_GetPriority (module)) != SymbolTable_NulSym)
    6468              :     {
    6469              :       /* module has been given a priority  */
    6470          420 :       ProcSym = GetTurnInterrupts (tok);
    6471          420 :       if (ProcSym != SymbolTable_NulSym)
    6472              :         {
    6473          420 :           old = static_cast<unsigned int> (M2StackWord_PopWord (PriorityStack));
    6474          420 :           GenQuad (M2Quads_RestorePriorityOp, old, scope, ProcSym);
    6475              :         }
    6476              :     }
    6477       183130 : }
    6478              : 
    6479              : 
    6480              : /*
    6481              :    BuildRTExceptEnter - informs RTExceptions that we are about to enter the except state.
    6482              : */
    6483              : 
    6484         2977 : static void BuildRTExceptEnter (unsigned int tok)
    6485              : {
    6486         2977 :   unsigned int old;
    6487         2977 :   unsigned int ProcSym;
    6488              : 
    6489         2977 :   if (M2Options_Exceptions)
    6490              :     {
    6491              :       /* now inform the Modula-2 runtime we are in the exception state  */
    6492         2977 :       ProcSym = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "SetExceptionState", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
    6493         2977 :       if (ProcSym == SymbolTable_NulSym)
    6494              :         {
    6495            0 :           M2MetaError_MetaErrorT0 (tok, (const char *) "{%W}no procedure SetExceptionState found in RTExceptions which is needed to implement exception handling", 104);
    6496              :         }
    6497              :       else
    6498              :         {
    6499         2977 :           old = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
    6500         2977 :           SymbolTable_PutVar (old, M2Base_Boolean);
    6501         5954 :           GenQuadO (tok, M2Quads_SaveExceptionOp, old, SymbolTable_NulSym, ProcSym, false);
    6502         2977 :           M2StackWord_PushWord (ExceptStack, old);
    6503              :         }
    6504              :     }
    6505              :   else
    6506              :     {
    6507            0 :       M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}cannot use {%kEXCEPT} blocks with the -fno-exceptions flag", 62);
    6508              :     }
    6509         2977 : }
    6510              : 
    6511              : 
    6512              : /*
    6513              :    BuildRTExceptLeave - informs RTExceptions that we are about to leave the except state.
    6514              :                         If, destroy, is TRUE then pop the ExceptStack.
    6515              : */
    6516              : 
    6517         3139 : static void BuildRTExceptLeave (unsigned int tok, bool destroy)
    6518              : {
    6519         3139 :   unsigned int old;
    6520         3139 :   unsigned int ProcSym;
    6521              : 
    6522         3139 :   if (M2Options_Exceptions)
    6523              :     {
    6524              :       /* avoid dangling else.  */
    6525              :       /* now inform the Modula-2 runtime we are in the exception state  */
    6526         3139 :       ProcSym = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "SetExceptionState", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
    6527         3139 :       if (ProcSym != SymbolTable_NulSym)
    6528              :         {
    6529         3139 :           if (destroy)
    6530              :             {
    6531         2977 :               old = static_cast<unsigned int> (M2StackWord_PopWord (ExceptStack));
    6532              :             }
    6533              :           else
    6534              :             {
    6535          162 :               old = static_cast<unsigned int> (M2StackWord_PeepWord (ExceptStack, 1));
    6536              :             }
    6537         3139 :           GenQuadO (tok, M2Quads_RestoreExceptionOp, old, SymbolTable_NulSym, ProcSym, false);
    6538              :         }
    6539              :     }
    6540              :   /* no need for an error message here as it will be generated in the Enter procedure above  */
    6541         3139 : }
    6542              : 
    6543              : 
    6544              : /*
    6545              :    SafeRequestSym - only used during scaffold to get argc, argv, envp.
    6546              :                     It attempts to get symbol name from the current scope(s) and if
    6547              :                     it fails then it falls back onto default constants.
    6548              : */
    6549              : 
    6550        16530 : static unsigned int SafeRequestSym (unsigned int tok, NameKey_Name name)
    6551              : {
    6552        16530 :   unsigned int sym;
    6553              : 
    6554        16530 :   sym = SymbolTable_GetSym (name);
    6555        16530 :   if (sym == SymbolTable_NulSym)
    6556              :     {
    6557              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    6558            0 :       if (name == (NameKey_MakeKey ((const char *) "argc", 4)))
    6559              :         {
    6560            0 :           return SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType);
    6561              :         }
    6562            0 :       else if ((name == (NameKey_MakeKey ((const char *) "argv", 4))) || (name == (NameKey_MakeKey ((const char *) "envp", 4))))
    6563              :         {
    6564              :           /* avoid dangling else.  */
    6565            0 :           return M2Base_Nil;
    6566              :         }
    6567              :       else
    6568              :         {
    6569              :           /* avoid dangling else.  */
    6570            0 :           M2Error_InternalError ((const char *) "not expecting this parameter name", 33);
    6571              :           return M2Base_Nil;
    6572              :         }
    6573              :     }
    6574              :   return sym;
    6575              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6576              :   __builtin_unreachable ();
    6577              : }
    6578              : 
    6579              : 
    6580              : /*
    6581              :    callRequestDependant - create a call:
    6582              :                           RequestDependant (GetSymName (modulesym), GetLibName (modulesym),
    6583              :                                             GetSymName (depModuleSym), GetLibName (depModuleSym));
    6584              : */
    6585              : 
    6586        38544 : static void callRequestDependant (unsigned int tokno, unsigned int moduleSym, unsigned int depModuleSym, unsigned int requestDep)
    6587              : {
    6588        38544 :   M2Debug_Assert (requestDep != SymbolTable_NulSym);
    6589        38544 :   M2Quads_PushTtok (requestDep, tokno);
    6590        38544 :   M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
    6591        38544 :   M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetSymName (moduleSym)), tokno);
    6592        38544 :   M2Quads_PushT (static_cast<unsigned int> (1));
    6593        38544 :   BuildAdrFunction ();
    6594        38544 :   M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
    6595        38544 :   M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetLibName (moduleSym)), tokno);
    6596        38544 :   M2Quads_PushT (static_cast<unsigned int> (1));
    6597        38544 :   BuildAdrFunction ();
    6598        38544 :   if (depModuleSym == SymbolTable_NulSym)
    6599              :     {
    6600        15519 :       M2Quads_PushTF (M2Base_Nil, M2System_Address);
    6601        15519 :       M2Quads_PushTF (M2Base_Nil, M2System_Address);
    6602              :     }
    6603              :   else
    6604              :     {
    6605        23025 :       M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
    6606        23025 :       M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetSymName (depModuleSym)), tokno);
    6607        23025 :       M2Quads_PushT (static_cast<unsigned int> (1));
    6608        23025 :       BuildAdrFunction ();
    6609        23025 :       M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
    6610        23025 :       M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetLibName (depModuleSym)), tokno);
    6611        23025 :       M2Quads_PushT (static_cast<unsigned int> (1));
    6612        23025 :       BuildAdrFunction ();
    6613              :     }
    6614        38544 :   M2Quads_PushT (static_cast<unsigned int> (4));
    6615        38544 :   M2Quads_BuildProcedureCall (tokno);
    6616        38544 : }
    6617              : 
    6618              : 
    6619              : /*
    6620              :    ForeachImportInDepDo -
    6621              : */
    6622              : 
    6623        31038 : static void ForeachImportInDepDo (Lists_List importStatements, unsigned int moduleSym, unsigned int requestDep)
    6624              : {
    6625        31038 :   unsigned int i;
    6626        31038 :   unsigned int j;
    6627        31038 :   unsigned int m;
    6628        31038 :   unsigned int n;
    6629        31038 :   unsigned int imported;
    6630        31038 :   unsigned int stmt;
    6631        31038 :   Lists_List l;
    6632              : 
    6633        31038 :   if (importStatements != NULL)
    6634              :     {
    6635        19323 :       i = 1;
    6636        19323 :       n = Lists_NoOfItemsInList (importStatements);
    6637        60921 :       while (i <= n)
    6638              :         {
    6639        22275 :           stmt = static_cast<unsigned int> (Lists_GetItemFromList (importStatements, i));
    6640        22275 :           M2Debug_Assert (SymbolTable_IsImportStatement (stmt));
    6641        22275 :           l = SymbolTable_GetImportStatementList (stmt);
    6642        22275 :           j = 1;
    6643        22275 :           m = Lists_NoOfItemsInList (l);
    6644        67575 :           while (j <= m)
    6645              :             {
    6646        23025 :               imported = static_cast<unsigned int> (Lists_GetItemFromList (l, j));
    6647        23025 :               M2Debug_Assert (SymbolTable_IsImport (imported));
    6648        23025 :               callRequestDependant (SymbolTable_GetImportDeclared (imported), moduleSym, SymbolTable_GetImportModule (imported), requestDep);
    6649        23025 :               j += 1;
    6650              :             }
    6651        22275 :           i += 1;
    6652              :         }
    6653              :     }
    6654        31038 : }
    6655              : 
    6656              : 
    6657              : /*
    6658              :    ForeachImportedModuleDo -
    6659              : */
    6660              : 
    6661        15519 : static void ForeachImportedModuleDo (unsigned int moduleSym, unsigned int requestDep)
    6662              : {
    6663        15519 :   Lists_List importStatements;
    6664              : 
    6665        15519 :   importStatements = SymbolTable_GetModuleModImportStatementList (moduleSym);
    6666        15519 :   ForeachImportInDepDo (importStatements, moduleSym, requestDep);
    6667        15519 :   importStatements = SymbolTable_GetModuleDefImportStatementList (moduleSym);
    6668        15519 :   ForeachImportInDepDo (importStatements, moduleSym, requestDep);
    6669        15519 : }
    6670              : 
    6671              : 
    6672              : /*
    6673              :    BuildM2DepFunction - creates the dependency graph procedure using IR:
    6674              :                         static void
    6675              :                         dependencies (void)
    6676              :                         {
    6677              :                            M2RTS_RequestDependant (module_name, libname, "b", "b libname");
    6678              :                            M2RTS_RequestDependant (module_name, libname, NULL, NULL);
    6679              :                         }
    6680              : */
    6681              : 
    6682        15595 : static void BuildM2DepFunction (unsigned int tokno, unsigned int moduleSym)
    6683              : {
    6684        15595 :   unsigned int requestDep;
    6685        15595 :   unsigned int ctor;
    6686        15595 :   unsigned int init;
    6687        15595 :   unsigned int fini;
    6688        15595 :   unsigned int dep;
    6689              : 
    6690        15595 :   if (M2Options_ScaffoldDynamic)
    6691              :     {
    6692              :       /* Scaffold required and dynamic dependency graph should be produced.  */
    6693        15519 :       SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
    6694        15519 :       M2Quads_PushT (dep);
    6695        15519 :       M2Quads_BuildProcedureStart ();
    6696        15519 :       M2Quads_BuildProcedureBegin ();
    6697        15519 :       SymbolTable_StartScope (dep);
    6698        15519 :       requestDep = GetQualidentImport (tokno, NameKey_MakeKey ((const char *) "RequestDependant", 16), NameKey_MakeKey ((const char *) "M2RTS", 5));
    6699        15519 :       if (requestDep != SymbolTable_NulSym)
    6700              :         {
    6701        15519 :           ForeachImportedModuleDo (moduleSym, requestDep);
    6702        15519 :           callRequestDependant (tokno, moduleSym, SymbolTable_NulSym, requestDep);
    6703              :         }
    6704        15519 :       SymbolTable_EndScope ();
    6705        15519 :       M2Quads_BuildProcedureEnd ();
    6706        15519 :       M2Quads_PopN (1);
    6707              :     }
    6708        15595 : }
    6709              : 
    6710              : 
    6711              : /*
    6712              :    BuildM2LinkFunction - creates the _M2_link procedure which will
    6713              :                          cause the linker to pull in all the module ctors.
    6714              : */
    6715              : 
    6716         2823 : static void BuildM2LinkFunction (unsigned int tokno)
    6717              : {
    6718         2823 :   if (M2Options_ScaffoldDynamic)
    6719              :     {
    6720         2755 :       if (M2Scaffold_linkFunction != SymbolTable_NulSym)
    6721              :         {
    6722              :           /* void
    6723              :            _M2_link (void)
    6724              :            {
    6725              :               for each module in uselist do
    6726              :                  PROC foo_%d = _M2_module_ctor
    6727              :               done
    6728              :            }.  */
    6729         2738 :           M2Quads_PushT (M2Scaffold_linkFunction);
    6730         2738 :           M2Quads_BuildProcedureStart ();
    6731         2738 :           M2Quads_BuildProcedureBegin ();
    6732         2738 :           SymbolTable_StartScope (M2Scaffold_linkFunction);
    6733         2738 :           M2Scaffold_PopulateCtorArray (tokno);
    6734         2738 :           SymbolTable_EndScope ();
    6735         2738 :           M2Quads_BuildProcedureEnd ();
    6736         2738 :           M2Quads_PopN (1);
    6737              :         }
    6738              :     }
    6739         2823 : }
    6740              : 
    6741              : 
    6742              : /*
    6743              :    BuildTry - build the try statement for main.
    6744              : */
    6745              : 
    6746         2755 : static void BuildTry (unsigned int tokno)
    6747              : {
    6748         2755 :   if (M2Options_Exceptions)
    6749              :     {
    6750         2755 :       M2StackWord_PushWord (TryStack, NextQuad);
    6751         2755 :       M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
    6752         2755 :       GenQuadO (tokno, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
    6753              :     }
    6754         2755 : }
    6755              : 
    6756              : 
    6757              : /*
    6758              :    BuildExcept - build the except block for main.
    6759              : */
    6760              : 
    6761         2755 : static void BuildExcept (unsigned int tokno)
    6762              : {
    6763         2755 :   unsigned int catchProcedure;
    6764              : 
    6765         2755 :   if (M2Options_Exceptions)
    6766              :     {
    6767         2755 :       M2Quads_BuildExceptInitial (tokno);
    6768         2755 :       catchProcedure = GetQualidentImport (tokno, NameKey_MakeKey ((const char *) "DefaultErrorCatch", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
    6769         2755 :       if (catchProcedure != SymbolTable_NulSym)
    6770              :         {
    6771         2755 :           M2Quads_PushTtok (catchProcedure, tokno);
    6772         2755 :           M2Quads_PushT (static_cast<unsigned int> (0));
    6773         2755 :           M2Quads_BuildProcedureCall (tokno);
    6774              :         }
    6775         2755 :       BuildRTExceptLeave (tokno, true);
    6776         2755 :       GenQuadO (tokno, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
    6777              :     }
    6778         2755 : }
    6779              : 
    6780              : 
    6781              : /*
    6782              :    BuildM2MainFunction - creates the main function with appropriate calls to the scaffold.
    6783              : */
    6784              : 
    6785         2823 : static void BuildM2MainFunction (unsigned int tokno)
    6786              : {
    6787         2823 :   if ((M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic) && ! M2Options_SharedFlag)
    6788              :     {
    6789              :       /* 
    6790              :          int
    6791              :          main (int argc, char *argv[], char *envp[])
    6792              :          {
    6793              :             try {
    6794              :                _M2_init (argc, argv, envp);
    6795              :                _M2_fini (argc, argv, envp);
    6796              :                return 0;
    6797              :             }
    6798              :             catch (...) {
    6799              :                RTExceptions_DefaultErrorCatch ();
    6800              :                return 0;
    6801              :             }
    6802              :          }
    6803              :   */
    6804         2755 :       M2Quads_PushT (M2Scaffold_mainFunction);
    6805         2755 :       M2Quads_BuildProcedureStart ();
    6806         2755 :       M2Quads_BuildProcedureBegin ();
    6807         2755 :       SymbolTable_StartScope (M2Scaffold_mainFunction);
    6808         2755 :       BuildTry (tokno);
    6809              :       /* _M2_init (argc, argv, envp);  */
    6810         2755 :       M2Quads_PushTtok (M2Scaffold_initFunction, tokno);
    6811         2755 :       M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argc", 4)), tokno);
    6812         2755 :       M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argv", 4)), tokno);
    6813         2755 :       M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "envp", 4)), tokno);
    6814         2755 :       M2Quads_PushT (static_cast<unsigned int> (3));
    6815         2755 :       M2Quads_BuildProcedureCall (tokno);
    6816              :       /* _M2_fini (argc, argv, envp);  */
    6817         2755 :       M2Quads_PushTtok (M2Scaffold_finiFunction, tokno);
    6818         2755 :       M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argc", 4)), tokno);
    6819         2755 :       M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argv", 4)), tokno);
    6820         2755 :       M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "envp", 4)), tokno);
    6821         2755 :       M2Quads_PushT (static_cast<unsigned int> (3));
    6822         2755 :       M2Quads_BuildProcedureCall (tokno);
    6823         2755 :       PushZero (tokno, M2Base_Integer);
    6824         2755 :       M2Quads_BuildReturn (tokno);
    6825         2755 :       BuildExcept (tokno);
    6826         2755 :       PushZero (tokno, M2Base_Integer);
    6827         2755 :       M2Quads_BuildReturn (tokno);
    6828         2755 :       SymbolTable_EndScope ();
    6829         2755 :       M2Quads_BuildProcedureEnd ();
    6830         2755 :       M2Quads_PopN (1);
    6831              :     }
    6832         2823 : }
    6833              : 
    6834              : 
    6835              : /*
    6836              :    DeferMakeConstStringCnul - return a C const string which will be nul terminated.
    6837              : */
    6838              : 
    6839         9762 : static unsigned int DeferMakeConstStringCnul (unsigned int tok, unsigned int sym)
    6840              : {
    6841         9762 :   unsigned int const_;
    6842              : 
    6843         9762 :   const_ = SymbolTable_MakeConstStringCnul (tok, NameKey_NulName, false);
    6844        19524 :   GenQuadO (tok, M2Quads_StringConvertCnulOp, const_, 0, sym, false);
    6845         9762 :   return const_;
    6846              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6847              :   __builtin_unreachable ();
    6848              : }
    6849              : 
    6850              : 
    6851              : /*
    6852              :    DeferMakeConstStringM2nul - return a const string which will be nul terminated.
    6853              : */
    6854              : 
    6855        34638 : static unsigned int DeferMakeConstStringM2nul (unsigned int tok, unsigned int sym)
    6856              : {
    6857        34638 :   unsigned int const_;
    6858              : 
    6859        34638 :   const_ = SymbolTable_MakeConstStringM2nul (tok, NameKey_NulName, false);
    6860        69276 :   GenQuadO (tok, M2Quads_StringConvertM2nulOp, const_, 0, sym, false);
    6861        34638 :   return const_;
    6862              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    6863              :   __builtin_unreachable ();
    6864              : }
    6865              : 
    6866              : 
    6867              : /*
    6868              :    BuildStringAdrParam - push the address of a nul terminated string onto the quad stack.
    6869              : */
    6870              : 
    6871         8265 : static void BuildStringAdrParam (unsigned int tok, NameKey_Name name)
    6872              : {
    6873         8265 :   unsigned int str;
    6874         8265 :   unsigned int m2strnul;
    6875              : 
    6876         8265 :   M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
    6877         8265 :   str = SymbolTable_MakeConstString (tok, name);
    6878         8265 :   SymbolTable_PutConstStringKnown (tok, str, name, false, true);
    6879         8265 :   m2strnul = DeferMakeConstStringM2nul (tok, str);
    6880         8265 :   M2Quads_PushTtok (m2strnul, tok);
    6881         8265 :   M2Quads_PushT (static_cast<unsigned int> (1));
    6882         8265 :   BuildAdrFunction ();
    6883         8265 : }
    6884              : 
    6885              : 
    6886              : /*
    6887              :    BuildM2InitFunction -
    6888              : */
    6889              : 
    6890         2823 : static void BuildM2InitFunction (unsigned int tok, unsigned int moduleSym)
    6891              : {
    6892         2823 :   unsigned int constructModules;
    6893              : 
    6894         2823 :   if (M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic)
    6895              :     {
    6896              :       /* int
    6897              :          _M2_init (int argc, char *argv[], char *envp[])
    6898              :          {
    6899              :             M2RTS_ConstructModules (module_name, libname,
    6900              :                                     overrideliborder, argc, argv, envp);
    6901              :          }  */
    6902         2755 :       M2Quads_PushT (M2Scaffold_initFunction);
    6903         2755 :       M2Quads_BuildProcedureStart ();
    6904         2755 :       M2Quads_BuildProcedureBegin ();
    6905         2755 :       SymbolTable_StartScope (M2Scaffold_initFunction);
    6906         2755 :       if (M2Options_ScaffoldDynamic)
    6907              :         {
    6908              :           /* avoid dangling else.  */
    6909         2755 :           if (M2Scaffold_linkFunction != SymbolTable_NulSym)
    6910              :             {
    6911              :               /* _M2_link ();  */
    6912         2738 :               M2Quads_PushTtok (M2Scaffold_linkFunction, tok);
    6913         2738 :               M2Quads_PushT (static_cast<unsigned int> (0));
    6914         2738 :               M2Quads_BuildProcedureCall (tok);
    6915              :             }
    6916              :           /* Lookup ConstructModules and call it.  */
    6917         2755 :           constructModules = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "ConstructModules", 16), NameKey_MakeKey ((const char *) "M2RTS", 5));
    6918         2755 :           if (constructModules != SymbolTable_NulSym)
    6919              :             {
    6920              :               /* ConstructModules (module_name, argc, argv, envp);  */
    6921         2755 :               M2Quads_PushTtok (constructModules, tok);
    6922         2755 :               BuildStringAdrParam (tok, SymbolTable_GetSymName (moduleSym));
    6923         2755 :               BuildStringAdrParam (tok, SymbolTable_GetLibName (moduleSym));
    6924         2755 :               BuildStringAdrParam (tok, NameKey_makekey (M2Options_GetRuntimeModuleOverride ()));
    6925         2755 :               M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argc", 4)), tok);
    6926         2755 :               M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argv", 4)), tok);
    6927         2755 :               M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "envp", 4)), tok);
    6928         2755 :               M2Quads_PushT (static_cast<unsigned int> (6));
    6929         2755 :               M2Quads_BuildProcedureCall (tok);
    6930              :             }
    6931              :         }
    6932            0 :       else if (M2Options_ScaffoldStatic)
    6933              :         {
    6934              :           /* avoid dangling else.  */
    6935            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)));
    6936              :         }
    6937         2755 :       SymbolTable_EndScope ();
    6938         2755 :       M2Quads_BuildProcedureEnd ();
    6939         2755 :       M2Quads_PopN (1);
    6940              :     }
    6941         2823 : }
    6942              : 
    6943              : 
    6944              : /*
    6945              :    BuildM2FiniFunction -
    6946              : */
    6947              : 
    6948         2823 : static void BuildM2FiniFunction (unsigned int tok, unsigned int moduleSym)
    6949              : {
    6950         2823 :   unsigned int deconstructModules;
    6951              : 
    6952         2823 :   if (M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic)
    6953              :     {
    6954              :       /* Scaffold required and main should be produced.  */
    6955         2755 :       M2Quads_PushT (M2Scaffold_finiFunction);
    6956         2755 :       M2Quads_BuildProcedureStart ();
    6957         2755 :       M2Quads_BuildProcedureBegin ();
    6958         2755 :       SymbolTable_StartScope (M2Scaffold_finiFunction);
    6959         2755 :       if (M2Options_ScaffoldDynamic)
    6960              :         {
    6961              :           /* avoid dangling else.  */
    6962              :           /* static void
    6963              :             _M2_finish (int argc, char *argv[], char *envp[])
    6964              :             {
    6965              :               M2RTS_DeconstructModules (module_name, argc, argv, envp);
    6966              :             }  */
    6967         2755 :           deconstructModules = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "DeconstructModules", 18), NameKey_MakeKey ((const char *) "M2RTS", 5));
    6968         2755 :           if (deconstructModules != SymbolTable_NulSym)
    6969              :             {
    6970              :               /* DeconstructModules (module_name, argc, argv, envp);  */
    6971         2755 :               M2Quads_PushTtok (deconstructModules, tok);
    6972         2755 :               M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
    6973         2755 :               M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetSymName (moduleSym)), tok);
    6974         2755 :               M2Quads_PushT (static_cast<unsigned int> (1));
    6975         2755 :               BuildAdrFunction ();
    6976         2755 :               M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
    6977         2755 :               M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetLibName (moduleSym)), tok);
    6978         2755 :               M2Quads_PushT (static_cast<unsigned int> (1));
    6979         2755 :               BuildAdrFunction ();
    6980         2755 :               M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argc", 4)), tok);
    6981         2755 :               M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argv", 4)), tok);
    6982         2755 :               M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "envp", 4)), tok);
    6983         2755 :               M2Quads_PushT (static_cast<unsigned int> (5));
    6984         2755 :               M2Quads_BuildProcedureCall (tok);
    6985              :             }
    6986              :         }
    6987            0 :       else if (M2Options_ScaffoldStatic)
    6988              :         {
    6989              :           /* avoid dangling else.  */
    6990            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)));
    6991              :         }
    6992         2755 :       SymbolTable_EndScope ();
    6993         2755 :       M2Quads_BuildProcedureEnd ();
    6994         2755 :       M2Quads_PopN (1);
    6995              :     }
    6996         2823 : }
    6997              : 
    6998              : 
    6999              : /*
    7000              :    BuildM2CtorFunction - create a constructor function associated with moduleSym.
    7001              : 
    7002              :                          void
    7003              :                          ctorFunction ()
    7004              :                          {
    7005              :                            M2RTS_RegisterModule (GetSymName (moduleSym), GetLibName (moduleSym),
    7006              :                                                  init, fini, dependencies);
    7007              :                          }
    7008              : */
    7009              : 
    7010        15595 : static void BuildM2CtorFunction (unsigned int tok, unsigned int moduleSym)
    7011              : {
    7012        15595 :   unsigned int RegisterModule;
    7013        15595 :   unsigned int ctor;
    7014        15595 :   unsigned int init;
    7015        15595 :   unsigned int fini;
    7016        15595 :   unsigned int dep;
    7017              : 
    7018        15595 :   if (M2Options_ScaffoldDynamic)
    7019              :     {
    7020        15519 :       SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
    7021        15519 :       if (ctor != SymbolTable_NulSym)
    7022              :         {
    7023        15519 :           M2Debug_Assert (SymbolTable_IsProcedure (ctor));
    7024        15519 :           M2Quads_PushT (ctor);
    7025        15519 :           M2Quads_BuildProcedureStart ();
    7026        15519 :           M2Quads_BuildProcedureBegin ();
    7027        15519 :           SymbolTable_StartScope (ctor);
    7028        15519 :           RegisterModule = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "RegisterModule", 14), NameKey_MakeKey ((const char *) "M2RTS", 5));
    7029        15519 :           if (RegisterModule != SymbolTable_NulSym)
    7030              :             {
    7031              :               /* RegisterModule (module_name, init, fini, dependencies);  */
    7032        15519 :               M2Quads_PushTtok (RegisterModule, tok);
    7033        15519 :               M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
    7034        15519 :               M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetSymName (moduleSym)), tok);
    7035        15519 :               M2Quads_PushT (static_cast<unsigned int> (1));
    7036        15519 :               BuildAdrFunction ();
    7037        15519 :               M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
    7038        15519 :               M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetLibName (moduleSym)), tok);
    7039        15519 :               M2Quads_PushT (static_cast<unsigned int> (1));
    7040        15519 :               BuildAdrFunction ();
    7041        15519 :               M2Quads_PushTtok (init, tok);
    7042        15519 :               M2Quads_PushTtok (fini, tok);
    7043        15519 :               M2Quads_PushTtok (dep, tok);
    7044        15519 :               M2Quads_PushT (static_cast<unsigned int> (5));
    7045        15519 :               M2Quads_BuildProcedureCall (tok);
    7046              :             }
    7047        15519 :           SymbolTable_EndScope ();
    7048        15519 :           M2Quads_BuildProcedureEnd ();
    7049        15519 :           M2Quads_PopN (1);
    7050              :         }
    7051              :     }
    7052        15595 : }
    7053              : 
    7054              : 
    7055              : /*
    7056              :    AddForInfo - adds the description of the FOR loop into the record list.
    7057              :                 This is used if -pedantic is turned on to check index variable
    7058              :                 usage.
    7059              : */
    7060              : 
    7061         2570 : static void AddForInfo (unsigned int Start, unsigned int End, unsigned int IncQuad, unsigned int Sym, unsigned int idtok)
    7062              : {
    7063         2570 :   M2Quads_ForLoopInfo forDesc;
    7064              : 
    7065         2570 :   if (M2Options_Pedantic)
    7066              :     {
    7067            0 :       Storage_ALLOCATE ((void **) &forDesc, sizeof (M2Quads__T5));
    7068            0 :       forDesc->IncrementQuad = IncQuad;
    7069            0 :       forDesc->StartOfForLoop = Start;
    7070            0 :       forDesc->EndOfForLoop = End;
    7071            0 :       forDesc->ForLoopIndex = Sym;
    7072            0 :       forDesc->IndexTok = idtok;
    7073            0 :       Indexing_IncludeIndiceIntoIndex (ForInfo, reinterpret_cast <void *> (forDesc));
    7074              :     }
    7075         2570 : }
    7076              : 
    7077              : 
    7078              : /*
    7079              :    CheckForIndex - checks the quadruples: Start..End to see whether a
    7080              :                    for loop index is manipulated by the programmer.
    7081              :                    It generates a warning if this is the case.
    7082              :                    It also checks to see whether the IndexSym is read
    7083              :                    immediately outside the loop in which case a warning
    7084              :                    is issued.
    7085              : */
    7086              : 
    7087            0 : static void CheckForIndex (M2Quads_ForLoopInfo forDesc)
    7088              : {
    7089            0 :   unsigned int ReadStart;
    7090            0 :   unsigned int ReadEnd;
    7091            0 :   unsigned int WriteStart;
    7092            0 :   unsigned int WriteEnd;
    7093              : 
    7094            0 :   SymbolTable_GetWriteLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->StartOfForLoop, forDesc->EndOfForLoop, &WriteStart, &WriteEnd);
    7095            0 :   if ((WriteStart < forDesc->IncrementQuad) && (WriteStart > forDesc->StartOfForLoop))
    7096              :     {
    7097            0 :       M2MetaError_MetaErrorT1 (forDesc->IndexTok, (const char *) "{%kFOR} loop index variable {%1Wad} is being manipulated inside the loop", 72, forDesc->ForLoopIndex);
    7098            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);
    7099              :     }
    7100            0 :   SymbolTable_GetWriteLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->EndOfForLoop, 0, &WriteStart, &WriteEnd);
    7101            0 :   SymbolTable_GetReadLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->EndOfForLoop, 0, &ReadStart, &ReadEnd);
    7102            0 :   if ((ReadStart != 0) && ((ReadStart < WriteStart) || (WriteStart == 0)))
    7103              :     {
    7104            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);
    7105            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);
    7106              :     }
    7107            0 : }
    7108              : 
    7109              : 
    7110              : /*
    7111              :    BuildRange - generates a RangeCheckOp quad with, r, as its operand.
    7112              : */
    7113              : 
    7114      2071858 : static void BuildRange (unsigned int r)
    7115              : {
    7116      2071858 :   GenQuad (M2Quads_RangeCheckOp, (unsigned int ) (M2LexBuf_GetLineNo ()), SymbolTable_NulSym, r);
    7117      2071858 : }
    7118              : 
    7119              : 
    7120              : /*
    7121              :    BuildError - generates a ErrorOp quad, indicating that if this
    7122              :                 quadruple is reachable, then a runtime error would
    7123              :                 occur.
    7124              : */
    7125              : 
    7126        21362 : static void BuildError (unsigned int r)
    7127              : {
    7128        21362 :   GenQuad (M2Quads_ErrorOp, (unsigned int ) (M2LexBuf_GetLineNo ()), SymbolTable_NulSym, r);
    7129        21362 : }
    7130              : 
    7131              : 
    7132              : /*
    7133              :    CheckPointerThroughNil - builds a range quadruple, providing, sym, is
    7134              :                             a candidate for checking against NIL.
    7135              :                             This range quadruple is only expanded into
    7136              :                             code during the code generation phase
    7137              :                             thus allowing limited compile time checking.
    7138              : */
    7139              : 
    7140        80204 : static void CheckPointerThroughNil (unsigned int tokpos, unsigned int sym)
    7141              : {
    7142        80204 :   if ((SymbolTable_IsVar (sym)) && (SymbolTable_GetVarPointerCheck (sym)))
    7143              :     {
    7144              :       /* PutVarPointerCheck(sym, FALSE) ;   so we do not detect this again  */
    7145        23402 :       BuildRange (M2Range_InitPointerRangeCheck (tokpos, sym, (SymbolTable_GetMode (sym)) == SymbolTable_LeftValue));
    7146              :     }
    7147        80204 : }
    7148              : 
    7149              : 
    7150              : /*
    7151              :    CollectLow - returns the low of the subrange value.
    7152              : */
    7153              : 
    7154          306 : static unsigned int CollectLow (unsigned int sym)
    7155              : {
    7156          306 :   unsigned int low;
    7157          306 :   unsigned int high;
    7158              : 
    7159          306 :   if (SymbolTable_IsSubrange (sym))
    7160              :     {
    7161          306 :       SymbolTable_GetSubrange (sym, &high, &low);
    7162          306 :       return low;
    7163              :     }
    7164              :   else
    7165              :     {
    7166            0 :       M2Error_InternalError ((const char *) "expecting Subrange symbol", 25);
    7167              :     }
    7168              :   ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
    7169              :   __builtin_unreachable ();
    7170              : }
    7171              : 
    7172              : 
    7173              : /*
    7174              :    CollectHigh - returns the high of the subrange value, sym.
    7175              : */
    7176              : 
    7177          558 : static unsigned int CollectHigh (unsigned int sym)
    7178              : {
    7179          558 :   unsigned int low;
    7180          558 :   unsigned int high;
    7181              : 
    7182          558 :   if (SymbolTable_IsSubrange (sym))
    7183              :     {
    7184          558 :       SymbolTable_GetSubrange (sym, &high, &low);
    7185          558 :       return high;
    7186              :     }
    7187              :   else
    7188              :     {
    7189            0 :       M2Error_InternalError ((const char *) "expecting Subrange symbol", 25);
    7190              :     }
    7191              :   ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
    7192              :   __builtin_unreachable ();
    7193              : }
    7194              : 
    7195              : 
    7196              : /*
    7197              :    CheckCompatibleWithBecomes - checks to see that symbol, sym, is
    7198              :                                 compatible with the := operator.
    7199              : */
    7200              : 
    7201       498996 : static void CheckCompatibleWithBecomes (unsigned int des, unsigned int expr, unsigned int destok, unsigned int exprtok)
    7202              : {
    7203       498996 :   if (SymbolTable_IsType (des))
    7204              :     {
    7205            0 :       M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to a type {%1a}", 51, des);
    7206              :     }
    7207       498996 :   else if (SymbolTable_IsProcedure (des))
    7208              :     {
    7209              :       /* avoid dangling else.  */
    7210            6 :       M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to a procedure {%1a}", 56, des);
    7211              :     }
    7212       498990 :   else if (SymbolTable_IsFieldEnumeration (des))
    7213              :     {
    7214              :       /* avoid dangling else.  */
    7215            0 :       M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to an enumeration field {%1a}", 65, des);
    7216              :     }
    7217       498996 :   if ((M2Base_IsPseudoBaseProcedure (expr)) || (M2Base_IsPseudoBaseFunction (expr)))
    7218              :     {
    7219            6 :       M2MetaError_MetaErrorT1 (exprtok, (const char *) "an assignment cannot assign a {%1dv} {%1a}", 42, expr);
    7220              :     }
    7221       498996 : }
    7222              : 
    7223              : 
    7224              : /*
    7225              :    BuildAssignmentWithoutBounds - calls BuildAssignment but makes sure we do not
    7226              :                                   check bounds.
    7227              : */
    7228              : 
    7229        82694 : static void BuildAssignmentWithoutBounds (unsigned int tok, bool checkTypes, bool checkOverflow)
    7230              : {
    7231        82694 :   bool old;
    7232              : 
    7233        82694 :   old = MustNotCheckBounds;
    7234        82694 :   MustNotCheckBounds = true;
    7235            0 :   doBuildAssignment (tok, checkTypes, checkOverflow);
    7236        82694 :   MustNotCheckBounds = old;
    7237            0 : }
    7238              : 
    7239              : 
    7240              : /*
    7241              :    MarkArrayWritten - marks, Array, as being written.
    7242              : */
    7243              : 
    7244       101126 : static void MarkArrayWritten (unsigned int Array)
    7245              : {
    7246       101126 :   if ((Array != SymbolTable_NulSym) && (SymbolTable_IsVarAParam (Array)))
    7247              :     {
    7248        12649 :       SymbolTable_PutVarWritten (Array, true);
    7249              :     }
    7250       101126 : }
    7251              : 
    7252              : 
    7253              : /*
    7254              :    MarkAsReadWrite - marks the variable or parameter as being
    7255              :                      read/write.
    7256              : */
    7257              : 
    7258        31038 : static void MarkAsReadWrite (unsigned int sym)
    7259              : {
    7260        31038 :   if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
    7261              :     {
    7262        21276 :       SymbolTable_PutReadQuad (sym, SymbolTable_RightValue, NextQuad);
    7263        21276 :       SymbolTable_PutWriteQuad (sym, SymbolTable_RightValue, NextQuad);
    7264              :     }
    7265        31038 : }
    7266              : 
    7267              : 
    7268              : /*
    7269              :    MarkAsRead - marks the variable or parameter as being read.
    7270              : */
    7271              : 
    7272      1266515 : static void MarkAsRead (unsigned int sym)
    7273              : {
    7274      1266515 :   if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
    7275              :     {
    7276       358727 :       SymbolTable_PutReadQuad (sym, SymbolTable_RightValue, NextQuad);
    7277              :     }
    7278      1266515 : }
    7279              : 
    7280              : 
    7281              : /*
    7282              :    MarkAsWrite - marks the variable or parameter as being written.
    7283              : */
    7284              : 
    7285       498996 : static void MarkAsWrite (unsigned int sym)
    7286              : {
    7287       498996 :   if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
    7288              :     {
    7289        85468 :       SymbolTable_PutWriteQuad (sym, SymbolTable_RightValue, NextQuad);
    7290              :     }
    7291       498996 : }
    7292              : 
    7293              : 
    7294              : /*
    7295              :    doVal - return an expression which is VAL(type, expr).  If
    7296              :            expr is a constant then return expr.
    7297              : */
    7298              : 
    7299        43922 : static unsigned int doVal (unsigned int type, unsigned int expr)
    7300              : {
    7301        43922 :   if ((! (SymbolTable_IsConst (expr))) && ((SymbolTable_SkipType (type)) != (SymbolTable_GetDType (expr))))
    7302              :     {
    7303        33295 :       M2Quads_PushTF (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym));
    7304        33295 :       M2Quads_PushT (SymbolTable_SkipType (type));
    7305        33295 :       M2Quads_PushT (expr);
    7306        33295 :       M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
    7307        33295 :       BuildConvertFunction (M2Base_Convert, false);  /* Two parameters  */
    7308        33295 :       M2Quads_PopT (&expr);
    7309              :     }
    7310        43922 :   return expr;
    7311              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    7312              :   __builtin_unreachable ();
    7313              : }
    7314              : 
    7315              : 
    7316              : /*
    7317              :    MoveWithMode -
    7318              : */
    7319              : 
    7320       498990 : static void MoveWithMode (unsigned int tokno, unsigned int Des, unsigned int Exp, unsigned int Array, unsigned int destok, unsigned int exptok, bool checkOverflow)
    7321              : {
    7322       498990 :   unsigned int t;
    7323              : 
    7324       498990 :   if ((SymbolTable_IsConstString (Exp)) && (SymbolTable_IsConst (Des)))
    7325              :     {
    7326         1295 :       GenQuadOtok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, destok, M2LexBuf_UnknownTokenNo, exptok);
    7327              :     }
    7328              :   else
    7329              :     {
    7330       497695 :       if ((SymbolTable_GetMode (Des)) == SymbolTable_RightValue)
    7331              :         {
    7332       155740 :           if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
    7333              :             {
    7334         2648 :               CheckPointerThroughNil (tokno, Exp);  /* Des = *Exp  */
    7335         2648 :               doIndrX (tokno, Des, Exp);  /* Des = *Exp  */
    7336              :             }
    7337              :           else
    7338              :             {
    7339       153092 :               GenQuadOtok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, destok, M2LexBuf_UnknownTokenNo, exptok);
    7340              :             }
    7341              :         }
    7342       341955 :       else if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
    7343              :         {
    7344              :           /* avoid dangling else.  */
    7345        43404 :           MarkArrayWritten (Array);
    7346        43404 :           if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
    7347              :             {
    7348         1103 :               t = SymbolTable_MakeTemporary (tokno, SymbolTable_RightValue);
    7349         1103 :               SymbolTable_PutVar (t, SymbolTable_GetSType (Exp));
    7350         1103 :               CheckPointerThroughNil (tokno, Exp);
    7351         1103 :               doIndrX (tokno, t, Exp);
    7352         1103 :               CheckPointerThroughNil (tokno, Des);  /* *Des = Exp  */
    7353         1103 :               GenQuadO (tokno, M2Quads_XIndrOp, Des, SymbolTable_GetSType (Des), doVal (SymbolTable_GetSType (Des), t), checkOverflow);  /* *Des = Exp  */
    7354              :             }
    7355              :           else
    7356              :             {
    7357        42301 :               CheckPointerThroughNil (tokno, Des);  /* *Des = Exp  */
    7358        42301 :               GenQuadO (tokno, M2Quads_XIndrOp, Des, SymbolTable_GetSType (Des), doVal (SymbolTable_GetSType (Des), Exp), checkOverflow);  /* *Des = Exp  */
    7359              :             }
    7360              :         }
    7361              :       else
    7362              :         {
    7363              :           /* avoid dangling else.  */
    7364              :           /* This might be inside a const expression.  */
    7365       298551 :           GenQuadOTypetok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, true, destok, M2LexBuf_UnknownTokenNo, exptok);
    7366              :         }
    7367              :     }
    7368       498990 : }
    7369              : 
    7370              : 
    7371              : /*
    7372              :    CheckBecomesMeta - checks to make sure that we are not
    7373              :                       assigning a variable to a constant.
    7374              :                       Also check we are not assigning to an
    7375              :                       unbounded array.
    7376              : */
    7377              : 
    7378       428006 : static void CheckBecomesMeta (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok)
    7379              : {
    7380       428006 :   if ((SymbolTable_IsConst (Des)) && (SymbolTable_IsVar (Exp)))
    7381              :     {
    7382           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);
    7383              :     }
    7384       428006 :   if ((((SymbolTable_GetDType (Des)) != SymbolTable_NulSym) && (SymbolTable_IsVar (Des))) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (Des))))
    7385              :     {
    7386            0 :       M2MetaError_MetaErrorT1 (destok, (const char *) "in assignment, cannot assign to an unbounded array {%1ad}", 57, Des);
    7387              :     }
    7388       428006 :   if ((((SymbolTable_GetDType (Exp)) != SymbolTable_NulSym) && (SymbolTable_IsVar (Exp))) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (Exp))))
    7389              :     {
    7390            0 :       M2MetaError_MetaErrorT1 (exprtok, (const char *) "in assignment, cannot assign from an unbounded array {%1ad}", 59, Exp);
    7391              :     }
    7392       428006 : }
    7393              : 
    7394              : 
    7395              : /*
    7396              :    BuildAssignmentBoolean - build the quadruples for a boolean variable or constant
    7397              :                             which will be assigned to the result of a boolean expression.
    7398              :                             For example:
    7399              : 
    7400              :                             foo := a = b ;
    7401              :                             foo := a IN b ;
    7402              : 
    7403              :                             The boolean result is contained in the control flow
    7404              :                             the true value will emerge from the quad path t.
    7405              :                             The false value will emerge from the quad path f.
    7406              :                             This procedure terminates both paths by backpatching
    7407              :                             and assigns TRUE or FALSE to the variable/constant.
    7408              :                             A variable maybe an L value so it will require dereferencing.
    7409              : */
    7410              : 
    7411         9963 : static void BuildAssignmentBoolean (unsigned int becomesTokNo, bool checkOverflow, unsigned int t, unsigned int f, unsigned int Des, unsigned int destok)
    7412              : {
    7413         9963 :   SymbolTable_PutVarConditional (Des, true);  /* Des will contain the result of a boolean relop.  */
    7414              :   /* Conditional Boolean Assignment.  */
    7415         9963 :   BackPatch (t, NextQuad);
    7416         9963 :   if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
    7417              :     {
    7418           61 :       CheckPointerThroughNil (destok, Des);
    7419          122 :       GenQuadO (destok, M2Quads_XIndrOp, Des, M2Base_Boolean, M2Base_True, checkOverflow);
    7420           61 :       GenQuadO (destok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, NextQuad+2, false);
    7421              :     }
    7422              :   else
    7423              :     {
    7424              :       /* This might be inside a const expression.  */
    7425        19804 :       GenQuadO (becomesTokNo, M2Quads_BecomesOp, Des, SymbolTable_NulSym, M2Base_True, checkOverflow);
    7426         9902 :       GenQuadO (destok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, NextQuad+2, false);
    7427              :     }
    7428         9963 :   BackPatch (f, NextQuad);
    7429         9963 :   if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
    7430              :     {
    7431           61 :       CheckPointerThroughNil (destok, Des);
    7432           61 :       GenQuadO (destok, M2Quads_XIndrOp, Des, M2Base_Boolean, M2Base_False, checkOverflow);
    7433              :     }
    7434              :   else
    7435              :     {
    7436         9902 :       GenQuadO (becomesTokNo, M2Quads_BecomesOp, Des, SymbolTable_NulSym, M2Base_False, checkOverflow);
    7437              :     }
    7438         9963 : }
    7439              : 
    7440              : 
    7441              : /*
    7442              :    doBuildAssignment - subsiduary procedure of BuildAssignment.
    7443              :                        It builds the assignment and optionally
    7444              :                        checks the types are compatible.
    7445              : */
    7446              : 
    7447       508959 : static void doBuildAssignment (unsigned int becomesTokNo, bool checkTypes, bool checkOverflow)
    7448              : {
    7449       508959 :   unsigned int r;
    7450       508959 :   unsigned int w;
    7451       508959 :   unsigned int t;
    7452       508959 :   unsigned int f;
    7453       508959 :   unsigned int Array;
    7454       508959 :   unsigned int Des;
    7455       508959 :   unsigned int Exp;
    7456       508959 :   unsigned int combinedtok;
    7457       508959 :   unsigned int destok;
    7458       508959 :   unsigned int exptok;
    7459              : 
    7460       508959 :   M2Quads_DisplayStack ();
    7461       508959 :   if (IsBoolean (1))
    7462              :     {
    7463        19926 :       PopBool (&t, &f);
    7464         9963 :       M2Quads_PopTtok (&Des, &destok);
    7465         9963 :       if ((SymbolTable_IsVar (Des)) || (SymbolTable_IsConstVar (Des)))
    7466              :         {
    7467         9963 :           BuildAssignmentBoolean (becomesTokNo, checkOverflow, t, f, Des, destok);
    7468              :         }
    7469              :       else
    7470              :         {
    7471            0 :           M2MetaError_MetaErrorT1 (destok, (const char *) "expecting the designator {%1Ead} to be a constant or a variable and not a {%1dv}", 80, Des);
    7472              :         }
    7473              :     }
    7474              :   else
    7475              :     {
    7476       498996 :       PopTrwtok (&Exp, &r, &exptok);
    7477       498996 :       MarkAsRead (r);
    7478       498996 :       if (Exp == SymbolTable_NulSym)
    7479              :         {
    7480            0 :           M2MetaError_MetaError0 ((const char *) "{%E}unknown expression found during assignment", 46);
    7481            0 :           M2Error_FlushErrors ();
    7482              :         }
    7483       498996 :       Array = static_cast<unsigned int> (M2Quads_OperandA (1));
    7484       498996 :       PopTrwtok (&Des, &w, &destok);
    7485       498996 :       MarkAsWrite (w);
    7486       498996 :       CheckCompatibleWithBecomes (Des, Exp, destok, exptok);
    7487       498996 :       if (DebugTokPos)
    7488              :         {
    7489              :           M2MetaError_MetaErrorT1 (becomesTokNo, (const char *) "becomestok {%1Oad}", 18, Des);
    7490              :           M2MetaError_MetaErrorT1 (destok, (const char *) "destok {%1Oad}", 14, Des);
    7491              :           M2MetaError_MetaErrorT1 (exptok, (const char *) "exptok {%1Oad}", 14, Exp);
    7492              :         }
    7493       498996 :       combinedtok = M2LexBuf_MakeVirtualTok (becomesTokNo, destok, exptok);
    7494       498996 :       if (DebugTokPos)
    7495              :         {
    7496              :           M2MetaError_MetaErrorT1 (combinedtok, (const char *) "combined {%1Oad}", 16, Des);
    7497              :         }
    7498       498996 :       if (M2Options_StrictTypeAssignment)
    7499              :         {
    7500       498996 :           BuildRange (M2Range_InitTypesAssignmentCheck (combinedtok, Des, Exp));
    7501              :         }
    7502       498996 :       if (((SymbolTable_GetSType (Des)) != SymbolTable_NulSym) && (! (SymbolTable_IsSet (SymbolTable_GetDType (Des)))))
    7503              :         {
    7504              :           /* Tell code generator to test runtime values of assignment so ensure we
    7505              :             catch overflow and underflow.  */
    7506       489479 :           BuildRange (M2Range_InitAssignmentRangeCheck (combinedtok, Des, Exp, destok, exptok));
    7507              :         }
    7508       498990 :       if (checkTypes)
    7509              :         {
    7510       428006 :           CheckBecomesMeta (Des, Exp, combinedtok, destok, exptok);
    7511              :         }
    7512              :       /* Simple assignment.  */
    7513       498990 :       MoveWithMode (combinedtok, Des, Exp, Array, destok, exptok, checkOverflow);
    7514       498990 :       if (checkTypes)
    7515              :         {
    7516       428006 :           CheckAssignCompatible (Des, Exp, combinedtok, destok, exptok);
    7517              :         }
    7518              :     }
    7519       508953 :   M2Quads_DisplayStack ();
    7520       508953 : }
    7521              : 
    7522              : 
    7523              : /*
    7524              :    CheckAssignCompatible - checks to see that an assignment is compatible.
    7525              :                            It performs limited checking - thorough checking
    7526              :                            is done in pass 3.  But we do what we can here
    7527              :                            given knowledge so far.
    7528              : */
    7529              : 
    7530       428006 : static void CheckAssignCompatible (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok)
    7531              : {
    7532       428006 :   unsigned int DesT;
    7533       428006 :   unsigned int ExpT;
    7534       428006 :   unsigned int DesL;
    7535              : 
    7536       428006 :   DesT = SymbolTable_GetSType (Des);
    7537       428006 :   ExpT = SymbolTable_GetSType (Exp);
    7538       428006 :   DesL = SymbolTable_GetLType (Des);
    7539       428006 :   if (((SymbolTable_IsProcedure (Exp)) && ((DesT != SymbolTable_NulSym) && (! (SymbolTable_IsProcType (DesT))))) && ((DesL != SymbolTable_NulSym) && (! (SymbolTable_IsProcType (DesL)))))
    7540              :     {
    7541            0 :       M2MetaError_MetaErrorT1 (destok, (const char *) "incorrectly assigning a procedure to a designator {%1Ead} (designator is not a procedure type, {%1ast})", 103, Des);
    7542              :     }
    7543              :   /* We ignore checking of these types in pass 3 - but we do check them thoroughly post pass 3  */
    7544       428006 :   else if ((SymbolTable_IsProcedure (Exp)) && (SymbolTable_IsProcedureNested (Exp)))
    7545              :     {
    7546              :       /* avoid dangling else.  */
    7547            6 :       M2MetaError_MetaErrorT1 (exprtok, (const char *) "cannot call nested procedure {%1Ead} indirectly as the outer scope will not be known", 84, Exp);
    7548              :     }
    7549       428000 :   else if (SymbolTable_IsConstString (Exp))
    7550              :     {
    7551              :       /* avoid dangling else.  */
    7552              :     }
    7553       425050 :   else if ((DesT != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (DesT)))
    7554              :     {
    7555              :       /* avoid dangling else.  */
    7556              :     }
    7557       425050 :   else if ((ExpT != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (ExpT)))
    7558              :     {
    7559              :       /* avoid dangling else.  */
    7560              :     }
    7561       425050 :   else if ((DesL != SymbolTable_NulSym) && (SymbolTable_IsArray (DesL)))
    7562              :     {
    7563              :       /* avoid dangling else.  */
    7564              :     }
    7565       424202 :   else if (SymbolTable_IsConstructor (Exp))
    7566              :     {
    7567              :       /* avoid dangling else.  */
    7568         6417 :       if (ExpT == SymbolTable_NulSym)
    7569              :         {}  /* empty.  */
    7570         6377 :       else if (((DesT == SymbolTable_NulSym) && (SymbolTable_IsConst (Des))) && ((SymbolTable_IsConstructor (Des)) || (SymbolTable_IsConstSet (Des))))
    7571              :         {
    7572              :           /* avoid dangling else.  */
    7573            0 :           SymbolTable_PutConst (Des, ExpT);
    7574              :         }
    7575         6377 :       else if (! (M2Base_IsAssignmentCompatible (DesT, ExpT)))
    7576              :         {
    7577              :           /* avoid dangling else.  */
    7578            0 :           M2MetaError_MetaErrorT1 (combinedtok, (const char *) "constructor expression is not compatible during assignment to {%1Ead}", 69, Des);
    7579              :         }
    7580              :     }
    7581       417785 :   else if (((DesT != SymbolTable_NulSym) && (SymbolTable_IsSet (DesT))) && (SymbolTable_IsConst (Exp)))
    7582              :     {
    7583              :       /* avoid dangling else.  */
    7584              :     }
    7585       417655 :   else if ((((((SymbolTable_IsConst (Exp)) && (ExpT != M2System_Address)) && (! (SymbolTable_IsConst (Des)))) && (DesL != SymbolTable_NulSym)) && ((DesL == M2Base_Cardinal) || (! (SymbolTable_IsSubrange (DesL))))) && (! (SymbolTable_IsEnumeration (DesL))))
    7586              :     {
    7587              :       /* avoid dangling else.  */
    7588        24660 :       if ((M2Base_IsBaseType (DesL)) || (M2System_IsSystemType (DesL)))
    7589              :         {
    7590        24660 :           M2Base_CheckAssignmentCompatible (combinedtok, ExpT, DesT);
    7591              :         }
    7592              :       else
    7593              :         {
    7594            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);
    7595              :         }
    7596              :     }
    7597              :   else
    7598              :     {
    7599              :       /* avoid dangling else.  */
    7600       392995 :       if (((DesT != SymbolTable_NulSym) && (SymbolTable_IsProcType (DesT))) && (SymbolTable_IsProcedure (Exp)))
    7601              :         {
    7602        32574 :           DesT = SymbolTable_GetSType (DesT);  /* we can at least check RETURN values of procedure variables  */
    7603              :           /* remember that thorough assignment checking is done post pass 3  */
    7604        32574 :           M2Base_CheckAssignmentCompatible (combinedtok, ExpT, DesT);
    7605              :         }
    7606              :     }
    7607       428006 : }
    7608              : 
    7609              : 
    7610              : /*
    7611              :    CheckBooleanId - Checks to see if the top operand is a boolean.
    7612              :                     If the operand is not a boolean then it is tested
    7613              :                     with true and a boolean is generated.
    7614              :                     The Stack:
    7615              : 
    7616              : 
    7617              :                     Entry                     Exit
    7618              :              Ptr ->                                          <- Ptr
    7619              :                     +------------+            +------------+
    7620              :                     | Sym        |            | t   | f    |
    7621              :                     |------------|            |------------|
    7622              : 
    7623              :                      Quadruples
    7624              : 
    7625              :                      q   If=      Sym   True   _
    7626              :                      q+1 GotoOp   _     _      _
    7627              : */
    7628              : 
    7629        84704 : static void CheckBooleanId (void)
    7630              : {
    7631        84704 :   unsigned int tok;
    7632              : 
    7633        84704 :   if (! (IsBoolean (1)))
    7634              :     {
    7635        17713 :       tok = static_cast<unsigned int> (M2Quads_OperandTok (1));
    7636        17713 :       if (SymbolTable_IsVar (M2Quads_OperandT (1)))
    7637              :         {
    7638        14036 :           if ((SymbolTable_GetSType (M2Quads_OperandT (1))) != M2Base_Boolean)
    7639              :             {
    7640            0 :               M2MetaError_MetaError1 ((const char *) "{%1Ua:is not a boolean expression}{!%1Ua:boolean expression expected}", 69, M2Quads_OperandT (1));
    7641              :             }
    7642              :         }
    7643        17713 :       M2Quads_PushT (M2Reserved_EqualTok);
    7644        17713 :       M2Quads_PushT (M2Base_True);
    7645        17713 :       M2Quads_BuildRelOp (tok);
    7646              :     }
    7647        84704 : }
    7648              : 
    7649              : 
    7650              : /*
    7651              :    PushOne - pushes the value one to the stack.
    7652              :              The Stack is changed:
    7653              : 
    7654              : 
    7655              :                     Entry                   Exit
    7656              :                     =====                   ====
    7657              : 
    7658              :                                                             <- Ptr
    7659              :                                             +------------+
    7660              :              Ptr ->                         | 1 | type   |
    7661              :                                             |------------|
    7662              : */
    7663              : 
    7664        15977 : static void PushOne (unsigned int tok, unsigned int type, const char *message_, unsigned int _message_high)
    7665              : {
    7666        15977 :   unsigned int const_;
    7667        15977 :   char message[_message_high+1];
    7668              : 
    7669              :   /* make a local copy of each unbounded array.  */
    7670        15977 :   memcpy (message, message_, _message_high+1);
    7671              : 
    7672        15977 :   if (type == SymbolTable_NulSym)
    7673              :     {
    7674          220 :       const_ = SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), SymbolTable_NulSym);
    7675          220 :       SymbolTable_PutConstLitInternal (const_, true);
    7676          220 :       M2Quads_PushTFtok (const_, static_cast<unsigned int> (SymbolTable_NulSym), tok);
    7677              :     }
    7678        15757 :   else if (SymbolTable_IsEnumeration (type))
    7679              :     {
    7680              :       /* avoid dangling else.  */
    7681          238 :       if ((SymbolTable_NoOfElements (type)) == 0)
    7682              :         {
    7683            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);
    7684            0 :           PushZero (tok, type);
    7685              :         }
    7686              :       else
    7687              :         {
    7688          238 :           M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
    7689          238 :           M2Quads_PushT (type);
    7690          238 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_ZType), M2Base_ZType, tok);
    7691          238 :           M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
    7692          238 :           BuildConvertFunction (M2Base_Convert, true);  /* Two parameters  */
    7693              :         }
    7694              :     }
    7695              :   else
    7696              :     {
    7697              :       /* avoid dangling else.  */
    7698        15519 :       const_ = SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), type);
    7699        15519 :       SymbolTable_PutConstLitInternal (const_, true);
    7700        15519 :       M2Quads_PushTFtok (const_, type, tok);
    7701              :     }
    7702        15977 : }
    7703              : 
    7704              : 
    7705              : /*
    7706              :    PushZero - pushes the value zero to the stack.
    7707              :               The Stack is changed:
    7708              : 
    7709              : 
    7710              :                     Entry                   Exit
    7711              :                     =====                   ====
    7712              : 
    7713              :                                                             <- Ptr
    7714              :                                             +------------+
    7715              :              Ptr ->                         | 0 | type   |
    7716              :                                             |------------|
    7717              : */
    7718              : 
    7719         8080 : static void PushZero (unsigned int tok, unsigned int type)
    7720              : {
    7721         8080 :   if (type == SymbolTable_NulSym)
    7722              :     {
    7723          424 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym), static_cast<unsigned int> (SymbolTable_NulSym), tok);
    7724              :     }
    7725         7656 :   else if (SymbolTable_IsEnumeration (type))
    7726              :     {
    7727              :       /* avoid dangling else.  */
    7728          196 :       M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
    7729          196 :       M2Quads_PushTtok (type, tok);
    7730          196 :       M2Quads_PushTtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType), tok);
    7731          196 :       M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
    7732          196 :       BuildConvertFunction (M2Base_Convert, true);  /* Two parameters  */
    7733              :     }
    7734              :   else
    7735              :     {
    7736              :       /* avoid dangling else.  */
    7737         7460 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), type), type, tok);
    7738              :     }
    7739         8080 : }
    7740              : 
    7741              : 
    7742              : /*
    7743              :    ForLoopLastIterator - calculate the last iterator value but avoid setting
    7744              :                          LastIterator twice if it is a constant (in the quads).
    7745              :                          In the ForLoopLastIteratorVariable case only one
    7746              :                          path will be chosen but at the time of quadruple
    7747              :                          generation we do not know the value of BySym.
    7748              : */
    7749              : 
    7750         2570 : static void ForLoopLastIterator (unsigned int LastIterator, unsigned int e1, unsigned int e2, unsigned int BySym, unsigned int e1tok, unsigned int e2tok, unsigned int bytok)
    7751              : {
    7752         2570 :   if (! (SymbolTable_IsConst (BySym)))
    7753              :     {
    7754           18 :       M2MetaError_MetaErrorT1 (bytok, (const char *) "{%E}the {%kFOR} loop {%kBY} expression must be constant, the expression {%1a} is variable", 89, BySym);
    7755           18 :       M2MetaError_MetaErrorDecl (BySym, true);
    7756              :     }
    7757              :   else
    7758              :     {
    7759         2552 :       e1 = DereferenceLValue (e1tok, e1);
    7760         2552 :       e2 = DereferenceLValue (e2tok, e2);
    7761         2552 :       GenQuadOTypetok (bytok, M2Quads_LastForIteratorOp, LastIterator, SymbolTable_Make2Tuple (e1, e2), BySym, false, false, bytok, M2LexBuf_MakeVirtual2Tok (e1tok, e2tok), bytok);
    7762              :     }
    7763         2570 : }
    7764              : 
    7765              : 
    7766              : /*
    7767              :    BuildSizeCheckEnd - checks to see whether the function "called" was in fact SIZE.
    7768              :                        If so then we restore quadruple generation.
    7769              : */
    7770              : 
    7771        16340 : static void BuildSizeCheckEnd (unsigned int ProcSym)
    7772              : {
    7773        16340 :   if (((ProcSym == M2Size_Size) || (ProcSym == M2System_TSize)) || (ProcSym == M2System_TBitSize))
    7774              :     {
    7775        13364 :       QuadrupleGeneration = true;
    7776        13364 :       BuildingSize = false;
    7777              :     }
    7778         2976 :   else if (ProcSym == M2Base_High)
    7779              :     {
    7780              :       /* avoid dangling else.  */
    7781         2976 :       QuadrupleGeneration = true;
    7782         2976 :       BuildingHigh = false;
    7783              :     }
    7784        16340 : }
    7785              : 
    7786              : 
    7787              : /*
    7788              :    BuildRealProcedureCall - builds a real procedure call.
    7789              :                             The Stack:
    7790              : 
    7791              : 
    7792              :                             Entry                      Exit
    7793              : 
    7794              :                      Ptr ->
    7795              :                             +----------------+
    7796              :                             | NoOfParam      |
    7797              :                             |----------------|
    7798              :                             | Param 1        |
    7799              :                             |----------------|
    7800              :                             | Param 2        |
    7801              :                             |----------------|
    7802              :                             .                .
    7803              :                             .                .
    7804              :                             .                .
    7805              :                             |----------------|
    7806              :                             | Param #        |
    7807              :                             |----------------|
    7808              :                             | ProcSym | Type |         Empty
    7809              :                             |----------------|
    7810              : */
    7811              : 
    7812       156436 : static void BuildRealProcedureCall (unsigned int tokno)
    7813              : {
    7814       156436 :   unsigned int NoOfParam;
    7815       156436 :   unsigned int ProcSym;
    7816              : 
    7817       156436 :   M2Quads_PopT (&NoOfParam);
    7818       156436 :   M2Quads_PushT (NoOfParam);
    7819       156436 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+2));
    7820       156436 :   ProcSym = PCSymBuild_SkipConst (ProcSym);
    7821              :   /* --checkme--  */
    7822       156436 :   if (SymbolTable_IsVar (ProcSym))
    7823              :     {
    7824              :       /* Procedure Variable ?  */
    7825          684 :       ProcSym = SymbolTable_SkipType (M2Quads_OperandF (NoOfParam+2));
    7826              :     }
    7827       156436 :   if ((SymbolTable_IsDefImp (SymbolTable_GetScope (ProcSym))) && (SymbolTable_IsDefinitionForC (SymbolTable_GetScope (ProcSym))))
    7828              :     {
    7829        14773 :       BuildRealFuncProcCall (tokno, false, true, false);
    7830              :     }
    7831              :   else
    7832              :     {
    7833       141663 :       BuildRealFuncProcCall (tokno, false, false, false);
    7834              :     }
    7835       156430 : }
    7836              : 
    7837              : 
    7838              : /*
    7839              :    BuildRealFuncProcCall - builds a real procedure or function call.
    7840              :                            The Stack:
    7841              : 
    7842              : 
    7843              :                             Entry                      Exit
    7844              : 
    7845              :                      Ptr ->
    7846              :                             +----------------+
    7847              :                             | NoOfParam      |
    7848              :                             |----------------|
    7849              :                             | Param 1        |
    7850              :                             |----------------|
    7851              :                             | Param 2        |
    7852              :                             |----------------|
    7853              :                             .                .
    7854              :                             .                .
    7855              :                             .                .
    7856              :                             |----------------|
    7857              :                             | Param #        |
    7858              :                             |----------------|
    7859              :                             | ProcSym | Type |         Empty
    7860              :                             |----------------|
    7861              : */
    7862              : 
    7863       219006 : static void BuildRealFuncProcCall (unsigned int tokno, bool IsFunc, bool IsForC, bool ConstExpr)
    7864              : {
    7865       219006 :   bool AllocateProc;
    7866       219006 :   bool DeallocateProc;
    7867       219006 :   bool ForcedFunc;
    7868       219006 :   bool ParamConstant;
    7869       219006 :   unsigned int trash;
    7870       219006 :   unsigned int resulttok;
    7871       219006 :   unsigned int paramtok;
    7872       219006 :   unsigned int proctok;
    7873       219006 :   unsigned int NoOfParameters;
    7874       219006 :   unsigned int i;
    7875       219006 :   unsigned int pi;
    7876       219006 :   unsigned int ParamType;
    7877       219006 :   unsigned int Param1;
    7878       219006 :   unsigned int ReturnVar;
    7879       219006 :   unsigned int ProcSym;
    7880       219006 :   unsigned int Proc;
    7881              : 
    7882       219006 :   Param1 = SymbolTable_NulSym;  /* Used to remember first param for allocate/deallocate.  */
    7883       219006 :   ParamType = SymbolTable_NulSym;
    7884       219006 :   CheckProcedureParameters (IsForC);
    7885       218988 :   M2Quads_PopT (&NoOfParameters);
    7886       218988 :   M2Quads_PushT (NoOfParameters);  /* Restore stack to original state.  */
    7887       218988 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+2));  /* Restore stack to original state.  */
    7888       218988 :   proctok = tokno;  /* OperandTtok (NoOfParameters+2) ;  */
    7889       218988 :   if (proctok == M2LexBuf_UnknownTokenNo)  /* OperandTtok (NoOfParameters+2) ;  */
    7890              :     {
    7891            0 :       proctok = M2LexBuf_GetTokenNo ();
    7892              :     }
    7893       218988 :   paramtok = proctok;
    7894       218988 :   ProcSym = PCSymBuild_SkipConst (ProcSym);
    7895       218988 :   ForcedFunc = false;
    7896       218988 :   AllocateProc = false;
    7897       218988 :   DeallocateProc = false;
    7898       218988 :   if (SymbolTable_IsVar (ProcSym))
    7899              :     {
    7900              :       /* Procedure Variable ?  */
    7901          772 :       Proc = SymbolTable_SkipType (M2Quads_OperandF (NoOfParameters+2));
    7902          772 :       ParamConstant = false;
    7903              :     }
    7904              :   else
    7905              :     {
    7906       218216 :       Proc = ProcSym;
    7907       218216 :       ParamConstant = true;
    7908       218216 :       AllocateProc = (SymbolTable_GetSymName (Proc)) == (NameKey_MakeKey ((const char *) "ALLOCATE", 8));
    7909       218216 :       DeallocateProc = (SymbolTable_GetSymName (Proc)) == (NameKey_MakeKey ((const char *) "DEALLOCATE", 10));
    7910              :     }
    7911       218988 :   if (IsFunc)
    7912              :     {
    7913              :       /* avoid dangling else.  */
    7914        62558 :       if ((SymbolTable_GetSType (Proc)) == SymbolTable_NulSym)
    7915              :         {
    7916            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);
    7917              :         }
    7918              :     }
    7919              :   else
    7920              :     {
    7921              :       /* is being called as a procedure  */
    7922       156430 :       if ((SymbolTable_GetSType (Proc)) != SymbolTable_NulSym)
    7923              :         {
    7924              :           /* however it was declared as a procedure function  */
    7925         9109 :           if (! (SymbolTable_IsReturnOptionalAny (Proc)))
    7926              :             {
    7927            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);
    7928              :             }
    7929              :           IsFunc = true;
    7930              :           ForcedFunc = true;
    7931              :         }
    7932              :     }
    7933       218988 :   if (AllocateProc || DeallocateProc)
    7934              :     {
    7935         1838 :       Param1 = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+1));  /* Remember this before manipulating.  */
    7936              :     }
    7937       218988 :   ManipulateParameters (IsForC);
    7938       218988 :   CheckParameterOrdinals ();
    7939       218988 :   M2Quads_PopT (&NoOfParameters);
    7940       218988 :   if (IsFunc)
    7941              :     {
    7942        71667 :       GenQuad (M2Quads_ParamOp, 0, Proc, ProcSym);  /* Space for return value  */
    7943              :     }
    7944       218988 :   if (((NoOfParameters+1) == (SymbolTable_NoOfParamAny (Proc))) && (SymbolTable_UsesOptArgAny (Proc)))
    7945              :     {
    7946         3493 :       GenQuad (M2Quads_OptParamOp, SymbolTable_NoOfParamAny (Proc), Proc, Proc);
    7947              :     }
    7948       218988 :   i = NoOfParameters;
    7949       218988 :   pi = 1;  /* stack index referencing stacked parameter, i  */
    7950       762011 :   while (i > 0)  /* stack index referencing stacked parameter, i  */
    7951              :     {
    7952       543023 :       paramtok = OperandTtok (pi);
    7953       543023 :       if (((AllocateProc || DeallocateProc) && (i == 1)) && (Param1 != SymbolTable_NulSym))
    7954              :         {
    7955         1838 :           ParamType = GetItemPointedTo (Param1);
    7956         1838 :           if (ParamType == SymbolTable_NulSym)
    7957              :             {
    7958            0 :               GenQuadO (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true);
    7959              :             }
    7960              :           else
    7961              :             {
    7962         1838 :               if (AllocateProc)
    7963              :                 {
    7964         1288 :                   trash = SymbolTable_MakeTemporary (paramtok, SymbolTable_RightValue);
    7965         1288 :                   SymbolTable_PutVar (trash, ParamType);
    7966         1288 :                   SymbolTable_PutVarHeap (trash, true);
    7967              :                 }
    7968              :               else
    7969              :                 {
    7970          550 :                   M2Debug_Assert (DeallocateProc);
    7971          550 :                   trash = M2Base_Nil;
    7972              :                 }
    7973         1838 :               GenQuadOTrash (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true, trash);
    7974              :             }
    7975              :         }
    7976              :       else
    7977              :         {
    7978       541185 :           GenQuadO (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true);
    7979              :         }
    7980       543023 :       if (! (SymbolTable_IsConst (M2Quads_OperandT (pi))))
    7981              :         {
    7982       458466 :           ParamConstant = false;
    7983              :         }
    7984       543023 :       i -= 1;
    7985       543023 :       pi += 1;
    7986              :     }
    7987       437976 :   GenQuadO (proctok, M2Quads_CallOp, SymbolTable_NulSym, SymbolTable_NulSym, ProcSym, true);
    7988       218988 :   M2Quads_PopN (NoOfParameters+1);  /* Destroy arguments and procedure call  */
    7989       218988 :   if (IsFunc)
    7990              :     {
    7991              :       /* ReturnVar has the type of the procedure.  */
    7992        71667 :       resulttok = M2LexBuf_MakeVirtualTok (proctok, proctok, paramtok);
    7993        71667 :       if (ConstExpr && (! (SymbolTable_IsProcedureBuiltinAvailable (Proc))))
    7994              :         {
    7995            0 :           M2MetaError_MetaError1 ((const char *) "{%1d} {%1ad} cannot be used in a constant expression", 52, Proc);
    7996            0 :           ParamConstant = false;
    7997              :         }
    7998        71667 :       ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (ParamConstant && ConstExpr));
    7999        71667 :       SymbolTable_PutVar (ReturnVar, SymbolTable_GetSType (Proc));
    8000       143334 :       GenQuadO (resulttok, M2Quads_FunctValueOp, ReturnVar, SymbolTable_NulSym, Proc, true);
    8001        71667 :       if (! ForcedFunc)
    8002              :         {
    8003        62558 :           M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (Proc), resulttok);
    8004              :         }
    8005              :     }
    8006       218988 : }
    8007              : 
    8008              : 
    8009              : /*
    8010              :    CheckProcedureParameters - Checks the parameters which are being passed to
    8011              :                               procedure ProcSym.
    8012              : 
    8013              :                               The Stack:
    8014              : 
    8015              : 
    8016              :                               Entry                      Exit
    8017              : 
    8018              :                        Ptr ->                                               <- Ptr
    8019              :                               +----------------+         +----------------+
    8020              :                               | NoOfParam      |         | NoOfParam      |
    8021              :                               |----------------|         |----------------|
    8022              :                               | Param 1        |         | Param 1        |
    8023              :                               |----------------|         |----------------|
    8024              :                               | Param 2        |         | Param 2        |
    8025              :                               |----------------|         |----------------|
    8026              :                               .                .         .                .
    8027              :                               .                .         .                .
    8028              :                               .                .         .                .
    8029              :                               |----------------|         |----------------|
    8030              :                               | Param #        |         | Param #        |
    8031              :                               |----------------|         |----------------|
    8032              :                               | ProcSym | Type |         | ProcSym | Type |
    8033              :                               |----------------|         |----------------|
    8034              : 
    8035              : */
    8036              : 
    8037       219006 : static void CheckProcedureParameters (bool IsForC)
    8038              : {
    8039       219006 :   unsigned int proctok;
    8040       219006 :   unsigned int paramtok;
    8041       219006 :   NameKey_Name n1;
    8042       219006 :   NameKey_Name n2;
    8043       219006 :   unsigned int ParamCheckId;
    8044       219006 :   unsigned int Dim;
    8045       219006 :   unsigned int Actual;
    8046       219006 :   unsigned int FormalI;
    8047       219006 :   unsigned int ParamTotal;
    8048       219006 :   unsigned int pi;
    8049       219006 :   unsigned int Proc;
    8050       219006 :   unsigned int ProcSym;
    8051       219006 :   unsigned int i;
    8052       219006 :   DynamicStrings_String s;
    8053              : 
    8054       219006 :   M2Quads_PopT (&ParamTotal);
    8055       219006 :   M2Quads_PushT (ParamTotal);  /* Restore stack to origional state  */
    8056       219006 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((ParamTotal+1)+1));  /* Restore stack to origional state  */
    8057       219006 :   proctok = OperandTtok ((ParamTotal+1)+1);
    8058       219006 :   if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (SymbolTable_GetDType (ProcSym))))
    8059              :     {
    8060              :       /* Procedure Variable ?  */
    8061          772 :       Proc = SymbolTable_SkipType (M2Quads_OperandF ((ParamTotal+1)+1));
    8062              :     }
    8063              :   else
    8064              :     {
    8065       218234 :       Proc = PCSymBuild_SkipConst (ProcSym);
    8066              :     }
    8067       219006 :   if (! ((SymbolTable_IsProcedure (Proc)) || (SymbolTable_IsProcType (Proc))))
    8068              :     {
    8069              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    8070           12 :       if (SymbolTable_IsUnknown (Proc))
    8071              :         {
    8072              :           /* Spellcheck.  */
    8073            0 :           M2MetaError_MetaError1 ((const char *) "{%1Ua} is not recognised as a procedure, check declaration or import {%1&s}", 75, Proc);
    8074            0 :           SymbolTable_UnknownReported (Proc);
    8075              :         }
    8076              :       else
    8077              :         {
    8078              :           /* --fixme-- filter on Var, Const, Procedure.  */
    8079           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);
    8080              :         }
    8081              :     }
    8082       219006 :   if (M2Options_CompilerDebugging)
    8083              :     {
    8084            0 :       n1 = SymbolTable_GetSymName (Proc);
    8085            0 :       M2Printf_printf1 ((const char *) "  %a ( ", 7, (const unsigned char *) &n1, (sizeof (n1)-1));
    8086              :     }
    8087       219006 :   if (DebugTokPos)
    8088              :     {
    8089              :       s = DynamicStrings_InitString ((const char *) "procedure", 9);
    8090              :       M2Error_WarnStringAt (s, proctok);
    8091              :     }
    8092       219006 :   i = 1;
    8093       219006 :   pi = ParamTotal+1;  /* stack index referencing stacked parameter, i  */
    8094       758843 :   while (i <= ParamTotal)  /* stack index referencing stacked parameter, i  */
    8095              :     {
    8096       539855 :       if (i <= (SymbolTable_NoOfParamAny (Proc)))
    8097              :         {
    8098              :           /* FormalI := GetParam(Proc, i) ;  */
    8099       534556 :           FormalI = SymbolTable_GetNthParamAnyClosest (Proc, i, SymbolTable_GetCurrentModule ());
    8100       534556 :           if (M2Options_CompilerDebugging)
    8101              :             {
    8102            0 :               n1 = SymbolTable_GetSymName (FormalI);
    8103            0 :               n2 = SymbolTable_GetSymName (SymbolTable_GetSType (FormalI));
    8104            0 :               M2Printf_printf2 ((const char *) "%a: %a", 6, (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
    8105              :             }
    8106       534556 :           Actual = static_cast<unsigned int> (M2Quads_OperandT (pi));
    8107       534556 :           Dim = static_cast<unsigned int> (OperandD (pi));
    8108       534556 :           paramtok = OperandTtok (pi);
    8109       534556 :           if (DebugTokPos)
    8110              :             {
    8111              :               s = DynamicStrings_InitString ((const char *) "actual", 6);
    8112              :               M2Error_WarnStringAt (s, paramtok);
    8113              :             }
    8114       534556 :           ParamCheckId = M2Range_InitTypesParameterCheck (paramtok, Proc, i, FormalI, Actual, 0);
    8115       534556 :           BuildRange (ParamCheckId);
    8116              :           /* Store the ParamCheckId on the quad stack so that any dependant checks
    8117              :             can be cancelled if the type check above detects an error.  */
    8118       534556 :           PutRangeDep (pi, ParamCheckId);
    8119       534556 :           if (SymbolTable_IsConst (Actual))
    8120              :             {
    8121              :               /* avoid dangling else.  */
    8122       119728 :               if (SymbolTable_IsVarParamAny (Proc, i))
    8123              :                 {
    8124            0 :                   FailParameter (paramtok, (const char *) "trying to pass a constant to a VAR parameter", 44, Actual, Proc, i);
    8125              :                 }
    8126       119728 :               else if (SymbolTable_IsConstString (Actual))
    8127              :                 {
    8128              :                   /* avoid dangling else.  */
    8129        39202 :                   if (! (SymbolTable_IsConstStringKnown (Actual)))
    8130              :                     {}  /* empty.  */
    8131        38968 :                   else if ((SymbolTable_IsArray (SymbolTable_GetDType (FormalI))) && ((SymbolTable_GetSType (SymbolTable_GetDType (FormalI))) == M2Base_Char))
    8132              :                     {
    8133              :                       /* avoid dangling else.  */
    8134              :                     }
    8135        38944 :                   else if ((SymbolTable_GetStringLength (paramtok, Actual)) == 1)
    8136              :                     {
    8137              :                       /* avoid dangling else.  */
    8138         5378 :                       CheckParameter (paramtok, Actual, Dim, FormalI, Proc, i, static_cast<Lists_List> (NULL), ParamCheckId);
    8139              :                     }
    8140        33566 :                   else if (! (SymbolTable_IsUnboundedParamAny (Proc, i)))
    8141              :                     {
    8142              :                       /* avoid dangling else.  */
    8143            0 :                       if (IsForC && ((SymbolTable_GetSType (FormalI)) == M2System_Address))
    8144              :                         {
    8145            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);
    8146              :                         }
    8147              :                       else
    8148              :                         {
    8149            0 :                           FailParameter (paramtok, (const char *) "cannot pass a string constant to a non unbounded array parameter", 64, Actual, Proc, i);
    8150              :                         }
    8151              :                     }
    8152              :                 }
    8153              :             }
    8154              :           else
    8155              :             {
    8156       414828 :               CheckParameter (paramtok, Actual, Dim, FormalI, Proc, i, static_cast<Lists_List> (NULL), ParamCheckId);
    8157              :             }
    8158              :         }
    8159              :       else
    8160              :         {
    8161         5287 :           if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
    8162              :             {
    8163              :               /* these are varargs, therefore we don't check them  */
    8164         5287 :               i = ParamTotal;
    8165              :             }
    8166              :           else
    8167              :             {
    8168            0 :               M2MetaError_MetaErrorT2 (proctok, (const char *) "too many parameters, {%2n} passed to {%1a} ", 43, Proc, i);
    8169              :             }
    8170              :         }
    8171       539837 :       i += 1;
    8172       539837 :       pi -= 1;
    8173       539837 :       if (M2Options_CompilerDebugging)
    8174              :         {
    8175              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    8176            0 :           if (i <= ParamTotal)
    8177              :             {
    8178            0 :               M2Printf_printf0 ((const char *) "; ", 2);
    8179              :             }
    8180              :           else
    8181              :             {
    8182            0 :               M2Printf_printf0 ((const char *) " ) ; \\n", 7);
    8183              :             }
    8184              :         }
    8185              :     }
    8186       218988 : }
    8187              : 
    8188              : 
    8189              : /*
    8190              :    CheckProcTypeAndProcedure - checks the ProcType with the call.
    8191              : */
    8192              : 
    8193        48462 : static void CheckProcTypeAndProcedure (unsigned int tokno, unsigned int ProcType, unsigned int call, unsigned int ParamCheckId)
    8194              : {
    8195        48462 :   NameKey_Name n1;
    8196        48462 :   NameKey_Name n2;
    8197        48462 :   unsigned int i;
    8198        48462 :   unsigned int n;
    8199        48462 :   unsigned int t;
    8200        48462 :   unsigned int CheckedProcedure;
    8201        48462 :   M2Error_Error e;
    8202              : 
    8203        48462 :   if (((SymbolTable_IsVar (call)) || (SymbolTable_IsTemporary (call))) || (SymbolTable_IsParameter (call)))
    8204              :     {
    8205          592 :       CheckedProcedure = SymbolTable_GetDType (call);
    8206              :     }
    8207              :   else
    8208              :     {
    8209              :       CheckedProcedure = call;
    8210              :     }
    8211        48462 :   if (ProcType != CheckedProcedure)
    8212              :     {
    8213        47940 :       n = SymbolTable_NoOfParamAny (ProcType);
    8214              :       /* We need to check the formal parameters between the procedure and proc type.  */
    8215        47940 :       if (n != (SymbolTable_NoOfParamAny (CheckedProcedure)))
    8216              :         {
    8217            0 :           e = M2Error_NewError (SymbolTable_GetDeclaredMod (ProcType));
    8218            0 :           n1 = SymbolTable_GetSymName (call);
    8219            0 :           n2 = SymbolTable_GetSymName (ProcType);
    8220            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));
    8221            0 :           e = M2Error_ChainError (SymbolTable_GetDeclaredMod (call), e);
    8222            0 :           t = SymbolTable_NoOfParamAny (CheckedProcedure);
    8223            0 :           if (n < 2)
    8224              :             {
    8225            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));
    8226              :             }
    8227              :           else
    8228              :             {
    8229            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));
    8230              :             }
    8231              :         }
    8232              :       else
    8233              :         {
    8234              :           i = 1;
    8235       142862 :           while (i <= n)
    8236              :             {
    8237        94922 :               if ((SymbolTable_IsVarParamAny (ProcType, i)) != (SymbolTable_IsVarParamAny (CheckedProcedure, i)))
    8238              :                 {
    8239            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);
    8240            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);
    8241              :                 }
    8242        94922 :               BuildRange (M2Range_InitTypesParameterCheck (tokno, CheckedProcedure, i, SymbolTable_GetNthParamAnyClosest (CheckedProcedure, i, SymbolTable_GetCurrentModule ()), SymbolTable_GetParam (ProcType, i), ParamCheckId));
    8243        94922 :               i += 1;
    8244              :             }
    8245              :         }
    8246              :     }
    8247        48462 : }
    8248              : 
    8249              : 
    8250              : /*
    8251              :    IsReallyPointer - returns TRUE is sym is a pointer, address or a type declared
    8252              :                      as a pointer or address.
    8253              : */
    8254              : 
    8255         1269 : static bool IsReallyPointer (unsigned int Sym)
    8256              : {
    8257         1269 :   if (SymbolTable_IsVar (Sym))
    8258              :     {
    8259         1268 :       Sym = SymbolTable_GetSType (Sym);
    8260              :     }
    8261         1269 :   Sym = SymbolTable_SkipType (Sym);
    8262         1269 :   return (SymbolTable_IsPointer (Sym)) || (Sym == M2System_Address);
    8263              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8264              :   __builtin_unreachable ();
    8265              : }
    8266              : 
    8267              : 
    8268              : /*
    8269              :    LegalUnboundedParam - returns TRUE if the parameter, Actual, can legitimately be
    8270              :                          passed to ProcSym, i, the, Formal, parameter.
    8271              : */
    8272              : 
    8273         9797 : static bool LegalUnboundedParam (unsigned int tokpos, unsigned int ProcSym, unsigned int i, unsigned int ActualType, unsigned int Actual, unsigned int Dimension, unsigned int Formal)
    8274              : {
    8275         9797 :   unsigned int FormalType;
    8276         9797 :   unsigned int n;
    8277         9797 :   unsigned int m;
    8278              : 
    8279         9797 :   ActualType = SymbolTable_SkipType (ActualType);
    8280         9797 :   FormalType = SymbolTable_GetDType (Formal);
    8281         9797 :   FormalType = SymbolTable_GetSType (FormalType);  /* type of the unbounded ARRAY  */
    8282         9797 :   if (SymbolTable_IsArray (ActualType))  /* type of the unbounded ARRAY  */
    8283              :     {
    8284         6771 :       m = SymbolTable_GetDimension (Formal);
    8285         6771 :       n = 0;
    8286        13788 :       while (SymbolTable_IsArray (ActualType))
    8287              :         {
    8288         6939 :           n += 1;
    8289         6939 :           ActualType = SymbolTable_GetDType (ActualType);
    8290         6939 :           if ((m == n) && (ActualType == FormalType))
    8291              :             {
    8292              :               return true;
    8293              :             }
    8294              :         }
    8295           78 :       if (n == m)
    8296              :         {}  /* empty.  */
    8297              :       else
    8298              :         {
    8299              :           /* now we fall though and test ActualType against FormalType  */
    8300           24 :           if (M2System_IsGenericSystemType (FormalType))
    8301              :             {
    8302              :               return true;
    8303              :             }
    8304              :           else
    8305              :             {
    8306           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);
    8307           12 :               return false;
    8308              :             }
    8309              :         }
    8310              :     }
    8311         3026 :   else if (SymbolTable_IsUnbounded (ActualType))
    8312              :     {
    8313              :       /* avoid dangling else.  */
    8314           36 :       if ((Dimension == 0) && ((SymbolTable_GetDimension (Formal)) == (SymbolTable_GetDimension (Actual))))
    8315              :         {
    8316              :           /* now we fall though and test ActualType against FormalType  */
    8317            0 :           ActualType = SymbolTable_GetSType (ActualType);
    8318              :         }
    8319              :       else
    8320              :         {
    8321           36 :           if (M2System_IsGenericSystemType (FormalType))
    8322              :             {
    8323              :               return true;
    8324              :             }
    8325              :           else
    8326              :             {
    8327           12 :               if (((SymbolTable_GetDimension (Actual))-Dimension) == (SymbolTable_GetDimension (Formal)))
    8328              :                 {
    8329           12 :                   ActualType = SymbolTable_GetSType (ActualType);
    8330              :                 }
    8331              :               else
    8332              :                 {
    8333            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);
    8334            0 :                   return false;
    8335              :                 }
    8336              :             }
    8337              :         }
    8338              :     }
    8339         3056 :   if (((M2System_IsGenericSystemType (FormalType)) || (M2System_IsGenericSystemType (ActualType))) || (M2Base_IsAssignmentCompatible (FormalType, ActualType)))
    8340              :     {
    8341              :       /* we think it is legal, but we ask post pass 3 to check as
    8342              :          not all types are known at this point  */
    8343              :       return true;
    8344              :     }
    8345              :   else
    8346              :     {
    8347            6 :       FailParameter (tokpos, (const char *) "identifier with an incompatible type is being passed to this procedure", 70, Actual, ProcSym, i);
    8348            6 :       return false;
    8349              :     }
    8350              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8351              :   __builtin_unreachable ();
    8352              : }
    8353              : 
    8354              : 
    8355              : /*
    8356              :    CheckParameter - checks that types ActualType and FormalType are compatible for parameter
    8357              :                     passing. ProcSym is the procedure and i is the parameter number.
    8358              : 
    8359              :                     We obey the following rules:
    8360              : 
    8361              :                     (1)  we allow WORD, BYTE, LOC to be compitable with any like sized
    8362              :                          type.
    8363              :                     (2)  we allow ADDRESS to be compatible with any pointer type.
    8364              :                     (3)  we relax INTEGER and CARDINAL checking for Temporary variables.
    8365              : 
    8366              :                     Note that type sizes are checked during the code generation pass.
    8367              : */
    8368              : 
    8369       420206 : 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)
    8370              : {
    8371       420206 :   bool NewList;
    8372       420206 :   unsigned int ActualType;
    8373       420206 :   unsigned int FormalType;
    8374              : 
    8375       420206 :   if ((SymbolTable_IsConstString (Actual)) && (! (SymbolTable_IsConstStringKnown (Actual))))
    8376              :     {
    8377              :       /* Cannot check if the string content is not yet known.  */
    8378              :       return;
    8379              :     }
    8380       420206 :   FormalType = SymbolTable_GetDType (Formal);
    8381       420206 :   if ((SymbolTable_IsConstString (Actual)) && ((SymbolTable_GetStringLength (tokpos, Actual)) == 1))  /* if = 1 then it maybe treated as a char  */
    8382              :     {
    8383         5378 :       ActualType = M2Base_Char;
    8384              :     }
    8385       414828 :   else if (Actual == M2Base_Boolean)
    8386              :     {
    8387              :       /* avoid dangling else.  */
    8388              :       ActualType = Actual;
    8389              :     }
    8390              :   else
    8391              :     {
    8392              :       /* avoid dangling else.  */
    8393       414828 :       ActualType = SymbolTable_GetDType (Actual);
    8394              :     }
    8395       420200 :   if (TypeList == NULL)
    8396              :     {
    8397       420200 :       NewList = true;
    8398       420200 :       Lists_InitList (&TypeList);
    8399              :     }
    8400              :   else
    8401              :     {
    8402              :       NewList = false;
    8403              :     }
    8404       420200 :   if (Lists_IsItemInList (TypeList, ActualType))
    8405              :     {
    8406              :       /* no need to check  */
    8407              :       return;
    8408              :     }
    8409       420200 :   Lists_IncludeItemIntoList (TypeList, ActualType);
    8410       420200 :   if (SymbolTable_IsProcType (FormalType))
    8411              :     {
    8412        48462 :       if ((! (SymbolTable_IsProcedure (Actual))) && ((ActualType == SymbolTable_NulSym) || (! (SymbolTable_IsProcType (SymbolTable_SkipType (ActualType))))))
    8413              :         {
    8414            0 :           FailParameter (tokpos, (const char *) "expecting a procedure or procedure variable as a parameter", 58, Actual, ProcSym, i);
    8415            0 :           return;
    8416              :         }
    8417        48462 :       if ((SymbolTable_IsProcedure (Actual)) && (SymbolTable_IsProcedureNested (Actual)))
    8418              :         {
    8419            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);
    8420              :         }
    8421              :       /* we can check the return type of both proc types  */
    8422        48462 :       if ((ActualType != SymbolTable_NulSym) && (SymbolTable_IsProcType (ActualType)))
    8423              :         {
    8424              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    8425          592 :           if (((SymbolTable_GetSType (ActualType)) != SymbolTable_NulSym) && ((SymbolTable_GetSType (FormalType)) == SymbolTable_NulSym))
    8426              :             {
    8427            0 :               FailParameter (tokpos, (const char *) "the item being passed is a function whereas the formal procedure parameter is a procedure", 89, Actual, ProcSym, i);
    8428            0 :               return;
    8429              :             }
    8430          592 :           else if (((SymbolTable_GetSType (ActualType)) == SymbolTable_NulSym) && ((SymbolTable_GetSType (FormalType)) != SymbolTable_NulSym))
    8431              :             {
    8432              :               /* avoid dangling else.  */
    8433            0 :               FailParameter (tokpos, (const char *) "the item being passed is a procedure whereas the formal procedure parameter is a function", 89, Actual, ProcSym, i);
    8434            0 :               return;
    8435              :             }
    8436          592 :           else if (M2Base_AssignmentRequiresWarning (SymbolTable_GetSType (ActualType), SymbolTable_GetSType (FormalType)))
    8437              :             {
    8438              :               /* avoid dangling else.  */
    8439            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);
    8440            0 :               return;
    8441              :             }
    8442          592 :           else if (((M2System_IsGenericSystemType (SymbolTable_GetSType (FormalType))) || (M2System_IsGenericSystemType (SymbolTable_GetSType (ActualType)))) || (M2Base_IsAssignmentCompatible (SymbolTable_GetSType (ActualType), SymbolTable_GetSType (FormalType))))
    8443              :             {
    8444              :               /* avoid dangling else.  */
    8445              :             }
    8446              :           else
    8447              :             {
    8448              :               /* avoid dangling else.  */
    8449              :               /* pass  */
    8450            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);
    8451            0 :               return;
    8452              :             }
    8453              :         }
    8454              :       /* now to check each parameter of the proc type  */
    8455        48462 :       CheckProcTypeAndProcedure (tokpos, FormalType, Actual, ParamCheckId);
    8456              :     }
    8457       371738 :   else if ((ActualType != FormalType) && (ActualType != SymbolTable_NulSym))
    8458              :     {
    8459              :       /* avoid dangling else.  */
    8460        17744 :       if (SymbolTable_IsUnknown (FormalType))
    8461              :         {
    8462              :           /* Spellcheck.  */
    8463            0 :           FailParameter (tokpos, (const char *) "procedure parameter type is undeclared {%1&s}", 45, Actual, ProcSym, i);
    8464            0 :           return;
    8465              :         }
    8466        17744 :       if ((SymbolTable_IsUnbounded (ActualType)) && (! (SymbolTable_IsUnboundedParamAny (ProcSym, i))))
    8467              :         {
    8468            0 :           FailParameter (tokpos, (const char *) "attempting to pass an unbounded array to a NON unbounded parameter", 66, Actual, ProcSym, i);
    8469            0 :           return;
    8470              :         }
    8471        17744 :       else if (SymbolTable_IsUnboundedParamAny (ProcSym, i))
    8472              :         {
    8473              :           /* avoid dangling else.  */
    8474         9797 :           if (! (LegalUnboundedParam (tokpos, ProcSym, i, ActualType, Actual, Dimension, Formal)))
    8475              :             {
    8476              :               return;
    8477              :             }
    8478              :         }
    8479         7947 :       else if (ActualType != FormalType)
    8480              :         {
    8481              :           /* avoid dangling else.  */
    8482         7947 :           if (M2Base_AssignmentRequiresWarning (FormalType, ActualType))
    8483              :             {
    8484            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);
    8485              :             }
    8486         7947 :           else if (((M2System_IsGenericSystemType (FormalType)) || (M2System_IsGenericSystemType (ActualType))) || (M2Base_IsAssignmentCompatible (ActualType, FormalType)))
    8487              :             {
    8488              :               /* avoid dangling else.  */
    8489              :             }
    8490              :           else
    8491              :             {
    8492              :               /* avoid dangling else.  */
    8493              :               /* so far we know it is legal, but not all types have been resolved
    8494              :                and so this is checked later on in another pass.  */
    8495           24 :               FailParameter (tokpos, (const char *) "identifier with an incompatible type is being passed to this procedure", 70, Actual, ProcSym, i);
    8496              :             }
    8497              :         }
    8498              :     }
    8499       420182 :   if (NewList)
    8500              :     {
    8501       420182 :       Lists_KillList (&TypeList);
    8502              :     }
    8503              : }
    8504              : 
    8505              : 
    8506              : /*
    8507              :    DescribeType - returns a String describing a symbol, Sym, name and its type.
    8508              : */
    8509              : 
    8510            0 : static DynamicStrings_String DescribeType (unsigned int Sym)
    8511              : {
    8512            0 :   DynamicStrings_String s;
    8513            0 :   DynamicStrings_String s1;
    8514            0 :   DynamicStrings_String s2;
    8515            0 :   unsigned int Low;
    8516            0 :   unsigned int High;
    8517            0 :   unsigned int Subrange;
    8518            0 :   unsigned int Subscript;
    8519            0 :   unsigned int Type;
    8520              : 
    8521            0 :   s = static_cast<DynamicStrings_String> (NULL);
    8522            0 :   if (SymbolTable_IsConstString (Sym))
    8523              :     {
    8524              :       /* If = 1 then it maybe treated as a char.  */
    8525            0 :       if ((SymbolTable_IsConstStringKnown (Sym)) && ((SymbolTable_GetStringLength (SymbolTable_GetDeclaredMod (Sym), Sym)) == 1))
    8526              :         {
    8527            0 :           s = DynamicStrings_InitString ((const char *) "(constant string) or {%kCHAR}", 29);
    8528              :         }
    8529              :       else
    8530              :         {
    8531            0 :           s = DynamicStrings_InitString ((const char *) "(constant string)", 17);
    8532              :         }
    8533              :     }
    8534            0 :   else if (SymbolTable_IsConst (Sym))
    8535              :     {
    8536              :       /* avoid dangling else.  */
    8537            0 :       s = DynamicStrings_InitString ((const char *) "(constant)", 10);
    8538              :     }
    8539            0 :   else if (SymbolTable_IsUnknown (Sym))
    8540              :     {
    8541              :       /* avoid dangling else.  */
    8542            0 :       s = DynamicStrings_InitString ((const char *) "(unknown)", 9);
    8543              :     }
    8544              :   else
    8545              :     {
    8546              :       /* avoid dangling else.  */
    8547            0 :       Type = SymbolTable_GetSType (Sym);
    8548            0 :       if (Type == SymbolTable_NulSym)
    8549              :         {
    8550            0 :           s = DynamicStrings_InitString ((const char *) "(unknown)", 9);
    8551              :         }
    8552            0 :       else if (SymbolTable_IsUnbounded (Type))
    8553              :         {
    8554              :           /* avoid dangling else.  */
    8555            0 :           s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (SymbolTable_GetSType (Type)))));
    8556            0 :           s = FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "{%%kARRAY} {%%kOF} %s", 21)), (const unsigned char *) &s1, (sizeof (s1)-1));
    8557              :         }
    8558            0 :       else if (SymbolTable_IsArray (Type))
    8559              :         {
    8560              :           /* avoid dangling else.  */
    8561            0 :           s = DynamicStrings_InitString ((const char *) "{%kARRAY} [", 11);
    8562            0 :           Subscript = SymbolTable_GetArraySubscript (Type);
    8563            0 :           if (Subscript != SymbolTable_NulSym)
    8564              :             {
    8565            0 :               M2Debug_Assert (SymbolTable_IsSubscript (Subscript));
    8566            0 :               Subrange = SymbolTable_GetSType (Subscript);
    8567            0 :               if (! (SymbolTable_IsSubrange (Subrange)))
    8568              :                 {
    8569            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);
    8570              :                 }
    8571            0 :               M2Debug_Assert (SymbolTable_IsSubrange (Subrange));
    8572            0 :               SymbolTable_GetSubrange (Subrange, &High, &Low);
    8573            0 :               s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Low))));
    8574            0 :               s2 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (High))));
    8575            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))));
    8576              :             }
    8577            0 :           s1 = DynamicStrings_Mark (DescribeType (Type));
    8578            0 :           s = DynamicStrings_ConCat (DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "] OF ", 5))), s1);
    8579              :         }
    8580              :       else
    8581              :         {
    8582              :           /* avoid dangling else.  */
    8583            0 :           if (SymbolTable_IsUnknown (Type))
    8584              :             {
    8585              :               /* Spellcheck.  */
    8586            0 :               s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Type))));
    8587            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));
    8588              :             }
    8589              :           else
    8590              :             {
    8591            0 :               s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Type)));
    8592              :             }
    8593              :         }
    8594              :     }
    8595            0 :   return s;
    8596              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8597              :   __builtin_unreachable ();
    8598              : }
    8599              : 
    8600              : 
    8601              : /*
    8602              :    FailParameter - generates an error message indicating that a parameter
    8603              :                    declaration has failed.
    8604              : 
    8605              :                    The parameters are:
    8606              : 
    8607              :                    CurrentState  - string describing the current failing state.
    8608              :                    Actual        - actual parameter.
    8609              :                    ParameterNo   - parameter number that has failed.
    8610              :                    ProcedureSym  - procedure symbol where parameter has failed.
    8611              : 
    8612              :                    If any parameter is Nul then it is ignored.
    8613              : */
    8614              : 
    8615           42 : static void FailParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo)
    8616              : {
    8617           42 :   unsigned int FormalParam;
    8618           42 :   DynamicStrings_String Msg;
    8619           42 :   char CurrentState[_CurrentState_high+1];
    8620              : 
    8621              :   /* make a local copy of each unbounded array.  */
    8622           42 :   memcpy (CurrentState, CurrentState_, _CurrentState_high+1);
    8623              : 
    8624           84 :   Msg = DynamicStrings_InitString ((const char *) "parameter mismatch between the {%2N} parameter of procedure {%1Ead}, ", 69);
    8625           42 :   Msg = DynamicStrings_ConCat (Msg, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) CurrentState, _CurrentState_high)));
    8626           42 :   M2MetaError_MetaErrorStringT2 (tokpos, Msg, ProcedureSym, ParameterNo);
    8627           42 :   if ((SymbolTable_NoOfParamAny (ProcedureSym)) >= ParameterNo)
    8628              :     {
    8629           42 :       FormalParam = SymbolTable_GetNthParamAnyClosest (ProcedureSym, ParameterNo, SymbolTable_GetCurrentModule ());
    8630           42 :       if (SymbolTable_IsUnboundedParamAny (ProcedureSym, ParameterNo))
    8631              :         {
    8632           18 :           M2MetaError_MetaErrorT2 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "formal parameter {%1ad} has an open array type {%2tad}", 54, FormalParam, SymbolTable_GetSType (SymbolTable_GetSType (FormalParam)));
    8633              :         }
    8634              :       else
    8635              :         {
    8636           24 :           M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "formal parameter {%1ad} has type {%1tad}", 40, FormalParam);
    8637              :         }
    8638              :     }
    8639              :   else
    8640              :     {
    8641            0 :       M2MetaError_MetaErrorT1 (SymbolTable_GetDeclaredMod (ProcedureSym), (const char *) "procedure declaration", 21, ProcedureSym);
    8642              :     }
    8643           42 :   if ((SymbolTable_GetLType (Actual)) == SymbolTable_NulSym)
    8644              :     {
    8645            0 :       M2MetaError_MetaError1 ((const char *) "actual parameter being passed is {%1Eda} {%1ad}", 47, Actual);
    8646              :     }
    8647              :   else
    8648              :     {
    8649           42 :       if (SymbolTable_IsVar (Actual))
    8650              :         {
    8651           36 :           M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (Actual), (const char *) "actual parameter variable being passed is {%1Eda} {%1ad} of an incompatible type {%1ts}", 87, Actual);
    8652              :         }
    8653              :       else
    8654              :         {
    8655            6 :           M2MetaError_MetaErrorT1 (tokpos, (const char *) "actual parameter being passed is {%1Eda} {%1ad} of an incompatible type {%1ts}", 78, Actual);
    8656              :         }
    8657              :     }
    8658           42 : }
    8659              : 
    8660              : 
    8661              : /*
    8662              :    WarnParameter - generates a warning message indicating that a parameter
    8663              :                    use might cause problems on another target.
    8664              : 
    8665              :                    CurrentState  - string describing the current failing state.
    8666              :                    Actual        - actual parameter.
    8667              :                    ParameterNo   - parameter number that has failed.
    8668              :                    ProcedureSym  - procedure symbol where parameter has failed.
    8669              : 
    8670              :                    If any parameter is Nul then it is ignored.
    8671              : */
    8672              : 
    8673            0 : static void WarnParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo)
    8674              : {
    8675            0 :   unsigned int FormalParam;
    8676            0 :   DynamicStrings_String Msg;
    8677            0 :   char CurrentState[_CurrentState_high+1];
    8678              : 
    8679              :   /* make a local copy of each unbounded array.  */
    8680            0 :   memcpy (CurrentState, CurrentState_, _CurrentState_high+1);
    8681              : 
    8682            0 :   Msg = DynamicStrings_InitString ((const char *) "{%W}parameter mismatch between the {%2N} parameter of procedure {%1ad}, ", 72);
    8683            0 :   Msg = DynamicStrings_ConCat (Msg, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) CurrentState, _CurrentState_high)));
    8684            0 :   M2MetaError_MetaErrorStringT2 (tokpos, Msg, ProcedureSym, ParameterNo);
    8685            0 :   if ((SymbolTable_NoOfParamAny (ProcedureSym)) >= ParameterNo)
    8686              :     {
    8687            0 :       FormalParam = SymbolTable_GetNthParamAnyClosest (ProcedureSym, ParameterNo, SymbolTable_GetCurrentModule ());
    8688            0 :       if (SymbolTable_IsUnboundedParamAny (ProcedureSym, ParameterNo))
    8689              :         {
    8690            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)));
    8691              :         }
    8692              :       else
    8693              :         {
    8694            0 :           M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "{%W}formal parameter {%1ad} has type {%1tad}", 44, FormalParam);
    8695              :         }
    8696              :     }
    8697              :   else
    8698              :     {
    8699            0 :       M2MetaError_MetaErrorT1 (SymbolTable_GetDeclaredMod (ProcedureSym), (const char *) "{%W}procedure declaration", 25, ProcedureSym);
    8700              :     }
    8701            0 :   if ((SymbolTable_GetLType (Actual)) == SymbolTable_NulSym)
    8702              :     {
    8703            0 :       M2MetaError_MetaError1 ((const char *) "actual parameter being passed is {%1Wda} {%1ad}", 47, Actual);
    8704              :     }
    8705              :   else
    8706              :     {
    8707            0 :       if (SymbolTable_IsVar (Actual))
    8708              :         {
    8709            0 :           M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (Actual), (const char *) "actual parameter variable being passed is {%1Wda} {%1ad} of type {%1ts}", 71, Actual);
    8710              :         }
    8711              :       else
    8712              :         {
    8713            0 :           M2MetaError_MetaErrorT1 (tokpos, (const char *) "actual parameter being passed is {%1Wda} {%1ad} of type {%1ts}", 62, Actual);
    8714              :         }
    8715              :     }
    8716            0 : }
    8717              : 
    8718              : 
    8719              : /*
    8720              :    doIndrX - perform des = *exp with a conversion if necessary.
    8721              : */
    8722              : 
    8723        16799 : static void doIndrX (unsigned int tok, unsigned int des, unsigned int exp)
    8724              : {
    8725        16799 :   unsigned int t;
    8726              : 
    8727        16799 :   if ((SymbolTable_GetDType (des)) == (SymbolTable_GetDType (exp)))
    8728              :     {
    8729        16281 :       GenQuadOtok (tok, M2Quads_IndrXOp, des, SymbolTable_GetSType (des), exp, true, tok, tok, tok);
    8730              :     }
    8731              :   else
    8732              :     {
    8733          518 :       if (M2Options_StrictTypeAssignment)
    8734              :         {
    8735          518 :           BuildRange (M2Range_InitTypesIndrXCheck (tok, des, exp));
    8736              :         }
    8737          518 :       t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
    8738          518 :       SymbolTable_PutVar (t, SymbolTable_GetSType (exp));
    8739          518 :       GenQuadOtok (tok, M2Quads_IndrXOp, t, SymbolTable_GetSType (exp), exp, true, tok, tok, tok);
    8740          518 :       GenQuadOtok (tok, M2Quads_BecomesOp, des, SymbolTable_NulSym, doVal (SymbolTable_GetSType (des), t), true, tok, M2LexBuf_UnknownTokenNo, tok);
    8741              :     }
    8742        16799 : }
    8743              : 
    8744              : 
    8745              : /*
    8746              :    MakeRightValue - returns a temporary which will have the RightValue of symbol, Sym.
    8747              :                     If Sym is a right value and has type, type, then no quadruples are
    8748              :                     generated and Sym is returned. Otherwise a new temporary is created
    8749              :                     and an IndrX quadruple is generated.
    8750              : */
    8751              : 
    8752         1515 : static unsigned int MakeRightValue (unsigned int tok, unsigned int Sym, unsigned int type)
    8753              : {
    8754         1515 :   unsigned int t;
    8755              : 
    8756         1515 :   if ((SymbolTable_GetMode (Sym)) == SymbolTable_RightValue)
    8757              :     {
    8758            0 :       if ((SymbolTable_GetSType (Sym)) == type)
    8759              :         {
    8760              :           return Sym;
    8761              :         }
    8762              :       else
    8763              :         {
    8764              :           /* 
    8765              :             type change or mode change, type changes are a pain, but I've
    8766              :             left them here as it is perhaps easier to remove them later.
    8767              :   */
    8768            0 :           t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
    8769            0 :           SymbolTable_PutVar (t, type);
    8770            0 :           GenQuadOtok (tok, M2Quads_BecomesOp, t, SymbolTable_NulSym, doVal (type, Sym), true, tok, tok, tok);
    8771            0 :           return t;
    8772              :         }
    8773              :     }
    8774              :   else
    8775              :     {
    8776         1515 :       t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
    8777         1515 :       SymbolTable_PutVar (t, type);
    8778         1515 :       CheckPointerThroughNil (tok, Sym);
    8779         1515 :       doIndrX (tok, t, Sym);
    8780         1515 :       return t;
    8781              :     }
    8782              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8783              :   __builtin_unreachable ();
    8784              : }
    8785              : 
    8786              : 
    8787              : /*
    8788              :    MakeLeftValue - returns a temporary coresponding to the LeftValue of
    8789              :                    symbol, Sym. No quadruple is generated if Sym is already
    8790              :                    a LeftValue and has the same type.
    8791              : */
    8792              : 
    8793       196032 : static unsigned int MakeLeftValue (unsigned int tok, unsigned int Sym, SymbolTable_ModeOfAddr with, unsigned int type)
    8794              : {
    8795       196032 :   unsigned int t;
    8796              : 
    8797       196032 :   if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
    8798              :     {
    8799         5181 :       if ((SymbolTable_GetSType (Sym)) == type)
    8800              :         {
    8801              :           return Sym;
    8802              :         }
    8803              :       else
    8804              :         {
    8805              :           /* 
    8806              :             type change or mode change, type changes are a pain, but I've
    8807              :             left them here as it is perhaps easier to remove them later
    8808              :   */
    8809          172 :           t = SymbolTable_MakeTemporary (tok, with);
    8810          172 :           SymbolTable_PutVar (t, type);
    8811          172 :           GenQuadOtok (tok, M2Quads_BecomesOp, t, SymbolTable_NulSym, Sym, true, tok, M2LexBuf_UnknownTokenNo, tok);
    8812          172 :           return t;
    8813              :         }
    8814              :     }
    8815              :   else
    8816              :     {
    8817       190851 :       t = SymbolTable_MakeTemporary (tok, with);
    8818       190851 :       SymbolTable_PutVar (t, type);
    8819       190851 :       GenQuadOtok (tok, M2Quads_AddrOp, t, SymbolTable_NulSym, Sym, true, tok, M2LexBuf_UnknownTokenNo, tok);
    8820       190851 :       return t;
    8821              :     }
    8822              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    8823              :   __builtin_unreachable ();
    8824              : }
    8825              : 
    8826              : 
    8827              : /*
    8828              :    ManipulatePseudoCallParameters - manipulates the parameters to a pseudo function or
    8829              :                                     procedure. It dereferences all LeftValue parameters
    8830              :                                     and Boolean parameters.
    8831              :                                     The Stack:
    8832              : 
    8833              : 
    8834              :                                     Entry                      Exit
    8835              : 
    8836              :                              Ptr ->                            exactly the same
    8837              :                                     +----------------+
    8838              :                                     | NoOfParameters |
    8839              :                                     |----------------|
    8840              :                                     | Param 1        |
    8841              :                                     |----------------|
    8842              :                                     | Param 2        |
    8843              :                                     |----------------|
    8844              :                                     .                .
    8845              :                                     .                .
    8846              :                                     .                .
    8847              :                                     |----------------|
    8848              :                                     | Param #        |
    8849              :                                     |----------------|
    8850              :                                     | ProcSym | Type |
    8851              :                                     |----------------|
    8852              : 
    8853              : */
    8854              : 
    8855        66462 : static void ManipulatePseudoCallParameters (void)
    8856              : {
    8857        66462 :   unsigned int NoOfParameters;
    8858        66462 :   unsigned int ProcSym;
    8859        66462 :   unsigned int Proc;
    8860        66462 :   unsigned int i;
    8861        66462 :   unsigned int pi;
    8862        66462 :   M2Quads_BoolFrame f;
    8863              : 
    8864        66462 :   M2Quads_PopT (&NoOfParameters);
    8865        66462 :   M2Quads_PushT (NoOfParameters);  /* restored to original state  */
    8866              :   /* Ptr points to the ProcSym  */
    8867        66462 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((NoOfParameters+1)+1));
    8868        66462 :   if (SymbolTable_IsVar (ProcSym))
    8869              :     {
    8870            0 :       M2Error_InternalError ((const char *) "expecting a pseudo procedure or a type", 38);
    8871              :     }
    8872              :   else
    8873              :     {
    8874        66462 :       Proc = ProcSym;
    8875              :     }
    8876        66462 :   i = 1;
    8877        66462 :   pi = NoOfParameters+1;
    8878       145744 :   while (i <= NoOfParameters)
    8879              :     {
    8880        79282 :       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)))
    8881              :         {
    8882              :           /* must dereference LeftValue  */
    8883         1344 :           f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pi));
    8884         1344 :           f->TrueExit = MakeRightValue (M2LexBuf_GetTokenNo (), M2Quads_OperandT (pi), SymbolTable_GetSType (M2Quads_OperandT (pi)));
    8885              :         }
    8886        79282 :       i += 1;
    8887        79282 :       pi -= 1;
    8888              :     }
    8889        66462 : }
    8890              : 
    8891              : 
    8892              : /*
    8893              :    ManipulateParameters - manipulates the procedure parameters in
    8894              :                           preparation for a procedure call.
    8895              :                           Prepares Boolean, Unbounded and VAR parameters.
    8896              :                           The Stack:
    8897              : 
    8898              : 
    8899              :                           Entry                      Exit
    8900              : 
    8901              :                    Ptr ->                            exactly the same
    8902              :                           +----------------+
    8903              :                           | NoOfParameters |
    8904              :                           |----------------|
    8905              :                           | Param 1        |
    8906              :                           |----------------|
    8907              :                           | Param 2        |
    8908              :                           |----------------|
    8909              :                           .                .
    8910              :                           .                .
    8911              :                           .                .
    8912              :                           |----------------|
    8913              :                           | Param #        |
    8914              :                           |----------------|
    8915              :                           | ProcSym | Type |
    8916              :                           |----------------|
    8917              : */
    8918              : 
    8919       218988 : static void ManipulateParameters (bool IsForC)
    8920              : {
    8921       218988 :   unsigned int tokpos;
    8922       218988 :   unsigned int np;
    8923       218988 :   DynamicStrings_String s;
    8924       218988 :   unsigned int ArraySym;
    8925       218988 :   unsigned int UnboundedType;
    8926       218988 :   unsigned int ParamType;
    8927       218988 :   unsigned int NoOfParameters;
    8928       218988 :   unsigned int i;
    8929       218988 :   unsigned int pi;
    8930       218988 :   unsigned int ProcSym;
    8931       218988 :   unsigned int rw;
    8932       218988 :   unsigned int Proc;
    8933       218988 :   unsigned int t;
    8934       218988 :   M2Quads_BoolFrame f;
    8935              : 
    8936       218988 :   M2Quads_PopT (&NoOfParameters);
    8937       218988 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+1));
    8938       218988 :   tokpos = OperandTtok (NoOfParameters+1);
    8939       218988 :   if (SymbolTable_IsVar (ProcSym))
    8940              :     {
    8941              :       /* Procedure Variable ?  */
    8942          772 :       Proc = SymbolTable_SkipType (M2Quads_OperandF (NoOfParameters+1));
    8943              :     }
    8944              :   else
    8945              :     {
    8946       218216 :       Proc = PCSymBuild_SkipConst (ProcSym);
    8947              :     }
    8948       218988 :   if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
    8949              :     {
    8950              :       /* avoid dangling else.  */
    8951         9791 :       if (NoOfParameters < (SymbolTable_NoOfParamAny (Proc)))
    8952              :         {
    8953            0 :           s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
    8954            0 :           np = SymbolTable_NoOfParamAny (Proc);
    8955            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));
    8956              :         }
    8957              :     }
    8958       209197 :   else if (SymbolTable_UsesOptArgAny (Proc))
    8959              :     {
    8960              :       /* avoid dangling else.  */
    8961         3673 :       if (! ((NoOfParameters == (SymbolTable_NoOfParamAny (Proc))) || ((NoOfParameters+1) == (SymbolTable_NoOfParamAny (Proc)))))
    8962              :         {
    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 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));
    8966              :         }
    8967              :     }
    8968       205524 :   else if (NoOfParameters != (SymbolTable_NoOfParamAny (Proc)))
    8969              :     {
    8970              :       /* avoid dangling else.  */
    8971            0 :       s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
    8972            0 :       np = SymbolTable_NoOfParamAny (Proc);
    8973            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));
    8974              :     }
    8975       218988 :   i = 1;
    8976       218988 :   pi = NoOfParameters;
    8977       762011 :   while (i <= NoOfParameters)
    8978              :     {
    8979       543023 :       f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pi));
    8980       543023 :       rw = static_cast<unsigned int> (OperandMergeRW (pi));
    8981       543023 :       M2Debug_Assert (SymbolTable_IsLegal (rw));
    8982       543023 :       if (i > (SymbolTable_NoOfParamAny (Proc)))
    8983              :         {
    8984         8473 :           if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
    8985              :             {
    8986              :               /* avoid dangling else.  */
    8987         8473 :               if (((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym) && (SymbolTable_IsArray (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
    8988              :                 {
    8989          156 :                   f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_RightValue, M2System_Address);
    8990          156 :                   MarkAsReadWrite (rw);
    8991              :                 }
    8992         8317 :               else if (SymbolTable_IsConstString (M2Quads_OperandT (pi)))
    8993              :                 {
    8994              :                   /* avoid dangling else.  */
    8995          283 :                   f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), DeferMakeConstStringCnul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi)), SymbolTable_RightValue, M2System_Address);
    8996          283 :                   MarkAsReadWrite (rw);
    8997              :                 }
    8998         8034 :               else if (((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (M2Quads_OperandT (pi)))))
    8999              :                 {
    9000              :                   /* avoid dangling else.  */
    9001          200 :                   MarkAsReadWrite (rw);
    9002              :                   /* pass the address field of an unbounded variable  */
    9003          200 :                   M2Quads_PushTFtok (M2System_Adr, M2System_Address, M2Quads_OperandTok (pi));
    9004          200 :                   PushTFAD (f->TrueExit, f->FalseExit, f->Unbounded, f->Dimension);
    9005          200 :                   M2Quads_PushT (static_cast<unsigned int> (1));
    9006          200 :                   BuildAdrFunction ();
    9007          200 :                   M2Quads_PopT (&f->TrueExit);
    9008              :                 }
    9009         7834 :               else if ((SymbolTable_GetMode (M2Quads_OperandT (pi))) == SymbolTable_LeftValue)
    9010              :                 {
    9011              :                   /* avoid dangling else.  */
    9012          506 :                   MarkAsReadWrite (rw);
    9013              :                   /* must dereference LeftValue (even if we are passing variable as a vararg)  */
    9014          506 :                   t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
    9015          506 :                   SymbolTable_PutVar (t, SymbolTable_GetSType (M2Quads_OperandT (pi)));
    9016          506 :                   CheckPointerThroughNil (tokpos, M2Quads_OperandT (pi));
    9017          506 :                   doIndrX (M2Quads_OperandTok (pi), t, M2Quads_OperandT (pi));
    9018          506 :                   f->TrueExit = t;
    9019              :                 }
    9020              :             }
    9021              :           else
    9022              :             {
    9023            0 :               M2MetaError_MetaErrorT2 (tokpos, (const char *) "attempting to pass too many parameters to procedure {%1a}, the {%2N} parameter does not exist", 93, Proc, i);
    9024              :             }
    9025              :         }
    9026       534550 :       else if (((IsForC && (SymbolTable_IsUnboundedParamAny (Proc, i))) && ((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym)) && (SymbolTable_IsArray (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
    9027              :         {
    9028              :           /* avoid dangling else.  */
    9029           24 :           f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_RightValue, M2System_Address);
    9030           24 :           MarkAsReadWrite (rw);
    9031              :         }
    9032       534526 :       else if (((IsForC && (SymbolTable_IsUnboundedParamAny (Proc, i))) && ((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym)) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
    9033              :         {
    9034              :           /* avoid dangling else.  */
    9035          184 :           MarkAsReadWrite (rw);
    9036              :           /* pass the address field of an unbounded variable  */
    9037          184 :           M2Quads_PushTFtok (M2System_Adr, M2System_Address, M2Quads_OperandTok (pi));
    9038          184 :           PushTFAD (f->TrueExit, f->FalseExit, f->Unbounded, f->Dimension);
    9039          184 :           M2Quads_PushT (static_cast<unsigned int> (1));
    9040          184 :           BuildAdrFunction ();
    9041          184 :           M2Quads_PopT (&f->TrueExit);
    9042              :         }
    9043       534342 :       else if ((IsForC && (SymbolTable_IsConstString (M2Quads_OperandT (pi)))) && ((SymbolTable_IsUnboundedParamAny (Proc, i)) || ((SymbolTable_GetDType (SymbolTable_GetParam (Proc, i))) == M2System_Address)))
    9044              :         {
    9045              :           /* avoid dangling else.  */
    9046         9479 :           f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), DeferMakeConstStringCnul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi)), SymbolTable_RightValue, M2System_Address);
    9047         9479 :           MarkAsReadWrite (rw);
    9048              :         }
    9049       524863 :       else if (SymbolTable_IsUnboundedParamAny (Proc, i))
    9050              :         {
    9051              :           /* avoid dangling else.  */
    9052              :           /* always pass constant strings with a nul terminator, but leave the HIGH as before.  */
    9053        40323 :           if (SymbolTable_IsConstString (M2Quads_OperandT (pi)))
    9054              :             {
    9055              :               /* this is a Modula-2 string which must be nul terminated.  */
    9056        26373 :               f->TrueExit = DeferMakeConstStringM2nul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi));
    9057              :             }
    9058        40323 :           t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
    9059        40323 :           UnboundedType = SymbolTable_GetSType (SymbolTable_GetParam (Proc, i));
    9060        40323 :           SymbolTable_PutVar (t, UnboundedType);
    9061        40323 :           ParamType = SymbolTable_GetSType (UnboundedType);
    9062        40323 :           if ((OperandD (pi)) == 0)
    9063              :             {
    9064        40275 :               ArraySym = static_cast<unsigned int> (M2Quads_OperandT (pi));
    9065              :             }
    9066              :           else
    9067              :             {
    9068           48 :               ArraySym = static_cast<unsigned int> (M2Quads_OperandA (pi));
    9069              :             }
    9070        40323 :           if (SymbolTable_IsVarParamAny (Proc, i))
    9071              :             {
    9072         4383 :               MarkArrayWritten (M2Quads_OperandT (pi));
    9073         4383 :               MarkArrayWritten (M2Quads_OperandA (pi));
    9074         4383 :               MarkAsReadWrite (rw);
    9075         4383 :               AssignUnboundedVar (OperandTtok (pi), M2Quads_OperandT (pi), ArraySym, t, ParamType, OperandD (pi));
    9076              :             }
    9077              :           else
    9078              :             {
    9079        35940 :               MarkAsRead (rw);
    9080        35940 :               AssignUnboundedNonVar (OperandTtok (pi), M2Quads_OperandT (pi), ArraySym, t, ParamType, OperandD (pi));
    9081              :             }
    9082        40323 :           f->TrueExit = t;
    9083              :         }
    9084       484540 :       else if (SymbolTable_IsVarParamAny (Proc, i))
    9085              :         {
    9086              :           /* avoid dangling else.  */
    9087              :           /* must reference by address, but we contain the type of the referenced entity  */
    9088        15823 :           MarkArrayWritten (M2Quads_OperandT (pi));
    9089        15823 :           MarkArrayWritten (M2Quads_OperandA (pi));
    9090        15823 :           MarkAsReadWrite (rw);
    9091        15823 :           f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_LeftValue, SymbolTable_GetSType (SymbolTable_GetParam (Proc, i)));
    9092              :         }
    9093       468717 :       else if ((! (SymbolTable_IsVarParamAny (Proc, i))) && ((SymbolTable_GetMode (M2Quads_OperandT (pi))) == SymbolTable_LeftValue))
    9094              :         {
    9095              :           /* avoid dangling else.  */
    9096              :           /* must dereference LeftValue  */
    9097         1504 :           t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
    9098         1504 :           SymbolTable_PutVar (t, SymbolTable_GetSType (M2Quads_OperandT (pi)));
    9099         1504 :           CheckPointerThroughNil (tokpos, M2Quads_OperandT (pi));
    9100         1504 :           doIndrX (M2Quads_OperandTok (pi), t, M2Quads_OperandT (pi));
    9101         1504 :           f->TrueExit = t;
    9102         1504 :           MarkAsRead (rw);
    9103              :         }
    9104              :       else
    9105              :         {
    9106              :           /* avoid dangling else.  */
    9107       467213 :           MarkAsRead (rw);
    9108              :         }
    9109       543023 :       i += 1;
    9110       543023 :       pi -= 1;
    9111              :     }
    9112       218988 :   M2Quads_PushT (NoOfParameters);
    9113       218988 : }
    9114              : 
    9115              : 
    9116              : /*
    9117              :    CheckParameterOrdinals - check that ordinal values are within type range.
    9118              : */
    9119              : 
    9120       218988 : static void CheckParameterOrdinals (void)
    9121              : {
    9122       218988 :   unsigned int tokno;
    9123       218988 :   unsigned int Proc;
    9124       218988 :   unsigned int ProcSym;
    9125       218988 :   unsigned int Actual;
    9126       218988 :   unsigned int FormalI;
    9127       218988 :   unsigned int ParamTotal;
    9128       218988 :   unsigned int pi;
    9129       218988 :   unsigned int i;
    9130              : 
    9131       218988 :   M2Quads_PopT (&ParamTotal);
    9132       218988 :   M2Quads_PushT (ParamTotal);  /* Restore stack to origional state  */
    9133       218988 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((ParamTotal+1)+1));  /* Restore stack to origional state  */
    9134       218988 :   if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (SymbolTable_GetDType (ProcSym))))
    9135              :     {
    9136              :       /* Indirect procedure call.  */
    9137          772 :       Proc = SymbolTable_SkipType (M2Quads_OperandF ((ParamTotal+1)+1));
    9138              :     }
    9139              :   else
    9140              :     {
    9141       218216 :       Proc = PCSymBuild_SkipConst (ProcSym);
    9142              :     }
    9143       218988 :   i = 1;
    9144       218988 :   pi = ParamTotal+1;  /* stack index referencing stacked parameter, i  */
    9145       762011 :   while (i <= ParamTotal)  /* stack index referencing stacked parameter, i  */
    9146              :     {
    9147       543023 :       if (i <= (SymbolTable_NoOfParamAny (Proc)))
    9148              :         {
    9149       534550 :           FormalI = SymbolTable_GetParam (Proc, i);
    9150       534550 :           Actual = static_cast<unsigned int> (M2Quads_OperandT (pi));
    9151       534550 :           tokno = static_cast<unsigned int> (M2Quads_OperandTok (pi));
    9152       534550 :           if (M2Base_IsOrdinalType (SymbolTable_GetLType (FormalI)))
    9153              :             {
    9154       140251 :               if (! (SymbolTable_IsSet (SymbolTable_GetDType (FormalI))))
    9155              :                 {
    9156              :                   /* Tell the code generator to test the runtime values of the assignment
    9157              :                   so ensure we catch overflow and underflow.  */
    9158       140251 :                   BuildRange (M2Range_InitParameterRangeCheck (tokno, Proc, i, FormalI, Actual, OperandRangeDep (pi)));
    9159              :                 }
    9160              :             }
    9161              :         }
    9162       543023 :       i += 1;
    9163       543023 :       pi -= 1;
    9164              :     }
    9165       218988 : }
    9166              : 
    9167              : 
    9168              : /*
    9169              :    IsSameUnbounded - returns TRUE if unbounded types, t1, and, t2,
    9170              :                      are compatible.
    9171              : */
    9172              : 
    9173           36 : static bool IsSameUnbounded (unsigned int t1, unsigned int t2)
    9174              : {
    9175           36 :   M2Debug_Assert (SymbolTable_IsUnbounded (t1));
    9176           36 :   M2Debug_Assert (SymbolTable_IsUnbounded (t2));
    9177           36 :   return (SymbolTable_GetDType (t1)) == (SymbolTable_GetDType (t2));
    9178              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    9179              :   __builtin_unreachable ();
    9180              : }
    9181              : 
    9182              : 
    9183              : /*
    9184              :    AssignUnboundedVar - assigns an Unbounded symbol fields,
    9185              :                         ArrayAddress and ArrayHigh, from an array symbol.
    9186              :                         UnboundedSym is not a VAR parameter and therefore
    9187              :                         this procedure can complete both of the fields.
    9188              :                         Sym can be a Variable with type Unbounded.
    9189              :                         Sym can be a Variable with type Array.
    9190              :                         Sym can be a String Constant.
    9191              : 
    9192              :                         ParamType is the TYPE of the parameter
    9193              : */
    9194              : 
    9195         4383 : static void AssignUnboundedVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
    9196              : {
    9197         4383 :   unsigned int Type;
    9198              : 
    9199         4383 :   if (SymbolTable_IsConst (Sym))
    9200              :     {
    9201            0 :       M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
    9202              :     }
    9203         4383 :   else if (SymbolTable_IsVar (Sym))
    9204              :     {
    9205              :       /* avoid dangling else.  */
    9206         4383 :       Type = SymbolTable_GetDType (Sym);
    9207         4383 :       if (Type == SymbolTable_NulSym)
    9208              :         {
    9209            0 :           M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} has no type and cannot be passed to a VAR formal parameter", 65, Sym);
    9210              :         }
    9211         4383 :       else if (SymbolTable_IsUnbounded (Type))
    9212              :         {
    9213              :           /* avoid dangling else.  */
    9214         1462 :           if (Type == (SymbolTable_GetSType (UnboundedSym)))
    9215              :             {
    9216              :               /* Copy Unbounded Symbol ie. UnboundedSym := Sym  */
    9217         1426 :               M2Quads_PushT (UnboundedSym);
    9218         1426 :               M2Quads_PushT (Sym);
    9219         1426 :               BuildAssignmentWithoutBounds (tok, false, true);
    9220              :             }
    9221           36 :           else if ((IsSameUnbounded (Type, SymbolTable_GetSType (UnboundedSym))) || (M2System_IsGenericSystemType (ParamType)))
    9222              :             {
    9223              :               /* avoid dangling else.  */
    9224           36 :               UnboundedVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
    9225              :             }
    9226              :           else
    9227              :             {
    9228              :               /* avoid dangling else.  */
    9229            0 :               M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
    9230              :             }
    9231              :         }
    9232         2921 :       else if ((SymbolTable_IsArray (Type)) || (M2System_IsGenericSystemType (ParamType)))
    9233              :         {
    9234              :           /* avoid dangling else.  */
    9235         2921 :           UnboundedVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
    9236              :         }
    9237              :       else
    9238              :         {
    9239              :           /* avoid dangling else.  */
    9240            0 :           M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
    9241              :         }
    9242              :     }
    9243              :   else
    9244              :     {
    9245              :       /* avoid dangling else.  */
    9246            0 :       M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
    9247              :     }
    9248         4383 : }
    9249              : 
    9250              : 
    9251              : /*
    9252              :    AssignUnboundedNonVar - assigns an Unbounded symbol fields,
    9253              :                            The difference between this procedure and
    9254              :                            AssignUnboundedVar is that this procedure cannot
    9255              :                            set the Unbounded.Address since the data from
    9256              :                            Sym will be copied because parameter is NOT a VAR
    9257              :                            parameter.
    9258              :                            UnboundedSym is not a VAR parameter and therefore
    9259              :                            this procedure can only complete the HIGH field
    9260              :                            and not the ADDRESS field.
    9261              :                            Sym can be a Variable with type Unbounded.
    9262              :                            Sym can be a Variable with type Array.
    9263              :                            Sym can be a String Constant.
    9264              : 
    9265              :                            ParamType is the TYPE of the paramater
    9266              : */
    9267              : 
    9268        35940 : static void AssignUnboundedNonVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
    9269              : {
    9270        35940 :   unsigned int Type;
    9271              : 
    9272        35940 :   if (SymbolTable_IsConst (Sym))  /* was IsConstString(Sym)  */
    9273              :     {
    9274        26427 :       UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
    9275              :     }
    9276         9513 :   else if (SymbolTable_IsVar (Sym))
    9277              :     {
    9278              :       /* avoid dangling else.  */
    9279         9513 :       Type = SymbolTable_GetDType (Sym);
    9280         9513 :       if (Type == SymbolTable_NulSym)
    9281              :         {
    9282            0 :           M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} has no type and cannot be passed to a non VAR formal parameter", 69, Sym);
    9283              :         }
    9284         9513 :       else if (SymbolTable_IsUnbounded (Type))
    9285              :         {
    9286              :           /* avoid dangling else.  */
    9287         4781 :           UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
    9288              :         }
    9289         4732 :       else if ((SymbolTable_IsArray (Type)) || (M2System_IsGenericSystemType (ParamType)))
    9290              :         {
    9291              :           /* avoid dangling else.  */
    9292         4720 :           UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
    9293              :         }
    9294              :       else
    9295              :         {
    9296              :           /* avoid dangling else.  */
    9297           12 :           M2MetaError_MetaErrorT1 (tok, (const char *) "illegal type parameter {%1Ead} expecting array or dynamic array", 63, Sym);
    9298              :         }
    9299              :     }
    9300              :   else
    9301              :     {
    9302              :       /* avoid dangling else.  */
    9303            0 :       M2MetaError_MetaErrorT1 (tok, (const char *) "illegal parameter {%1Ead} which cannot be passed as {%kVAR} {%kARRAY} {%kOF} {%1tsad}", 85, Sym);
    9304              :     }
    9305        35940 : }
    9306              : 
    9307              : 
    9308              : /*
    9309              :    GenHigh - generates a HighOp but it checks if op3 is a
    9310              :              L value and if so it dereferences it.  This
    9311              :              is inefficient, however it is clean and we let the gcc
    9312              :              backend detect these as common subexpressions.
    9313              :              It will also detect that a R value -> L value -> R value
    9314              :              via indirection and eleminate these.
    9315              : */
    9316              : 
    9317        41765 : static void GenHigh (unsigned int tok, unsigned int op1, unsigned int op2, unsigned int op3)
    9318              : {
    9319        41765 :   unsigned int sym;
    9320              : 
    9321        41765 :   if (((SymbolTable_GetMode (op3)) == SymbolTable_LeftValue) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (op3))))
    9322              :     {
    9323           48 :       sym = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
    9324           48 :       SymbolTable_PutVar (sym, SymbolTable_GetSType (op3));
    9325           48 :       doIndrX (tok, sym, op3);
    9326           48 :       GenQuadO (tok, M2Quads_HighOp, op1, op2, sym, true);
    9327              :     }
    9328              :   else
    9329              :     {
    9330        41717 :       GenQuadO (tok, M2Quads_HighOp, op1, op2, op3, true);
    9331              :     }
    9332        41765 : }
    9333              : 
    9334              : 
    9335              : /*
    9336              :    AssignHighField -
    9337              : */
    9338              : 
    9339        39041 : static void AssignHighField (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int actuali, unsigned int formali)
    9340              : {
    9341        39041 :   unsigned int ReturnVar;
    9342        39041 :   unsigned int ArrayType;
    9343        39041 :   unsigned int Field;
    9344              : 
    9345              :   /* Unbounded.ArrayHigh := HIGH(ArraySym)  */
    9346        39041 :   M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
    9347        39041 :   Field = SymbolTable_GetUnboundedHighOffset (SymbolTable_GetSType (UnboundedSym), formali);
    9348        39041 :   M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
    9349        39041 :   M2Quads_PushT (static_cast<unsigned int> (1));
    9350        39041 :   M2Quads_BuildDesignatorRecord (tok);
    9351        39041 :   if (M2System_IsGenericSystemType (ParamType))
    9352              :     {
    9353         2036 :       if (SymbolTable_IsConstString (Sym))
    9354              :         {
    9355           18 :           M2Quads_PushTtok (DeferMakeLengthConst (tok, Sym), tok);
    9356              :         }
    9357              :       else
    9358              :         {
    9359         2018 :           ArrayType = SymbolTable_GetSType (Sym);
    9360         2018 :           if (SymbolTable_IsUnbounded (ArrayType))
    9361              :             {
    9362              :               /* 
    9363              :              *  SIZE(parameter) DIV TSIZE(ParamType)
    9364              :              *  however in this case parameter
    9365              :              *  is an unbounded symbol and therefore we must use
    9366              :              *  (HIGH(parameter)+1)*SIZE(unbounded type) DIV TSIZE(ParamType)
    9367              :              *
    9368              :              *  we call upon the function SIZE(ArraySym)
    9369              :              *  remember SIZE doubles as
    9370              :              *  (HIGH(a)+1) * SIZE(ArrayType) for unbounded symbols
    9371              :   */
    9372         1106 :               M2Quads_PushTFtok (calculateMultipicand (tok, ArraySym, ArrayType, actuali-1), M2Base_Cardinal, tok);
    9373         1106 :               M2Quads_PushT (M2Reserved_DivideTok);  /* Divide by  */
    9374         1106 :               M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok);  /* TSIZE(ParamType)  */
    9375         1106 :               M2Quads_PushTtok (ParamType, tok);  /* TSIZE(ParamType)  */
    9376         1106 :               M2Quads_PushT (static_cast<unsigned int> (1));  /* 1 parameter for TSIZE()  */
    9377         1106 :               M2Quads_BuildFunctionCall (false);  /* 1 parameter for TSIZE()  */
    9378         1106 :               M2Quads_BuildBinaryOp ();
    9379              :             }
    9380              :           else
    9381              :             {
    9382              :               /* SIZE(parameter) DIV TSIZE(ParamType)  */
    9383          912 :               M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok);  /* TSIZE(ArrayType)  */
    9384          912 :               M2Quads_PushTtok (ArrayType, tok);  /* TSIZE(ArrayType)  */
    9385          912 :               M2Quads_PushT (static_cast<unsigned int> (1));  /* 1 parameter for TSIZE()  */
    9386          912 :               M2Quads_BuildFunctionCall (true);  /* 1 parameter for TSIZE()  */
    9387          912 :               M2Quads_PushT (M2Reserved_DivideTok);  /* Divide by  */
    9388          912 :               M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok);  /* TSIZE(ParamType)  */
    9389          912 :               M2Quads_PushTtok (ParamType, tok);  /* TSIZE(ParamType)  */
    9390          912 :               M2Quads_PushT (static_cast<unsigned int> (1));  /* 1 parameter for TSIZE()  */
    9391          912 :               M2Quads_BuildFunctionCall (true);  /* 1 parameter for TSIZE()  */
    9392          912 :               M2Quads_BuildBinaryOp ();
    9393              :             }
    9394              :           /* now convert from no of elements into HIGH by subtracting 1  */
    9395         2018 :           M2Quads_PushT (M2Reserved_MinusTok);  /* -1  */
    9396         2018 :           M2Quads_PushTtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal), tok);  /* -1  */
    9397         2018 :           M2Quads_BuildBinaryOp ();
    9398              :         }
    9399              :     }
    9400              :   else
    9401              :     {
    9402        37005 :       ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
    9403        37005 :       SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
    9404        37005 :       if (((actuali != formali) && (ArraySym != SymbolTable_NulSym)) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (ArraySym))))
    9405              :         {
    9406           12 :           GenHigh (tok, ReturnVar, actuali, ArraySym);
    9407              :         }
    9408              :       else
    9409              :         {
    9410        36993 :           GenHigh (tok, ReturnVar, formali, Sym);
    9411              :         }
    9412        37005 :       M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), tok);
    9413              :     }
    9414        39041 :   BuildAssignmentWithoutBounds (tok, false, true);
    9415        39041 : }
    9416              : 
    9417              : 
    9418              : /*
    9419              :    AssignHighFields -
    9420              : */
    9421              : 
    9422        38885 : static void AssignHighFields (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
    9423              : {
    9424        38885 :   unsigned int type;
    9425        38885 :   unsigned int actuali;
    9426        38885 :   unsigned int formali;
    9427        38885 :   unsigned int actualn;
    9428        38885 :   unsigned int formaln;
    9429              : 
    9430        38885 :   type = SymbolTable_GetDType (Sym);
    9431        38885 :   actualn = 1;
    9432        38885 :   if ((type != SymbolTable_NulSym) && ((SymbolTable_IsUnbounded (type)) || (SymbolTable_IsArray (type))))
    9433              :     {
    9434        11576 :       actualn = SymbolTable_GetDimension (type);
    9435              :     }
    9436        38885 :   actuali = dim+1;
    9437        38885 :   formali = 1;
    9438        38885 :   formaln = SymbolTable_GetDimension (SymbolTable_GetDType (UnboundedSym));
    9439        77926 :   while ((actuali < actualn) && (formali < formaln))
    9440              :     {
    9441          156 :       AssignHighField (tok, Sym, ArraySym, UnboundedSym, SymbolTable_NulSym, actuali, formali);
    9442          156 :       actuali += 1;
    9443          156 :       formali += 1;
    9444              :     }
    9445        38885 :   AssignHighField (tok, Sym, ArraySym, UnboundedSym, ParamType, actuali, formali);
    9446        38885 : }
    9447              : 
    9448              : 
    9449              : /*
    9450              :    UnboundedNonVarLinkToArray - links an array, ArraySym, to an unbounded
    9451              :                                 array, UnboundedSym. The parameter is a
    9452              :                                 NON VAR variety.
    9453              : */
    9454              : 
    9455        35928 : static void UnboundedNonVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
    9456              : {
    9457        35928 :   unsigned int Field;
    9458        35928 :   unsigned int AddressField;
    9459              : 
    9460              :   /* Unbounded.ArrayAddress := to be assigned at runtime.  */
    9461        35928 :   M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
    9462        35928 :   Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
    9463        35928 :   M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
    9464        35928 :   M2Quads_PushT (static_cast<unsigned int> (1));
    9465        35928 :   M2Quads_BuildDesignatorRecord (tok);
    9466        35928 :   M2Quads_PopT (&AddressField);
    9467              :   /* caller saves non var unbounded array contents.  */
    9468        71856 :   GenQuadO (tok, M2Quads_UnboundedOp, AddressField, SymbolTable_NulSym, Sym, false);
    9469        35928 :   AssignHighFields (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
    9470        35928 : }
    9471              : 
    9472              : 
    9473              : /*
    9474              :    UnboundedVarLinkToArray - links an array, ArraySym, to an unbounded array,
    9475              :                              UnboundedSym. The parameter is a VAR variety.
    9476              : */
    9477              : 
    9478         2957 : static void UnboundedVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
    9479              : {
    9480         2957 :   unsigned int SymType;
    9481         2957 :   unsigned int Field;
    9482              : 
    9483         2957 :   SymType = SymbolTable_GetSType (Sym);
    9484              :   /* Unbounded.ArrayAddress := ADR(Sym)  */
    9485         2957 :   M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
    9486         2957 :   Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
    9487         2957 :   M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
    9488         2957 :   M2Quads_PushT (static_cast<unsigned int> (1));
    9489         2957 :   M2Quads_BuildDesignatorRecord (tok);
    9490         2957 :   M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);  /* ADR (Sym).  */
    9491         2957 :   if ((SymbolTable_IsUnbounded (SymType)) && (dim == 0))  /* ADR (Sym).  */
    9492              :     {
    9493           12 :       PushTFADtok (Sym, SymType, UnboundedSym, dim, tok);
    9494              :     }
    9495              :   else
    9496              :     {
    9497         2945 :       PushTFADtok (Sym, SymType, ArraySym, dim, tok);
    9498              :     }
    9499         2957 :   M2Quads_PushT (static_cast<unsigned int> (1));  /* 1 parameter for ADR().  */
    9500         2957 :   M2Quads_BuildFunctionCall (false);  /* 1 parameter for ADR().  */
    9501         2957 :   BuildAssignmentWithoutBounds (tok, false, true);
    9502         2957 :   AssignHighFields (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
    9503         2957 : }
    9504              : 
    9505              : 
    9506              : /*
    9507              :    BuildPseudoProcedureCall - builds a pseudo procedure call.
    9508              :                               This procedure does not directly alter the
    9509              :                               stack, but by calling routines the stack
    9510              :                               will change in the following way when this
    9511              :                               procedure returns.
    9512              : 
    9513              :                               The Stack:
    9514              : 
    9515              : 
    9516              :                               Entry                      Exit
    9517              : 
    9518              :                        Ptr ->
    9519              :                               +----------------+
    9520              :                               | NoOfParam      |
    9521              :                               |----------------|
    9522              :                               | Param 1        |
    9523              :                               |----------------|
    9524              :                               | Param 2        |
    9525              :                               |----------------|
    9526              :                               .                .
    9527              :                               .                .
    9528              :                               .                .
    9529              :                               |----------------|
    9530              :                               | Param #        |
    9531              :                               |----------------|
    9532              :                               | ProcSym | Type |         Empty
    9533              :                               |----------------|
    9534              : */
    9535              : 
    9536        21047 : static void BuildPseudoProcedureCall (unsigned int tokno)
    9537              : {
    9538        21047 :   unsigned int NoOfParam;
    9539        21047 :   unsigned int ProcSym;
    9540              : 
    9541        21047 :   M2Quads_PopT (&NoOfParam);
    9542        21047 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
    9543        21047 :   M2Quads_PushT (NoOfParam);
    9544              :   /* Compile time stack restored to entry state  */
    9545        21047 :   if (ProcSym == M2Base_New)
    9546              :     {
    9547          867 :       BuildNewProcedure (tokno);
    9548              :     }
    9549        20180 :   else if (ProcSym == M2Base_Dispose)
    9550              :     {
    9551              :       /* avoid dangling else.  */
    9552          330 :       BuildDisposeProcedure (tokno);
    9553              :     }
    9554        19850 :   else if (ProcSym == M2Base_Inc)
    9555              :     {
    9556              :       /* avoid dangling else.  */
    9557        13996 :       BuildIncProcedure (tokno);
    9558              :     }
    9559         5854 :   else if (ProcSym == M2Base_Dec)
    9560              :     {
    9561              :       /* avoid dangling else.  */
    9562         3865 :       BuildDecProcedure (tokno);
    9563              :     }
    9564         1989 :   else if (ProcSym == M2Base_Incl)
    9565              :     {
    9566              :       /* avoid dangling else.  */
    9567         1112 :       BuildInclProcedure (tokno);
    9568              :     }
    9569          877 :   else if (ProcSym == M2Base_Excl)
    9570              :     {
    9571              :       /* avoid dangling else.  */
    9572          766 :       BuildExclProcedure (tokno);
    9573              :     }
    9574          111 :   else if (ProcSym == M2System_Throw)
    9575              :     {
    9576              :       /* avoid dangling else.  */
    9577          111 :       BuildThrowProcedure (tokno);
    9578              :     }
    9579              :   else
    9580              :     {
    9581              :       /* avoid dangling else.  */
    9582            0 :       M2Error_InternalError ((const char *) "pseudo procedure not implemented yet", 36);
    9583              :     }
    9584        21047 : }
    9585              : 
    9586              : 
    9587              : /*
    9588              :    GetItemPointedTo - returns the symbol type that is being pointed to
    9589              :                       by Sym.
    9590              : */
    9591              : 
    9592         3034 : static unsigned int GetItemPointedTo (unsigned int Sym)
    9593              : {
    9594         6076 :   if (SymbolTable_IsPointer (Sym))
    9595              :     {
    9596         3034 :       return SymbolTable_GetSType (Sym);
    9597              :     }
    9598         3042 :   else if ((SymbolTable_IsVar (Sym)) || (SymbolTable_IsType (Sym)))
    9599              :     {
    9600              :       /* avoid dangling else.  */
    9601         3042 :       return GetItemPointedTo (SymbolTable_GetSType (Sym));
    9602              :     }
    9603              :   else
    9604              :     {
    9605              :       /* avoid dangling else.  */
    9606              :       return SymbolTable_NulSym;
    9607              :     }
    9608              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    9609              :   __builtin_unreachable ();
    9610              : }
    9611              : 
    9612              : 
    9613              : /*
    9614              :    BuildThrowProcedure - builds the pseudo procedure call M2RTS.Throw.
    9615              :                          The Stack:
    9616              : 
    9617              : 
    9618              :                          Entry                      Exit
    9619              : 
    9620              :                 Ptr ->
    9621              :                          +----------------+
    9622              :                          | NoOfParam      |
    9623              :                          |----------------|
    9624              :                          | Param 1        |
    9625              :                          |----------------|
    9626              :                          | Param 2        |
    9627              :                          |----------------|
    9628              :                          .                .
    9629              :                          .                .
    9630              :                          .                .
    9631              :                          |----------------|
    9632              :                          | Param #        |
    9633              :                          |----------------|
    9634              :                          | ProcSym | Type |         Empty
    9635              :                          |----------------|
    9636              : */
    9637              : 
    9638          111 : static void BuildThrowProcedure (unsigned int functok)
    9639              : {
    9640          111 :   unsigned int op;
    9641          111 :   unsigned int NoOfParam;
    9642              : 
    9643          111 :   M2Quads_PopT (&NoOfParam);
    9644          111 :   if (NoOfParam == 1)
    9645              :     {
    9646          111 :       op = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
    9647          111 :       GenQuadO (functok, M2Quads_ThrowOp, SymbolTable_NulSym, SymbolTable_NulSym, op, false);
    9648              :     }
    9649              :   else
    9650              :     {
    9651            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure %{1Ea} takes one INTEGER parameter", 55, M2System_Throw);
    9652              :     }
    9653          111 :   M2Quads_PopN (NoOfParam+1);
    9654          111 : }
    9655              : 
    9656              : 
    9657              : /*
    9658              :    BuildNewProcedure - builds the pseudo procedure call NEW.
    9659              :                        This procedure is traditionally a "macro" for
    9660              :                        NEW(x, ...) --> ALLOCATE(x, TSIZE(x^, ...))
    9661              :                        One method of implementation is to emulate a "macro"
    9662              :                        processor by pushing the relevant input tokens
    9663              :                        back onto the input stack.
    9664              :                        However this causes two problems:
    9665              : 
    9666              :                        (i)  Unnecessary code is produced for x^
    9667              :                        (ii) SIZE must be imported from SYSTEM
    9668              :                        Therefore we chose an alternative method of
    9669              :                        implementation;
    9670              :                        generate quadruples for ALLOCATE(x, TSIZE(x^, ...))
    9671              :                        this, although slightly more efficient,
    9672              :                        is more complex and circumvents problems (i) and (ii).
    9673              : 
    9674              :                        The Stack:
    9675              : 
    9676              : 
    9677              :                        Entry                      Exit
    9678              : 
    9679              :                 Ptr ->
    9680              :                        +----------------+
    9681              :                        | NoOfParam      |
    9682              :                        |----------------|
    9683              :                        | Param 1        |
    9684              :                        |----------------|
    9685              :                        | Param 2        |
    9686              :                        |----------------|
    9687              :                        .                .
    9688              :                        .                .
    9689              :                        .                .
    9690              :                        |----------------|
    9691              :                        | Param #        |
    9692              :                        |----------------|
    9693              :                        | ProcSym | Type |         Empty
    9694              :                        |----------------|
    9695              : */
    9696              : 
    9697          867 : static void BuildNewProcedure (unsigned int functok)
    9698              : {
    9699          867 :   unsigned int NoOfParam;
    9700          867 :   unsigned int SizeSym;
    9701          867 :   unsigned int PtrSym;
    9702          867 :   unsigned int ProcSym;
    9703          867 :   unsigned int paramtok;
    9704          867 :   unsigned int combinedtok;
    9705              : 
    9706          867 :   M2Quads_PopT (&NoOfParam);
    9707          867 :   if (NoOfParam >= 1)
    9708              :     {
    9709          867 :       ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "ALLOCATE", 8));
    9710          867 :       if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
    9711              :         {
    9712          867 :           PtrSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
    9713          867 :           paramtok = OperandTtok (1);
    9714          867 :           if (IsReallyPointer (PtrSym))
    9715              :             {
    9716          866 :               combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
    9717              :               /* 
    9718              :                Build macro: ALLOCATE( PtrSym, SIZE(PtrSym^) )
    9719              :   */
    9720          866 :               M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, paramtok);  /* Procedure  */
    9721              :               /* x^  */
    9722          866 :               M2Quads_PushTtok (GetItemPointedTo (PtrSym), paramtok);
    9723          866 :               M2Quads_PushT (static_cast<unsigned int> (1));  /* One parameter  */
    9724          866 :               M2Quads_BuildFunctionCall (false);  /* One parameter  */
    9725          866 :               M2Quads_PopT (&SizeSym);
    9726          866 :               M2Quads_PushTtok (ProcSym, combinedtok);  /* ALLOCATE  */
    9727          866 :               M2Quads_PushTtok (PtrSym, paramtok);  /* x  */
    9728          866 :               M2Quads_PushTtok (SizeSym, paramtok);  /* TSIZE(x^)  */
    9729          866 :               M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
    9730          866 :               M2Quads_BuildProcedureCall (combinedtok);  /* Two parameters  */
    9731              :             }
    9732              :           else
    9733              :             {
    9734            1 :               M2MetaError_MetaErrorT1 (paramtok, (const char *) "parameter to {%EkNEW} must be a pointer, seen {%1Ed} {%1&s}", 59, PtrSym);
    9735              :             }
    9736              :         }
    9737              :       else
    9738              :         {
    9739            0 :           M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}ALLOCATE procedure not found for NEW substitution", 53);
    9740              :         }
    9741              :     }
    9742              :   else
    9743              :     {
    9744            0 :       M2MetaError_MetaErrorT0 (functok, (const char *) "the pseudo procedure {%EkNEW} has one or more parameters", 56);
    9745              :     }
    9746          867 :   M2Quads_PopN (NoOfParam+1);
    9747          867 : }
    9748              : 
    9749              : 
    9750              : /*
    9751              :    BuildDisposeProcedure - builds the pseudo procedure call DISPOSE.
    9752              :                            This procedure is traditionally a "macro" for
    9753              :                            DISPOSE(x) --> DEALLOCATE(x, TSIZE(x^))
    9754              :                            One method of implementation is to emulate a "macro"
    9755              :                            processor by pushing the relevant input tokens
    9756              :                            back onto the input stack.
    9757              :                            However this causes two problems:
    9758              : 
    9759              :                            (i)  Unnecessary code is produced for x^
    9760              :                            (ii) TSIZE must be imported from SYSTEM
    9761              :                            Therefore we chose an alternative method of
    9762              :                            implementation;
    9763              :                            generate quadruples for DEALLOCATE(x, TSIZE(x^))
    9764              :                            this, although slightly more efficient,
    9765              :                            is more complex and circumvents problems (i)
    9766              :                            and (ii).
    9767              : 
    9768              :                            The Stack:
    9769              : 
    9770              : 
    9771              :                            Entry                      Exit
    9772              : 
    9773              :                     Ptr ->
    9774              :                            +----------------+
    9775              :                            | NoOfParam      |
    9776              :                            |----------------|
    9777              :                            | Param 1        |
    9778              :                            |----------------|
    9779              :                            | Param 2        |
    9780              :                            |----------------|
    9781              :                            .                .
    9782              :                            .                .
    9783              :                            .                .
    9784              :                            |----------------|
    9785              :                            | Param #        |
    9786              :                            |----------------|
    9787              :                            | ProcSym | Type |         Empty
    9788              :                            |----------------|
    9789              : */
    9790              : 
    9791          330 : static void BuildDisposeProcedure (unsigned int functok)
    9792              : {
    9793          330 :   unsigned int NoOfParam;
    9794          330 :   unsigned int SizeSym;
    9795          330 :   unsigned int PtrSym;
    9796          330 :   unsigned int ProcSym;
    9797          330 :   unsigned int combinedtok;
    9798          330 :   unsigned int paramtok;
    9799              : 
    9800          330 :   M2Quads_PopT (&NoOfParam);
    9801          330 :   if (NoOfParam >= 1)
    9802              :     {
    9803          330 :       ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "DEALLOCATE", 10));
    9804          330 :       if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
    9805              :         {
    9806          330 :           PtrSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
    9807          330 :           paramtok = OperandTtok (1);
    9808          330 :           if (IsReallyPointer (PtrSym))
    9809              :             {
    9810          330 :               combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
    9811              :               /* 
    9812              :                Build macro: DEALLOCATE( PtrSym, TSIZE(PtrSym^) )
    9813              :   */
    9814          330 :               M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, paramtok);  /* Procedure  */
    9815              :               /* x^  */
    9816          330 :               M2Quads_PushTtok (GetItemPointedTo (PtrSym), paramtok);
    9817          330 :               M2Quads_PushT (static_cast<unsigned int> (1));  /* One parameter  */
    9818          330 :               M2Quads_BuildFunctionCall (false);  /* One parameter  */
    9819          330 :               M2Quads_PopT (&SizeSym);
    9820          330 :               M2Quads_PushTtok (ProcSym, combinedtok);  /* DEALLOCATE  */
    9821          330 :               M2Quads_PushTtok (PtrSym, paramtok);  /* x  */
    9822          330 :               M2Quads_PushTtok (SizeSym, paramtok);  /* TSIZE(x^)  */
    9823          330 :               M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
    9824          330 :               M2Quads_BuildProcedureCall (combinedtok);  /* Two parameters  */
    9825              :             }
    9826              :           else
    9827              :             {
    9828            0 :               M2MetaError_MetaErrorT1 (paramtok, (const char *) "argument to {%EkDISPOSE} must be a pointer, seen {%1Ed} {%1&s}", 62, PtrSym);
    9829              :             }
    9830              :         }
    9831              :       else
    9832              :         {
    9833            0 :           M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}DEALLOCATE procedure not found for DISPOSE substitution", 59);
    9834              :         }
    9835              :     }
    9836              :   else
    9837              :     {
    9838            0 :       M2MetaError_MetaErrorT0 (functok, (const char *) "the pseudo procedure {%EkDISPOSE} has one or more parameters", 60);
    9839              :     }
    9840          330 :   M2Quads_PopN (NoOfParam+1);
    9841          330 : }
    9842              : 
    9843              : 
    9844              : /*
    9845              :    CheckRangeIncDec - performs des := des <tok> expr
    9846              :                       with range checking (if enabled).
    9847              : 
    9848              :                                Stack
    9849              :                       Entry              Exit
    9850              : 
    9851              :                                      +------------+
    9852              :                       empty          | des + expr |
    9853              :                                      |------------|
    9854              : */
    9855              : 
    9856        17859 : static void CheckRangeIncDec (unsigned int tokenpos, unsigned int des, unsigned int expr, NameKey_Name tok)
    9857              : {
    9858        17859 :   unsigned int dtype;
    9859        17859 :   unsigned int etype;
    9860              : 
    9861        17859 :   dtype = SymbolTable_GetDType (des);
    9862        17859 :   etype = SymbolTable_GetDType (expr);
    9863        17859 :   if ((etype == SymbolTable_NulSym) && (SymbolTable_IsPointer (SymbolTable_GetTypeMode (des))))
    9864              :     {
    9865           24 :       expr = ConvertToAddress (tokenpos, expr);
    9866           24 :       etype = M2System_Address;
    9867              :     }
    9868        17859 :   if (M2Options_WholeValueChecking && ! MustNotCheckBounds)
    9869              :     {
    9870              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    9871         1488 :       if (tok == M2Reserved_PlusTok)
    9872              :         {
    9873          804 :           BuildRange (M2Range_InitIncRangeCheck (des, expr));
    9874              :         }
    9875              :       else
    9876              :         {
    9877          684 :           BuildRange (M2Range_InitDecRangeCheck (des, expr));
    9878              :         }
    9879              :     }
    9880        17859 :   if (M2Base_IsExpressionCompatible (dtype, etype))
    9881              :     {
    9882              :       /* the easy case simulate a straightforward macro  */
    9883        16389 :       M2Quads_PushTFtok (des, dtype, tokenpos);
    9884        16389 :       M2Quads_PushT (tok);
    9885        16389 :       M2Quads_PushTFtok (expr, etype, tokenpos);
    9886        16389 :       doBuildBinaryOp (false, true);
    9887              :     }
    9888              :   else
    9889              :     {
    9890         1470 :       if ((((M2Base_IsOrdinalType (dtype)) || (dtype == M2System_Address)) || (SymbolTable_IsPointer (dtype))) && (((M2Base_IsOrdinalType (etype)) || (etype == M2System_Address)) || (SymbolTable_IsPointer (etype))))
    9891              :         {
    9892         1470 :           M2Quads_PushTFtok (des, dtype, tokenpos);
    9893         1470 :           M2Quads_PushT (tok);
    9894         1470 :           M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tokenpos);
    9895         1470 :           M2Quads_PushTtok (dtype, tokenpos);
    9896         1470 :           M2Quads_PushTtok (expr, tokenpos);
    9897         1470 :           M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
    9898         1470 :           BuildConvertFunction (M2Base_Convert, false);  /* Two parameters  */
    9899         1470 :           doBuildBinaryOp (false, true);
    9900              :         }
    9901              :       else
    9902              :         {
    9903            0 :           if (tok == M2Reserved_PlusTok)
    9904              :             {
    9905            0 :               M2MetaError_MetaError0 ((const char *) "cannot perform {%EkINC} using non ordinal types", 47);
    9906              :             }
    9907              :           else
    9908              :             {
    9909            0 :               M2MetaError_MetaError0 ((const char *) "cannot perform {%EkDEC} using non ordinal types", 47);
    9910              :             }
    9911            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (tokenpos, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym), static_cast<unsigned int> (SymbolTable_NulSym), tokenpos);
    9912              :         }
    9913              :     }
    9914        17859 : }
    9915              : 
    9916              : 
    9917              : /*
    9918              :    BuildIncProcedure - builds the pseudo procedure call INC.
    9919              :                        INC is a procedure which increments a variable.
    9920              :                        It takes one or two parameters:
    9921              :                        INC(a, b)  or  INC(a)
    9922              :                        a := a+b   or  a := a+1
    9923              : 
    9924              :                        The Stack:
    9925              : 
    9926              : 
    9927              :                        Entry                      Exit
    9928              : 
    9929              :                 Ptr ->
    9930              :                        +----------------+
    9931              :                        | NoOfParam      |
    9932              :                        |----------------|
    9933              :                        | Param 1        |
    9934              :                        |----------------|
    9935              :                        | Param 2        |
    9936              :                        |----------------|
    9937              :                        .                .
    9938              :                        .                .
    9939              :                        .                .
    9940              :                        |----------------|
    9941              :                        | Param #        |
    9942              :                        |----------------|
    9943              :                        | ProcSym | Type |         Empty
    9944              :                        |----------------|
    9945              : */
    9946              : 
    9947        13996 : static void BuildIncProcedure (unsigned int proctok)
    9948              : {
    9949        13996 :   unsigned int vartok;
    9950        13996 :   unsigned int NoOfParam;
    9951        13996 :   unsigned int dtype;
    9952        13996 :   unsigned int OperandSym;
    9953        13996 :   unsigned int VarSym;
    9954        13996 :   unsigned int TempSym;
    9955              : 
    9956        13996 :   M2Quads_PopT (&NoOfParam);
    9957        13996 :   if ((NoOfParam == 1) || (NoOfParam == 2))
    9958              :     {
    9959        13996 :       VarSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));  /* Bottom/first parameter.  */
    9960        13996 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam));  /* Bottom/first parameter.  */
    9961        13996 :       if (SymbolTable_IsVar (VarSym))
    9962              :         {
    9963        13995 :           dtype = SymbolTable_GetDType (VarSym);
    9964        13995 :           if (NoOfParam == 2)
    9965              :             {
    9966         2731 :               OperandSym = DereferenceLValue (proctok, M2Quads_OperandT (1));
    9967              :             }
    9968              :           else
    9969              :             {
    9970        11264 :               PushOne (proctok, dtype, (const char *) "the {%EkINC} will cause an overflow {%1ad}", 42);
    9971        11264 :               M2Quads_PopT (&OperandSym);
    9972              :             }
    9973        13995 :           M2Quads_PushTtok (VarSym, vartok);
    9974        13995 :           TempSym = DereferenceLValue (vartok, VarSym);
    9975        13995 :           CheckRangeIncDec (proctok, TempSym, OperandSym, M2Reserved_PlusTok);  /* TempSym + OperandSym.  */
    9976        13995 :           BuildAssignmentWithoutBounds (proctok, false, true);  /* VarSym := TempSym + OperandSym.  */
    9977              :         }
    9978              :       else
    9979              :         {
    9980            1 :           M2MetaError_MetaErrorT1 (vartok, (const char *) "base procedure {%EkINC} expects a variable as a parameter but was given {%1Ed} {%1&s}", 85, VarSym);
    9981              :         }
    9982              :     }
    9983              :   else
    9984              :     {
    9985            0 :       M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkINC} expects 1 or 2 parameters", 53);
    9986              :     }
    9987        13996 :   M2Quads_PopN (NoOfParam+1);
    9988        13996 : }
    9989              : 
    9990              : 
    9991              : /*
    9992              :    BuildDecProcedure - builds the pseudo procedure call DEC.
    9993              :                        DEC is a procedure which decrements a variable.
    9994              :                        It takes one or two parameters:
    9995              :                        DEC(a, b)  or  DEC(a)
    9996              :                        a := a-b   or  a := a-1
    9997              : 
    9998              :                        The Stack:
    9999              : 
   10000              : 
   10001              :                        Entry                      Exit
   10002              : 
   10003              :                 Ptr ->
   10004              :                        +----------------+
   10005              :                        | NoOfParam      |
   10006              :                        |----------------|
   10007              :                        | Param 1        |
   10008              :                        |----------------|
   10009              :                        | Param 2        |
   10010              :                        |----------------|
   10011              :                        .                .
   10012              :                        .                .
   10013              :                        .                .
   10014              :                        |----------------|
   10015              :                        | Param #        |
   10016              :                        |----------------|
   10017              :                        | ProcSym | Type |         Empty
   10018              :                        |----------------|
   10019              : */
   10020              : 
   10021         3865 : static void BuildDecProcedure (unsigned int proctok)
   10022              : {
   10023         3865 :   unsigned int vartok;
   10024         3865 :   unsigned int NoOfParam;
   10025         3865 :   unsigned int dtype;
   10026         3865 :   unsigned int OperandSym;
   10027         3865 :   unsigned int VarSym;
   10028         3865 :   unsigned int TempSym;
   10029              : 
   10030         3865 :   M2Quads_PopT (&NoOfParam);
   10031         3865 :   if ((NoOfParam == 1) || (NoOfParam == 2))
   10032              :     {
   10033         3865 :       VarSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));  /* Bottom/first parameter.  */
   10034         3865 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam));  /* Bottom/first parameter.  */
   10035         3865 :       if (SymbolTable_IsVar (VarSym))
   10036              :         {
   10037         3864 :           dtype = SymbolTable_GetDType (VarSym);
   10038         3864 :           if (NoOfParam == 2)
   10039              :             {
   10040         1361 :               OperandSym = DereferenceLValue (proctok, M2Quads_OperandT (1));
   10041              :             }
   10042              :           else
   10043              :             {
   10044         2503 :               PushOne (proctok, dtype, (const char *) "the {%EkDEC} will cause an overflow {%1ad}", 42);
   10045         2503 :               M2Quads_PopT (&OperandSym);
   10046              :             }
   10047         3864 :           M2Quads_PushTtok (VarSym, vartok);
   10048         3864 :           TempSym = DereferenceLValue (vartok, VarSym);
   10049         3864 :           CheckRangeIncDec (proctok, TempSym, OperandSym, M2Reserved_MinusTok);  /* TempSym - OperandSym.  */
   10050         3864 :           BuildAssignmentWithoutBounds (proctok, false, true);  /* VarSym := TempSym - OperandSym.  */
   10051              :         }
   10052              :       else
   10053              :         {
   10054            1 :           M2MetaError_MetaErrorT1 (vartok, (const char *) "base procedure {%EkDEC} expects a variable as a parameter but was given {%1Ed} {%1&s}", 85, VarSym);
   10055              :         }
   10056              :     }
   10057              :   else
   10058              :     {
   10059            0 :       M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkDEC} expects 1 or 2 parameters", 53);
   10060              :     }
   10061         3865 :   M2Quads_PopN (NoOfParam+1);
   10062         3865 : }
   10063              : 
   10064              : 
   10065              : /*
   10066              :    DereferenceLValue - checks to see whether, operand, is declare as an LValue
   10067              :                        and if so it dereferences it.
   10068              : */
   10069              : 
   10070        30073 : static unsigned int DereferenceLValue (unsigned int tok, unsigned int operand)
   10071              : {
   10072        30073 :   unsigned int sym;
   10073              : 
   10074        30073 :   if ((SymbolTable_GetMode (operand)) == SymbolTable_LeftValue)
   10075              :     {
   10076              :       /* dereference the pointer  */
   10077         1442 :       sym = SymbolTable_MakeTemporary (tok, AreConstant (SymbolTable_IsConst (operand)));
   10078          721 :       SymbolTable_PutVar (sym, SymbolTable_GetSType (operand));
   10079          721 :       M2Quads_PushTtok (sym, tok);
   10080          721 :       M2Quads_PushTtok (operand, tok);
   10081          721 :       BuildAssignmentWithoutBounds (tok, false, true);
   10082          721 :       return sym;
   10083              :     }
   10084              :   else
   10085              :     {
   10086              :       return operand;
   10087              :     }
   10088              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   10089              :   __builtin_unreachable ();
   10090              : }
   10091              : 
   10092              : 
   10093              : /*
   10094              :    BuildInclProcedure - builds the pseudo procedure call INCL.
   10095              :                         INCL is a procedure which adds bit b into a BITSET a.
   10096              :                         It takes two parameters:
   10097              :                         INCL(a, b)
   10098              : 
   10099              :                         a := a + {b}
   10100              : 
   10101              :                         The Stack:
   10102              : 
   10103              : 
   10104              :                         Entry                      Exit
   10105              : 
   10106              :                  Ptr ->
   10107              :                         +----------------+
   10108              :                         | NoOfParam      |
   10109              :                         |----------------|
   10110              :                         | Param 1        |
   10111              :                         |----------------|
   10112              :                         | Param 2        |
   10113              :                         |----------------|
   10114              :                         | ProcSym | Type |         Empty
   10115              :                         |----------------|
   10116              : */
   10117              : 
   10118         1112 : static void BuildInclProcedure (unsigned int proctok)
   10119              : {
   10120         1112 :   unsigned int vartok;
   10121         1112 :   unsigned int optok;
   10122         1112 :   unsigned int NoOfParam;
   10123         1112 :   unsigned int DerefSym;
   10124         1112 :   unsigned int OperandSym;
   10125         1112 :   unsigned int VarSym;
   10126              : 
   10127         1112 :   M2Quads_PopT (&NoOfParam);
   10128         1112 :   if (NoOfParam == 2)
   10129              :     {
   10130         1112 :       VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
   10131         1112 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
   10132         1112 :       MarkArrayWritten (M2Quads_OperandA (2));
   10133         1112 :       OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
   10134         1112 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   10135         1112 :       if (SymbolTable_IsVar (VarSym))
   10136              :         {
   10137         1105 :           if (SymbolTable_IsSet (SymbolTable_GetDType (VarSym)))
   10138              :             {
   10139         1105 :               DerefSym = DereferenceLValue (optok, OperandSym);
   10140         1105 :               BuildRange (M2Range_InitInclCheck (VarSym, DerefSym));
   10141         1105 :               GenQuadO (proctok, M2Quads_InclOp, VarSym, SymbolTable_NulSym, DerefSym, false);
   10142              :             }
   10143              :           else
   10144              :             {
   10145            0 :               M2MetaError_MetaErrorT1 (vartok, (const char *) "the first parameter to {%EkINCL} must be a set variable, seen {%1Ed} {%1&s}", 75, VarSym);
   10146              :             }
   10147              :         }
   10148              :       else
   10149              :         {
   10150            7 :           M2MetaError_MetaErrorT1 (vartok, (const char *) "base procedure {%EkINCL} expects a variable as a parameter, seen {%1Ed} {%1&s}", 78, VarSym);
   10151              :         }
   10152              :     }
   10153              :   else
   10154              :     {
   10155            0 :       M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkINCL} expects 1 or 2 parameters", 54);
   10156              :     }
   10157         1112 :   M2Quads_PopN (NoOfParam+1);
   10158         1112 : }
   10159              : 
   10160              : 
   10161              : /*
   10162              :    BuildExclProcedure - builds the pseudo procedure call EXCL.
   10163              :                         INCL is a procedure which removes bit b from SET a.
   10164              :                         It takes two parameters:
   10165              :                         EXCL(a, b)
   10166              : 
   10167              :                         a := a - {b}
   10168              : 
   10169              :                         The Stack:
   10170              : 
   10171              : 
   10172              :                         Entry                      Exit
   10173              : 
   10174              :                  Ptr ->
   10175              :                         +----------------+
   10176              :                         | NoOfParam      |
   10177              :                         |----------------|
   10178              :                         | Param 1        |
   10179              :                         |----------------|
   10180              :                         | Param 2        |
   10181              :                         |----------------|
   10182              :                         | ProcSym | Type |         Empty
   10183              :                         |----------------|
   10184              : */
   10185              : 
   10186          766 : static void BuildExclProcedure (unsigned int proctok)
   10187              : {
   10188          766 :   unsigned int vartok;
   10189          766 :   unsigned int optok;
   10190          766 :   unsigned int NoOfParam;
   10191          766 :   unsigned int DerefSym;
   10192          766 :   unsigned int OperandSym;
   10193          766 :   unsigned int VarSym;
   10194              : 
   10195          766 :   M2Quads_PopT (&NoOfParam);
   10196          766 :   if (NoOfParam == 2)
   10197              :     {
   10198          766 :       VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
   10199          766 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
   10200          766 :       MarkArrayWritten (M2Quads_OperandA (2));
   10201          766 :       OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
   10202          766 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   10203          766 :       if (SymbolTable_IsVar (VarSym))
   10204              :         {
   10205          765 :           if (SymbolTable_IsSet (SymbolTable_GetDType (VarSym)))
   10206              :             {
   10207          765 :               DerefSym = DereferenceLValue (optok, OperandSym);
   10208          765 :               BuildRange (M2Range_InitExclCheck (VarSym, DerefSym));
   10209          765 :               GenQuadO (proctok, M2Quads_ExclOp, VarSym, SymbolTable_NulSym, DerefSym, false);
   10210              :             }
   10211              :           else
   10212              :             {
   10213            0 :               M2MetaError_MetaErrorT1 (vartok, (const char *) "the first parameter to {%EkEXCL} must be a set variable, seen {%1Ed} {%1&s}", 75, VarSym);
   10214              :             }
   10215              :         }
   10216              :       else
   10217              :         {
   10218            1 :           M2MetaError_MetaErrorT1 (vartok, (const char *) "base procedure {%EkEXCL} expects a variable as a parameter, seen {%1Ed} {%1&s}", 78, VarSym);
   10219              :         }
   10220              :     }
   10221              :   else
   10222              :     {
   10223            0 :       M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkEXCL} expects 1 or 2 parameters", 54);
   10224              :     }
   10225          766 :   M2Quads_PopN (NoOfParam+1);
   10226          766 : }
   10227              : 
   10228              : 
   10229              : /*
   10230              :    BuildTypeCoercion - builds the type coersion.
   10231              :                        Modula-2 allows types to be coersed with no runtime
   10232              :                        penility.
   10233              :                        It insists that the TSIZE(t1)=TSIZE(t2) where
   10234              :                        t2 variable := t2(variable of type t1).
   10235              :                        The ReturnVar on the stack is of type t2.
   10236              : 
   10237              :                        The Stack:
   10238              : 
   10239              : 
   10240              :                        Entry                      Exit
   10241              : 
   10242              :                 Ptr ->
   10243              :                        +----------------+
   10244              :                        | NoOfParam      |
   10245              :                        |----------------|
   10246              :                        | Param 1        |
   10247              :                        |----------------|
   10248              :                        | Param 2        |
   10249              :                        |----------------|
   10250              :                        .                .
   10251              :                        .                .
   10252              :                        .                .
   10253              :                        |----------------|
   10254              :                        | Param #        |                        <- Ptr
   10255              :                        |----------------|         +------------+
   10256              :                        | ProcSym | Type |         | ReturnVar  |
   10257              :                        |----------------|         |------------|
   10258              : 
   10259              :                        Quadruples:
   10260              : 
   10261              :                        CoerceOp  ReturnVar  Type  Param1
   10262              : 
   10263              :                        A type coercion will only be legal if the different
   10264              :                        types have exactly the same size.
   10265              :                        Since we can only decide this after M2Eval has processed
   10266              :                        the symbol table then we create a quadruple explaining
   10267              :                        the coercion taking place, the code generator can test
   10268              :                        this assertion and report an error if the type sizes
   10269              :                        differ.
   10270              : */
   10271              : 
   10272         2574 : static void BuildTypeCoercion (bool ConstExpr)
   10273              : {
   10274         2574 :   unsigned int resulttok;
   10275         2574 :   unsigned int proctok;
   10276         2574 :   unsigned int exptok;
   10277         2574 :   unsigned int r;
   10278         2574 :   unsigned int exp;
   10279         2574 :   unsigned int NoOfParam;
   10280         2574 :   unsigned int ReturnVar;
   10281         2574 :   unsigned int ProcSym;
   10282              : 
   10283         2574 :   M2Quads_PopT (&NoOfParam);
   10284         2574 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   10285         2574 :   proctok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   10286         2574 :   if (! (SymbolTable_IsAModula2Type (ProcSym)))
   10287              :     {
   10288            0 :       M2MetaError_MetaError1 ((const char *) "coersion expecting a type, seen {%1Ea} which is {%1Ed} {%1&s}", 61, ProcSym);
   10289              :     }
   10290         2574 :   if (NoOfParam == 1)
   10291              :     {
   10292         2574 :       PopTrwtok (&exp, &r, &exptok);
   10293         2574 :       MarkAsRead (r);
   10294         2574 :       resulttok = M2LexBuf_MakeVirtual2Tok (proctok, exptok);
   10295         2574 :       M2Quads_PopN (1);  /* Pop procedure.  */
   10296         2574 :       if (ConstExprError (ProcSym, exp, exptok, ConstExpr))  /* Pop procedure.  */
   10297              :         {
   10298            0 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
   10299            0 :           SymbolTable_PutVar (ReturnVar, ProcSym);  /* Set ReturnVar's TYPE.  */
   10300              :         }
   10301              :        /* Set ReturnVar's TYPE.  */
   10302         2574 :       else if ((SymbolTable_IsConst (exp)) || (SymbolTable_IsVar (exp)))
   10303              :         {
   10304              :           /* avoid dangling else.  */
   10305         5148 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (SymbolTable_IsConst (exp)));
   10306         2574 :           SymbolTable_PutVar (ReturnVar, ProcSym);  /* Set ReturnVar's TYPE.  */
   10307         2574 :           GenQuad (M2Quads_CoerceOp, ReturnVar, ProcSym, exp);  /* Set ReturnVar's TYPE.  */
   10308              :         }
   10309              :       else
   10310              :         {
   10311              :           /* avoid dangling else.  */
   10312            0 :           M2MetaError_MetaError2 ((const char *) "trying to coerse {%1EMRad} which is not a variable or constant into {%2ad}", 74, exp, ProcSym);
   10313            0 :           M2MetaError_MetaError2 ((const char *) "trying to coerse {%1ECad} which is not a variable or constant into {%2ad}", 73, exp, ProcSym);
   10314            0 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_RightValue);
   10315            0 :           SymbolTable_PutVar (ReturnVar, ProcSym);  /* Set ReturnVar's TYPE.  */
   10316              :         }
   10317         2574 :       M2Quads_PushTFtok (ReturnVar, ProcSym, resulttok);
   10318              :     }
   10319              :   else
   10320              :     {
   10321            0 :       M2MetaError_MetaError0 ((const char *) "{%E}only one parameter expected in a TYPE coersion", 50);
   10322              :     }
   10323         2574 : }
   10324              : 
   10325              : 
   10326              : /*
   10327              :    BuildRealFunctionCall - builds a function call.
   10328              :                            The Stack:
   10329              : 
   10330              : 
   10331              :                            Entry                      Exit
   10332              : 
   10333              :                     Ptr ->
   10334              :                            +----------------+
   10335              :                            | NoOfParam      |
   10336              :                            |----------------|
   10337              :                            | Param 1        |
   10338              :                            |----------------|
   10339              :                            | Param 2        |
   10340              :                            |----------------|
   10341              :                            .                .
   10342              :                            .                .
   10343              :                            .                .
   10344              :                            |----------------|
   10345              :                            | Param #        |                        <- Ptr
   10346              :                            |----------------|         +------------+
   10347              :                            | ProcSym | Type |         | ReturnVar  |
   10348              :                            |----------------|         |------------|
   10349              : */
   10350              : 
   10351        62570 : static void BuildRealFunctionCall (unsigned int tokno, bool ConstExpr)
   10352              : {
   10353        62570 :   unsigned int NoOfParam;
   10354        62570 :   unsigned int ProcSym;
   10355              : 
   10356        62570 :   M2Quads_PopT (&NoOfParam);
   10357        62570 :   M2Quads_PushT (NoOfParam);
   10358        62570 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+2));
   10359        62570 :   ProcSym = PCSymBuild_SkipConst (ProcSym);
   10360        62570 :   if (SymbolTable_IsVar (ProcSym))
   10361              :     {
   10362              :       /* Procedure Variable therefore get its type to see if it is a FOR "C" call.  */
   10363           94 :       ProcSym = SymbolTable_SkipType (M2Quads_OperandF (NoOfParam+2));
   10364              :     }
   10365        62570 :   if ((SymbolTable_IsDefImp (SymbolTable_GetScope (ProcSym))) && (SymbolTable_IsDefinitionForC (SymbolTable_GetScope (ProcSym))))
   10366              :     {
   10367         8552 :       BuildRealFuncProcCall (tokno, true, true, ConstExpr);
   10368              :     }
   10369              :   else
   10370              :     {
   10371        54018 :       BuildRealFuncProcCall (tokno, true, false, ConstExpr);
   10372              :     }
   10373        62558 : }
   10374              : 
   10375              : 
   10376              : /*
   10377              :    BuildPseudoFunctionCall - builds the pseudo function
   10378              :                              The Stack:
   10379              : 
   10380              : 
   10381              :                              Entry                      Exit
   10382              : 
   10383              :                       Ptr ->
   10384              :                              +----------------+
   10385              :                              | NoOfParam      |
   10386              :                              |----------------|
   10387              :                              | Param 1        |
   10388              :                              |----------------|
   10389              :                              | Param 2        |
   10390              :                              |----------------|
   10391              :                              .                .
   10392              :                              .                .
   10393              :                              .                .
   10394              :                              |----------------|
   10395              :                              | Param #        |                        <- Ptr
   10396              :                              |----------------|         +------------+
   10397              :                              | ProcSym | Type |         | ReturnVar  |
   10398              :                              |----------------|         |------------|
   10399              : 
   10400              : */
   10401              : 
   10402        42871 : static void BuildPseudoFunctionCall (bool ConstExpr)
   10403              : {
   10404        42871 :   unsigned int NoOfParam;
   10405        42871 :   unsigned int ProcSym;
   10406              : 
   10407        42871 :   M2Quads_PopT (&NoOfParam);
   10408        42871 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   10409        42871 :   ProcSym = PCSymBuild_SkipConst (ProcSym);
   10410        42871 :   M2Quads_PushT (NoOfParam);
   10411              :   /* Compile time stack restored to entry state.  */
   10412        42871 :   if (ProcSym == M2Base_High)
   10413              :     {
   10414         2976 :       BuildHighFunction ();
   10415              :     }
   10416        39895 :   else if (ProcSym == M2Base_LengthS)
   10417              :     {
   10418              :       /* avoid dangling else.  */
   10419          346 :       BuildLengthFunction (ProcSym, ConstExpr);
   10420              :     }
   10421        39549 :   else if (ProcSym == M2System_Adr)
   10422              :     {
   10423              :       /* avoid dangling else.  */
   10424         9649 :       BuildAdrFunction ();
   10425              :     }
   10426        29900 :   else if (ProcSym == M2Size_Size)
   10427              :     {
   10428              :       /* avoid dangling else.  */
   10429         2097 :       BuildSizeFunction ();
   10430              :     }
   10431        27803 :   else if (ProcSym == M2System_TSize)
   10432              :     {
   10433              :       /* avoid dangling else.  */
   10434         4766 :       BuildTSizeFunction ();
   10435              :     }
   10436        23037 :   else if (ProcSym == M2System_TBitSize)
   10437              :     {
   10438              :       /* avoid dangling else.  */
   10439         6508 :       BuildTBitSizeFunction ();
   10440              :     }
   10441        16529 :   else if (ProcSym == M2Base_Convert)
   10442              :     {
   10443              :       /* avoid dangling else.  */
   10444           12 :       BuildConvertFunction (ProcSym, ConstExpr);
   10445              :     }
   10446        16517 :   else if (ProcSym == M2Base_Odd)
   10447              :     {
   10448              :       /* avoid dangling else.  */
   10449           44 :       BuildOddFunction (ProcSym, ConstExpr);
   10450              :     }
   10451        16473 :   else if (ProcSym == M2Base_Abs)
   10452              :     {
   10453              :       /* avoid dangling else.  */
   10454          177 :       BuildAbsFunction (ProcSym, ConstExpr);
   10455              :     }
   10456        16296 :   else if (ProcSym == M2Base_Cap)
   10457              :     {
   10458              :       /* avoid dangling else.  */
   10459          125 :       BuildCapFunction (ProcSym, ConstExpr);
   10460              :     }
   10461        16171 :   else if (ProcSym == M2Base_Val)
   10462              :     {
   10463              :       /* avoid dangling else.  */
   10464         4922 :       BuildValFunction (ProcSym, ConstExpr);
   10465              :     }
   10466        11249 :   else if (ProcSym == M2Base_Chr)
   10467              :     {
   10468              :       /* avoid dangling else.  */
   10469         1020 :       BuildChrFunction (ProcSym, ConstExpr);
   10470              :     }
   10471        10229 :   else if (M2Base_IsOrd (ProcSym))
   10472              :     {
   10473              :       /* avoid dangling else.  */
   10474         4708 :       BuildOrdFunction (ProcSym, ConstExpr);
   10475              :     }
   10476         5521 :   else if (M2Base_IsInt (ProcSym))
   10477              :     {
   10478              :       /* avoid dangling else.  */
   10479            6 :       BuildIntFunction (ProcSym, ConstExpr);
   10480              :     }
   10481         5515 :   else if (M2Base_IsTrunc (ProcSym))
   10482              :     {
   10483              :       /* avoid dangling else.  */
   10484           60 :       BuildTruncFunction (ProcSym, ConstExpr);
   10485              :     }
   10486         5455 :   else if (M2Base_IsFloat (ProcSym))
   10487              :     {
   10488              :       /* avoid dangling else.  */
   10489           88 :       BuildFloatFunction (ProcSym, ConstExpr);
   10490              :     }
   10491         5367 :   else if (ProcSym == M2Base_Min)
   10492              :     {
   10493              :       /* avoid dangling else.  */
   10494         1248 :       BuildMinFunction ();
   10495              :     }
   10496         4119 :   else if (ProcSym == M2Base_Max)
   10497              :     {
   10498              :       /* avoid dangling else.  */
   10499         2023 :       BuildMaxFunction ();
   10500              :     }
   10501         2096 :   else if (ProcSym == M2System_AddAdr)
   10502              :     {
   10503              :       /* avoid dangling else.  */
   10504           36 :       BuildAddAdrFunction (ProcSym, ConstExpr);
   10505              :     }
   10506         2060 :   else if (ProcSym == M2System_SubAdr)
   10507              :     {
   10508              :       /* avoid dangling else.  */
   10509           12 :       BuildSubAdrFunction (ProcSym, ConstExpr);
   10510              :     }
   10511         2048 :   else if (ProcSym == M2System_DifAdr)
   10512              :     {
   10513              :       /* avoid dangling else.  */
   10514           12 :       BuildDifAdrFunction (ProcSym, ConstExpr);
   10515              :     }
   10516         2036 :   else if (ProcSym == M2System_Cast)
   10517              :     {
   10518              :       /* avoid dangling else.  */
   10519          156 :       BuildCastFunction (ProcSym, ConstExpr);
   10520              :     }
   10521         1880 :   else if (ProcSym == M2System_Shift)
   10522              :     {
   10523              :       /* avoid dangling else.  */
   10524          682 :       BuildShiftFunction ();
   10525              :     }
   10526         1198 :   else if (ProcSym == M2System_Rotate)
   10527              :     {
   10528              :       /* avoid dangling else.  */
   10529          406 :       BuildRotateFunction ();
   10530              :     }
   10531          792 :   else if (ProcSym == M2System_MakeAdr)
   10532              :     {
   10533              :       /* avoid dangling else.  */
   10534           12 :       BuildMakeAdrFunction ();
   10535              :     }
   10536          780 :   else if (ProcSym == M2Base_Re)
   10537              :     {
   10538              :       /* avoid dangling else.  */
   10539           84 :       BuildReFunction (ProcSym, ConstExpr);
   10540              :     }
   10541          696 :   else if (ProcSym == M2Base_Im)
   10542              :     {
   10543              :       /* avoid dangling else.  */
   10544           84 :       BuildImFunction (ProcSym, ConstExpr);
   10545              :     }
   10546          612 :   else if (ProcSym == M2Base_Cmplx)
   10547              :     {
   10548              :       /* avoid dangling else.  */
   10549          612 :       BuildCmplxFunction (ProcSym, ConstExpr);
   10550              :     }
   10551              :   else
   10552              :     {
   10553              :       /* avoid dangling else.  */
   10554            0 :       M2Error_InternalError ((const char *) "pseudo function not implemented yet", 35);
   10555              :     }
   10556        42853 : }
   10557              : 
   10558              : 
   10559              : /*
   10560              :    BuildAddAdrFunction - builds the pseudo procedure call ADDADR.
   10561              : 
   10562              :                          PROCEDURE ADDADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
   10563              : 
   10564              :                          Which returns address given by (addr + offset),
   10565              :                          [ the standard says that it _may_
   10566              :                            "raise an exception if this address is not valid."
   10567              :                            currently we do not generate any exception code ]
   10568              : 
   10569              :                          The Stack:
   10570              : 
   10571              :                          Entry                      Exit
   10572              : 
   10573              :                   Ptr ->
   10574              :                          +----------------+
   10575              :                          | NoOfParam      |
   10576              :                          |----------------|
   10577              :                          | Param 1        |
   10578              :                          |----------------|
   10579              :                          | Param 2        |                        <- Ptr
   10580              :                          |----------------|         +------------+
   10581              :                          | ProcSym | Type |         | ReturnVar  |
   10582              :                          |----------------|         |------------|
   10583              : */
   10584              : 
   10585           36 : static void BuildAddAdrFunction (unsigned int ProcSym, bool ConstExpr)
   10586              : {
   10587           36 :   unsigned int combinedtok;
   10588           36 :   unsigned int functok;
   10589           36 :   unsigned int vartok;
   10590           36 :   unsigned int optok;
   10591           36 :   unsigned int opa;
   10592           36 :   unsigned int ReturnVar;
   10593           36 :   unsigned int NoOfParam;
   10594           36 :   unsigned int OperandSym;
   10595           36 :   unsigned int VarSym;
   10596              : 
   10597           36 :   M2Quads_PopT (&NoOfParam);
   10598           36 :   functok = OperandTtok (NoOfParam+1);
   10599           36 :   if (NoOfParam == 2)
   10600              :     {
   10601           36 :       VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
   10602           36 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
   10603           36 :       OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
   10604           36 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   10605           36 :       combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
   10606           36 :       M2Quads_PopN (NoOfParam+1);
   10607           36 :       if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
   10608              :         {
   10609              :           /* Fake return result.  */
   10610            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
   10611              :         }
   10612           36 :       else if (SymbolTable_IsVar (VarSym))
   10613              :         {
   10614              :           /* avoid dangling else.  */
   10615           36 :           if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
   10616              :             {
   10617           36 :               ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
   10618           36 :               SymbolTable_PutVar (ReturnVar, M2System_Address);
   10619           36 :               opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
   10620           72 :               GenQuadOtok (combinedtok, M2Quads_AddOp, ReturnVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
   10621           36 :               M2Quads_PushTFtok (ReturnVar, M2System_Address, combinedtok);
   10622              :             }
   10623              :           else
   10624              :             {
   10625            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);
   10626            0 :               M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
   10627              :             }
   10628              :         }
   10629              :       else
   10630              :         {
   10631              :           /* avoid dangling else.  */
   10632            0 :           M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure ADDADR expects a variable of type ADDRESS or POINTER as its first parameter", 96);
   10633            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
   10634              :         }
   10635              :     }
   10636              :   else
   10637              :     {
   10638            0 :       M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure {%EkADDADR} expects 2 parameters", 53);
   10639            0 :       M2Quads_PopN (NoOfParam+1);
   10640            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, functok);
   10641              :     }
   10642           36 : }
   10643              : 
   10644              : 
   10645              : /*
   10646              :    BuildSubAdrFunction - builds the pseudo procedure call ADDADR.
   10647              : 
   10648              :                          PROCEDURE SUBADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
   10649              : 
   10650              :                          Which returns address given by (addr - offset),
   10651              :                          [ the standard says that it _may_
   10652              :                            "raise an exception if this address is not valid."
   10653              :                            currently we do not generate any exception code ]
   10654              : 
   10655              :                          The Stack:
   10656              : 
   10657              :                          Entry                      Exit
   10658              : 
   10659              :                   Ptr ->
   10660              :                          +----------------+
   10661              :                          | NoOfParam      |
   10662              :                          |----------------|
   10663              :                          | Param 1        |
   10664              :                          |----------------|
   10665              :                          | Param 2        |                        <- Ptr
   10666              :                          |----------------|         +------------+
   10667              :                          | ProcSym | Type |         | ReturnVar  |
   10668              :                          |----------------|         |------------|
   10669              : */
   10670              : 
   10671           12 : static void BuildSubAdrFunction (unsigned int ProcSym, bool ConstExpr)
   10672              : {
   10673           12 :   unsigned int functok;
   10674           12 :   unsigned int combinedtok;
   10675           12 :   unsigned int optok;
   10676           12 :   unsigned int vartok;
   10677           12 :   unsigned int ReturnVar;
   10678           12 :   unsigned int NoOfParam;
   10679           12 :   unsigned int OperandSym;
   10680           12 :   unsigned int opa;
   10681           12 :   unsigned int VarSym;
   10682              : 
   10683           12 :   M2Quads_PopT (&NoOfParam);
   10684           12 :   functok = OperandTtok (NoOfParam+1);
   10685           12 :   if (NoOfParam == 2)
   10686              :     {
   10687           12 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   10688           12 :       OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
   10689           12 :       VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
   10690           12 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
   10691           12 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
   10692           12 :       M2Quads_PopN (NoOfParam+1);
   10693           12 :       if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
   10694              :         {
   10695              :           /* Fake return result.  */
   10696            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
   10697              :         }
   10698           12 :       else if (SymbolTable_IsVar (VarSym))
   10699              :         {
   10700              :           /* avoid dangling else.  */
   10701           12 :           if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
   10702              :             {
   10703           12 :               ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
   10704           12 :               SymbolTable_PutVar (ReturnVar, M2System_Address);
   10705           12 :               opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
   10706           24 :               GenQuadOtok (combinedtok, M2Quads_SubOp, ReturnVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
   10707           12 :               M2Quads_PushTFtok (ReturnVar, M2System_Address, combinedtok);
   10708              :             }
   10709              :           else
   10710              :             {
   10711            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);
   10712            0 :               M2Quads_PushTFtok (SymbolTable_MakeConstLit (vartok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, vartok);
   10713              :             }
   10714              :         }
   10715              :       else
   10716              :         {
   10717              :           /* avoid dangling else.  */
   10718            0 :           combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
   10719            0 :           M2MetaError_MetaErrorT0 (combinedtok, (const char *) "{%E}SYSTEM procedure {%EkSUBADR} expects a variable of type ADDRESS or POINTER as its first parameter", 101);
   10720            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
   10721              :         }
   10722              :     }
   10723              :   else
   10724              :     {
   10725            0 :       M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure {%EkSUBADR} expects 2 parameters", 53);
   10726            0 :       M2Quads_PopN (NoOfParam+1);
   10727            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, functok);
   10728              :     }
   10729           12 : }
   10730              : 
   10731              : 
   10732              : /*
   10733              :    BuildDifAdrFunction - builds the pseudo procedure call DIFADR.
   10734              : 
   10735              :                          PROCEDURE DIFADR (addr1, addr2: ADDRESS): INTEGER ;
   10736              : 
   10737              :                          Which returns address given by (addr1 - addr2),
   10738              :                          [ the standard says that it _may_
   10739              :                            "raise an exception if this address is invalid or
   10740              :                             address space is non-contiguous."
   10741              :                            currently we do not generate any exception code ]
   10742              : 
   10743              :                          The Stack:
   10744              : 
   10745              :                          Entry                      Exit
   10746              : 
   10747              :                   Ptr ->
   10748              :                          +----------------+
   10749              :                          | NoOfParam      |
   10750              :                          |----------------|
   10751              :                          | Param 1        |
   10752              :                          |----------------|
   10753              :                          | Param 2        |                        <- Ptr
   10754              :                          |----------------|         +------------+
   10755              :                          | ProcSym | Type |         | ReturnVar  |
   10756              :                          |----------------|         |------------|
   10757              : */
   10758              : 
   10759           12 : static void BuildDifAdrFunction (unsigned int ProcSym, bool ConstExpr)
   10760              : {
   10761           12 :   unsigned int functok;
   10762           12 :   unsigned int optok;
   10763           12 :   unsigned int vartok;
   10764           12 :   unsigned int combinedtok;
   10765           12 :   unsigned int TempVar;
   10766           12 :   unsigned int NoOfParam;
   10767           12 :   unsigned int OperandSym;
   10768           12 :   unsigned int opa;
   10769           12 :   unsigned int VarSym;
   10770              : 
   10771           12 :   M2Quads_PopT (&NoOfParam);
   10772           12 :   functok = OperandTtok (NoOfParam+1);
   10773           12 :   if (NoOfParam >= 1)
   10774              :     {
   10775           12 :       OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
   10776           12 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   10777              :     }
   10778              :   else
   10779              :     {
   10780              :       optok = functok;
   10781              :     }
   10782           12 :   if (NoOfParam == 2)
   10783              :     {
   10784           12 :       VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
   10785           12 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
   10786           12 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
   10787           12 :       M2Quads_PopN (NoOfParam+1);
   10788           12 :       if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
   10789              :         {
   10790              :           /* Fake return result.  */
   10791            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
   10792              :         }
   10793           12 :       else if (SymbolTable_IsVar (VarSym))
   10794              :         {
   10795              :           /* avoid dangling else.  */
   10796           12 :           if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
   10797              :             {
   10798           12 :               if ((IsReallyPointer (OperandSym)) || ((SymbolTable_GetSType (OperandSym)) == M2System_Address))
   10799              :                 {
   10800           12 :                   TempVar = SymbolTable_MakeTemporary (vartok, SymbolTable_RightValue);
   10801           12 :                   SymbolTable_PutVar (TempVar, M2System_Address);
   10802           12 :                   opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
   10803           24 :                   GenQuadOtok (combinedtok, M2Quads_SubOp, TempVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
   10804              :                   /* 
   10805              :                   Build macro: CONVERT( INTEGER, TempVar )
   10806              :   */
   10807           12 :                   M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
   10808           12 :                   M2Quads_PushTtok (M2Base_Integer, functok);
   10809           12 :                   M2Quads_PushTtok (TempVar, vartok);
   10810           12 :                   M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
   10811           12 :                   BuildConvertFunction (M2Base_Convert, ConstExpr);  /* Two parameters  */
   10812              :                 }
   10813              :               else
   10814              :                 {
   10815            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);
   10816            0 :                   M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
   10817              :                 }
   10818              :             }
   10819              :           else
   10820              :             {
   10821            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);
   10822            0 :               M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
   10823              :             }
   10824              :         }
   10825              :       else
   10826              :         {
   10827              :           /* avoid dangling else.  */
   10828            0 :           M2MetaError_MetaError0 ((const char *) "{%E}SYSTEM procedure {%EkDIFADR} expects a variable of type ADDRESS or POINTER as its first parameter", 101);
   10829            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
   10830              :         }
   10831              :     }
   10832              :   else
   10833              :     {
   10834            0 :       combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
   10835            0 :       M2MetaError_MetaErrorT0 (combinedtok, (const char *) "{%E}SYSTEM procedure {%EkDIFADR} expects 2 parameters", 53);
   10836            0 :       M2Quads_PopN (NoOfParam+1);
   10837            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
   10838              :     }
   10839           12 : }
   10840              : 
   10841              : 
   10842              : /*
   10843              :    BuildHighFunction - checks the stack in preparation for generating
   10844              :                        quadruples which perform HIGH.
   10845              :                        This procedure does not alter the stack but
   10846              :                        determines whether, a, in HIGH(a) is an ArraySym
   10847              :                        or UnboundedSym.
   10848              :                        Both cases are different and appropriate quadruple
   10849              :                        generating routines are called.
   10850              : 
   10851              :                        The Stack:
   10852              : 
   10853              : 
   10854              :                        Entry                      Exit
   10855              : 
   10856              :                 Ptr ->
   10857              :                        +----------------+
   10858              :                        | NoOfParam      |
   10859              :                        |----------------|
   10860              :                        | Param 1        |
   10861              :                        |----------------|
   10862              :                        | Param 2        |
   10863              :                        |----------------|
   10864              :                        .                .
   10865              :                        .                .
   10866              :                        .                .
   10867              :                        |----------------|
   10868              :                        | Param #        |                        <- Ptr
   10869              :                        |----------------|         +------------+
   10870              :                        | ProcSym | Type |         | ReturnVar  |
   10871              :                        |----------------|         |------------|
   10872              : 
   10873              : */
   10874              : 
   10875         2976 : static void BuildHighFunction (void)
   10876              : {
   10877         2976 :   unsigned int functok;
   10878         2976 :   unsigned int combinedtok;
   10879         2976 :   unsigned int paramtok;
   10880         2976 :   unsigned int ProcSym;
   10881         2976 :   unsigned int Type;
   10882         2976 :   unsigned int NoOfParam;
   10883         2976 :   unsigned int Param;
   10884              : 
   10885         2976 :   M2Quads_PopT (&NoOfParam);
   10886         2976 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   10887         2976 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   10888         2976 :   BuildSizeCheckEnd (ProcSym);  /* quadruple generation now on  */
   10889         2976 :   if (NoOfParam == 1)  /* quadruple generation now on  */
   10890              :     {
   10891         2976 :       Param = static_cast<unsigned int> (M2Quads_OperandT (1));
   10892         2976 :       paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   10893         2976 :       combinedtok = M2LexBuf_MakeVirtualTok (paramtok, functok, paramtok);
   10894         2976 :       Type = SymbolTable_GetDType (Param);
   10895              :       /* Restore stack to original form  */
   10896         2976 :       M2Quads_PushT (NoOfParam);
   10897         2976 :       if (((! (SymbolTable_IsVar (Param))) && (! (SymbolTable_IsConstString (Param)))) && (! (SymbolTable_IsConst (Param))))
   10898              :         {
   10899              :           /* we cannot test for IsConst(Param) AND (GetSType(Param)=Char)  as the type might not be assigned yet  */
   10900            0 :           M2MetaError_MetaError1 ((const char *) "base procedure {%EkHIGH} expects a variable or string constant as its parameter {%1d:rather than {%1d}} {%1asa}", 111, Param);
   10901              :         }
   10902         2976 :       else if ((Type != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (Type)))
   10903              :         {
   10904              :           /* avoid dangling else.  */
   10905         2743 :           BuildHighFromUnbounded (combinedtok);
   10906              :         }
   10907              :       else
   10908              :         {
   10909              :           /* avoid dangling else.  */
   10910          233 :           BuildConstHighFromSym (combinedtok);
   10911              :         }
   10912              :     }
   10913              :   else
   10914              :     {
   10915            0 :       M2MetaError_MetaError0 ((const char *) "base procedure {%EkHIGH} requires one parameter", 47);
   10916            0 :       M2Quads_PopN (2);
   10917            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
   10918              :     }
   10919         2976 : }
   10920              : 
   10921              : 
   10922              : /*
   10923              :    BuildConstHighFromSym - builds the pseudo function HIGH from an Sym.
   10924              :                            Sym is a constant or an array which has constant bounds
   10925              :                            and therefore it can be calculated at compile time.
   10926              : 
   10927              :                            The Stack:
   10928              : 
   10929              : 
   10930              :                            Entry                      Exit
   10931              : 
   10932              :                    Ptr ->
   10933              :                            +----------------+
   10934              :                            | NoOfParam      |
   10935              :                            |----------------|
   10936              :                            | Param 1        |
   10937              :                            |----------------|
   10938              :                            | Param 2        |
   10939              :                            |----------------|
   10940              :                            .                .
   10941              :                            .                .
   10942              :                            .                .
   10943              :                            |----------------|
   10944              :                            | Param #        |                        <- Ptr
   10945              :                            |----------------|         +------------+
   10946              :                            | ProcSym | Type |         | ReturnVar  |
   10947              :                            |----------------|         |------------|
   10948              : */
   10949              : 
   10950          233 : static void BuildConstHighFromSym (unsigned int tok)
   10951              : {
   10952          233 :   unsigned int NoOfParam;
   10953          233 :   unsigned int ReturnVar;
   10954              : 
   10955          233 :   M2Quads_PopT (&NoOfParam);
   10956          233 :   ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
   10957          233 :   SymbolTable_PutConst (ReturnVar, M2Base_Cardinal);
   10958          233 :   GenHigh (tok, ReturnVar, 1, M2Quads_OperandT (1));
   10959          233 :   M2Quads_PopN (NoOfParam+1);
   10960          233 :   M2Quads_PushTtok (ReturnVar, tok);
   10961          233 : }
   10962              : 
   10963              : 
   10964              : /*
   10965              :    BuildHighFromUnbounded - builds the pseudo function HIGH from an
   10966              :                             UnboundedSym.
   10967              : 
   10968              :                             The Stack:
   10969              : 
   10970              : 
   10971              :                             Entry                      Exit
   10972              : 
   10973              :                      Ptr ->
   10974              :                             +----------------+
   10975              :                             | NoOfParam      |
   10976              :                             |----------------|
   10977              :                             | Param #        |                        <- Ptr
   10978              :                             |----------------|         +------------+
   10979              :                             | ProcSym | Type |         | ReturnVar  |
   10980              :                             |----------------|         |------------|
   10981              : 
   10982              : */
   10983              : 
   10984         2743 : static void BuildHighFromUnbounded (unsigned int tok)
   10985              : {
   10986         2743 :   unsigned int Dim;
   10987         2743 :   unsigned int NoOfParam;
   10988         2743 :   unsigned int ReturnVar;
   10989              : 
   10990         2743 :   M2Quads_PopT (&NoOfParam);
   10991         2743 :   M2Debug_Assert (NoOfParam == 1);
   10992         2743 :   ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
   10993         2743 :   SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
   10994         2743 :   Dim = static_cast<unsigned int> (OperandD (1));
   10995         2743 :   Dim += 1;
   10996         2743 :   if (Dim > 1)
   10997              :     {
   10998           36 :       GenHigh (tok, ReturnVar, Dim, M2Quads_OperandA (1));
   10999              :     }
   11000              :   else
   11001              :     {
   11002         2707 :       GenHigh (tok, ReturnVar, Dim, M2Quads_OperandT (1));
   11003              :     }
   11004         2743 :   M2Quads_PopN (2);
   11005         2743 :   M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), tok);
   11006         2743 : }
   11007              : 
   11008              : 
   11009              : /*
   11010              :    GetQualidentImport - returns the symbol as if it were qualified from, module.n.
   11011              :                         This is used to reference runtime support procedures and an
   11012              :                         error is generated if the symbol cannot be obtained.
   11013              : */
   11014              : 
   11015        46971 : static unsigned int GetQualidentImport (unsigned int tokno, NameKey_Name n, NameKey_Name module)
   11016              : {
   11017        46971 :   unsigned int sym;
   11018        46971 :   unsigned int ModSym;
   11019              : 
   11020        46971 :   ModSym = M2Batch_MakeDefinitionSource (tokno, module);
   11021        46971 :   if (ModSym == SymbolTable_NulSym)
   11022              :     {
   11023            0 :       M2MetaError_MetaErrorNT2 (tokno, (const char *) "module %a cannot be found and is needed to import %a", 52, module, n);
   11024            0 :       M2Error_FlushErrors ();
   11025            0 :       return SymbolTable_NulSym;
   11026              :     }
   11027        46971 :   M2Debug_Assert (SymbolTable_IsDefImp (ModSym));
   11028        46971 :   if (((SymbolTable_GetExported (tokno, ModSym, n)) == SymbolTable_NulSym) || (SymbolTable_IsUnknown (SymbolTable_GetExported (tokno, ModSym, n))))
   11029              :     {
   11030            0 :       sym = SymbolTable_GetExported (tokno, ModSym, n);
   11031            0 :       if (SymbolTable_IsUnknown (sym))
   11032              :         {
   11033              :           /* Spellcheck.  */
   11034            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);
   11035            0 :           M2MetaError_MetaErrorT1 (tokno, (const char *) "unknown symbol {%1&s}", 21, sym);
   11036            0 :           SymbolTable_UnknownReported (sym);
   11037              :         }
   11038              :       else
   11039              :         {
   11040            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);
   11041              :         }
   11042            0 :       M2Error_FlushErrors ();
   11043            0 :       return SymbolTable_NulSym;
   11044              :     }
   11045        46971 :   return SymbolTable_GetExported (tokno, M2Batch_MakeDefinitionSource (tokno, module), n);
   11046              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   11047              :   __builtin_unreachable ();
   11048              : }
   11049              : 
   11050              : 
   11051              : /*
   11052              :    ConstExprError - return TRUE if a constant expression is being built and Var is a variable.
   11053              : */
   11054              : 
   11055        72164 : static bool ConstExprError (unsigned int Func, unsigned int Var, unsigned int optok, bool ConstExpr)
   11056              : {
   11057        72164 :   if (ConstExpr && (SymbolTable_IsVar (Var)))
   11058              :     {
   11059          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);
   11060          108 :       return true;
   11061              :     }
   11062              :   else
   11063              :     {
   11064              :       return false;
   11065              :     }
   11066              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   11067              :   __builtin_unreachable ();
   11068              : }
   11069              : 
   11070              : 
   11071              : /*
   11072              :    DeferMakeLengthConst - creates a constant which contains the length of string, sym.
   11073              : */
   11074              : 
   11075           66 : static unsigned int DeferMakeLengthConst (unsigned int tok, unsigned int sym)
   11076              : {
   11077           66 :   unsigned int const_;
   11078              : 
   11079           66 :   const_ = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
   11080           66 :   SymbolTable_PutVar (const_, M2Base_ZType);
   11081          132 :   GenQuadO (tok, M2Quads_StringLengthOp, const_, 0, sym, false);
   11082           66 :   return const_;
   11083              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   11084              :   __builtin_unreachable ();
   11085              : }
   11086              : 
   11087              : 
   11088              : /*
   11089              :    BuildLengthFunction - builds the inline standard function LENGTH.
   11090              : 
   11091              :                          The Stack:
   11092              : 
   11093              : 
   11094              :                          Entry                      Exit
   11095              : 
   11096              :                   Ptr ->
   11097              :                          +----------------+
   11098              :                          | NoOfParam      |
   11099              :                          |----------------|
   11100              :                          | Param 1        |                        <- Ptr
   11101              :                          |----------------|         +------------+
   11102              :                          | ProcSym | Type |         | ReturnVar  |
   11103              :                          |----------------|         |------------|
   11104              : 
   11105              : */
   11106              : 
   11107          346 : static void BuildLengthFunction (unsigned int Function, bool ConstExpr)
   11108              : {
   11109          346 :   unsigned int combinedtok;
   11110          346 :   unsigned int paramtok;
   11111          346 :   unsigned int functok;
   11112          346 :   unsigned int ProcSym;
   11113          346 :   unsigned int Type;
   11114          346 :   unsigned int NoOfParam;
   11115          346 :   unsigned int Param;
   11116          346 :   unsigned int ReturnVar;
   11117              : 
   11118          346 :   M2Quads_PopT (&NoOfParam);
   11119          346 :   Param = static_cast<unsigned int> (M2Quads_OperandT (1));
   11120          346 :   paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   11121          346 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11122              :   /* Restore stack to origional form.  */
   11123          346 :   M2Quads_PushT (NoOfParam);
   11124          346 :   Type = SymbolTable_GetSType (Param);  /* Get the type from the symbol, not the stack.  */
   11125          346 :   if (NoOfParam != 1)  /* Get the type from the symbol, not the stack.  */
   11126              :     {
   11127            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "base procedure {%1EkLENGTH} expects 1 parameter, seen {%1n} parameters", 70, NoOfParam);
   11128              :     }
   11129          346 :   if (NoOfParam >= 1)
   11130              :     {
   11131          346 :       combinedtok = M2LexBuf_MakeVirtual2Tok (functok, paramtok);
   11132          346 :       if ((SymbolTable_IsConst (Param)) && ((SymbolTable_GetSType (Param)) == M2Base_Char))
   11133              :         {
   11134            6 :           M2Quads_PopT (&NoOfParam);
   11135            6 :           M2Quads_PopN (NoOfParam+1);
   11136            6 :           ReturnVar = SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal);
   11137            6 :           M2Quads_PushTtok (ReturnVar, combinedtok);
   11138              :         }
   11139          340 :       else if (SymbolTable_IsConstString (Param))
   11140              :         {
   11141              :           /* avoid dangling else.  */
   11142           48 :           M2Quads_PopT (&NoOfParam);
   11143           48 :           ReturnVar = DeferMakeLengthConst (combinedtok, M2Quads_OperandT (1));
   11144           48 :           M2Quads_PopN (NoOfParam+1);
   11145           48 :           M2Quads_PushTtok (ReturnVar, combinedtok);
   11146              :         }
   11147              :       else
   11148              :         {
   11149              :           /* avoid dangling else.  */
   11150          292 :           ProcSym = GetQualidentImport (functok, NameKey_MakeKey ((const char *) "Length", 6), NameKey_MakeKey ((const char *) "M2RTS", 5));
   11151          292 :           if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
   11152              :             {
   11153          292 :               M2Quads_PopT (&NoOfParam);
   11154          292 :               if (SymbolTable_IsConst (Param))
   11155              :                 {
   11156              :                   /* This can be folded in M2GenGCC.  */
   11157            0 :                   ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_ImmediateValue);
   11158            0 :                   SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
   11159            0 :                   GenQuad (M2Quads_StandardFunctionOp, ReturnVar, ProcSym, Param);
   11160            0 :                   M2Quads_PopN (NoOfParam+1);
   11161            0 :                   M2Quads_PushTtok (ReturnVar, combinedtok);
   11162              :                 }
   11163          292 :               else if (ConstExprError (Function, Param, paramtok, ConstExpr))
   11164              :                 {
   11165              :                   /* avoid dangling else.  */
   11166              :                   /* Fake a result as we have detected and reported an error.  */
   11167            6 :                   M2Quads_PopN (NoOfParam+1);
   11168            6 :                   ReturnVar = SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal);
   11169            6 :                   M2Quads_PushTtok (ReturnVar, combinedtok);
   11170              :                 }
   11171              :               else
   11172              :                 {
   11173              :                   /* avoid dangling else.  */
   11174              :                   /* We must resolve this at runtime or in the GCC optimizer.  */
   11175          286 :                   M2Quads_PopTF (&Param, &Type);
   11176          286 :                   M2Quads_PopN (NoOfParam);
   11177          286 :                   M2Quads_PushTtok (ProcSym, functok);
   11178          286 :                   M2Quads_PushTFtok (Param, Type, paramtok);
   11179          286 :                   M2Quads_PushT (NoOfParam);
   11180          286 :                   BuildRealFunctionCall (functok, false);
   11181              :                 }
   11182              :             }
   11183              :           else
   11184              :             {
   11185            0 :               M2Quads_PopT (&NoOfParam);
   11186            0 :               M2Quads_PopN (NoOfParam+1);
   11187            0 :               M2Quads_PushTtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), combinedtok);
   11188            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);
   11189              :             }
   11190              :         }
   11191              :     }
   11192              :   else
   11193              :     {
   11194              :       /* NoOfParam is _very_ wrong, we flush all outstanding errors  */
   11195            0 :       M2Error_FlushErrors ();
   11196              :     }
   11197          346 : }
   11198              : 
   11199              : 
   11200              : /*
   11201              :    BuildOddFunction - builds the pseudo procedure call ODD.
   11202              :                       This procedure is actually a "macro" for
   11203              :                       ORD(x) --> VAL(BOOLEAN, x MOD 2)
   11204              :                       However we cannot push tokens back onto the input stack
   11205              :                       because the compiler is currently building a function
   11206              :                       call and expecting a ReturnVar on the stack.
   11207              :                       Hence we manipulate the stack and call
   11208              :                       BuildConvertFunction.
   11209              : 
   11210              :                       The Stack:
   11211              : 
   11212              : 
   11213              :                       Entry                      Exit
   11214              : 
   11215              :                Ptr ->
   11216              :                       +----------------+
   11217              :                       | NoOfParam      |
   11218              :                       |----------------|
   11219              :                       | Param 1        |
   11220              :                       |----------------|
   11221              :                       | Param 2        |
   11222              :                       |----------------|
   11223              :                       .                .
   11224              :                       .                .
   11225              :                       .                .
   11226              :                       |----------------|
   11227              :                       | Param #        |
   11228              :                       |----------------|
   11229              :                       | ProcSym | Type |         Empty
   11230              :                       |----------------|
   11231              : */
   11232              : 
   11233           44 : static void BuildOddFunction (unsigned int ProcSym, bool ConstExpr)
   11234              : {
   11235           44 :   unsigned int combinedtok;
   11236           44 :   unsigned int optok;
   11237           44 :   unsigned int functok;
   11238           44 :   unsigned int NoOfParam;
   11239           44 :   unsigned int Res;
   11240           44 :   unsigned int Var;
   11241              : 
   11242           44 :   M2Quads_PopT (&NoOfParam);
   11243           44 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11244           44 :   if (NoOfParam == 1)
   11245              :     {
   11246           44 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   11247           44 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   11248           44 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
   11249           44 :       if (ConstExprError (ProcSym, Var, optok, ConstExpr))
   11250              :         {
   11251              :           /* Nothing to do.  */
   11252            6 :           M2Quads_PushTtok (M2Base_False, combinedtok);
   11253              :         }
   11254           38 :       else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   11255              :         {
   11256              :           /* avoid dangling else.  */
   11257           38 :           M2Quads_PopN (NoOfParam+1);
   11258              :           /* compute (x MOD 2)  */
   11259           38 :           M2Quads_PushTFtok (Var, SymbolTable_GetSType (Var), optok);
   11260           38 :           M2Quads_PushT (M2Reserved_ModTok);
   11261           38 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (optok, NameKey_MakeKey ((const char *) "2", 1), M2Base_ZType), M2Base_ZType, optok);
   11262           38 :           M2Quads_BuildBinaryOp ();
   11263           38 :           M2Quads_PopT (&Res);
   11264              :           /* compute IF ...=0  */
   11265           38 :           M2Quads_PushTtok (Res, optok);
   11266           38 :           M2Quads_PushT (M2Reserved_EqualTok);
   11267           38 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (optok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType), M2Base_ZType, optok);
   11268           38 :           M2Quads_BuildRelOp (combinedtok);
   11269           38 :           M2Quads_BuildThenIf ();
   11270           38 :           Res = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
   11271           38 :           SymbolTable_PutVar (Res, M2Base_Boolean);
   11272           38 :           M2Quads_PushTtok (Res, combinedtok);
   11273           38 :           M2Quads_PushTtok (M2Base_False, combinedtok);
   11274           38 :           M2Quads_BuildAssignment (combinedtok);
   11275           38 :           M2Quads_BuildElse ();
   11276           38 :           M2Quads_PushTtok (Res, combinedtok);
   11277           38 :           M2Quads_PushTtok (M2Base_True, combinedtok);
   11278           38 :           M2Quads_BuildAssignment (combinedtok);
   11279           38 :           M2Quads_BuildEndIf ();
   11280           38 :           M2Quads_PushTtok (Res, combinedtok);
   11281              :         }
   11282              :       else
   11283              :         {
   11284              :           /* avoid dangling else.  */
   11285            0 :           M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%1EkODD} must be a variable or constant, seen {%1ad} {%1&s}", 77, Var);
   11286            0 :           M2Quads_PushTtok (M2Base_False, combinedtok);
   11287              :         }
   11288              :     }
   11289              :   else
   11290              :     {
   11291            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%E1kODD} only has one parameter, seen {%1n} parameters", 76, NoOfParam);
   11292            0 :       M2Quads_PushTtok (M2Base_False, functok);
   11293              :     }
   11294           44 : }
   11295              : 
   11296              : 
   11297              : /*
   11298              :    BuildAbsFunction - builds a call to the standard function ABS.
   11299              : 
   11300              :                       We cannot implement it as a macro or inline an
   11301              :                       IF THEN statement as the IF THEN ELSE requires
   11302              :                       we write the value to the same variable (or constant)
   11303              :                       twice. The macro implementation will fail as
   11304              :                       the compiler maybe building a function
   11305              :                       call and expecting a ReturnVar on the stack.
   11306              :                       The only method to implement this is to pass it to the
   11307              :                       gcc backend.
   11308              : 
   11309              :                       The Stack:
   11310              : 
   11311              : 
   11312              :                       Entry                      Exit
   11313              : 
   11314              :                Ptr ->
   11315              :                       +----------------+
   11316              :                       | NoOfParam      |
   11317              :                       |----------------|
   11318              :                       | Param 1        |
   11319              :                       |----------------|
   11320              :                       | Param 2        |
   11321              :                       |----------------|
   11322              :                       .                .
   11323              :                       .                .
   11324              :                       .                .
   11325              :                       |----------------|
   11326              :                       | Param #        |
   11327              :                       |----------------|
   11328              :                       | ProcSym | Type |         Empty
   11329              :                       |----------------|
   11330              : */
   11331              : 
   11332          177 : static void BuildAbsFunction (unsigned int ProcSym, bool ConstExpr)
   11333              : {
   11334          177 :   unsigned int vartok;
   11335          177 :   unsigned int functok;
   11336          177 :   unsigned int combinedtok;
   11337          177 :   unsigned int NoOfParam;
   11338          177 :   unsigned int Res;
   11339          177 :   unsigned int Var;
   11340              : 
   11341          177 :   M2Quads_PopT (&NoOfParam);
   11342          177 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11343          177 :   if (NoOfParam == 1)
   11344              :     {
   11345          177 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   11346          177 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   11347          177 :       M2Quads_PopN (NoOfParam+1);
   11348          177 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
   11349          177 :       if (ConstExprError (ProcSym, Var, vartok, ConstExpr))
   11350              :         {
   11351              :           /* Create fake result.  */
   11352           24 :           Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   11353           12 :           SymbolTable_PutVar (Res, SymbolTable_GetSType (Var));
   11354           12 :           M2Quads_PushTFtok (Res, SymbolTable_GetSType (Var), combinedtok);
   11355              :         }
   11356          165 :       else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   11357              :         {
   11358              :           /* avoid dangling else.  */
   11359          316 :           Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   11360          158 :           SymbolTable_PutVar (Res, SymbolTable_GetSType (Var));
   11361          316 :           GenQuadO (combinedtok, M2Quads_StandardFunctionOp, Res, ProcSym, Var, false);
   11362          158 :           M2Quads_PushTFtok (Res, SymbolTable_GetSType (Var), combinedtok);
   11363              :         }
   11364              :       else
   11365              :         {
   11366              :           /* avoid dangling else.  */
   11367            7 :           M2MetaError_MetaErrorT1 (vartok, (const char *) "the parameter to {%AkABS} must be a variable or constant, seen {%1ad} {%1&s}", 76, Var);
   11368              :         }
   11369              :     }
   11370              :   else
   11371              :     {
   11372            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkABS} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
   11373              :     }
   11374          170 : }
   11375              : 
   11376              : 
   11377              : /*
   11378              :    BuildCapFunction - builds the pseudo procedure call CAP.
   11379              :                       We generate a the following quad:
   11380              : 
   11381              : 
   11382              :                       StandardFunctionOp  ReturnVal  Cap  Param1
   11383              : 
   11384              :                       The Stack:
   11385              : 
   11386              : 
   11387              :                       Entry                      Exit
   11388              : 
   11389              :                Ptr ->
   11390              :                       +----------------+
   11391              :                       | NoOfParam = 1  |
   11392              :                       |----------------|
   11393              :                       | Param 1        |
   11394              :                       |----------------|         +-------------+
   11395              :                       | ProcSym | Type |         | ReturnVal   |
   11396              :                       |----------------|         |-------------|
   11397              : */
   11398              : 
   11399          125 : static void BuildCapFunction (unsigned int ProcSym, bool ConstExpr)
   11400              : {
   11401          125 :   unsigned int optok;
   11402          125 :   unsigned int functok;
   11403          125 :   unsigned int combinedtok;
   11404          125 :   unsigned int NoOfParam;
   11405          125 :   unsigned int Res;
   11406          125 :   unsigned int Var;
   11407              : 
   11408          125 :   M2Quads_PopT (&NoOfParam);
   11409          125 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11410          125 :   if (NoOfParam == 1)
   11411              :     {
   11412          125 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   11413          125 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   11414          125 :       M2Quads_PopN (NoOfParam+1);
   11415          125 :       if (ConstExprError (ProcSym, Var, optok, ConstExpr))
   11416              :         {
   11417              :           /* Create fake result.  */
   11418           12 :           combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
   11419           24 :           Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   11420           12 :           SymbolTable_PutVar (Res, M2Base_Char);
   11421           12 :           M2Quads_PushTFtok (Res, M2Base_Char, combinedtok);
   11422              :         }
   11423          113 :       else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   11424              :         {
   11425              :           /* avoid dangling else.  */
   11426          112 :           combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
   11427          224 :           Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   11428          112 :           SymbolTable_PutVar (Res, M2Base_Char);
   11429          224 :           GenQuadO (combinedtok, M2Quads_StandardFunctionOp, Res, ProcSym, Var, false);
   11430          112 :           M2Quads_PushTFtok (Res, M2Base_Char, combinedtok);
   11431              :         }
   11432              :       else
   11433              :         {
   11434              :           /* avoid dangling else.  */
   11435            1 :           M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%AkCAP} must be a variable or constant, seen {%1ad} {%1&s}", 76, Var);
   11436              :         }
   11437              :     }
   11438              :   else
   11439              :     {
   11440            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkCAP} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
   11441              :     }
   11442          124 : }
   11443              : 
   11444              : 
   11445              : /*
   11446              :    BuildChrFunction - builds the pseudo procedure call CHR.
   11447              :                       This procedure is actually a "macro" for
   11448              :                       CHR(x) --> CONVERT(CHAR, x)
   11449              :                       However we cannot push tokens back onto the input stack
   11450              :                       because the compiler is currently building a function
   11451              :                       call and expecting a ReturnVar on the stack.
   11452              :                       Hence we manipulate the stack and call
   11453              :                       BuildConvertFunction.
   11454              : 
   11455              :                       The Stack:
   11456              : 
   11457              : 
   11458              :                       Entry                      Exit
   11459              : 
   11460              :                Ptr ->
   11461              :                       +----------------+
   11462              :                       | NoOfParam      |
   11463              :                       |----------------|
   11464              :                       | Param 1        |
   11465              :                       |----------------|
   11466              :                       | Param 2        |
   11467              :                       |----------------|
   11468              :                       .                .
   11469              :                       .                .
   11470              :                       .                .
   11471              :                       |----------------|
   11472              :                       | Param #        |
   11473              :                       |----------------|
   11474              :                       | ProcSym | Type |         Empty
   11475              :                       |----------------|
   11476              : */
   11477              : 
   11478         1020 : static void BuildChrFunction (unsigned int ProcSym, bool ConstExpr)
   11479              : {
   11480         1020 :   unsigned int functok;
   11481         1020 :   unsigned int combinedtok;
   11482         1020 :   unsigned int optok;
   11483         1020 :   unsigned int ReturnVar;
   11484         1020 :   unsigned int NoOfParam;
   11485         1020 :   unsigned int Var;
   11486              : 
   11487         1020 :   M2Quads_PopT (&NoOfParam);
   11488         1020 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11489         1020 :   if (NoOfParam == 1)
   11490              :     {
   11491         1020 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   11492         1020 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   11493         1020 :       M2Quads_PopN (NoOfParam+1);
   11494         1020 :       if (ConstExprError (ProcSym, Var, optok, ConstExpr))
   11495              :         {
   11496              :           /* Generate fake result.  */
   11497           12 :           combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
   11498           24 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   11499           12 :           SymbolTable_PutVar (ReturnVar, M2Base_Char);
   11500           12 :           M2Quads_PushTFtok (ReturnVar, M2Base_Char, combinedtok);
   11501              :         }
   11502         1008 :       else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   11503              :         {
   11504              :           /* avoid dangling else.  */
   11505              :           /* 
   11506              :             Build macro: CONVERT( CHAR, Var )
   11507              :   */
   11508         1007 :           M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
   11509         1007 :           M2Quads_PushTtok (M2Base_Char, functok);
   11510         1007 :           M2Quads_PushTtok (Var, optok);
   11511         1007 :           M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
   11512         1007 :           BuildConvertFunction (M2Base_Convert, ConstExpr);  /* Two parameters  */
   11513              :         }
   11514              :       else
   11515              :         {
   11516              :           /* avoid dangling else.  */
   11517            1 :           M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%AkCHR} must be a variable or constant, seen {%1ad} {%1&s}", 76, Var);
   11518              :         }
   11519              :     }
   11520              :   else
   11521              :     {
   11522            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkCHR} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
   11523              :     }
   11524         1019 : }
   11525              : 
   11526              : 
   11527              : /*
   11528              :    BuildOrdFunction - builds the pseudo procedure call ORD.
   11529              :                       This procedure is actually a "macro" for
   11530              :                       ORD(x) --> CONVERT(GetSType(sym), x)
   11531              :                       However we cannot push tokens back onto the input stack
   11532              :                       because the compiler is currently building a function
   11533              :                       call and expecting a ReturnVar on the stack.
   11534              :                       Hence we manipulate the stack and call
   11535              :                       BuildConvertFunction.
   11536              : 
   11537              :                       The Stack:
   11538              : 
   11539              : 
   11540              :                       Entry                      Exit
   11541              : 
   11542              :                Ptr ->
   11543              :                       +----------------+
   11544              :                       | NoOfParam      |
   11545              :                       |----------------|
   11546              :                       | Param 1        |
   11547              :                       |----------------|
   11548              :                       | Param 2        |
   11549              :                       |----------------|
   11550              :                       .                .
   11551              :                       .                .
   11552              :                       .                .
   11553              :                       |----------------|
   11554              :                       | Param #        |
   11555              :                       |----------------|
   11556              :                       | ProcSym | Type |         Empty
   11557              :                       |----------------|
   11558              : */
   11559              : 
   11560         4708 : static void BuildOrdFunction (unsigned int Sym, bool ConstExpr)
   11561              : {
   11562         4708 :   unsigned int combinedtok;
   11563         4708 :   unsigned int functok;
   11564         4708 :   unsigned int optok;
   11565         4708 :   unsigned int ReturnVar;
   11566         4708 :   unsigned int NoOfParam;
   11567         4708 :   unsigned int Type;
   11568         4708 :   unsigned int Var;
   11569              : 
   11570         4708 :   M2Quads_PopT (&NoOfParam);
   11571         4708 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11572         4708 :   if (NoOfParam == 1)
   11573              :     {
   11574         4708 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   11575         4708 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   11576         4708 :       M2Quads_PopN (NoOfParam+1);
   11577         4708 :       if (ConstExprError (Sym, Var, optok, ConstExpr))
   11578              :         {
   11579              :           /* Generate fake result.  */
   11580           12 :           combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
   11581           24 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   11582           12 :           SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
   11583           12 :           M2Quads_PushTFtok (ReturnVar, M2Base_Cardinal, combinedtok);
   11584              :         }
   11585         4696 :       else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   11586              :         {
   11587              :           /* avoid dangling else.  */
   11588         4696 :           Type = SymbolTable_GetSType (Sym);
   11589              :           /* 
   11590              :             Build macro: CONVERT( CARDINAL, Var )
   11591              :   */
   11592         4696 :           M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
   11593         4696 :           M2Quads_PushTtok (Type, optok);
   11594         4696 :           M2Quads_PushTtok (Var, optok);
   11595         4696 :           M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
   11596         4696 :           BuildConvertFunction (M2Base_Convert, ConstExpr);  /* Two parameters  */
   11597              :         }
   11598              :       else
   11599              :         {
   11600              :           /* avoid dangling else.  */
   11601            0 :           M2MetaError_MetaErrorT2 (optok, (const char *) "the parameter to {%1Aa} must be a variable or constant, seen {%2ad} {%2&s}", 74, Sym, Var);
   11602              :         }
   11603              :     }
   11604              :   else
   11605              :     {
   11606            0 :       M2MetaError_MetaErrorT2 (functok, (const char *) "the pseudo procedure {%1Aa} only has one parameter, seen {%2n} parameters", 73, Sym, NoOfParam);
   11607              :     }
   11608         4708 : }
   11609              : 
   11610              : 
   11611              : /*
   11612              :    BuildIntFunction - builds the pseudo procedure call INT.
   11613              :                       This procedure is actually a "macro" for
   11614              :                       INT(x) --> CONVERT(INTEGER, x)
   11615              :                       However we cannot push tokens back onto the input stack
   11616              :                       because the compiler is currently building a function
   11617              :                       call and expecting a ReturnVar on the stack.
   11618              :                       Hence we manipulate the stack and call
   11619              :                       BuildConvertFunction.
   11620              : 
   11621              :                       The Stack:
   11622              : 
   11623              : 
   11624              :                       Entry                      Exit
   11625              : 
   11626              :                Ptr ->
   11627              :                       +----------------+
   11628              :                       | NoOfParam      |
   11629              :                       |----------------|
   11630              :                       | Param 1        |
   11631              :                       |----------------|
   11632              :                       | Param 2        |
   11633              :                       |----------------|
   11634              :                       .                .
   11635              :                       .                .
   11636              :                       .                .
   11637              :                       |----------------|
   11638              :                       | Param #        |
   11639              :                       |----------------|
   11640              :                       | ProcSym | Type |         Empty
   11641              :                       |----------------|
   11642              : */
   11643              : 
   11644            6 : static void BuildIntFunction (unsigned int Sym, bool ConstExpr)
   11645              : {
   11646            6 :   unsigned int combinedtok;
   11647            6 :   unsigned int functok;
   11648            6 :   unsigned int optok;
   11649            6 :   unsigned int ReturnVar;
   11650            6 :   unsigned int NoOfParam;
   11651            6 :   unsigned int Type;
   11652            6 :   unsigned int Var;
   11653              : 
   11654            6 :   M2Quads_PopT (&NoOfParam);
   11655            6 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11656            6 :   if (NoOfParam == 1)
   11657              :     {
   11658            6 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   11659            6 :       optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   11660            6 :       M2Quads_PopN (NoOfParam+1);
   11661            6 :       if (ConstExprError (Sym, Var, optok, ConstExpr))
   11662              :         {
   11663              :           /* Generate fake result.  */
   11664            6 :           combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
   11665           12 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   11666            6 :           SymbolTable_PutVar (ReturnVar, M2Base_Integer);
   11667            6 :           M2Quads_PushTFtok (ReturnVar, M2Base_Integer, combinedtok);
   11668              :         }
   11669            0 :       else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   11670              :         {
   11671              :           /* avoid dangling else.  */
   11672            0 :           Type = SymbolTable_GetSType (Sym);  /* return type of function  */
   11673              :           /* Build macro: CONVERT( CARDINAL, Var ).  */
   11674            0 :           M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
   11675            0 :           M2Quads_PushTtok (Type, functok);
   11676            0 :           M2Quads_PushTtok (Var, optok);
   11677            0 :           M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
   11678            0 :           BuildConvertFunction (M2Base_Convert, ConstExpr);  /* Two parameters  */
   11679              :         }
   11680              :       else
   11681              :         {
   11682              :           /* avoid dangling else.  */
   11683            0 :           combinedtok = M2LexBuf_MakeVirtualTok (functok, optok, optok);
   11684            0 :           M2MetaError_MetaErrorT2 (optok, (const char *) "the parameter to {%1Ea} must be a variable or constant, seen {%2ad} {%2&s}", 74, Sym, Var);
   11685            0 :           M2Quads_PushTtok (combinedtok, SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType));
   11686              :         }
   11687              :     }
   11688              :   else
   11689              :     {
   11690            0 :       M2MetaError_MetaErrorT2 (functok, (const char *) "the pseudo procedure {%1Ea} only has one parameter, seen {%2n} parameters", 73, Sym, NoOfParam);
   11691            0 :       M2Quads_PushTtok (functok, SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType));
   11692              :     }
   11693            6 : }
   11694              : 
   11695              : 
   11696              : /*
   11697              :    BuildMakeAdrFunction - builds the pseudo procedure call MAKEADR.
   11698              : 
   11699              :                           The Stack:
   11700              : 
   11701              : 
   11702              :                           Entry                      Exit
   11703              : 
   11704              :                    Ptr ->
   11705              :                           +----------------+
   11706              :                           | NoOfParam      |
   11707              :                           |----------------|
   11708              :                           | Param 1        |
   11709              :                           |----------------|
   11710              :                           | Param 2        |
   11711              :                           |----------------|
   11712              :                           .                .
   11713              :                           .                .
   11714              :                           .                .
   11715              :                           |----------------|
   11716              :                           | Param #        |
   11717              :                           |----------------|
   11718              :                           | ProcSym | Type |         Empty
   11719              :                           |----------------|
   11720              : */
   11721              : 
   11722           12 : static void BuildMakeAdrFunction (void)
   11723              : {
   11724           12 :   unsigned int functok;
   11725           12 :   unsigned int starttok;
   11726           12 :   unsigned int endtok;
   11727           12 :   unsigned int resulttok;
   11728           12 :   bool AreConst;
   11729           12 :   unsigned int i;
   11730           12 :   unsigned int pi;
   11731           12 :   unsigned int NoOfParameters;
   11732           12 :   unsigned int ReturnVar;
   11733              : 
   11734           12 :   M2Quads_PopT (&NoOfParameters);
   11735           12 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParameters+1));
   11736           12 :   if (NoOfParameters > 0)
   11737              :     {
   11738           12 :       starttok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParameters+1));  /* ADR token.  */
   11739           12 :       endtok = static_cast<unsigned int> (M2Quads_OperandTok (1));  /* last parameter.  */
   11740           24 :       GenQuad (M2Quads_ParamOp, 0, M2System_MakeAdr, M2System_MakeAdr);  /* last parameter.  */
   11741           12 :       i = NoOfParameters;
   11742              :       /* stack index referencing stacked parameter, i  */
   11743           12 :       pi = 1;
   11744           24 :       while (i > 0)
   11745              :         {
   11746           12 :           GenQuadO (M2Quads_OperandTok (pi), M2Quads_ParamOp, i, M2System_MakeAdr, M2Quads_OperandT (pi), true);
   11747           12 :           i -= 1;
   11748           12 :           pi += 1;
   11749              :         }
   11750              :       AreConst = true;
   11751              :       i = 1;
   11752           24 :       while (i <= NoOfParameters)
   11753              :         {
   11754           12 :           if (SymbolTable_IsVar (M2Quads_OperandT (i)))
   11755              :             {
   11756              :               AreConst = false;
   11757              :             }
   11758           12 :           else if (! (SymbolTable_IsConst (M2Quads_OperandT (i))))
   11759              :             {
   11760              :               /* avoid dangling else.  */
   11761            0 :               M2MetaError_MetaError1 ((const char *) "problem in the {%1EN} argument for {%kMAKEADR}, all arguments to {%kMAKEADR} must be either variables or constants", 114, i);
   11762              :             }
   11763           12 :           i += 1;
   11764              :         }
   11765              :       /* ReturnVar - will have the type of the procedure  */
   11766           12 :       resulttok = M2LexBuf_MakeVirtualTok (starttok, starttok, endtok);
   11767           12 :       ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (AreConst));
   11768           12 :       SymbolTable_PutVar (ReturnVar, SymbolTable_GetSType (M2System_MakeAdr));
   11769           24 :       GenQuadO (resulttok, M2Quads_FunctValueOp, ReturnVar, SymbolTable_NulSym, M2System_MakeAdr, true);
   11770           12 :       M2Quads_PopN (NoOfParameters+1);
   11771           12 :       M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (M2System_MakeAdr), resulttok);
   11772              :     }
   11773              :   else
   11774              :     {
   11775            0 :       M2MetaError_MetaError1 ((const char *) "the pseudo procedure {%EkMAKEADR} requires at least one parameter, seen {%1n}", 77, NoOfParameters);
   11776            0 :       M2Quads_PopN (1);
   11777            0 :       M2Quads_PushTFtok (M2Base_Nil, SymbolTable_GetSType (M2System_MakeAdr), functok);
   11778              :     }
   11779           12 : }
   11780              : 
   11781              : 
   11782              : /*
   11783              :    BuildShiftFunction - builds the pseudo procedure call SHIFT.
   11784              : 
   11785              :                         PROCEDURE SHIFT (val: <any type>;
   11786              :                                          num: INTEGER): <any type> ;
   11787              : 
   11788              :                        "Returns a bit sequence obtained from val by
   11789              :                         shifting up or down (left or right) by the
   11790              :                         absolute value of num, introducing
   11791              :                         zeros as necessary.  The direction is down if
   11792              :                         the sign of num is negative, otherwise the
   11793              :                         direction is up."
   11794              : 
   11795              :                         The Stack:
   11796              : 
   11797              :                         Entry                      Exit
   11798              : 
   11799              :                  Ptr ->
   11800              :                         +----------------+
   11801              :                         | NoOfParam      |
   11802              :                         |----------------|
   11803              :                         | Param 1        |
   11804              :                         |----------------|
   11805              :                         | Param 2        |                        <- Ptr
   11806              :                         |----------------|         +------------+
   11807              :                         | ProcSym | Type |         | ReturnVar  |
   11808              :                         |----------------|         |------------|
   11809              : */
   11810              : 
   11811          682 : static void BuildShiftFunction (void)
   11812              : {
   11813          682 :   unsigned int combinedtok;
   11814          682 :   unsigned int paramtok;
   11815          682 :   unsigned int functok;
   11816          682 :   unsigned int vartok;
   11817          682 :   unsigned int exptok;
   11818          682 :   unsigned int r;
   11819          682 :   unsigned int procSym;
   11820          682 :   unsigned int returnVar;
   11821          682 :   unsigned int NoOfParam;
   11822          682 :   unsigned int derefExp;
   11823          682 :   unsigned int Exp;
   11824          682 :   unsigned int varSet;
   11825              : 
   11826          682 :   M2Quads_PopT (&NoOfParam);
   11827          682 :   paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   11828          682 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11829          682 :   if (NoOfParam == 2)
   11830              :     {
   11831          682 :       PopTrwtok (&Exp, &r, &exptok);
   11832          682 :       MarkAsRead (r);
   11833          682 :       M2Quads_PopTtok (&varSet, &vartok);
   11834          682 :       M2Quads_PopT (&procSym);
   11835          682 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
   11836          682 :       if (((SymbolTable_GetSType (varSet)) != SymbolTable_NulSym) && ((SymbolTable_IsSet (SymbolTable_GetDType (varSet))) || (M2System_IsGenericSystemType (SymbolTable_GetDType (varSet)))))
   11837              :         {
   11838          682 :           derefExp = DereferenceLValue (exptok, Exp);
   11839          682 :           BuildRange (M2Range_InitShiftCheck (varSet, derefExp));
   11840          682 :           returnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
   11841          682 :           SymbolTable_PutVar (returnVar, SymbolTable_GetSType (varSet));
   11842         1364 :           GenQuadO (combinedtok, M2Quads_LogicalShiftOp, returnVar, varSet, derefExp, true);
   11843          682 :           M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (varSet), combinedtok);
   11844              :         }
   11845              :       else
   11846              :         {
   11847            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);
   11848            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, combinedtok);
   11849              :         }
   11850              :     }
   11851              :   else
   11852              :     {
   11853            0 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   11854            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%kSHIFT} requires at least two parameters, seen {%1En}", 76, NoOfParam);
   11855            0 :       M2Quads_PopN (NoOfParam+1);
   11856            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, combinedtok);
   11857              :     }
   11858          682 : }
   11859              : 
   11860              : 
   11861              : /*
   11862              :    BuildRotateFunction - builds the pseudo procedure call ROTATE.
   11863              : 
   11864              :                          PROCEDURE ROTATE (val: <any type>;
   11865              :                                            num: INTEGER): <any type> ;
   11866              : 
   11867              :                         "Returns a bit sequence obtained from val
   11868              :                          by rotating up or down (left or right) by
   11869              :                          the absolute value of num.  The direction is
   11870              :                          down if the sign of num is negative, otherwise
   11871              :                          the direction is up."
   11872              : 
   11873              :                          The Stack:
   11874              : 
   11875              :                          Entry                      Exit
   11876              : 
   11877              :                   Ptr ->
   11878              :                          +----------------+
   11879              :                          | NoOfParam      |
   11880              :                          |----------------|
   11881              :                          | Param 1        |
   11882              :                          |----------------|
   11883              :                          | Param 2        |                        <- Ptr
   11884              :                          |----------------|         +------------+
   11885              :                          | ProcSym | Type |         | ReturnVar  |
   11886              :                          |----------------|         |------------|
   11887              : */
   11888              : 
   11889          406 : static void BuildRotateFunction (void)
   11890              : {
   11891          406 :   unsigned int combinedtok;
   11892          406 :   unsigned int functok;
   11893          406 :   unsigned int vartok;
   11894          406 :   unsigned int exptok;
   11895          406 :   unsigned int r;
   11896          406 :   unsigned int procSym;
   11897          406 :   unsigned int returnVar;
   11898          406 :   unsigned int NoOfParam;
   11899          406 :   unsigned int derefExp;
   11900          406 :   unsigned int Exp;
   11901          406 :   unsigned int varSet;
   11902              : 
   11903          406 :   M2Quads_PopT (&NoOfParam);
   11904          406 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11905          406 :   if (NoOfParam == 2)
   11906              :     {
   11907          406 :       PopTrwtok (&Exp, &r, &exptok);
   11908          406 :       MarkAsRead (r);
   11909          406 :       M2Quads_PopTtok (&varSet, &vartok);
   11910          406 :       M2Quads_PopT (&procSym);
   11911          406 :       if (((SymbolTable_GetSType (varSet)) != SymbolTable_NulSym) && ((SymbolTable_IsSet (SymbolTable_GetDType (varSet))) || (M2System_IsGenericSystemType (SymbolTable_GetDType (varSet)))))
   11912              :         {
   11913          406 :           combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
   11914          406 :           derefExp = DereferenceLValue (exptok, Exp);
   11915          406 :           BuildRange (M2Range_InitRotateCheck (varSet, derefExp));
   11916          406 :           returnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
   11917          406 :           SymbolTable_PutVar (returnVar, SymbolTable_GetSType (varSet));
   11918          812 :           GenQuadO (combinedtok, M2Quads_LogicalRotateOp, returnVar, varSet, derefExp, true);
   11919          406 :           M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (varSet), combinedtok);
   11920              :         }
   11921              :       else
   11922              :         {
   11923            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);
   11924            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
   11925              :         }
   11926              :     }
   11927              :   else
   11928              :     {
   11929            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "SYSTEM procedure {%EkROTATE} expects 2 parameters and was given {%1n} parameters", 80, NoOfParam);
   11930            0 :       M2Quads_PopN (NoOfParam+1);
   11931            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
   11932              :     }
   11933          406 : }
   11934              : 
   11935              : 
   11936              : /*
   11937              :    BuildValFunction - builds the pseudo procedure call VAL.
   11938              :                       This procedure is actually a "macro" for
   11939              :                       VAL(Type, x) --> CONVERT(Type, x)
   11940              :                       However we cannot push tokens back onto the input stack
   11941              :                       because the compiler is currently building a function
   11942              :                       call and expecting a ReturnVar on the stack.
   11943              :                       Hence we manipulate the stack and call
   11944              :                       BuildConvertFunction.
   11945              : 
   11946              :                       The Stack:
   11947              : 
   11948              : 
   11949              :                       Entry                      Exit
   11950              : 
   11951              :                Ptr ->
   11952              :                       +----------------+
   11953              :                       | NoOfParam      |
   11954              :                       |----------------|
   11955              :                       | Param 1        |
   11956              :                       |----------------|
   11957              :                       | Param 2        |
   11958              :                       |----------------|
   11959              :                       .                .
   11960              :                       .                .
   11961              :                       .                .
   11962              :                       |----------------|
   11963              :                       | Param #        |
   11964              :                       |----------------|
   11965              :                       | ProcSym | Type |         Empty
   11966              :                       |----------------|
   11967              : */
   11968              : 
   11969         4922 : static void BuildValFunction (unsigned int ProcSym, bool ConstExpr)
   11970              : {
   11971         4922 :   unsigned int combinedtok;
   11972         4922 :   unsigned int functok;
   11973         4922 :   unsigned int ReturnVar;
   11974         4922 :   unsigned int NoOfParam;
   11975         4922 :   unsigned int Exp;
   11976         4922 :   unsigned int Type;
   11977         4922 :   unsigned int tok;
   11978         4922 :   unsigned int r;
   11979         4922 :   unsigned int typetok;
   11980         4922 :   unsigned int exptok;
   11981              : 
   11982         4922 :   M2Quads_PopT (&NoOfParam);
   11983         4922 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   11984         4922 :   if (NoOfParam == 2)
   11985              :     {
   11986         4922 :       PopTrwtok (&Exp, &r, &exptok);
   11987         4922 :       MarkAsRead (r);
   11988         4922 :       M2Quads_PopTtok (&Type, &typetok);
   11989         4922 :       M2Quads_PopTtok (&ProcSym, &tok);
   11990         4922 :       if (SymbolTable_IsUnknown (Type))
   11991              :         {
   11992              :           /* It is sensible not to try and recover when we dont know the return type.  */
   11993            7 :           M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type found in builtin procedure function {%AkVAL} {%1ad} {%1&Ts}", 75, Type);
   11994              :           /* Non recoverable error.  */
   11995            0 :           SymbolTable_UnknownReported (Type);
   11996              :         }
   11997         4915 :       else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
   11998              :         {
   11999              :           /* avoid dangling else.  */
   12000              :           /* Generate fake result.  */
   12001            6 :           combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
   12002           12 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
   12003            6 :           SymbolTable_PutVar (ReturnVar, Type);
   12004            6 :           M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12005              :         }
   12006         4909 :       else if (SymbolTable_IsUnknown (Exp))
   12007              :         {
   12008              :           /* avoid dangling else.  */
   12009              :           /* Spellcheck.  */
   12010            2 :           M2MetaError_MetaErrorT1 (exptok, (const char *) "undeclared variable or constant expression found in builtin procedure function {%AkVAL} {%1ad} {%1&VCs}", 103, Exp);
   12011              :           /* Non recoverable error.  */
   12012            0 :           SymbolTable_UnknownReported (Exp);
   12013              :         }
   12014         4907 :       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))))
   12015              :         {
   12016              :           /* avoid dangling else.  */
   12017              :           /* 
   12018              :             Build macro: CONVERT( Type, Var )
   12019              :   */
   12020         4907 :           M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
   12021         4907 :           M2Quads_PushTtok (Type, typetok);
   12022         4907 :           M2Quads_PushTtok (Exp, exptok);
   12023         4907 :           M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
   12024         4907 :           BuildConvertFunction (M2Base_Convert, ConstExpr);
   12025              :         }
   12026              :       else
   12027              :         {
   12028              :           /* avoid dangling else.  */
   12029              :           /* non recoverable error.  */
   12030            0 :           M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkVAL} has the following formal parameter declaration {%kVAL} (type, expression)", 104);
   12031              :         }
   12032              :     }
   12033              :   else
   12034              :     {
   12035              :       /* non recoverable error.  */
   12036            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);
   12037              :     }
   12038         4913 : }
   12039              : 
   12040              : 
   12041              : /*
   12042              :    BuildCastFunction - builds the pseudo procedure call CAST.
   12043              :                        This procedure is actually a "macro" for
   12044              :                        CAST(Type, x) --> Type(x)
   12045              :                        However we cannot push tokens back onto the input stack
   12046              :                        because the compiler is currently building a function
   12047              :                        call and expecting a ReturnVar on the stack.
   12048              :                        Hence we manipulate the stack and call
   12049              :                        BuildConvertFunction.
   12050              : 
   12051              :                        The Stack:
   12052              : 
   12053              : 
   12054              :                        Entry                      Exit
   12055              : 
   12056              :                 Ptr ->
   12057              :                        +----------------+
   12058              :                        | NoOfParam      |
   12059              :                        |----------------|
   12060              :                        | Param 1        |
   12061              :                        |----------------|
   12062              :                        | Param 2        |
   12063              :                        |----------------|
   12064              :                        .                .
   12065              :                        .                .
   12066              :                        .                .
   12067              :                        |----------------|
   12068              :                        | Param #        |
   12069              :                        |----------------|
   12070              :                        | ProcSym | Type |         Empty
   12071              :                        |----------------|
   12072              : */
   12073              : 
   12074          156 : static void BuildCastFunction (unsigned int ProcSym, bool ConstExpr)
   12075              : {
   12076          156 :   unsigned int combinedtok;
   12077          156 :   unsigned int exptok;
   12078          156 :   unsigned int typetok;
   12079          156 :   unsigned int functok;
   12080          156 :   unsigned int ReturnVar;
   12081          156 :   unsigned int NoOfParam;
   12082          156 :   unsigned int Exp;
   12083          156 :   unsigned int Type;
   12084              : 
   12085          156 :   M2Quads_PopT (&NoOfParam);
   12086          156 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   12087          156 :   if (NoOfParam == 2)
   12088              :     {
   12089          156 :       Type = static_cast<unsigned int> (M2Quads_OperandT (2));
   12090          156 :       typetok = static_cast<unsigned int> (M2Quads_OperandTok (2));
   12091          156 :       Exp = static_cast<unsigned int> (M2Quads_OperandT (1));
   12092          156 :       exptok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   12093          156 :       if (SymbolTable_IsUnknown (Type))
   12094              :         {
   12095              :           /* We cannot recover if we dont have a type.  */
   12096            0 :           M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type {%1Aad} found in {%kCAST} {%1&s}", 48, Type);
   12097              :           /* Non recoverable error.  */
   12098            0 :           SymbolTable_UnknownReported (Type);
   12099              :         }
   12100          156 :       else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
   12101              :         {
   12102              :           /* avoid dangling else.  */
   12103              :           /* Generate fake result.  */
   12104            0 :           combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
   12105            0 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
   12106            0 :           SymbolTable_PutVar (ReturnVar, Type);
   12107            0 :           M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12108              :         }
   12109          156 :       else if (((((((SymbolTable_IsSet (Type)) || (SymbolTable_IsEnumeration (Type))) || (SymbolTable_IsSubrange (Type))) || (SymbolTable_IsType (Type))) || (SymbolTable_IsPointer (Type))) || (SymbolTable_IsArray (Type))) || (SymbolTable_IsProcType (Type)))
   12110              :         {
   12111              :           /* avoid dangling else.  */
   12112          156 :           if (SymbolTable_IsConst (Exp))
   12113              :             {
   12114           30 :               M2Quads_PopN (NoOfParam+1);
   12115              :               /* 
   12116              :                Build macro: Type( Var )
   12117              :   */
   12118           30 :               M2Quads_PushTFtok (Type, static_cast<unsigned int> (SymbolTable_NulSym), typetok);
   12119           30 :               M2Quads_PushTtok (Exp, exptok);
   12120           30 :               M2Quads_PushT (static_cast<unsigned int> (1));  /* one parameter  */
   12121           30 :               BuildTypeCoercion (ConstExpr);  /* one parameter  */
   12122              :             }
   12123          126 :           else if ((SymbolTable_IsVar (Exp)) || (SymbolTable_IsProcedure (Exp)))
   12124              :             {
   12125              :               /* avoid dangling else.  */
   12126          126 :               M2Quads_PopN (NoOfParam+1);
   12127          126 :               combinedtok = M2LexBuf_MakeVirtual2Tok (functok, exptok);
   12128          126 :               ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
   12129          126 :               SymbolTable_PutVar (ReturnVar, Type);
   12130          252 :               GenQuadO (combinedtok, M2Quads_CastOp, ReturnVar, Type, Exp, false);
   12131          126 :               M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12132              :             }
   12133              :           else
   12134              :             {
   12135              :               /* avoid dangling else.  */
   12136              :               /* non recoverable error.  */
   12137            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);
   12138              :             }
   12139              :         }
   12140              :       else
   12141              :         {
   12142              :           /* avoid dangling else.  */
   12143              :           /* non recoverable error.  */
   12144            0 :           M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkCAST} has the following formal parameter declaration {%kCAST} (type, expression)", 106);
   12145              :         }
   12146              :     }
   12147              :   else
   12148              :     {
   12149              :       /* non recoverable error.  */
   12150            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);
   12151              :     }
   12152          156 : }
   12153              : 
   12154              : 
   12155              : /*
   12156              :    BuildConvertFunction - builds the pseudo function CONVERT.
   12157              :                           CONVERT( Type, Variable ) ;
   12158              : 
   12159              :                           The Stack:
   12160              : 
   12161              : 
   12162              :                           Entry                      Exit
   12163              : 
   12164              :                    Ptr ->
   12165              :                           +----------------+
   12166              :                           | NoOfParam      |
   12167              :                           |----------------|
   12168              :                           | Param 1        |
   12169              :                           |----------------|
   12170              :                           | Param 2        |
   12171              :                           |----------------|
   12172              :                           .                .
   12173              :                           .                .
   12174              :                           .                .
   12175              :                           |----------------|
   12176              :                           | Param #        |                                 <- Ptr
   12177              :                           |----------------|         +---------------------+
   12178              :                           | ProcSym | Type |         | ReturnVar | Param1  |
   12179              :                           |----------------|         |---------------------|
   12180              : 
   12181              :                           Quadruples:
   12182              : 
   12183              :                           ConvertOp  ReturnVar  Param1  Param2
   12184              : 
   12185              :                           Converts variable Param2 into a variable Param1
   12186              :                           with a type Param1.
   12187              : */
   12188              : 
   12189        56487 : static void BuildConvertFunction (unsigned int ProcSym, bool ConstExpr)
   12190              : {
   12191        56487 :   unsigned int combinedtok;
   12192        56487 :   unsigned int functok;
   12193        56487 :   unsigned int typetok;
   12194        56487 :   unsigned int exptok;
   12195        56487 :   unsigned int t;
   12196        56487 :   unsigned int r;
   12197        56487 :   unsigned int Exp;
   12198        56487 :   unsigned int Type;
   12199        56487 :   unsigned int NoOfParam;
   12200        56487 :   unsigned int ReturnVar;
   12201              : 
   12202        56487 :   M2Quads_PopT (&NoOfParam);
   12203        56487 :   functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
   12204        56487 :   if (NoOfParam == 2)
   12205              :     {
   12206        56487 :       PopTrwtok (&Exp, &r, &exptok);
   12207        56487 :       MarkAsRead (r);
   12208        56487 :       M2Quads_PopTtok (&Type, &typetok);
   12209        56487 :       M2Quads_PopT (&ProcSym);
   12210        56487 :       if (SymbolTable_IsUnknown (Type))
   12211              :         {
   12212              :           /* We cannot recover if we dont have a type.  */
   12213            0 :           M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type {%1Aad} found in {%kCONVERT} {%1&s}", 51, Type);
   12214              :           /* Non recoverable error.  */
   12215            0 :           SymbolTable_UnknownReported (Type);
   12216              :         }
   12217        56487 :       else if (SymbolTable_IsUnknown (Exp))
   12218              :         {
   12219              :           /* avoid dangling else.  */
   12220              :           /* We cannot recover if we dont have an expression.  */
   12221            0 :           M2MetaError_MetaErrorT1 (typetok, (const char *) "unknown {%1Ad} {%1ad} found in {%kCONVERT} {%1&s}", 49, Exp);
   12222              :           /* Non recoverable error.  */
   12223            0 :           SymbolTable_UnknownReported (Exp);
   12224              :         }
   12225        56487 :       else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
   12226              :         {
   12227              :           /* avoid dangling else.  */
   12228              :           /* Generate fake result.  */
   12229            0 :           combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
   12230            0 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
   12231            0 :           SymbolTable_PutVar (ReturnVar, Type);
   12232            0 :           M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12233              :         }
   12234        56487 :       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))))
   12235              :         {
   12236              :           /* avoid dangling else.  */
   12237              :           /* firstly dereference Var  */
   12238        56481 :           if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
   12239              :             {
   12240            0 :               t = SymbolTable_MakeTemporary (exptok, SymbolTable_RightValue);
   12241            0 :               SymbolTable_PutVar (t, SymbolTable_GetSType (Exp));
   12242            0 :               CheckPointerThroughNil (exptok, Exp);
   12243            0 :               doIndrX (exptok, t, Exp);
   12244            0 :               Exp = t;
   12245              :             }
   12246        56481 :           combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
   12247       112962 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
   12248        56481 :           SymbolTable_PutVar (ReturnVar, Type);
   12249       112962 :           GenQuadO (combinedtok, M2Quads_ConvertOp, ReturnVar, Type, Exp, true);
   12250        56481 :           M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12251              :         }
   12252              :       else
   12253              :         {
   12254              :           /* avoid dangling else.  */
   12255              :           /* non recoverable error.  */
   12256            6 :           M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkCONVERT} has the following formal parameter declaration {%kCONVERT} (type, expression)", 112);
   12257              :         }
   12258              :     }
   12259              :   else
   12260              :     {
   12261              :       /* non recoverable error.  */
   12262            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);
   12263              :     }
   12264        56481 : }
   12265              : 
   12266              : 
   12267              : /*
   12268              :    CheckBaseTypeValue - checks to see whether the value, min, really exists.
   12269              : */
   12270              : 
   12271         2019 : static unsigned int CheckBaseTypeValue (unsigned int tok, unsigned int type, unsigned int min, unsigned int func)
   12272              : {
   12273         2019 :   if (((type == M2Base_Real) || (type == M2Base_LongReal)) || (type == M2Base_ShortReal))
   12274              :     {
   12275          102 :       SymbolTable_PushValue (min);
   12276          102 :       if (! (M2ALU_IsValueAndTreeKnown ()))
   12277              :         {
   12278            0 :           M2MetaError_MetaErrorT2 (tok, (const char *) "{%1Ead} ({%2ad}) cannot be calculated at compile time for the target architecture", 81, func, type);
   12279            0 :           return SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType);
   12280              :         }
   12281              :     }
   12282              :   return min;
   12283              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   12284              :   __builtin_unreachable ();
   12285              : }
   12286              : 
   12287              : 
   12288              : /*
   12289              :    GetTypeMin - returns the minimium value of type and generate an error
   12290              :                 if this is unavailable.
   12291              : */
   12292              : 
   12293         1324 : static unsigned int GetTypeMin (unsigned int tok, unsigned int func, unsigned int type)
   12294              : {
   12295         1324 :   unsigned int min;
   12296              : 
   12297         1324 :   min = GetTypeMinLower (tok, func, type);
   12298         1324 :   if (min == SymbolTable_NulSym)
   12299              :     {
   12300            0 :       M2MetaError_MetaErrorT1 (tok, (const char *) "unable to obtain the {%AkMIN} value for type {%1ad}", 51, type);
   12301              :     }
   12302         1324 :   return min;
   12303              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   12304              :   __builtin_unreachable ();
   12305              : }
   12306              : 
   12307              : 
   12308              : /*
   12309              :    GetTypeMinLower - obtain the maximum value for type.
   12310              : */
   12311              : 
   12312         1324 : static unsigned int GetTypeMinLower (unsigned int tok, unsigned int func, unsigned int type)
   12313              : {
   12314         1324 :   unsigned int min;
   12315         1324 :   unsigned int max;
   12316              : 
   12317         1324 :   if (SymbolTable_IsSubrange (type))
   12318              :     {
   12319          306 :       min = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
   12320          306 :       SymbolTable_PutVar (min, type);
   12321          612 :       GenQuad (M2Quads_SubrangeLowOp, min, SymbolTable_NulSym, type);
   12322          306 :       return min;
   12323              :     }
   12324         1018 :   else if (SymbolTable_IsSet (SymbolTable_SkipType (type)))
   12325              :     {
   12326              :       /* avoid dangling else.  */
   12327           60 :       return GetTypeMin (tok, func, SymbolTable_GetSType (SymbolTable_SkipType (type)));
   12328              :     }
   12329          958 :   else if ((M2Base_IsBaseType (type)) || (SymbolTable_IsEnumeration (type)))
   12330              :     {
   12331              :       /* avoid dangling else.  */
   12332          756 :       M2Base_GetBaseTypeMinMax (type, &min, &max);
   12333          756 :       min = CheckBaseTypeValue (tok, type, min, func);
   12334          756 :       return min;
   12335              :     }
   12336          202 :   else if (M2System_IsSystemType (type))
   12337              :     {
   12338              :       /* avoid dangling else.  */
   12339          186 :       M2System_GetSystemTypeMinMax (type, &min, &max);
   12340          186 :       return min;
   12341              :     }
   12342           16 :   else if ((SymbolTable_GetSType (type)) == SymbolTable_NulSym)
   12343              :     {
   12344              :       /* avoid dangling else.  */
   12345              :       return SymbolTable_NulSym;
   12346              :     }
   12347              :   else
   12348              :     {
   12349              :       /* avoid dangling else.  */
   12350           16 :       return GetTypeMin (tok, func, SymbolTable_GetSType (type));
   12351              :     }
   12352              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   12353              :   __builtin_unreachable ();
   12354              : }
   12355              : 
   12356              : 
   12357              : /*
   12358              :    GetTypeMax - returns the maximum value of type and generate an error
   12359              :                 if this is unavailable.
   12360              : */
   12361              : 
   12362         2249 : static unsigned int GetTypeMax (unsigned int tok, unsigned int func, unsigned int type)
   12363              : {
   12364         2249 :   unsigned int max;
   12365              : 
   12366         2249 :   max = GetTypeMaxLower (tok, func, type);
   12367         2249 :   if (max == SymbolTable_NulSym)
   12368              :     {
   12369            0 :       M2MetaError_MetaErrorT1 (tok, (const char *) "unable to obtain the {%AkMAX} value for type {%1ad}", 51, type);
   12370              :     }
   12371         2249 :   return max;
   12372              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   12373              :   __builtin_unreachable ();
   12374              : }
   12375              : 
   12376              : 
   12377              : /*
   12378              :    GetTypeMaxLower - obtain the maximum value for type.
   12379              : */
   12380              : 
   12381         2249 : static unsigned int GetTypeMaxLower (unsigned int tok, unsigned int func, unsigned int type)
   12382              : {
   12383         2249 :   unsigned int min;
   12384         2249 :   unsigned int max;
   12385              : 
   12386         2249 :   if (SymbolTable_IsSubrange (type))
   12387              :     {
   12388          558 :       max = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
   12389          558 :       SymbolTable_PutVar (max, type);
   12390         1116 :       GenQuad (M2Quads_SubrangeHighOp, max, SymbolTable_NulSym, type);
   12391          558 :       return max;
   12392              :     }
   12393         1691 :   else if (SymbolTable_IsSet (SymbolTable_SkipType (type)))
   12394              :     {
   12395              :       /* avoid dangling else.  */
   12396          210 :       return GetTypeMax (tok, func, SymbolTable_GetSType (SymbolTable_SkipType (type)));
   12397              :     }
   12398         1481 :   else if ((M2Base_IsBaseType (type)) || (SymbolTable_IsEnumeration (type)))
   12399              :     {
   12400              :       /* avoid dangling else.  */
   12401         1263 :       M2Base_GetBaseTypeMinMax (type, &min, &max);
   12402         1263 :       min = CheckBaseTypeValue (tok, type, min, func);
   12403         1263 :       return max;
   12404              :     }
   12405          218 :   else if (M2System_IsSystemType (type))
   12406              :     {
   12407              :       /* avoid dangling else.  */
   12408          202 :       M2System_GetSystemTypeMinMax (type, &min, &max);
   12409          202 :       return max;
   12410              :     }
   12411           16 :   else if ((SymbolTable_GetSType (type)) == SymbolTable_NulSym)
   12412              :     {
   12413              :       /* avoid dangling else.  */
   12414              :       return SymbolTable_NulSym;
   12415              :     }
   12416              :   else
   12417              :     {
   12418              :       /* avoid dangling else.  */
   12419           16 :       return GetTypeMax (tok, func, SymbolTable_GetSType (type));
   12420              :     }
   12421              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   12422              :   __builtin_unreachable ();
   12423              : }
   12424              : 
   12425              : 
   12426              : /*
   12427              :    BuildMinFunction - builds the pseudo function call Min.
   12428              : 
   12429              :                       The Stack:
   12430              : 
   12431              :                       Entry                      Exit
   12432              : 
   12433              :                Ptr ->
   12434              :                       +----------------+
   12435              :                       | NoOfParam=1    |
   12436              :                       |----------------|
   12437              :                       | Param 1        |
   12438              :                       |----------------|
   12439              :                       | ProcSym | Type |         Empty
   12440              :                       |----------------|
   12441              : */
   12442              : 
   12443         1248 : static void BuildMinFunction (void)
   12444              : {
   12445         1248 :   unsigned int combinedtok;
   12446         1248 :   unsigned int functok;
   12447         1248 :   unsigned int vartok;
   12448         1248 :   unsigned int func;
   12449         1248 :   unsigned int min;
   12450         1248 :   unsigned int NoOfParam;
   12451         1248 :   unsigned int Var;
   12452              : 
   12453         1248 :   M2Quads_PopT (&NoOfParam);
   12454         1248 :   func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   12455         1248 :   functok = OperandTtok (NoOfParam+1);
   12456         1248 :   if (NoOfParam == 1)
   12457              :     {
   12458         1248 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   12459         1248 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   12460         1248 :       M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function  */
   12461         1248 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);  /* destroy arguments to this function  */
   12462         1248 :       if (SymbolTable_IsAModula2Type (Var))
   12463              :         {
   12464         1224 :           min = GetTypeMin (vartok, func, Var);
   12465         1224 :           M2Quads_PushTFtok (min, SymbolTable_GetSType (min), combinedtok);
   12466              :         }
   12467           24 :       else if (SymbolTable_IsVar (Var))
   12468              :         {
   12469              :           /* avoid dangling else.  */
   12470           24 :           min = GetTypeMin (vartok, func, SymbolTable_GetSType (Var));
   12471           24 :           M2Quads_PushTFtok (min, SymbolTable_GetSType (Var), combinedtok);
   12472              :         }
   12473              :       else
   12474              :         {
   12475              :           /* avoid dangling else.  */
   12476              :           /* non recoverable error.  */
   12477            0 :           M2MetaError_MetaErrorT1 (vartok, (const char *) "parameter to {%AkMIN} must be a type or a variable, seen {%1ad} {%1&s}", 70, Var);
   12478              :         }
   12479              :     }
   12480              :   else
   12481              :     {
   12482              :       /* non recoverable error.  */
   12483            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkMIN} only has one parameter, seen  {%1n}", 82, NoOfParam);
   12484              :     }
   12485         1248 : }
   12486              : 
   12487              : 
   12488              : /*
   12489              :    BuildMaxFunction - builds the pseudo function call Max.
   12490              : 
   12491              :                       The Stack:
   12492              : 
   12493              :                       Entry                      Exit
   12494              : 
   12495              :                Ptr ->
   12496              :                       +----------------+
   12497              :                       | NoOfParam=1    |
   12498              :                       |----------------|
   12499              :                       | Param 1        |
   12500              :                       |----------------|
   12501              :                       | ProcSym | Type |         Empty
   12502              :                       |----------------|
   12503              : */
   12504              : 
   12505         2023 : static void BuildMaxFunction (void)
   12506              : {
   12507         2023 :   unsigned int combinedtok;
   12508         2023 :   unsigned int functok;
   12509         2023 :   unsigned int vartok;
   12510         2023 :   unsigned int func;
   12511         2023 :   unsigned int max;
   12512         2023 :   unsigned int NoOfParam;
   12513         2023 :   unsigned int Var;
   12514              : 
   12515         2023 :   M2Quads_PopT (&NoOfParam);
   12516         2023 :   func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   12517         2023 :   functok = OperandTtok (NoOfParam+1);
   12518         2023 :   if (NoOfParam == 1)
   12519              :     {
   12520         2023 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   12521         2023 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   12522         2023 :       M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function  */
   12523         2023 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);  /* destroy arguments to this function  */
   12524         2023 :       if (SymbolTable_IsAModula2Type (Var))
   12525              :         {
   12526         2023 :           max = GetTypeMax (vartok, func, Var);
   12527         2023 :           M2Quads_PushTFtok (max, SymbolTable_GetSType (max), combinedtok);
   12528              :         }
   12529            0 :       else if (SymbolTable_IsVar (Var))
   12530              :         {
   12531              :           /* avoid dangling else.  */
   12532            0 :           max = GetTypeMax (vartok, func, SymbolTable_GetSType (Var));
   12533            0 :           M2Quads_PushTFtok (max, SymbolTable_GetSType (Var), combinedtok);
   12534              :         }
   12535              :       else
   12536              :         {
   12537              :           /* avoid dangling else.  */
   12538              :           /* non recoverable error.  */
   12539            0 :           M2MetaError_MetaErrorT1 (vartok, (const char *) "parameter to {%AkMAX} must be a type or a variable, seen {%1ad} {%1&s}", 70, Var);
   12540              :         }
   12541              :     }
   12542              :   else
   12543              :     {
   12544              :       /* non recoverable error.  */
   12545            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkMAX} only has one parameter, seen {%1n}", 81, NoOfParam);
   12546              :     }
   12547         2023 : }
   12548              : 
   12549              : 
   12550              : /*
   12551              :    BuildTruncFunction - builds the pseudo procedure call TRUNC.
   12552              :                         This procedure is actually a "macro" for
   12553              :                         TRUNC(x) --> CONVERT(INTEGER, x)
   12554              :                         However we cannot push tokens back onto the input stack
   12555              :                         because the compiler is currently building a function
   12556              :                         call and expecting a ReturnVar on the stack.
   12557              :                         Hence we manipulate the stack and call
   12558              :                         BuildConvertFunction.
   12559              : 
   12560              :                         The Stack:
   12561              : 
   12562              : 
   12563              :                         Entry                      Exit
   12564              : 
   12565              :                  Ptr ->
   12566              :                         +----------------+
   12567              :                         | NoOfParam      |
   12568              :                         |----------------|
   12569              :                         | Param 1        |
   12570              :                         |----------------|
   12571              :                         | Param 2        |
   12572              :                         |----------------|
   12573              :                         .                .
   12574              :                         .                .
   12575              :                         .                .
   12576              :                         |----------------|
   12577              :                         | Param #        |
   12578              :                         |----------------|
   12579              :                         | ProcSym | Type |         Empty
   12580              :                         |----------------|
   12581              : */
   12582              : 
   12583           60 : static void BuildTruncFunction (unsigned int Sym, bool ConstExpr)
   12584              : {
   12585           60 :   unsigned int combinedtok;
   12586           60 :   unsigned int vartok;
   12587           60 :   unsigned int functok;
   12588           60 :   unsigned int NoOfParam;
   12589           60 :   unsigned int ReturnVar;
   12590           60 :   unsigned int ProcSym;
   12591           60 :   unsigned int Type;
   12592           60 :   unsigned int Var;
   12593              : 
   12594           60 :   M2Quads_PopT (&NoOfParam);
   12595           60 :   M2Debug_Assert (M2Base_IsTrunc (M2Quads_OperandT (NoOfParam+1)));
   12596           60 :   functok = OperandTtok (NoOfParam+1);
   12597           60 :   if (NoOfParam == 1)
   12598              :     {
   12599           60 :       ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "CONVERT", 7));
   12600           60 :       if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
   12601              :         {
   12602           60 :           Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   12603           60 :           vartok = OperandTtok (1);
   12604           60 :           Type = SymbolTable_GetSType (Sym);
   12605           60 :           M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function  */
   12606           60 :           if (ConstExprError (Sym, Var, vartok, ConstExpr))
   12607              :             {
   12608              :               /* Generate fake result.  */
   12609            6 :               combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
   12610           12 :               ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   12611            6 :               SymbolTable_PutVar (ReturnVar, Type);
   12612            6 :               M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12613              :             }
   12614           54 :           else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   12615              :             {
   12616              :               /* avoid dangling else.  */
   12617           54 :               if (M2Base_IsRealType (SymbolTable_GetSType (Var)))
   12618              :                 {
   12619              :                   /* build macro: CONVERT( INTEGER, Var ).  */
   12620           54 :                   M2Quads_PushTFtok (ProcSym, static_cast<unsigned int> (SymbolTable_NulSym), functok);
   12621           54 :                   M2Quads_PushTtok (Type, functok);
   12622           54 :                   M2Quads_PushTtok (Var, vartok);
   12623           54 :                   M2Quads_PushT (static_cast<unsigned int> (2));  /* two parameters  */
   12624           54 :                   BuildConvertFunction (M2Base_Convert, ConstExpr);  /* two parameters  */
   12625              :                 }
   12626              :               else
   12627              :                 {
   12628            0 :                   M2MetaError_MetaErrorT1 (functok, (const char *) "argument to {%1Ead} must be a float point type", 46, Sym);
   12629            0 :                   M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), Type), Type, functok);
   12630              :                 }
   12631              :             }
   12632              :           else
   12633              :             {
   12634              :               /* avoid dangling else.  */
   12635            0 :               M2MetaError_MetaErrorT2 (vartok, (const char *) "argument to {%1Ead} must be a variable or constant, seen {%2ad} {%2&s}", 70, Sym, Var);
   12636            0 :               M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), Type), Type, functok);
   12637              :             }
   12638              :         }
   12639              :       else
   12640              :         {
   12641            0 :           M2Error_InternalError ((const char *) "CONVERT procedure not found for TRUNC substitution", 50);
   12642              :         }
   12643              :     }
   12644              :   else
   12645              :     {
   12646              :       /* non recoverable error.  */
   12647            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkTRUNC} only has one parameter, seen  {%1n}", 84, NoOfParam);
   12648              :     }
   12649           60 : }
   12650              : 
   12651              : 
   12652              : /*
   12653              :    BuildFloatFunction - builds the pseudo procedure call FLOAT.
   12654              :                         This procedure is actually a "macro" for
   12655              :                         FLOAT(x) --> CONVERT(REAL, x)
   12656              :                         However we cannot push tokens back onto the input stack
   12657              :                         because the compiler is currently building a function
   12658              :                         call and expecting a ReturnVar on the stack.
   12659              :                         Hence we manipulate the stack and call
   12660              :                         BuildConvertFunction.
   12661              : 
   12662              :                         The Stack:
   12663              : 
   12664              : 
   12665              :                         Entry                      Exit
   12666              : 
   12667              :                  Ptr ->
   12668              :                         +----------------+
   12669              :                         | NoOfParam      |
   12670              :                         |----------------|
   12671              :                         | Param 1        |
   12672              :                         |----------------|
   12673              :                         | Param 2        |
   12674              :                         |----------------|
   12675              :                         .                .
   12676              :                         .                .
   12677              :                         .                .
   12678              :                         |----------------|
   12679              :                         | Param #        |
   12680              :                         |----------------|
   12681              :                         | ProcSym | Type |         Empty
   12682              :                         |----------------|
   12683              : */
   12684              : 
   12685           88 : static void BuildFloatFunction (unsigned int Sym, bool ConstExpr)
   12686              : {
   12687           88 :   unsigned int combinedtok;
   12688           88 :   unsigned int vartok;
   12689           88 :   unsigned int functok;
   12690           88 :   unsigned int NoOfParam;
   12691           88 :   unsigned int ReturnVar;
   12692           88 :   unsigned int Type;
   12693           88 :   unsigned int Var;
   12694           88 :   unsigned int ProcSym;
   12695              : 
   12696           88 :   M2Quads_PopT (&NoOfParam);
   12697           88 :   functok = OperandTtok (NoOfParam+1);
   12698           88 :   Type = SymbolTable_GetSType (Sym);
   12699           88 :   if (NoOfParam == 1)
   12700              :     {
   12701           88 :       ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "CONVERT", 7));
   12702           88 :       if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
   12703              :         {
   12704           88 :           Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   12705           88 :           vartok = OperandTtok (1);
   12706           88 :           M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function.  */
   12707           88 :           if (ConstExprError (Sym, Var, vartok, ConstExpr))
   12708              :             {
   12709              :               /* Generate fake result.  */
   12710            6 :               combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
   12711           12 :               ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   12712            6 :               SymbolTable_PutVar (ReturnVar, Type);
   12713            6 :               M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12714              :             }
   12715           82 :           else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   12716              :             {
   12717              :               /* avoid dangling else.  */
   12718              :               /* build macro: CONVERT (REAL, Var).  */
   12719           82 :               M2Quads_PushTFtok (ProcSym, static_cast<unsigned int> (SymbolTable_NulSym), functok);
   12720           82 :               M2Quads_PushTtok (Type, functok);
   12721           82 :               M2Quads_PushTtok (Var, vartok);
   12722           82 :               M2Quads_PushT (static_cast<unsigned int> (2));  /* two parameters.  */
   12723           82 :               BuildConvertFunction (ProcSym, ConstExpr);  /* two parameters.  */
   12724              :             }
   12725              :           else
   12726              :             {
   12727              :               /* avoid dangling else.  */
   12728            0 :               M2MetaError_MetaErrorT1 (vartok, (const char *) "argument to {%1Ead} must be a variable or constant", 50, ProcSym);
   12729            0 :               M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0.0", 3), Type), Type, functok);
   12730              :             }
   12731              :         }
   12732              :       else
   12733              :         {
   12734            0 :           M2Error_InternalError ((const char *) "CONVERT procedure not found for FLOAT substitution", 50);
   12735              :         }
   12736              :     }
   12737              :   else
   12738              :     {
   12739            0 :       M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function.  */
   12740            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter", 61, Sym);  /* destroy arguments to this function.  */
   12741            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0.0", 3), Type), Type, functok);
   12742              :     }
   12743           88 : }
   12744              : 
   12745              : 
   12746              : /*
   12747              :    BuildReFunction - builds the pseudo procedure call RE.
   12748              : 
   12749              :                      The Stack:
   12750              : 
   12751              : 
   12752              :                          Entry                      Exit
   12753              : 
   12754              :                  Ptr ->
   12755              :                         +----------------+
   12756              :                         | NoOfParam      |
   12757              :                         |----------------|
   12758              :                         | Param 1        |
   12759              :                         |----------------|
   12760              :                         | Param 2        |
   12761              :                         |----------------|
   12762              :                         .                .
   12763              :                         .                .
   12764              :                         .                .
   12765              :                         |----------------|
   12766              :                         | Param #        |
   12767              :                         |----------------|
   12768              :                         | ProcSym | Type |         Empty
   12769              :                         |----------------|
   12770              : */
   12771              : 
   12772           84 : static void BuildReFunction (unsigned int Sym, bool ConstExpr)
   12773              : {
   12774           84 :   unsigned int func;
   12775           84 :   unsigned int combinedtok;
   12776           84 :   unsigned int vartok;
   12777           84 :   unsigned int functok;
   12778           84 :   unsigned int NoOfParam;
   12779           84 :   unsigned int ReturnVar;
   12780           84 :   unsigned int Type;
   12781           84 :   unsigned int Var;
   12782              : 
   12783           84 :   M2Quads_PopT (&NoOfParam);
   12784           84 :   functok = OperandTtok (NoOfParam+1);
   12785           84 :   func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   12786           84 :   if (NoOfParam == 1)
   12787              :     {
   12788           84 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   12789           84 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   12790           84 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
   12791           84 :       Type = M2Base_ComplexToScalar (SymbolTable_GetDType (Var));
   12792           84 :       M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function  */
   12793           84 :       if (ConstExprError (Sym, Var, vartok, ConstExpr))
   12794              :         {
   12795              :           /* Generate fake result.  */
   12796            6 :           combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
   12797           12 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   12798            6 :           SymbolTable_PutVar (ReturnVar, Type);
   12799            6 :           M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12800              :         }
   12801           78 :       else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   12802              :         {
   12803              :           /* avoid dangling else.  */
   12804          156 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   12805           78 :           SymbolTable_PutVar (ReturnVar, Type);
   12806          156 :           GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Re, Var, false);
   12807           78 :           M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12808              :         }
   12809              :       else
   12810              :         {
   12811              :           /* avoid dangling else.  */
   12812            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, combinedtok);
   12813            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);
   12814              :         }
   12815              :     }
   12816              :   else
   12817              :     {
   12818            0 :       M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function  */
   12819            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, functok);  /* destroy arguments to this function  */
   12820            0 :       M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter, seen {%2n}", 73, func, NoOfParam);
   12821              :     }
   12822           84 : }
   12823              : 
   12824              : 
   12825              : /*
   12826              :    BuildImFunction - builds the pseudo procedure call IM.
   12827              : 
   12828              :                      The Stack:
   12829              : 
   12830              : 
   12831              :                          Entry                      Exit
   12832              : 
   12833              :                  Ptr ->
   12834              :                         +----------------+
   12835              :                         | NoOfParam      |
   12836              :                         |----------------|
   12837              :                         | Param 1        |
   12838              :                         |----------------|
   12839              :                         | Param 2        |
   12840              :                         |----------------|
   12841              :                         .                .
   12842              :                         .                .
   12843              :                         .                .
   12844              :                         |----------------|
   12845              :                         | Param #        |
   12846              :                         |----------------|
   12847              :                         | ProcSym | Type |         Empty
   12848              :                         |----------------|
   12849              : */
   12850              : 
   12851           84 : static void BuildImFunction (unsigned int Sym, bool ConstExpr)
   12852              : {
   12853           84 :   unsigned int func;
   12854           84 :   unsigned int combinedtok;
   12855           84 :   unsigned int vartok;
   12856           84 :   unsigned int functok;
   12857           84 :   unsigned int NoOfParam;
   12858           84 :   unsigned int ReturnVar;
   12859           84 :   unsigned int Type;
   12860           84 :   unsigned int Var;
   12861              : 
   12862           84 :   M2Quads_PopT (&NoOfParam);
   12863           84 :   functok = OperandTtok (NoOfParam+1);
   12864           84 :   func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   12865           84 :   if (NoOfParam == 1)
   12866              :     {
   12867           84 :       Var = static_cast<unsigned int> (M2Quads_OperandT (1));
   12868           84 :       vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   12869           84 :       Type = M2Base_ComplexToScalar (SymbolTable_GetDType (Var));
   12870           84 :       combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
   12871           84 :       M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function  */
   12872           84 :       if (ConstExprError (Sym, Var, vartok, ConstExpr))
   12873              :         {
   12874              :           /* Generate fake result.  */
   12875            6 :           combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
   12876           12 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   12877            6 :           SymbolTable_PutVar (ReturnVar, Type);
   12878            6 :           M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
   12879              :         }
   12880           78 :       else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
   12881              :         {
   12882              :           /* avoid dangling else.  */
   12883          156 :           ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
   12884           78 :           SymbolTable_PutVar (ReturnVar, M2Base_ComplexToScalar (SymbolTable_GetDType (Var)));
   12885          156 :           GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Im, Var, false);
   12886           78 :           M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), combinedtok);
   12887              :         }
   12888              :       else
   12889              :         {
   12890              :           /* avoid dangling else.  */
   12891            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, combinedtok);
   12892            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);
   12893              :         }
   12894              :     }
   12895              :   else
   12896              :     {
   12897            0 :       M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function  */
   12898            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, functok);  /* destroy arguments to this function  */
   12899            0 :       M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter, seen {%2n}", 73, func, NoOfParam);
   12900              :     }
   12901           84 : }
   12902              : 
   12903              : 
   12904              : /*
   12905              :    BuildCmplxFunction - builds the pseudo procedure call CMPLX.
   12906              : 
   12907              :                         The Stack:
   12908              : 
   12909              : 
   12910              :                         Entry                      Exit
   12911              : 
   12912              :                  Ptr ->
   12913              :                         +----------------+
   12914              :                         | NoOfParam      |
   12915              :                         |----------------|
   12916              :                         | Param 1        |
   12917              :                         |----------------|
   12918              :                         | Param 2        |
   12919              :                         |----------------|
   12920              :                         .                .
   12921              :                         .                .
   12922              :                         .                .
   12923              :                         |----------------|
   12924              :                         | Param #        |
   12925              :                         |----------------|
   12926              :                         | ProcSym | Type |         Empty
   12927              :                         |----------------|
   12928              : */
   12929              : 
   12930          612 : static void BuildCmplxFunction (unsigned int func, bool ConstExpr)
   12931              : {
   12932          612 :   bool failure;
   12933          612 :   unsigned int functok;
   12934          612 :   unsigned int rtok;
   12935          612 :   unsigned int ltok;
   12936          612 :   unsigned int combinedtok;
   12937          612 :   unsigned int NoOfParam;
   12938          612 :   unsigned int type;
   12939          612 :   unsigned int ReturnVar;
   12940          612 :   unsigned int l;
   12941          612 :   unsigned int r;
   12942              : 
   12943          612 :   M2Quads_PopT (&NoOfParam);
   12944          612 :   functok = OperandTtok (NoOfParam+1);
   12945          612 :   if (NoOfParam == 2)
   12946              :     {
   12947          612 :       l = static_cast<unsigned int> (M2Quads_OperandT (2));
   12948          612 :       ltok = OperandTtok (2);
   12949          612 :       r = static_cast<unsigned int> (M2Quads_OperandT (1));
   12950          612 :       rtok = OperandTtok (1);
   12951          612 :       combinedtok = M2LexBuf_MakeVirtual2Tok (functok, rtok);
   12952          612 :       M2Quads_PopN (NoOfParam+1);  /* Destroy arguments to this function.  */
   12953          612 :       type = M2Base_GetCmplxReturnType (SymbolTable_GetDType (l), SymbolTable_GetDType (r));  /* Destroy arguments to this function.  */
   12954          738 :       ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant ((SymbolTable_IsConst (l)) && (SymbolTable_IsConst (r))));
   12955          612 :       SymbolTable_PutVar (ReturnVar, type);
   12956          612 :       failure = false;
   12957          612 :       if (ConstExprError (func, l, ltok, ConstExpr))
   12958              :         {
   12959              :           /* ConstExprError has generated an error message we will fall through
   12960              :             and check the right operand.  */
   12961              :           failure = true;
   12962              :         }
   12963          612 :       if (ConstExprError (func, r, rtok, ConstExpr))
   12964              :         {
   12965              :           /* Right operand is in error as a variable.  */
   12966              :           failure = true;
   12967              :         }
   12968          606 :       if (failure)
   12969              :         {
   12970              :           /* Generate a fake result if either operand was a variable (and we
   12971              :             are in a const expression).  */
   12972            6 :           M2Quads_PushTFtok (ReturnVar, type, combinedtok);
   12973              :         }
   12974          606 :       else if (((SymbolTable_IsVar (l)) || (SymbolTable_IsConst (l))) && ((SymbolTable_IsVar (r)) || (SymbolTable_IsConst (r))))
   12975              :         {
   12976              :           /* avoid dangling else.  */
   12977          606 :           M2Base_CheckExpressionCompatible (combinedtok, SymbolTable_GetSType (l), SymbolTable_GetSType (r));
   12978          606 :           GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Cmplx, SymbolTable_Make2Tuple (l, r), true);
   12979          606 :           M2Quads_PushTFtok (ReturnVar, type, combinedtok);
   12980              :         }
   12981              :       else
   12982              :         {
   12983              :           /* avoid dangling else.  */
   12984            0 :           if ((SymbolTable_IsVar (l)) || (SymbolTable_IsConst (l)))
   12985              :             {
   12986            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);
   12987              :             }
   12988              :           else
   12989              :             {
   12990            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);
   12991              :             }
   12992            0 :           M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_CType), M2Base_CType, combinedtok);
   12993              :         }
   12994              :     }
   12995              :   else
   12996              :     {
   12997            0 :       M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure {%1Ead} requires two parameters, seen {%2n}", 65, func, NoOfParam);
   12998            0 :       M2Quads_PopN (NoOfParam+1);  /* destroy arguments to this function  */
   12999            0 :       M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_CType), M2Base_CType, functok);  /* destroy arguments to this function  */
   13000              :     }
   13001          612 : }
   13002              : 
   13003              : 
   13004              : /*
   13005              :    BuildAdrFunction - builds the pseudo function ADR
   13006              :                       The Stack:
   13007              : 
   13008              : 
   13009              :                       Entry                      Exit
   13010              : 
   13011              :                Ptr ->
   13012              :                       +----------------+
   13013              :                       | NoOfParam      |
   13014              :                       |----------------|
   13015              :                       | Param 1        |
   13016              :                       |----------------|
   13017              :                       | Param 2        |
   13018              :                       |----------------|
   13019              :                       .                .
   13020              :                       .                .
   13021              :                       .                .
   13022              :                       |----------------|
   13023              :                       | Param #        |                        <- Ptr
   13024              :                       |----------------|         +------------+
   13025              :                       | ProcSym | Type |         | ReturnVar  |
   13026              :                       |----------------|         |------------|
   13027              : 
   13028              : */
   13029              : 
   13030       177984 : static void BuildAdrFunction (void)
   13031              : {
   13032       177984 :   unsigned int param;
   13033       177984 :   unsigned int paramTok;
   13034       177984 :   unsigned int combinedTok;
   13035       177984 :   unsigned int procTok;
   13036       177984 :   unsigned int t;
   13037       177984 :   unsigned int UnboundedSym;
   13038       177984 :   unsigned int Dim;
   13039       177984 :   unsigned int Field;
   13040       177984 :   unsigned int noOfParameters;
   13041       177984 :   unsigned int procSym;
   13042       177984 :   unsigned int returnVar;
   13043       177984 :   unsigned int Type;
   13044       177984 :   unsigned int rw;
   13045              : 
   13046       177984 :   M2Quads_DisplayStack ();
   13047       177984 :   M2Quads_PopT (&noOfParameters);
   13048       177984 :   procSym = static_cast<unsigned int> (M2Quads_OperandT (noOfParameters+1));
   13049       177984 :   procTok = static_cast<unsigned int> (M2Quads_OperandTok (noOfParameters+1));  /* token of procedure ADR.  */
   13050       177984 :   paramTok = static_cast<unsigned int> (M2Quads_OperandTok (1));  /* last parameter.  */
   13051       177984 :   param = static_cast<unsigned int> (M2Quads_OperandT (1));  /* last parameter.  */
   13052       177984 :   combinedTok = M2LexBuf_MakeVirtualTok (procTok, procTok, static_cast<unsigned int> (M2Reserved_endtok));
   13053       177984 :   if (noOfParameters != 1)
   13054              :     {
   13055            0 :       M2MetaError_MetaErrorNT0 (combinedTok, (const char *) "SYSTEM procedure ADR expects 1 parameter", 40);
   13056            0 :       M2Quads_PopN (noOfParameters+1);  /* destroy the arguments and function  */
   13057            0 :       M2Quads_PushTF (M2Base_Nil, M2System_Address);  /* destroy the arguments and function  */
   13058              :     }
   13059       177984 :   else if (SymbolTable_IsConstString (param))
   13060              :     {
   13061              :       /* avoid dangling else.  */
   13062       170243 :       returnVar = MakeLeftValue (combinedTok, param, SymbolTable_RightValue, SymbolTable_GetSType (procSym));
   13063       170243 :       M2Quads_PopN (noOfParameters+1);  /* destroy the arguments and function  */
   13064       170243 :       M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (returnVar), combinedTok);  /* destroy the arguments and function  */
   13065              :     }
   13066         7741 :   else if ((! (SymbolTable_IsVar (param))) && (! (SymbolTable_IsProcedure (param))))
   13067              :     {
   13068              :       /* avoid dangling else.  */
   13069            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);
   13070            1 :       M2Quads_PopN (noOfParameters+1);  /* destroy the arguments and function  */
   13071            1 :       M2Quads_PushTFtok (M2Base_Nil, M2System_Address, combinedTok);  /* destroy the arguments and function  */
   13072              :     }
   13073         7740 :   else if (SymbolTable_IsProcedure (param))
   13074              :     {
   13075              :       /* avoid dangling else.  */
   13076           24 :       returnVar = MakeLeftValue (combinedTok, param, SymbolTable_RightValue, SymbolTable_GetSType (procSym));
   13077           24 :       M2Quads_PopN (noOfParameters+1);  /* destroy the arguments and function  */
   13078           24 :       M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (returnVar), combinedTok);  /* destroy the arguments and function  */
   13079              :     }
   13080              :   else
   13081              :     {
   13082              :       /* avoid dangling else.  */
   13083         7716 :       Type = SymbolTable_GetSType (param);
   13084         7716 :       Dim = static_cast<unsigned int> (OperandD (1));
   13085         7716 :       MarkArrayWritten (param);
   13086         7716 :       MarkArrayWritten (M2Quads_OperandA (1));
   13087              :       /* if the operand is an unbounded which has not been indexed
   13088              :          then we will lookup its address from the unbounded record.
   13089              :          Otherwise we obtain the address of the operand.
   13090              :   */
   13091         7716 :       if ((SymbolTable_IsUnbounded (Type)) && (Dim == 0))
   13092              :         {
   13093              :           /* we will reference the address field of the unbounded structure  */
   13094         2369 :           UnboundedSym = param;
   13095         2369 :           rw = static_cast<unsigned int> (OperandRW (1));
   13096         2369 :           PushTFrw (UnboundedSym, SymbolTable_GetSType (UnboundedSym), rw);
   13097         2369 :           Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
   13098         2369 :           M2Quads_PushTF (Field, SymbolTable_GetSType (Field));
   13099         2369 :           M2Quads_PushT (static_cast<unsigned int> (1));
   13100         2369 :           M2Quads_BuildDesignatorRecord (combinedTok);
   13101         2369 :           PopTrw (&returnVar, &rw);
   13102         2369 :           if ((SymbolTable_GetMode (returnVar)) == SymbolTable_LeftValue)
   13103              :             {
   13104            0 :               t = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
   13105            0 :               SymbolTable_PutVar (t, SymbolTable_GetSType (procSym));
   13106            0 :               doIndrX (combinedTok, t, returnVar);
   13107            0 :               returnVar = t;
   13108              :             }
   13109              :           else
   13110              :             {
   13111              :               /* we need to cast returnVar into ADDRESS  */
   13112         2369 :               t = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
   13113         2369 :               SymbolTable_PutVar (t, SymbolTable_GetSType (procSym));
   13114         2369 :               GenQuadO (combinedTok, M2Quads_ConvertOp, t, SymbolTable_GetSType (procSym), returnVar, false);
   13115         2369 :               returnVar = t;
   13116              :             }
   13117              :         }
   13118              :       else
   13119              :         {
   13120         5347 :           returnVar = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
   13121         5347 :           SymbolTable_PutVar (returnVar, SymbolTable_GetSType (procSym));
   13122         5347 :           if ((SymbolTable_GetMode (param)) == SymbolTable_LeftValue)
   13123              :             {
   13124          439 :               SymbolTable_PutVar (returnVar, SymbolTable_GetSType (procSym));
   13125          439 :               GenQuadO (combinedTok, M2Quads_ConvertOp, returnVar, SymbolTable_GetSType (procSym), param, false);
   13126              :             }
   13127              :           else
   13128              :             {
   13129         4908 :               GenQuadO (combinedTok, M2Quads_AddrOp, returnVar, SymbolTable_NulSym, param, false);
   13130              :             }
   13131         5347 :           SymbolTable_PutWriteQuad (param, SymbolTable_GetMode (param), NextQuad-1);
   13132         5347 :           rw = static_cast<unsigned int> (OperandMergeRW (1));
   13133         5347 :           M2Debug_Assert (SymbolTable_IsLegal (rw));
   13134              :         }
   13135         7716 :       M2Quads_PopN (noOfParameters+1);  /* destroy the arguments and function  */
   13136         7716 :       PushTFrwtok (returnVar, SymbolTable_GetSType (returnVar), rw, combinedTok);  /* destroy the arguments and function  */
   13137              :     }
   13138       177984 : }
   13139              : 
   13140              : 
   13141              : /*
   13142              :    BuildSizeFunction - builds the pseudo function SIZE
   13143              :                        The Stack:
   13144              : 
   13145              : 
   13146              :                        Entry                      Exit
   13147              : 
   13148              :                 Ptr ->
   13149              :                        +----------------+
   13150              :                        | NoOfParam      |
   13151              :                        |----------------|
   13152              :                        | Param 1        |
   13153              :                        |----------------|
   13154              :                        | Param 2        |
   13155              :                        |----------------|
   13156              :                        .                .
   13157              :                        .                .
   13158              :                        .                .
   13159              :                        |----------------|
   13160              :                        | Param #        |                        <- Ptr
   13161              :                        |----------------|         +------------+
   13162              :                        | ProcSym | Type |         | ReturnVar  |
   13163              :                        |----------------|         |------------|
   13164              : */
   13165              : 
   13166         2097 : static void BuildSizeFunction (void)
   13167              : {
   13168         2097 :   unsigned int resulttok;
   13169         2097 :   unsigned int paramtok;
   13170         2097 :   unsigned int functok;
   13171         2097 :   unsigned int dim;
   13172         2097 :   unsigned int Type;
   13173         2097 :   unsigned int NoOfParam;
   13174         2097 :   unsigned int ProcSym;
   13175         2097 :   unsigned int ReturnVar;
   13176              : 
   13177         2097 :   M2Quads_PopT (&NoOfParam);
   13178         2097 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   13179         2097 :   functok = OperandTtok (NoOfParam+1);
   13180         2097 :   if (NoOfParam != 1)
   13181              :     {
   13182            0 :       M2MetaError_MetaErrorT1 (functok, (const char *) "{%E} SYSTEM procedure function {%kSIZE} requires one parameter, seen {%1n}", 74, NoOfParam);
   13183            0 :       resulttok = functok;
   13184            0 :       ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
   13185              :     }
   13186              :   else
   13187              :     {
   13188         2097 :       paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   13189         2097 :       resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   13190         2097 :       if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
   13191              :         {
   13192          992 :           BuildSizeCheckEnd (ProcSym);  /* Quadruple generation now on.  */
   13193          992 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);  /* Quadruple generation now on.  */
   13194          992 :           GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, M2Quads_OperandT (1), true);
   13195              :         }
   13196         1105 :       else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
   13197              :         {
   13198              :           /* avoid dangling else.  */
   13199         1098 :           BuildSizeCheckEnd (ProcSym);  /* Quadruple generation now on.  */
   13200         1098 :           Type = SymbolTable_GetSType (M2Quads_OperandT (1));  /* Quadruple generation now on.  */
   13201         1098 :           if (SymbolTable_IsUnbounded (Type))
   13202              :             {
   13203              :               /* Eg. SIZE(a) ; where a is unbounded dereference HIGH and multiply by the TYPE.  */
   13204          168 :               dim = static_cast<unsigned int> (OperandD (1));
   13205          168 :               if (dim == 0)
   13206              :                 {
   13207           72 :                   ReturnVar = calculateMultipicand (resulttok, M2Quads_OperandT (1), Type, dim);
   13208              :                 }
   13209              :               else
   13210              :                 {
   13211           96 :                   ReturnVar = calculateMultipicand (resulttok, M2Quads_OperandA (1), Type, dim);
   13212              :                 }
   13213              :             }
   13214              :           else
   13215              :             {
   13216          930 :               ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
   13217          930 :               if (Type == SymbolTable_NulSym)
   13218              :                 {
   13219            0 :                   M2MetaError_MetaErrorT1 (resulttok, (const char *) "cannot get the type and size of {%1Ead}", 39, M2Quads_OperandT (1));
   13220              :                 }
   13221          930 :               GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, Type, true);
   13222              :             }
   13223              :         }
   13224              :       else
   13225              :         {
   13226              :           /* avoid dangling else.  */
   13227            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));
   13228            7 :           ReturnVar = SymbolTable_MakeConstLit (paramtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
   13229              :         }
   13230              :     }
   13231         2097 :   M2Quads_PopN (NoOfParam+1);  /* Destroy the arguments and function.  */
   13232         2097 :   M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok);  /* Destroy the arguments and function.  */
   13233         2097 : }
   13234              : 
   13235              : 
   13236              : /*
   13237              :    BuildTSizeFunction - builds the pseudo function TSIZE
   13238              :                         The Stack:
   13239              : 
   13240              : 
   13241              :                         Entry                      Exit
   13242              : 
   13243              :                  Ptr ->
   13244              :                         +----------------+
   13245              :                         | NoOfParam      |
   13246              :                         |----------------|
   13247              :                         | Param 1        |
   13248              :                         |----------------|
   13249              :                         | Param 2        |
   13250              :                         |----------------|
   13251              :                         .                .
   13252              :                         .                .
   13253              :                         .                .
   13254              :                         |----------------|
   13255              :                         | Param #        |                        <- Ptr
   13256              :                         |----------------|         +------------+
   13257              :                         | ProcSym | Type |         | ReturnVar  |
   13258              :                         |----------------|         |------------|
   13259              : 
   13260              : */
   13261              : 
   13262         4766 : static void BuildTSizeFunction (void)
   13263              : {
   13264         4766 :   unsigned int resulttok;
   13265         4766 :   unsigned int paramtok;
   13266         4766 :   unsigned int functok;
   13267         4766 :   unsigned int NoOfParam;
   13268         4766 :   unsigned int ProcSym;
   13269         4766 :   unsigned int Record;
   13270         4766 :   unsigned int ReturnVar;
   13271              : 
   13272         4766 :   M2Quads_PopT (&NoOfParam);
   13273         4766 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   13274         4766 :   functok = OperandTtok (NoOfParam);
   13275         4766 :   BuildSizeCheckEnd (ProcSym);  /* quadruple generation now on  */
   13276         4766 :   if (NoOfParam == 1)  /* quadruple generation now on  */
   13277              :     {
   13278         4766 :       paramtok = OperandTtok (1);
   13279         4766 :       resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   13280         4766 :       if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
   13281              :         {
   13282         4732 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
   13283         4732 :           SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
   13284         4732 :           GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, M2Quads_OperandT (1), false);
   13285              :         }
   13286           34 :       else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
   13287              :         {
   13288              :           /* avoid dangling else.  */
   13289           28 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
   13290           28 :           SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
   13291           28 :           GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, SymbolTable_GetSType (M2Quads_OperandT (1)), false);
   13292              :         }
   13293              :       else
   13294              :         {
   13295              :           /* avoid dangling else.  */
   13296              :           /* Spellcheck.  */
   13297            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));
   13298            6 :           ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
   13299              :         }
   13300              :     }
   13301            0 :   else if (NoOfParam == 0)
   13302              :     {
   13303              :       /* avoid dangling else.  */
   13304            0 :       resulttok = functok;
   13305            0 :       M2MetaError_MetaErrorT0 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTSIZE} expects either one or two parameters, seen none", 87);
   13306            0 :       ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
   13307              :     }
   13308              :   else
   13309              :     {
   13310              :       /* avoid dangling else.  */
   13311            0 :       Record = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
   13312            0 :       paramtok = OperandTtok (1);
   13313            0 :       resulttok = OperandTtok (NoOfParam);
   13314            0 :       if (SymbolTable_IsRecord (Record))
   13315              :         {
   13316            0 :           paramtok = OperandTtok (1);
   13317            0 :           resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   13318            0 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
   13319            0 :           SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
   13320            0 :           GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, Record, false);
   13321              :         }
   13322              :       else
   13323              :         {
   13324            0 :           resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   13325            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);
   13326            0 :           ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
   13327              :         }
   13328              :     }
   13329         4766 :   M2Quads_PopN (NoOfParam+1);  /* destroy the arguments and function  */
   13330         4766 :   M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok);  /* destroy the arguments and function  */
   13331         4766 : }
   13332              : 
   13333              : 
   13334              : /*
   13335              :    BuildTBitSizeFunction - builds the pseudo function TBITSIZE
   13336              :                            The Stack:
   13337              : 
   13338              : 
   13339              :                            Entry                      Exit
   13340              : 
   13341              :                    Ptr ->
   13342              :                            +----------------+
   13343              :                            | NoOfParam      |
   13344              :                            |----------------|
   13345              :                            | Param 1        |
   13346              :                            |----------------|
   13347              :                            | Param 2        |
   13348              :                            |----------------|
   13349              :                            .                .
   13350              :                            .                .
   13351              :                            .                .
   13352              :                            |----------------|
   13353              :                            | Param #        |                        <- Ptr
   13354              :                            |----------------|         +------------+
   13355              :                            | ProcSym | Type |         | ReturnVar  |
   13356              :                            |----------------|         |------------|
   13357              : 
   13358              : */
   13359              : 
   13360         6508 : static void BuildTBitSizeFunction (void)
   13361              : {
   13362         6508 :   unsigned int resulttok;
   13363         6508 :   unsigned int paramtok;
   13364         6508 :   unsigned int functok;
   13365         6508 :   unsigned int NoOfParam;
   13366         6508 :   unsigned int ProcSym;
   13367         6508 :   unsigned int Record;
   13368         6508 :   unsigned int ReturnVar;
   13369              : 
   13370         6508 :   M2Quads_PopT (&NoOfParam);
   13371         6508 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   13372         6508 :   functok = OperandTtok (NoOfParam);
   13373         6508 :   BuildSizeCheckEnd (ProcSym);  /* quadruple generation now on  */
   13374         6508 :   if (NoOfParam == 1)  /* quadruple generation now on  */
   13375              :     {
   13376         6508 :       paramtok = OperandTtok (1);
   13377         6508 :       resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   13378         6508 :       if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
   13379              :         {
   13380         6436 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
   13381         6436 :           GenQuadO (resulttok, M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1), false);
   13382              :         }
   13383           72 :       else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
   13384              :         {
   13385              :           /* avoid dangling else.  */
   13386           72 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
   13387           72 :           GenQuadO (resulttok, M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1), false);
   13388              :         }
   13389              :       else
   13390              :         {
   13391              :           /* avoid dangling else.  */
   13392            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));
   13393            0 :           ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
   13394              :         }
   13395              :     }
   13396            0 :   else if (NoOfParam == 0)
   13397              :     {
   13398              :       /* avoid dangling else.  */
   13399            0 :       resulttok = functok;
   13400            0 :       M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure function {%kTBITSIZE} expects either one or two parameters, seen none", 90);
   13401            0 :       ReturnVar = SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
   13402              :     }
   13403              :   else
   13404              :     {
   13405              :       /* avoid dangling else.  */
   13406            0 :       Record = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
   13407            0 :       paramtok = OperandTtok (1);
   13408            0 :       resulttok = OperandTtok (NoOfParam);
   13409            0 :       if (SymbolTable_IsRecord (Record))
   13410              :         {
   13411            0 :           paramtok = OperandTtok (1);
   13412            0 :           resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   13413            0 :           ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
   13414            0 :           GenQuad (M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1));
   13415              :         }
   13416              :       else
   13417              :         {
   13418            0 :           resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   13419            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);
   13420            0 :           ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
   13421              :         }
   13422              :     }
   13423         6508 :   M2Quads_PopN (NoOfParam+1);  /* destroy the arguments and function  */
   13424         6508 :   M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok);  /* destroy the arguments and function  */
   13425         6508 : }
   13426              : 
   13427              : 
   13428              : /*
   13429              :    ExpectingParameterType -
   13430              : */
   13431              : 
   13432        94156 : static void ExpectingParameterType (unsigned int BlockSym, unsigned int Type)
   13433              : {
   13434        94156 :   if (! (SymbolTable_IsAModula2Type (Type)))
   13435              :     {
   13436              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   13437            6 :       if (((Type == SymbolTable_NulSym) || (SymbolTable_IsPartialUnbounded (Type))) || (SymbolTable_IsUnknown (Type)))
   13438              :         {
   13439            0 :           if (SymbolTable_IsUnknown (Type))
   13440              :             {
   13441              :               /* Spellcheck.  */
   13442            0 :               M2MetaError_MetaError2 ((const char *) "the type used in the formal parameter declaration in {%1Md} {%1a} is unknown {%2&s}", 83, BlockSym, Type);
   13443            0 :               SymbolTable_UnknownReported (Type);
   13444              :             }
   13445              :           else
   13446              :             {
   13447            0 :               M2MetaError_MetaError1 ((const char *) "the type used in the formal parameter declaration in {%1Md} {%1a} is unknown", 76, BlockSym);
   13448              :             }
   13449              :         }
   13450              :       else
   13451              :         {
   13452              :           /* --fixme-- filter spellcheck on type.  */
   13453            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);
   13454              :         }
   13455              :     }
   13456        94156 : }
   13457              : 
   13458              : 
   13459              : /*
   13460              :    ExpectingVariableType -
   13461              : */
   13462              : 
   13463        82244 : static void ExpectingVariableType (unsigned int BlockSym, unsigned int Type)
   13464              : {
   13465        82244 :   if (! (SymbolTable_IsAModula2Type (Type)))
   13466              :     {
   13467              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   13468            0 :       if (Type == SymbolTable_NulSym)
   13469              :         {
   13470            0 :           M2MetaError_MetaError1 ((const char *) "the type used during the variable declaration section in procedure {%1EMad} is unknown", 86, BlockSym);
   13471            0 :           M2MetaError_MetaError1 ((const char *) "the type used during the variable declaration section in procedure {%1Ead} is unknown", 85, BlockSym);
   13472              :         }
   13473            0 :       else if ((SymbolTable_IsPartialUnbounded (Type)) || (SymbolTable_IsUnknown (Type)))
   13474              :         {
   13475              :           /* avoid dangling else.  */
   13476              :           /* Spellcheck.  */
   13477            0 :           M2MetaError_MetaError2 ((const char *) "the type {%1EMad} used during variable declaration section in procedure {%2ad} is unknown {%1&s}", 96, Type, BlockSym);
   13478            0 :           M2MetaError_MetaError2 ((const char *) "the type {%1Ead} used during variable declaration section in procedure {%2Mad} is unknown", 89, Type, BlockSym);
   13479            0 :           SymbolTable_UnknownReported (Type);
   13480              :         }
   13481              :       else
   13482              :         {
   13483              :           /* avoid dangling else.  */
   13484            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);
   13485              :         }
   13486              :     }
   13487        82244 : }
   13488              : 
   13489              : 
   13490              : /*
   13491              :    CheckVariablesAndParameterTypesInBlock - checks to make sure that block, BlockSym, has
   13492              :                                             parameters types and variable types which are legal.
   13493              : */
   13494              : 
   13495       183130 : static void CheckVariablesAndParameterTypesInBlock (unsigned int BlockSym)
   13496              : {
   13497       183130 :   unsigned int i;
   13498       183130 :   unsigned int n;
   13499       183130 :   unsigned int ParamNo;
   13500              : 
   13501       183130 :   if (SymbolTable_IsProcedure (BlockSym))
   13502              :     {
   13503        82730 :       ParamNo = SymbolTable_NoOfParamAny (BlockSym);
   13504              :     }
   13505              :   else
   13506              :     {
   13507              :       ParamNo = 0;
   13508              :     }
   13509       183130 :   i = 1;
   13510      1315055 :   do {
   13511      1315055 :     n = SymbolTable_GetNth (BlockSym, i);
   13512      1315055 :     if (((n != SymbolTable_NulSym) && (! (SymbolTable_IsTemporary (n)))) && ((SymbolTable_IsProcedure (BlockSym)) || (((SymbolTable_IsDefImp (BlockSym)) && ((SymbolTable_GetMainModule ()) == BlockSym)) || (SymbolTable_IsModule (BlockSym)))))
   13513              :       {
   13514              :         /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   13515       176400 :         if (i <= ParamNo)
   13516              :           {
   13517              :             /* n is a parameter  */
   13518        94156 :             ExpectingParameterType (BlockSym, SymbolTable_GetSType (n));
   13519              :           }
   13520              :         else
   13521              :           {
   13522              :             /* n is a local variable  */
   13523        82244 :             ExpectingVariableType (BlockSym, SymbolTable_GetSType (n));
   13524              :           }
   13525              :       }
   13526      1315055 :     i += 1;
   13527      1315055 :   } while (! (n == SymbolTable_NulSym));
   13528       183130 : }
   13529              : 
   13530              : 
   13531              : /*
   13532              :    IsNeverAltered - returns TRUE if variable, sym, is never altered
   13533              :                     between quadruples: Start..End
   13534              : */
   13535              : 
   13536           30 : static bool IsNeverAltered (unsigned int sym, unsigned int Start, unsigned int End)
   13537              : {
   13538           30 :   unsigned int WriteStart;
   13539           30 :   unsigned int WriteEnd;
   13540              : 
   13541           30 :   SymbolTable_GetWriteLimitQuads (sym, SymbolTable_GetMode (sym), Start, End, &WriteStart, &WriteEnd);
   13542           30 :   return (WriteStart == 0) && (WriteEnd == 0);
   13543              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   13544              :   __builtin_unreachable ();
   13545              : }
   13546              : 
   13547              : 
   13548              : /*
   13549              :    IsConditionVariable - returns TRUE if the condition at quadruple, q, is variable.
   13550              : */
   13551              : 
   13552           24 : static bool IsConditionVariable (unsigned int q, unsigned int Start, unsigned int End)
   13553              : {
   13554           24 :   M2Quads_QuadOperator op;
   13555           24 :   unsigned int op1;
   13556           24 :   unsigned int op2;
   13557           24 :   unsigned int op3;
   13558           24 :   bool LeftFixed;
   13559           24 :   bool RightFixed;
   13560              : 
   13561           24 :   M2Quads_GetQuad (q, &op, &op1, &op2, &op3);
   13562           24 :   if (op == M2Quads_GotoOp)
   13563              :     {
   13564              :       return false;
   13565              :     }
   13566              :   else
   13567              :     {
   13568           24 :       LeftFixed = SymbolTable_IsConst (op1);
   13569           24 :       RightFixed = SymbolTable_IsConst (op2);
   13570           24 :       if (! LeftFixed)
   13571              :         {
   13572           24 :           LeftFixed = IsNeverAltered (op1, Start, End);
   13573              :         }
   13574           24 :       if (! RightFixed)
   13575              :         {
   13576            6 :           RightFixed = IsNeverAltered (op2, Start, End);
   13577              :         }
   13578           24 :       return ! (LeftFixed && RightFixed);
   13579              :     }
   13580              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   13581              :   __builtin_unreachable ();
   13582              : }
   13583              : 
   13584              : 
   13585              : /*
   13586              :    IsInfiniteLoop - returns TRUE if an infinite loop is found.
   13587              :                     Given a backwards jump at, End, it returns a BOOLEAN which depends on
   13588              :                     whether a jump is found to jump beyond, End. If a conditonal jump is found
   13589              :                     to pass over, End, the condition is tested for global variables, procedure variables and
   13590              :                     constants.
   13591              : 
   13592              :                          constant        - ignored
   13593              :                          variables       - tested to see whether they are altered inside the loop
   13594              :                          global variable - the procedure tests to see whether it is altered as above
   13595              :                                            but will also test to see whether this loop calls a procedure
   13596              :                                            in which case it believes the loop NOT to be infinite
   13597              :                                            (as this procedure call might alter the global variable)
   13598              : 
   13599              :                     Note that this procedure can easily be fooled by the user altering variables
   13600              :                     with pointers.
   13601              : */
   13602              : 
   13603           24 : static bool IsInfiniteLoop (unsigned int End)
   13604              : {
   13605           24 :   bool SeenCall;
   13606           24 :   bool IsGlobal;
   13607           24 :   unsigned int Current;
   13608           24 :   unsigned int Start;
   13609           24 :   M2Quads_QuadOperator op;
   13610           24 :   unsigned int op1;
   13611           24 :   unsigned int op2;
   13612           24 :   unsigned int op3;
   13613              : 
   13614           24 :   SeenCall = false;
   13615           24 :   IsGlobal = false;
   13616           24 :   M2Quads_GetQuad (End, &op, &op1, &op2, &Start);
   13617           24 :   Current = Start;
   13618          216 :   while (Current != End)
   13619              :     {
   13620          216 :       M2Quads_GetQuad (Current, &op, &op1, &op2, &op3);
   13621              :       /* remember that this function is only called once we have optimized the redundant gotos and conditionals  */
   13622          216 :       if ((M2Quads_IsConditional (Current)) && ! IsGlobal)
   13623              :         {
   13624           24 :           IsGlobal = ((SymbolTable_IsVar (op1)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op1))))) || ((SymbolTable_IsVar (op2)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op2)))));
   13625              :         }
   13626          216 :       if (op == M2Quads_CallOp)
   13627              :         {
   13628           12 :           SeenCall = true;
   13629              :         }
   13630          216 :       if ((op == M2Quads_GotoOp) || ((M2Quads_IsConditional (Current)) && (IsConditionVariable (Current, Start, End))))
   13631              :         {
   13632           24 :           if ((op3 > End) || (op3 < Start))
   13633              :             {
   13634              :               return false;  /* may jump out of this loop, good  */
   13635              :             }
   13636              :         }
   13637          192 :       Current = M2Quads_GetNextQuad (Current);
   13638              :     }
   13639            0 :   M2Quads_GetQuad (End, &op, &op1, &op2, &op3);
   13640            0 :   if (M2Quads_IsConditional (End))
   13641              :     {
   13642              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   13643            0 :       if (IsConditionVariable (End, Start, End))
   13644              :         {
   13645              :           return false;
   13646              :         }
   13647              :       else
   13648              :         {
   13649            0 :           if (! IsGlobal)
   13650              :             {
   13651            0 :               IsGlobal = ((SymbolTable_IsVar (op1)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op1))))) || ((SymbolTable_IsVar (op2)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op2)))));
   13652              :             }
   13653              :         }
   13654              :     }
   13655              :   /* we have found a likely infinite loop if no conditional uses a global and no procedure call was seen  */
   13656            0 :   return ! (IsGlobal && SeenCall);
   13657              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   13658              :   __builtin_unreachable ();
   13659              : }
   13660              : 
   13661              : 
   13662              : /*
   13663              :    CheckVariablesInBlock - given a block, BlockSym, check whether all variables are used.
   13664              : */
   13665              : 
   13666       183130 : static void CheckVariablesInBlock (unsigned int BlockSym)
   13667              : {
   13668            0 :   CheckVariablesAndParameterTypesInBlock (BlockSym);
   13669            0 : }
   13670              : 
   13671              : 
   13672              : /*
   13673              :    CheckFunctionReturn - checks to see that a RETURN statement was present in a function.
   13674              : */
   13675              : 
   13676        82730 : static void CheckFunctionReturn (unsigned int ProcSym)
   13677              : {
   13678        82730 :   M2Quads_QuadOperator Op;
   13679        82730 :   unsigned int Op1;
   13680        82730 :   unsigned int Op2;
   13681        82730 :   unsigned int Op3;
   13682        82730 :   unsigned int Scope;
   13683        82730 :   unsigned int Start;
   13684        82730 :   unsigned int End;
   13685              : 
   13686        82730 :   if ((SymbolTable_GetSType (ProcSym)) != SymbolTable_NulSym)
   13687              :     {
   13688              :       /* yes it is a function  */
   13689        20871 :       SymbolTable_GetProcedureQuads (ProcSym, &Scope, &Start, &End);
   13690        20871 :       M2Quads_GetQuad (Start, &Op, &Op1, &Op2, &Op3);
   13691        20871 :       if (Start == 0)
   13692              :         {
   13693            0 :           M2Error_InternalError ((const char *) "incorrect start quad", 20);
   13694              :         }
   13695       788702 :       while (((Start != End) && (Op != M2Quads_ReturnValueOp)) && (Op != M2Quads_InlineOp))
   13696              :         {
   13697       767831 :           Start = M2Quads_GetNextQuad (Start);
   13698       767831 :           M2Quads_GetQuad (Start, &Op, &Op1, &Op2, &Op3);
   13699              :         }
   13700        20871 :       if ((Op != M2Quads_ReturnValueOp) && (Op != M2Quads_InlineOp))
   13701              :         {
   13702              :           /* an InlineOp can always be used to emulate a RETURN  */
   13703            6 :           M2MetaError_MetaError1 ((const char *) "procedure function {%1Ea} does not RETURN a value", 49, ProcSym);
   13704              :         }
   13705              :     }
   13706        82730 : }
   13707              : 
   13708              : 
   13709              : /*
   13710              :    CheckReturnType - checks to see that the return type from currentProc is
   13711              :                      assignment compatible with actualType.
   13712              : */
   13713              : 
   13714        29799 : static void CheckReturnType (unsigned int tokno, unsigned int currentProc, unsigned int actualVal, unsigned int actualType)
   13715              : {
   13716        29799 :   unsigned int procType;
   13717        29799 :   DynamicStrings_String s1;
   13718        29799 :   DynamicStrings_String s2;
   13719        29799 :   NameKey_Name n1;
   13720        29799 :   NameKey_Name n2;
   13721              : 
   13722        29799 :   procType = SymbolTable_GetSType (currentProc);
   13723        29799 :   if (procType == SymbolTable_NulSym)
   13724              :     {
   13725            0 :       M2MetaError_MetaError1 ((const char *) "attempting to RETURN a value from procedure {%1Ea} which was not a declared as a procedure function", 99, currentProc);
   13726              :     }
   13727        29799 :   else if (M2Base_AssignmentRequiresWarning (actualType, SymbolTable_GetSType (currentProc)))
   13728              :     {
   13729              :       /* avoid dangling else.  */
   13730            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);
   13731              :     }
   13732        29799 :   else if (! (M2Base_IsAssignmentCompatible (actualType, procType)))
   13733              :     {
   13734              :       /* avoid dangling else.  */
   13735            0 :       n1 = SymbolTable_GetSymName (actualType);
   13736            0 :       n2 = SymbolTable_GetSymName (procType);
   13737            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));
   13738              :     }
   13739        29799 :   else if ((SymbolTable_IsProcedure (actualVal)) && (! (M2Base_IsAssignmentCompatible (actualVal, procType))))
   13740              :     {
   13741              :       /* avoid dangling else.  */
   13742              :       /* 
   13743              :       MetaWarnings2('attempting to RETURN a value with an incompatible type {%1ad} from function {%2a} which returns {%2ta}',
   13744              :                     actualVal, currentProc)
   13745              : 
   13746              :       --fixme--  introduce MetaWarning, MetaWarning2, MetaWarning3 into M2MetaError
   13747              :   */
   13748            0 :       s1 = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (actualVal)));
   13749            0 :       s2 = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (procType)));
   13750            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)));
   13751              :     }
   13752        29799 :   else if ((SymbolTable_IsProcedure (actualVal)) && (! (M2Base_IsAssignmentCompatible (actualVal, SymbolTable_GetSType (CurrentProc)))))
   13753              :     {
   13754              :       /* avoid dangling else.  */
   13755            0 :       n1 = SymbolTable_GetSymName (actualVal);
   13756            0 :       n2 = SymbolTable_GetSymName (SymbolTable_GetSType (currentProc));
   13757            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));
   13758              :     }
   13759              :   else
   13760              :     {
   13761              :       /* avoid dangling else.  */
   13762              :       /* this checks the types are compatible, not the data contents.  */
   13763        29799 :       BuildRange (M2Range_InitTypesReturnTypeCheck (tokno, currentProc, actualVal));
   13764              :     }
   13765        29799 : }
   13766              : 
   13767              : 
   13768              : /*
   13769              :    BuildReturnLower - check the return type and value to ensure type
   13770              :                       compatibility and no range overflow will occur.
   13771              : */
   13772              : 
   13773        29799 : static void BuildReturnLower (unsigned int tokcombined, unsigned int tokexpr, unsigned int e1, unsigned int t1)
   13774              : {
   13775        29799 :   unsigned int e2;
   13776        29799 :   unsigned int t2;
   13777              : 
   13778              :   /* This will check that the type returned is compatible with
   13779              :       the formal return type of the procedure.  */
   13780        29799 :   CheckReturnType (tokcombined, CurrentProc, e1, t1);
   13781              :   /* Dereference LeftValue if necessary.  */
   13782        29799 :   if ((SymbolTable_GetMode (e1)) == SymbolTable_LeftValue)
   13783              :     {
   13784          172 :       t2 = SymbolTable_GetSType (CurrentProc);
   13785          172 :       e2 = SymbolTable_MakeTemporary (tokexpr, SymbolTable_RightValue);
   13786          172 :       SymbolTable_PutVar (e2, t2);
   13787          172 :       CheckPointerThroughNil (tokexpr, e1);
   13788          172 :       doIndrX (tokexpr, e2, e1);
   13789          172 :       e1 = e2;
   13790              :     }
   13791              :   /* Here we check the data contents to ensure no overflow.  */
   13792        29799 :   BuildRange (M2Range_InitReturnRangeCheck (tokcombined, CurrentProc, e1));
   13793        29799 :   GenQuadOtok (tokcombined, M2Quads_ReturnValueOp, e1, SymbolTable_NulSym, CurrentProc, false, tokcombined, M2LexBuf_UnknownTokenNo, SymbolTable_GetDeclaredMod (CurrentProc));
   13794        29799 : }
   13795              : 
   13796              : 
   13797              : /*
   13798              :    IsReadOnly - a helper procedure function to detect constants.
   13799              : */
   13800              : 
   13801       272655 : static bool IsReadOnly (unsigned int sym)
   13802              : {
   13803       272655 :   return (SymbolTable_IsConst (sym)) || ((SymbolTable_IsVar (sym)) && (SymbolTable_IsVarConst (sym)));
   13804              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   13805              :   __builtin_unreachable ();
   13806              : }
   13807              : 
   13808              : 
   13809              : /*
   13810              :    BuildDesignatorError - removes the designator from the stack and replaces
   13811              :                           it with an error symbol.
   13812              : */
   13813              : 
   13814           54 : static void BuildDesignatorError (const char *message_, unsigned int _message_high)
   13815              : {
   13816           54 :   unsigned int combinedTok;
   13817           54 :   unsigned int arrayTok;
   13818           54 :   unsigned int exprTok;
   13819           54 :   unsigned int e;
   13820           54 :   unsigned int d;
   13821           54 :   unsigned int error;
   13822           54 :   unsigned int Sym;
   13823           54 :   unsigned int Type;
   13824           54 :   char message[_message_high+1];
   13825              : 
   13826              :   /* make a local copy of each unbounded array.  */
   13827           54 :   memcpy (message, message_, _message_high+1);
   13828              : 
   13829           54 :   M2Quads_PopTtok (&e, &exprTok);
   13830           54 :   PopTFDtok (&Sym, &Type, &d, &arrayTok);
   13831           54 :   combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, exprTok);
   13832           54 :   error = SymbolTable_MakeError (combinedTok, NameKey_MakeKey ((const char *) message, _message_high));
   13833           54 :   PushTFDtok (error, Type, d, arrayTok);
   13834           54 : }
   13835              : 
   13836              : 
   13837              : /*
   13838              :    BuildDesignatorPointerError - removes the designator from the stack and replaces
   13839              :                                  it with an error symbol.
   13840              : */
   13841              : 
   13842            2 : static void BuildDesignatorPointerError (unsigned int type, unsigned int rw, unsigned int tokpos, const char *message_, unsigned int _message_high)
   13843              : {
   13844            2 :   unsigned int error;
   13845            2 :   char message[_message_high+1];
   13846              : 
   13847              :   /* make a local copy of each unbounded array.  */
   13848            2 :   memcpy (message, message_, _message_high+1);
   13849              : 
   13850            2 :   error = SymbolTable_MakeError (tokpos, NameKey_MakeKey ((const char *) message, _message_high));
   13851            2 :   if ((SymbolTable_GetSType (type)) != SymbolTable_NulSym)
   13852              :     {
   13853            2 :       type = SymbolTable_GetSType (type);
   13854              :     }
   13855            2 :   PushTFrwtok (error, type, rw, tokpos);
   13856            2 : }
   13857              : 
   13858              : 
   13859              : /*
   13860              :    BuildDesignatorArrayStaticDynamic - Builds the array referencing.
   13861              :                                        The purpose of this procedure is to work out
   13862              :                                        whether the DesignatorArray is a static or
   13863              :                                        dynamic array and to call the appropriate
   13864              :                                        BuildRoutine.
   13865              : 
   13866              :                                        The Stack is expected to contain:
   13867              : 
   13868              : 
   13869              :                                        Entry                   Exit
   13870              :                                        =====                   ====
   13871              : 
   13872              :                                 Ptr ->
   13873              :                                        +--------------+
   13874              :                                        | e            |                        <- Ptr
   13875              :                                        |--------------|        +------------+
   13876              :                                        | Sym  | Type  |        | S    | T   |
   13877              :                                        |--------------|        |------------|
   13878              : */
   13879              : 
   13880        56480 : static void BuildDesignatorArrayStaticDynamic (void)
   13881              : {
   13882        56480 :   unsigned int combinedTok;
   13883        56480 :   unsigned int arrayTok;
   13884        56480 :   unsigned int exprTok;
   13885        56480 :   unsigned int e;
   13886        56480 :   unsigned int type;
   13887        56480 :   unsigned int dim;
   13888        56480 :   unsigned int result;
   13889        56480 :   unsigned int Sym;
   13890        56480 :   unsigned int Type;
   13891              : 
   13892        56480 :   if (SymbolTable_IsConst (M2Quads_OperandT (2)))
   13893              :     {
   13894          204 :       type = SymbolTable_GetDType (M2Quads_OperandT (2));
   13895          204 :       if ((type != SymbolTable_NulSym) && (SymbolTable_IsArray (type)))
   13896              :         {
   13897          204 :           M2Quads_PopTtok (&e, &exprTok);
   13898          204 :           PopTFDtok (&Sym, &Type, &dim, &arrayTok);
   13899          204 :           result = SymbolTable_MakeTemporary (exprTok, SymbolTable_RightValue);
   13900          204 :           SymbolTable_PutVar (result, Type);
   13901          204 :           M2Quads_PushTFtok (result, SymbolTable_GetSType (result), exprTok);
   13902          204 :           M2Quads_PushTtok (Sym, arrayTok);
   13903          204 :           combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, exprTok);
   13904          204 :           SymbolTable_PutVarConst (result, true);
   13905          204 :           M2Quads_BuildAssignConstant (combinedTok);
   13906          204 :           PushTFDtok (result, SymbolTable_GetDType (result), dim, arrayTok);
   13907          204 :           M2Quads_PushTtok (e, exprTok);
   13908              :         }
   13909              :     }
   13910        56480 :   if ((! (SymbolTable_IsVar (M2Quads_OperandT (2)))) && (! (SymbolTable_IsTemporary (M2Quads_OperandT (2)))))
   13911              :     {
   13912           18 :       M2MetaError_MetaErrorT1 (OperandTtok (2), (const char *) "can only access arrays using constants, variables or formal parameters not {%1Ead}", 82, M2Quads_OperandT (2));
   13913           18 :       BuildDesignatorError ((const char *) "bad array access", 16);
   13914              :     }
   13915        56480 :   Sym = static_cast<unsigned int> (M2Quads_OperandT (2));
   13916        56480 :   Type = SymbolTable_GetDType (Sym);
   13917        56480 :   arrayTok = OperandTtok (2);
   13918        56480 :   if (Type == SymbolTable_NulSym)
   13919              :     {
   13920            0 :       if ((arrayTok == M2LexBuf_UnknownTokenNo) || (arrayTok == M2LexBuf_BuiltinTokenNo))
   13921              :         {
   13922            0 :           arrayTok = M2LexBuf_GetTokenNo ();
   13923              :         }
   13924            0 :       M2MetaError_MetaErrorT0 (arrayTok, (const char *) "type of array is undefined", 26);
   13925            0 :       BuildDesignatorError ((const char *) "bad array access", 16);
   13926              :     }
   13927        56480 :   else if (SymbolTable_IsUnbounded (Type))
   13928              :     {
   13929              :       /* avoid dangling else.  */
   13930         8980 :       BuildDynamicArray ();
   13931              :     }
   13932        47500 :   else if (SymbolTable_IsArray (Type))
   13933              :     {
   13934              :       /* avoid dangling else.  */
   13935        47470 :       BuildStaticArray ();
   13936              :     }
   13937              :   else
   13938              :     {
   13939              :       /* avoid dangling else.  */
   13940           30 :       M2MetaError_MetaErrorT1 (arrayTok, (const char *) "can only index static or dynamic arrays, {%1Ead} is not an array but a {%tadv}", 78, Sym);
   13941           30 :       BuildDesignatorError ((const char *) "bad array access", 16);
   13942              :     }
   13943        56474 : }
   13944              : 
   13945              : 
   13946              : /*
   13947              :    BuildStaticArray - Builds the array referencing for static arrays.
   13948              :                       The Stack is expected to contain:
   13949              : 
   13950              : 
   13951              :                       Entry                   Exit
   13952              :                       =====                   ====
   13953              : 
   13954              :               Ptr ->
   13955              :                       +--------------+
   13956              :                       | e            |                       <- Ptr
   13957              :                       |--------------|        +------------+
   13958              :                       | Sym  | Type  |        | S    | T   |
   13959              :                       |--------------|        |------------|
   13960              : */
   13961              : 
   13962        47470 : static void BuildStaticArray (void)
   13963              : {
   13964        47470 :   unsigned int combinedTok;
   13965        47470 :   unsigned int indexTok;
   13966        47470 :   unsigned int arrayTok;
   13967        47470 :   unsigned int rw;
   13968        47470 :   unsigned int Dim;
   13969        47470 :   unsigned int Array;
   13970        47470 :   unsigned int Index;
   13971        47470 :   unsigned int BackEndType;
   13972        47470 :   unsigned int Type;
   13973        47470 :   unsigned int Adr;
   13974              : 
   13975        47470 :   Index = static_cast<unsigned int> (M2Quads_OperandT (1));
   13976        47470 :   indexTok = OperandTtok (1);
   13977        47470 :   Array = static_cast<unsigned int> (M2Quads_OperandT (2));
   13978        47470 :   arrayTok = OperandTtok (2);
   13979        47470 :   Type = SymbolTable_SkipType (M2Quads_OperandF (2));
   13980        47470 :   rw = static_cast<unsigned int> (OperandMergeRW (2));
   13981        47470 :   M2Debug_Assert (SymbolTable_IsLegal (rw));
   13982        47470 :   Dim = static_cast<unsigned int> (OperandD (2));
   13983        47470 :   Dim += 1;
   13984        47470 :   if ((SymbolTable_GetMode (Index)) == SymbolTable_LeftValue)
   13985              :     {
   13986          171 :       Index = MakeRightValue (indexTok, Index, SymbolTable_GetSType (Index));
   13987              :     }
   13988        47464 :   BuildRange (M2Range_InitStaticArraySubscriptRangeCheck (SymbolTable_GetArraySubscript (Type), Index, Dim));
   13989              :   /* now make Adr point to the address of the indexed element  */
   13990        47464 :   combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, indexTok);
   13991        47464 :   Adr = SymbolTable_MakeTemporary (combinedTok, SymbolTable_LeftValue);
   13992        47464 :   if (SymbolTable_IsVar (Array))
   13993              :     {
   13994              :       /* BuildDesignatorArray may have detected des is a constant.  */
   13995        47464 :       SymbolTable_PutVarConst (Adr, SymbolTable_IsVarConst (Array));
   13996              :     }
   13997        47464 :   SymbolTable_PutVarArrayRef (Adr, true);
   13998              :   /* 
   13999              :       From now on it must reference the array element by its lvalue
   14000              :       - so we create the type of the referenced entity
   14001              :   */
   14002        47464 :   BackEndType = SymbolTable_MakePointer (combinedTok, NameKey_NulName);
   14003        47464 :   SymbolTable_PutPointer (BackEndType, SymbolTable_GetDType (Type));
   14004              :   /* PutVar(Adr, BackEndType) ;  */
   14005        47464 :   SymbolTable_PutLeftValueFrontBackType (Adr, SymbolTable_GetDType (Type), BackEndType);
   14006        94928 :   GenQuadO (combinedTok, M2Quads_ArrayOp, Adr, Index, Array, true);
   14007        47464 :   M2Quads_PopN (2);  /* remove all parameters to this procedure  */
   14008        47464 :   PushTFDrwtok (Adr, SymbolTable_GetSType (Adr), Dim, rw, combinedTok);  /* remove all parameters to this procedure  */
   14009        47464 : }
   14010              : 
   14011              : 
   14012              : /*
   14013              :    calculateMultipicand - generates quadruples which calculate the
   14014              :                           multiplicand for the array at dimension, dim.
   14015              : */
   14016              : 
   14017        12038 : static unsigned int calculateMultipicand (unsigned int tok, unsigned int arraySym, unsigned int arrayType, unsigned int dim)
   14018              : {
   14019        12038 :   unsigned int ti;
   14020        12038 :   unsigned int tj;
   14021        12038 :   unsigned int tk;
   14022        12038 :   unsigned int tl;
   14023              : 
   14024        12038 :   if (dim == (SymbolTable_GetDimension (arrayType)))
   14025              :     {
   14026              :       /* ti has no type since constant  */
   14027        10254 :       ti = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
   14028        10254 :       SymbolTable_PutVar (ti, M2Base_Cardinal);
   14029        10254 :       GenQuadO (tok, M2Quads_ElementSizeOp, ti, arrayType, 1, true);
   14030              :     }
   14031              :   else
   14032              :     {
   14033         1784 :       dim += 1;
   14034         1784 :       tk = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
   14035         1784 :       SymbolTable_PutVar (tk, M2Base_Cardinal);
   14036         1784 :       GenHigh (tok, tk, dim, arraySym);
   14037         1784 :       tl = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
   14038         1784 :       SymbolTable_PutVar (tl, M2Base_Cardinal);
   14039         1784 :       GenQuadOtok (tok, M2Quads_AddOp, tl, tk, SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal), true, tok, tok, tok);
   14040         1784 :       tj = calculateMultipicand (tok, arraySym, arrayType, dim);
   14041         1784 :       ti = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
   14042         1784 :       SymbolTable_PutVar (ti, M2Base_Cardinal);
   14043         1784 :       GenQuadO (tok, M2Quads_MultOp, ti, tj, tl, true);
   14044              :     }
   14045        12038 :   return ti;
   14046              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   14047              :   __builtin_unreachable ();
   14048              : }
   14049              : 
   14050              : 
   14051              : /*
   14052              :    ConvertToAddress - convert sym to an address.
   14053              : */
   14054              : 
   14055         9064 : static unsigned int ConvertToAddress (unsigned int tokpos, unsigned int sym)
   14056              : {
   14057         9064 :   unsigned int adr;
   14058              : 
   14059         9064 :   if ((SymbolTable_GetSType (sym)) == M2System_Address)
   14060              :     {
   14061              :       return sym;
   14062              :     }
   14063              :   else
   14064              :     {
   14065         9052 :       M2Quads_PushTF (SymbolTable_RequestSym (tokpos, NameKey_MakeKey ((const char *) "CONVERT", 7)), static_cast<unsigned int> (SymbolTable_NulSym));
   14066         9052 :       M2Quads_PushT (M2System_Address);
   14067         9052 :       M2Quads_PushTtok (sym, tokpos);
   14068         9052 :       M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
   14069         9052 :       BuildConvertFunction (M2Base_Convert, false);  /* Two parameters  */
   14070         9052 :       M2Quads_PopT (&adr);
   14071         9052 :       return adr;
   14072              :     }
   14073              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   14074              :   __builtin_unreachable ();
   14075              : }
   14076              : 
   14077              : 
   14078              : /*
   14079              :    BuildDynamicArray - Builds the array referencing for dynamic arrays.
   14080              :                        The Stack is expected to contain:
   14081              : 
   14082              : 
   14083              :                        Entry                          Exit
   14084              :                        =====                          ====
   14085              : 
   14086              :                Ptr ->
   14087              :                        +-----------------------+
   14088              :                        | Index                 |                                    <- Ptr
   14089              :                        |-----------------------|      +---------------------------+
   14090              :                        | ArraySym | Type | Dim |      | S  | T | ArraySym | Dim+1 |
   14091              :                        |-----------------------|      |---------------------------|
   14092              : 
   14093              : 
   14094              :    if Dim=1
   14095              :    then
   14096              :       S := base of ArraySym + TSIZE(Type)*Index
   14097              :    else
   14098              :       S := S + TSIZE(Type)*Index
   14099              :    fi
   14100              : */
   14101              : 
   14102         8980 : static void BuildDynamicArray (void)
   14103              : {
   14104         8980 :   unsigned int combinedTok;
   14105         8980 :   unsigned int arrayTok;
   14106         8980 :   unsigned int indexTok;
   14107         8980 :   unsigned int Sym;
   14108         8980 :   unsigned int idx;
   14109         8980 :   unsigned int Type;
   14110         8980 :   unsigned int Adr;
   14111         8980 :   unsigned int ArraySym;
   14112         8980 :   unsigned int BackEndType;
   14113         8980 :   unsigned int UnboundedType;
   14114         8980 :   unsigned int PtrToBase;
   14115         8980 :   unsigned int Base;
   14116         8980 :   unsigned int Dim;
   14117         8980 :   unsigned int rw;
   14118         8980 :   unsigned int ti;
   14119         8980 :   unsigned int tj;
   14120         8980 :   unsigned int tk;
   14121         8980 :   unsigned int tka;
   14122              : 
   14123         8980 :   M2Quads_DisplayStack ();
   14124         8980 :   Sym = static_cast<unsigned int> (M2Quads_OperandT (2));
   14125         8980 :   Type = SymbolTable_SkipType (M2Quads_OperandF (2));
   14126         8980 :   arrayTok = static_cast<unsigned int> (M2Quads_OperandTok (2));
   14127         8980 :   indexTok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   14128         8980 :   combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, indexTok);
   14129         8980 :   Dim = static_cast<unsigned int> (OperandD (2));
   14130         8980 :   rw = static_cast<unsigned int> (OperandMergeRW (2));
   14131         8980 :   M2Debug_Assert (SymbolTable_IsLegal (rw));
   14132         8980 :   Dim += 1;
   14133         8980 :   if (Dim == 1)
   14134              :     {
   14135              :       /* 
   14136              :          Base has type address since
   14137              :          BuildDesignatorRecord references by address.
   14138              : 
   14139              :          Build a record for retrieving the address of dynamic array.
   14140              :          BuildDesignatorRecord will generate the required quadruples,
   14141              :          therefore build sets up the stack for BuildDesignatorRecord
   14142              :          which will generate the quads to access the record.
   14143              :   */
   14144         8842 :       ArraySym = Sym;
   14145         8842 :       UnboundedType = SymbolTable_GetUnboundedRecordType (SymbolTable_GetSType (Sym));
   14146         8842 :       PushTFrwtok (Sym, UnboundedType, rw, arrayTok);
   14147         8842 :       M2Quads_PushTF (SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (Sym)), SymbolTable_GetSType (SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (Sym))));
   14148         8842 :       M2Quads_PushT (static_cast<unsigned int> (1));  /* One record field to dereference  */
   14149         8842 :       M2Quads_BuildDesignatorRecord (combinedTok);  /* One record field to dereference  */
   14150         8842 :       M2Quads_PopT (&PtrToBase);
   14151         8842 :       M2Quads_DisplayStack ();
   14152              :       /* Now actually copy Unbounded.ArrayAddress into base  */
   14153         8842 :       if ((SymbolTable_GetMode (PtrToBase)) == SymbolTable_LeftValue)
   14154              :         {
   14155            0 :           Base = SymbolTable_MakeTemporary (arrayTok, SymbolTable_RightValue);
   14156            0 :           SymbolTable_PutVar (Base, M2System_Address);  /* has type ADDRESS  */
   14157            0 :           CheckPointerThroughNil (arrayTok, PtrToBase);  /* has type ADDRESS  */
   14158            0 :           GenQuad (M2Quads_IndrXOp, Base, M2System_Address, PtrToBase);  /* Base = *PtrToBase  */
   14159              :         }
   14160              :       else
   14161              :         {
   14162         8842 :           M2Debug_Assert ((SymbolTable_GetMode (PtrToBase)) != SymbolTable_ImmediateValue);
   14163         8842 :           Base = PtrToBase;
   14164              :         }
   14165              :     }
   14166              :   else
   14167              :     {
   14168              :       /* Base already calculated previously and pushed to stack  */
   14169          138 :       UnboundedType = SymbolTable_SkipType (M2Quads_OperandF (2));
   14170          138 :       Base = Sym;
   14171          138 :       ArraySym = static_cast<unsigned int> (M2Quads_OperandA (2));
   14172              :     }
   14173         8980 :   M2Debug_Assert ((SymbolTable_GetSType (Sym)) == Type);
   14174         8980 :   ti = calculateMultipicand (indexTok, Sym, Type, Dim);
   14175         8980 :   idx = static_cast<unsigned int> (M2Quads_OperandT (1));
   14176         8980 :   if ((SymbolTable_IsConst (idx)) && (SymbolTable_IsConst (ti)))
   14177              :     {
   14178              :       /* tj has no type since constant  */
   14179          460 :       tj = SymbolTable_MakeTemporary (indexTok, SymbolTable_ImmediateValue);
   14180          460 :       tk = SymbolTable_MakeTemporary (indexTok, SymbolTable_ImmediateValue);
   14181          460 :       SymbolTable_PutVar (tj, M2Base_Cardinal);
   14182          460 :       SymbolTable_PutVar (tk, M2Base_Cardinal);
   14183              :     }
   14184              :   else
   14185              :     {
   14186              :       /* tj has Cardinal type since we have multiplied array indices  */
   14187         8520 :       tj = SymbolTable_MakeTemporary (indexTok, SymbolTable_RightValue);
   14188         8520 :       if ((SymbolTable_GetSType (idx)) != M2Base_Cardinal)
   14189              :         {
   14190          270 :           M2Quads_PushTF (SymbolTable_RequestSym (indexTok, NameKey_MakeKey ((const char *) "CONVERT", 7)), static_cast<unsigned int> (SymbolTable_NulSym));
   14191          270 :           M2Quads_PushT (M2Base_Cardinal);
   14192          270 :           M2Quads_PushTtok (idx, indexTok);
   14193          270 :           M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
   14194          270 :           BuildConvertFunction (M2Base_Convert, false);  /* Two parameters  */
   14195          270 :           M2Quads_PopT (&idx);
   14196              :         }
   14197         8520 :       SymbolTable_PutVar (tj, M2Base_Cardinal);
   14198         8520 :       tk = SymbolTable_MakeTemporary (indexTok, SymbolTable_RightValue);
   14199         8520 :       SymbolTable_PutVar (tk, M2Base_Cardinal);
   14200              :     }
   14201         8980 :   BuildRange (M2Range_InitDynamicArraySubscriptRangeCheck (ArraySym, idx, Dim));
   14202         8980 :   M2Quads_PushTtok (tj, indexTok);
   14203         8980 :   M2Quads_PushTtok (idx, indexTok);
   14204         8980 :   BuildAssignmentWithoutBounds (indexTok, false, true);
   14205        17960 :   GenQuad (M2Quads_MultOp, tk, ti, tj);
   14206        17960 :   Adr = SymbolTable_MakeTemporary (combinedTok, SymbolTable_LeftValue);
   14207         8980 :   SymbolTable_PutVarArrayRef (Adr, true);
   14208              :   /* 
   14209              :       Ok must reference by address
   14210              :       - but we contain the type of the referenced entity
   14211              :   */
   14212         8980 :   BackEndType = SymbolTable_MakePointer (combinedTok, NameKey_NulName);
   14213         8980 :   SymbolTable_PutPointer (BackEndType, SymbolTable_GetSType (Type));
   14214              :   /* Create a temporary pointer for addition.  */
   14215         8980 :   tka = ConvertToAddress (combinedTok, tk);
   14216         8980 :   if (Dim == (SymbolTable_GetDimension (Type)))
   14217              :     {
   14218         8662 :       SymbolTable_PutLeftValueFrontBackType (Adr, SymbolTable_GetSType (Type), BackEndType);
   14219        17324 :       GenQuadOtok (combinedTok, M2Quads_AddOp, Adr, Base, tka, false, combinedTok, combinedTok, combinedTok);
   14220         8662 :       M2Quads_PopN (2);
   14221         8662 :       PushTFADrwtok (Adr, SymbolTable_GetSType (Adr), ArraySym, Dim, rw, combinedTok);
   14222              :     }
   14223              :   else
   14224              :     {
   14225              :       /* more to index  */
   14226          318 :       SymbolTable_PutLeftValueFrontBackType (Adr, Type, BackEndType);
   14227          636 :       GenQuadOtok (combinedTok, M2Quads_AddOp, Adr, Base, tka, false, combinedTok, combinedTok, combinedTok);
   14228          318 :       M2Quads_PopN (2);
   14229          318 :       PushTFADrwtok (Adr, SymbolTable_GetSType (Adr), ArraySym, Dim, rw, combinedTok);
   14230              :     }
   14231         8980 : }
   14232              : 
   14233              : 
   14234              : /*
   14235              :    DebugLocation -
   14236              : */
   14237              : 
   14238        57763 : static void DebugLocation (unsigned int tok, const char *message_, unsigned int _message_high)
   14239              : {
   14240        57763 :   char message[_message_high+1];
   14241              : 
   14242              :   /* make a local copy of each unbounded array.  */
   14243        57763 :   memcpy (message, message_, _message_high+1);
   14244              : 
   14245        57763 :   if (DebugTokPos)
   14246              :     {
   14247              :       M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) message, _message_high), tok);
   14248              :     }
   14249        57763 : }
   14250              : 
   14251              : 
   14252              : /*
   14253              :    PushWith - pushes sym and type onto the with stack. It checks for
   14254              :               previous declaration of this record type.
   14255              : */
   14256              : 
   14257         5965 : static void PushWith (unsigned int Sym, unsigned int Type, unsigned int Ref, unsigned int Tok)
   14258              : {
   14259         5965 :   unsigned int i;
   14260         5965 :   unsigned int n;
   14261         5965 :   M2Quads_WithFrame f;
   14262              : 
   14263         5965 :   if (M2Options_Pedantic)
   14264              :     {
   14265            0 :       n = M2StackAddress_NoOfItemsInStackAddress (WithStack);
   14266            0 :       i = 1;  /* Top of the stack.  */
   14267              :       /* Search for other declarations of the with using Type.  */
   14268            0 :       while (i <= n)
   14269              :         {
   14270            0 :           f = static_cast<M2Quads_WithFrame> (M2StackAddress_PeepAddress (WithStack, i));
   14271            0 :           if (f->RecordSym == Type)
   14272              :             {
   14273            0 :               M2MetaError_MetaErrorT1 (Tok, (const char *) "cannot have nested {%kWITH} statements referencing the same {%kRECORD} {%1Ead}", 78, Sym);
   14274            0 :               M2MetaError_MetaErrorT1 (f->RecordTokPos, (const char *) "cannot have nested {%kWITH} statements referencing the same {%kRECORD} {%1Ead}", 78, f->RecordSym);
   14275              :             }
   14276            0 :           i += 1;
   14277              :         }
   14278              :     }
   14279         5965 :   Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T4));
   14280         5965 :   f->RecordSym = Sym;
   14281         5965 :   f->RecordType = Type;
   14282         5965 :   f->RecordRef = Ref;
   14283         5965 :   f->rw = Sym;
   14284         5965 :   f->RecordTokPos = Tok;
   14285         5965 :   M2StackAddress_PushAddress (WithStack, reinterpret_cast <void *> (f));
   14286         5965 : }
   14287              : 
   14288         5965 : static void PopWith (void)
   14289              : {
   14290         5965 :   M2Quads_WithFrame f;
   14291              : 
   14292         5965 :   f = static_cast<M2Quads_WithFrame> (M2StackAddress_PopAddress (WithStack));
   14293         5965 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T4));
   14294         5965 : }
   14295              : 
   14296              : 
   14297              : /*
   14298              :    BuildAccessWithField - similar to BuildDesignatorRecord except it
   14299              :                           does not perform the address operation.
   14300              :                           The address will have been computed at the
   14301              :                           beginning of the WITH statement.
   14302              :                           It also stops the GenQuad procedure from examining the
   14303              :                           with stack.
   14304              : 
   14305              :                           The Stack
   14306              : 
   14307              :                           Entry
   14308              : 
   14309              :                    Ptr ->
   14310              :                           +--------------+
   14311              :                           | Field | Type1|                          <- Ptr
   14312              :                           |-------|------|          +-------------+
   14313              :                           | Adr   | Type2|          | Sym  | Type1|
   14314              :                           |--------------|          |-------------|
   14315              : */
   14316              : 
   14317        30024 : static void BuildAccessWithField (void)
   14318              : {
   14319        30024 :   unsigned int rectok;
   14320        30024 :   unsigned int fieldtok;
   14321        30024 :   bool OldSuppressWith;
   14322        30024 :   unsigned int rw;
   14323        30024 :   unsigned int Field;
   14324        30024 :   unsigned int FieldType;
   14325        30024 :   unsigned int Record;
   14326        30024 :   unsigned int RecordType;
   14327        30024 :   unsigned int Ref;
   14328              : 
   14329        30024 :   OldSuppressWith = SuppressWith;
   14330        30024 :   SuppressWith = true;
   14331              :   /* 
   14332              :       now the WITH cannot look at the stack of outstanding WITH records.
   14333              :   */
   14334        30024 :   M2Quads_PopTFtok (&Field, &FieldType, &fieldtok);
   14335        30024 :   PopTFrwtok (&Record, &RecordType, &rw, &rectok);
   14336        30024 :   Ref = SymbolTable_MakeComponentRef (SymbolTable_MakeComponentRecord (fieldtok, SymbolTable_RightValue, Record), Field);
   14337        30024 :   SymbolTable_PutVarConst (Ref, IsReadOnly (Record));
   14338        60048 :   GenQuadO (fieldtok, M2Quads_RecordFieldOp, Ref, Record, Field, true);
   14339        30024 :   PushTFrwtok (Ref, FieldType, rw, fieldtok);
   14340        30024 :   SuppressWith = OldSuppressWith;
   14341        30024 : }
   14342              : 
   14343              : 
   14344              : /*
   14345              :    SafeCheckWithField - only call CheckWithReference if the top of stack
   14346              :                         contains a record field.
   14347              : */
   14348              : 
   14349        12040 : static void SafeCheckWithField (void)
   14350              : {
   14351        12040 :   if (SymbolTable_IsRecordField (M2Quads_OperandT (1)))
   14352              :     {
   14353           24 :       M2Quads_CheckWithReference ();
   14354              :     }
   14355        12040 : }
   14356              : 
   14357              : 
   14358              : /*
   14359              :    PushConstructor -
   14360              : */
   14361              : 
   14362        48319 : static void PushConstructor (unsigned int sym)
   14363              : {
   14364        48319 :   M2Quads_ConstructorFrame c;
   14365              : 
   14366        48319 :   Storage_ALLOCATE ((void **) &c, sizeof (M2Quads__T1));
   14367        48319 :   c->type = SymbolTable_SkipType (sym);
   14368        48319 :   c->index = 1;
   14369        48319 :   M2StackAddress_PushAddress (ConstructorStack, reinterpret_cast <void *> (c));
   14370        48319 : }
   14371              : 
   14372              : 
   14373              : /*
   14374              :    AddFieldTo - adds field to value.
   14375              : */
   14376              : 
   14377        25782 : static unsigned int AddFieldTo (unsigned int value, unsigned int field, unsigned int valuetok, unsigned int fieldtok)
   14378              : {
   14379        25782 :   if (SymbolTable_IsSet (SymbolTable_GetDType (value)))
   14380              :     {
   14381        12040 :       SymbolTable_PutConstSet (value);
   14382        12040 :       M2Quads_PushTtok (value, valuetok);
   14383        12040 :       M2Quads_PushTtok (field, fieldtok);
   14384        12040 :       M2Quads_BuildInclBit ();
   14385        12040 :       M2Quads_PopT (&value);
   14386              :     }
   14387              :   else
   14388              :     {
   14389        13742 :       SymbolTable_PushValue (value);
   14390        13742 :       M2ALU_AddField (fieldtok, field);
   14391        13742 :       SymbolTable_PopValue (value);
   14392              :     }
   14393        25782 :   return value;
   14394              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   14395              :   __builtin_unreachable ();
   14396              : }
   14397              : 
   14398              : 
   14399              : /*
   14400              :    CheckLogicalOperator - returns a logical operator if the operands imply
   14401              :                           a logical operation should be performed.
   14402              : */
   14403              : 
   14404        78406 : static NameKey_Name CheckLogicalOperator (NameKey_Name Tok, unsigned int left, unsigned int lefttype)
   14405              : {
   14406        78406 :   if ((((Tok == M2Reserved_PlusTok) || (Tok == M2Reserved_TimesTok)) || (Tok == M2Reserved_DivideTok)) || (Tok == M2Reserved_MinusTok))
   14407              :     {
   14408              :       /* --fixme-- when we add complex arithmetic, we must check constructor is not a complex constant.  */
   14409        69164 :       if ((((lefttype != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_SkipType (lefttype)))) || (SymbolTable_IsConstSet (left))) || (SymbolTable_IsConstructor (left)))
   14410              :         {
   14411              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   14412         1448 :           if (Tok == M2Reserved_PlusTok)
   14413              :             {
   14414          974 :               return LogicalOrTok;
   14415              :             }
   14416          474 :           else if (Tok == M2Reserved_DivideTok)
   14417              :             {
   14418              :               /* avoid dangling else.  */
   14419          124 :               return LogicalXorTok;
   14420              :             }
   14421          350 :           else if (Tok == M2Reserved_TimesTok)
   14422              :             {
   14423              :               /* avoid dangling else.  */
   14424          284 :               return LogicalAndTok;
   14425              :             }
   14426           66 :           else if (Tok == M2Reserved_MinusTok)
   14427              :             {
   14428              :               /* avoid dangling else.  */
   14429           66 :               return LogicalDifferenceTok;
   14430              :             }
   14431              :         }
   14432              :     }
   14433              :   return Tok;
   14434              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   14435              :   __builtin_unreachable ();
   14436              : }
   14437              : 
   14438              : 
   14439              : /*
   14440              :    CheckDivModRem - initiates calls to check the divisor for DIV, MOD, REM
   14441              :                     expressions.
   14442              : */
   14443              : 
   14444        77806 : static void CheckDivModRem (unsigned int TokPos, NameKey_Name tok, unsigned int d, unsigned int e)
   14445              : {
   14446        77806 :   if (tok == M2Reserved_DivTok)
   14447              :     {
   14448         6786 :       BuildRange (M2Range_InitWholeZeroDivisionCheck (TokPos, d, e));
   14449              :     }
   14450        71020 :   else if (tok == M2Reserved_ModTok)
   14451              :     {
   14452              :       /* avoid dangling else.  */
   14453         2360 :       BuildRange (M2Range_InitWholeZeroDivisionCheck (TokPos, d, e));
   14454              :     }
   14455        68660 :   else if (tok == M2Reserved_RemTok)
   14456              :     {
   14457              :       /* avoid dangling else.  */
   14458           96 :       BuildRange (M2Range_InitWholeZeroRemainderCheck (TokPos, d, e));
   14459              :     }
   14460        77806 : }
   14461              : 
   14462              : 
   14463              : /*
   14464              :    doConvert - convert, sym, to a new symbol with, type.
   14465              :                Return the new symbol.
   14466              : */
   14467              : 
   14468         5152 : static unsigned int doConvert (unsigned int type, unsigned int sym)
   14469              : {
   14470         5152 :   if ((SymbolTable_GetSType (sym)) != type)
   14471              :     {
   14472         1064 :       M2Quads_PushTF (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym));
   14473         1064 :       M2Quads_PushT (type);
   14474         1064 :       M2Quads_PushT (sym);
   14475         1064 :       M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters  */
   14476         1064 :       BuildConvertFunction (M2Base_Convert, false);  /* Two parameters  */
   14477         1058 :       M2Quads_PopT (&sym);
   14478              :     }
   14479         5146 :   return sym;
   14480              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   14481              :   __builtin_unreachable ();
   14482              : }
   14483              : 
   14484              : 
   14485              : /*
   14486              :    doBuildBinaryOp - build the binary op, with or without type
   14487              :                      checking.
   14488              : */
   14489              : 
   14490        91578 : static void doBuildBinaryOp (bool checkTypes, bool checkOverflow)
   14491              : {
   14492        91578 :   DynamicStrings_String s;
   14493        91578 :   NameKey_Name NewOp;
   14494        91578 :   NameKey_Name Operator;
   14495        91578 :   unsigned int OperatorPos;
   14496        91578 :   unsigned int OldPos;
   14497        91578 :   unsigned int leftrw;
   14498        91578 :   unsigned int rightrw;
   14499        91578 :   unsigned int t1;
   14500        91578 :   unsigned int f1;
   14501        91578 :   unsigned int t2;
   14502        91578 :   unsigned int f2;
   14503        91578 :   unsigned int lefttype;
   14504        91578 :   unsigned int righttype;
   14505        91578 :   unsigned int left;
   14506        91578 :   unsigned int right;
   14507        91578 :   unsigned int leftpos;
   14508        91578 :   unsigned int rightpos;
   14509        91578 :   unsigned int value;
   14510              : 
   14511        91578 :   Operator = static_cast<NameKey_Name> (M2Quads_OperandT (2));
   14512        91578 :   if (Operator == M2Reserved_OrTok)
   14513              :     {
   14514         3536 :       CheckBooleanId ();
   14515         3536 :       PopBooltok (&t1, &f1, &rightpos);
   14516         3536 :       M2Quads_PopTtok (&Operator, &OperatorPos);
   14517         3536 :       PopBooltok (&t2, &f2, &leftpos);
   14518         3536 :       M2Debug_Assert (f2 == 0);
   14519         3536 :       OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
   14520         3536 :       PushBooltok (Merge (t1, t2), f1, OperatorPos);
   14521              :     }
   14522        88042 :   else if ((Operator == M2Reserved_AndTok) || (Operator == M2Reserved_AmbersandTok))
   14523              :     {
   14524              :       /* avoid dangling else.  */
   14525         9636 :       CheckBooleanId ();
   14526         9636 :       PopBooltok (&t1, &f1, &rightpos);
   14527         9636 :       M2Quads_PopTtok (&Operator, &OperatorPos);
   14528         9636 :       PopBooltok (&t2, &f2, &leftpos);
   14529         9636 :       M2Debug_Assert (t2 == 0);
   14530         9636 :       OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
   14531         9636 :       PushBooltok (t1, Merge (f1, f2), OperatorPos);
   14532              :     }
   14533              :   else
   14534              :     {
   14535              :       /* avoid dangling else.  */
   14536        78406 :       PopTFrwtok (&right, &righttype, &rightrw, &rightpos);
   14537        78406 :       M2Quads_PopTtok (&Operator, &OperatorPos);
   14538        78406 :       PopTFrwtok (&left, &lefttype, &leftrw, &leftpos);
   14539        78406 :       MarkAsRead (rightrw);
   14540        78406 :       MarkAsRead (leftrw);
   14541        78406 :       NewOp = CheckLogicalOperator (Operator, left, lefttype);  /* right, righttype,  */
   14542        78406 :       if (NewOp == Operator)
   14543              :         {
   14544              :           /* avoid dangling else.  */
   14545              :           /* 
   14546              :             BinaryOps and UnaryOps only work with immediate and
   14547              :             offset addressing.  This is fine for calculating
   14548              :             array and record offsets but we need to get the real
   14549              :             values to perform normal arithmetic. Not address
   14550              :             arithmetic.
   14551              : 
   14552              :             However the set operators will dereference LValues
   14553              :             (to optimize large set arithemetic)
   14554              :   */
   14555        76958 :           if ((SymbolTable_GetMode (right)) == SymbolTable_LeftValue)
   14556              :             {
   14557          298 :               value = SymbolTable_MakeTemporary (rightpos, SymbolTable_RightValue);
   14558          298 :               SymbolTable_PutVar (value, righttype);
   14559          298 :               CheckPointerThroughNil (rightpos, right);
   14560          298 :               doIndrX (rightpos, value, right);
   14561          298 :               right = value;
   14562              :             }
   14563        76958 :           if ((SymbolTable_GetMode (left)) == SymbolTable_LeftValue)
   14564              :             {
   14565          844 :               value = SymbolTable_MakeTemporary (leftpos, SymbolTable_RightValue);
   14566          844 :               SymbolTable_PutVar (value, lefttype);
   14567          844 :               CheckPointerThroughNil (leftpos, left);
   14568          844 :               doIndrX (leftpos, value, left);
   14569          844 :               left = value;
   14570              :             }
   14571              :         }
   14572              :       /* CheckForGenericNulSet(e1, e2, t1, t2)  */
   14573        78406 :       OldPos = OperatorPos;
   14574        78406 :       OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
   14575        78406 :       if (((Operator == M2Reserved_PlusTok) && (SymbolTable_IsConstString (left))) && (SymbolTable_IsConstString (right)))
   14576              :         {
   14577          492 :           value = SymbolTable_MakeConstString (OperatorPos, NameKey_NulName);
   14578          492 :           SymbolTable_PutConstStringKnown (OperatorPos, value, NameKey_NulName, false, false);
   14579          492 :           GenQuadOtok (OperatorPos, MakeOp (M2Reserved_PlusTok), value, left, right, false, OperatorPos, leftpos, rightpos);
   14580              :         }
   14581              :       else
   14582              :         {
   14583        77914 :           if (checkTypes)
   14584              :             {
   14585        60055 :               BuildRange (M2Range_InitTypesExpressionCheck (OperatorPos, left, right, false, false));
   14586              :             }
   14587       120654 :           value = SymbolTable_MakeTemporaryFromExpressions (OperatorPos, right, left, AreConstant ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right))));
   14588        77806 :           CheckDivModRem (OperatorPos, NewOp, value, right);
   14589        77806 :           if (DebugTokPos)
   14590              :             {
   14591              :               s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (M2LexBuf_GetTokenName (Operator)));
   14592              :               M2Error_WarnStringAt (s, OldPos);
   14593              :               s = DynamicStrings_InitString ((const char *) "left", 4);
   14594              :               M2Error_WarnStringAt (s, leftpos);
   14595              :               s = DynamicStrings_InitString ((const char *) "right", 5);
   14596              :               M2Error_WarnStringAt (s, rightpos);
   14597              :               s = DynamicStrings_InitString ((const char *) "caret", 5);
   14598              :               M2Error_WarnStringAt (s, OldPos);
   14599              :               s = DynamicStrings_InitString ((const char *) "combined", 8);
   14600              :               M2Error_WarnStringAt (s, OperatorPos);
   14601              :             }
   14602              :           /* MetaErrorT1 (GetDeclaredMod (t), 'in binary with a {%1av}', t)  */
   14603        77806 :           GenQuadOtok (OperatorPos, MakeOp (NewOp), value, left, right, checkOverflow, OperatorPos, leftpos, rightpos);
   14604              :         }
   14605        78298 :       M2Quads_PushTFtok (value, SymbolTable_GetSType (value), OperatorPos);
   14606              :     }
   14607        91470 : }
   14608              : 
   14609              : 
   14610              : /*
   14611              :    AreConstant - returns immediate addressing mode if b is true else
   14612              :                  offset mode is returned. b determines whether the
   14613              :                  operands are all constant - in which case we can use
   14614              :                  a constant temporary variable.
   14615              : */
   14616              : 
   14617       160359 : static SymbolTable_ModeOfAddr AreConstant (bool b)
   14618              : {
   14619       131965 :   if (b)
   14620              :     {
   14621              :       return SymbolTable_ImmediateValue;
   14622              :     }
   14623              :   else
   14624              :     {
   14625        60056 :       return SymbolTable_RightValue;
   14626              :     }
   14627              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   14628              :   __builtin_unreachable ();
   14629              : }
   14630              : 
   14631              : 
   14632              : /*
   14633              :    ConvertBooleanToVariable - converts a BoolStack(i) from a Boolean True|False
   14634              :                               exit pair into a variable containing the value TRUE or
   14635              :                               FALSE.  The parameter i is relative to the top
   14636              :                               of the stack.
   14637              : */
   14638              : 
   14639         7344 : static void ConvertBooleanToVariable (unsigned int tok, unsigned int i)
   14640              : {
   14641         7344 :   unsigned int Des;
   14642         7344 :   M2Quads_BoolFrame f;
   14643              : 
   14644         7344 :   M2Debug_Assert (IsBoolean (i));
   14645              :   /* We need to convert the boolean top of stack into a variable or
   14646              :       constant boolean.  */
   14647        14556 :   Des = SymbolTable_MakeTemporary (tok, AreConstant (M2Quads_IsInConstExpression ()));
   14648         7344 :   SymbolTable_PutVar (Des, M2Base_Boolean);
   14649         7344 :   SymbolTable_PutVarConditional (Des, true);
   14650         7344 :   M2Quads_PushTtok (Des, tok);  /* we have just increased the stack so we must use i+1  */
   14651         7344 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, i+1));  /* we have just increased the stack so we must use i+1  */
   14652        14688 :   PushBool (f->TrueExit, f->FalseExit);
   14653         7344 :   BuildAssignmentWithoutBounds (tok, false, true);
   14654              :   /* Restored stack after the BuildAssign... above.  */
   14655         7344 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, i));
   14656         7344 :   f->TrueExit = Des;  /* Alter Stack(i) to contain the variable.  */
   14657         7344 :   f->FalseExit = M2Base_Boolean;  /* Alter Stack(i) to contain the variable.  */
   14658         7344 :   f->BooleanOp = false;  /* No longer a Boolean True|False pair.  */
   14659         7344 :   f->Unbounded = SymbolTable_NulSym;  /* No longer a Boolean True|False pair.  */
   14660         7344 :   f->Dimension = 0;
   14661         7344 :   f->ReadWrite = SymbolTable_NulSym;
   14662         7344 :   f->tokenno = tok;
   14663         7344 :   f->Annotation = DynamicStrings_KillString (f->Annotation);
   14664         7344 :   f->Annotation = DynamicStrings_InitString ((const char *) "%1s(%1d)|%2s(%2d)||boolean var|type", 35);
   14665         7344 :   f->RangeDep = 0;
   14666         7344 : }
   14667              : 
   14668              : 
   14669              : /*
   14670              :    DumpQuadSummary -
   14671              : */
   14672              : 
   14673            0 : static void DumpQuadSummary (unsigned int quad)
   14674              : {
   14675            0 :   M2Quads_QuadFrame f;
   14676              : 
   14677            0 :   if (quad != 0)
   14678              :     {
   14679            0 :       f = GetQF (quad);
   14680            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));
   14681              :     }
   14682            0 : }
   14683              : 
   14684              : 
   14685              : /*
   14686              :    BuildRelOpFromBoolean - builds a relational operator sequence of quadruples
   14687              :                            instead of using a temporary boolean variable.
   14688              :                            This function can only be used when we perform
   14689              :                            the following translation:
   14690              : 
   14691              :                            (a=b) # (c=d)  alternatively   (a=b) = (c=d)
   14692              :                                  ^                              ^
   14693              : 
   14694              :                            it only allows # = to be used as >= <= > < all
   14695              :                            assume a particular value for TRUE and FALSE.
   14696              :                            (In which case the user should specify ORD)
   14697              : 
   14698              : 
   14699              :                            before
   14700              : 
   14701              :                            q      if r1      op1     op2     t2
   14702              :                            q+1    Goto                       f2
   14703              :                            ...
   14704              :                            q+n    if r2      op3     op4     t1
   14705              :                            q+n+1  Goto                       f1
   14706              : 
   14707              :                            after (in case of =)
   14708              : 
   14709              :                            q    if r1      op1     op2     q+2
   14710              :                            q+1  Goto                       q+4
   14711              :                            q+2  if r2      op3     op4     t
   14712              :                            q+3  Goto                       f
   14713              :                            q+4  if r2      op3     op4     f
   14714              :                            q+5  Goto                       t
   14715              : 
   14716              :                            after (in case of #)
   14717              : 
   14718              :                            q      if r1      op1     op2     q+2
   14719              :                            q+1    Goto                       q+n+2
   14720              :                            q+2    ...
   14721              :                            ...    ...
   14722              :                            q+n    if r2      op3     op4     f
   14723              :                            q+n+1  Goto                       t
   14724              :                            q+n+2  if r2      op3     op4     t
   14725              :                            q+n+3  Goto                       f
   14726              : 
   14727              :                            The Stack is expected to contain:
   14728              : 
   14729              : 
   14730              :                            Entry                   Exit
   14731              :                            =====                   ====
   14732              : 
   14733              :                     Ptr ->
   14734              :                            +------------+
   14735              :                            | t1 | f1    |
   14736              :                            |------------|
   14737              :                            | Operator   |                          <- Ptr
   14738              :                            |------------|          +------------+
   14739              :                            | t2 | f2    |          | t    | f   |
   14740              :                            |------------|          |------------|
   14741              : 
   14742              : 
   14743              : */
   14744              : 
   14745            0 : static void BuildRelOpFromBoolean (unsigned int tokpos)
   14746              : {
   14747            0 :   unsigned int Tok;
   14748            0 :   unsigned int t1;
   14749            0 :   unsigned int f1;
   14750            0 :   unsigned int t2;
   14751            0 :   unsigned int f2;
   14752            0 :   M2Quads_QuadFrame f;
   14753              : 
   14754            0 :   M2Debug_Assert ((IsBoolean (1)) && (IsBoolean (3)));
   14755            0 :   if ((M2Quads_OperandT (2)) == M2Reserved_EqualTok)
   14756              :     {
   14757              :       /* Are the two boolean expressions the same?  */
   14758            0 :       PopBool (&t1, &f1);
   14759            0 :       M2Quads_PopT (&Tok);
   14760            0 :       PopBool (&t2, &f2);
   14761              :       /* Give the false exit a second chance.  */
   14762            0 :       BackPatch (t2, t1);  /* q    if   _     _    q+2  */
   14763            0 :       BackPatch (f2, NextQuad);  /* q+1  if   _     _    q+4  */
   14764            0 :       M2Debug_Assert (NextQuad == (f1+1));  /* q+1  if   _     _    q+4  */
   14765            0 :       f = GetQF (t1);
   14766            0 :       GenQuadO (tokpos, f->Operator, f->Operand1, f->Operand2, 0, false);
   14767            0 :       GenQuadO (tokpos, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
   14768            0 :       PushBooltok (Merge (NextQuad-1, t1), Merge (NextQuad-2, f1), tokpos);
   14769              :     }
   14770            0 :   else if (((M2Quads_OperandT (2)) == M2Reserved_HashTok) || ((M2Quads_OperandT (2)) == M2Reserved_LessGreaterTok))
   14771              :     {
   14772              :       /* avoid dangling else.  */
   14773            0 :       if (M2Options_CompilerDebugging)
   14774              :         {
   14775            0 :           M2Printf_printf0 ((const char *) "BuildRelOpFromBoolean (NotEqualTok)\\n", 37);
   14776            0 :           M2Quads_DisplayStack ();
   14777              :         }
   14778              :       /* Are the two boolean expressions different?  */
   14779            0 :       PopBool (&t1, &f1);
   14780            0 :       M2Quads_PopT (&Tok);
   14781            0 :       PopBool (&t2, &f2);
   14782            0 :       if (M2Options_CompilerDebugging)
   14783              :         {
   14784            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));
   14785            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));
   14786            0 :           DumpQuadSummary (t1);
   14787            0 :           DumpQuadSummary (f1);
   14788            0 :           DumpQuadSummary (t2);
   14789            0 :           DumpQuadSummary (f2);
   14790              :         }
   14791              :       /* Give the false exit a second chance.  */
   14792            0 :       BackPatch (t2, t1);  /* q    if   _     _    q+2  */
   14793            0 :       BackPatch (f2, NextQuad);  /* q+1  if   _     _    q+4  */
   14794            0 :       M2Debug_Assert (NextQuad == (f1+1));  /* q+1  if   _     _    q+4  */
   14795            0 :       f = GetQF (t1);
   14796            0 :       GenQuadO (tokpos, f->Operator, f->Operand1, f->Operand2, 0, false);
   14797            0 :       GenQuadO (tokpos, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
   14798            0 :       PushBooltok (Merge (NextQuad-2, f1), Merge (NextQuad-1, t1), tokpos);
   14799              :     }
   14800              :   else
   14801              :     {
   14802              :       /* avoid dangling else.  */
   14803            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);
   14804              :     }
   14805            0 : }
   14806              : 
   14807              : 
   14808              : /*
   14809              :    CheckVariableOrConstantOrProcedure - checks to make sure sym is a variable, constant or procedure.
   14810              : */
   14811              : 
   14812       181532 : static void CheckVariableOrConstantOrProcedure (unsigned int tokpos, unsigned int sym)
   14813              : {
   14814       181532 :   unsigned int type;
   14815              : 
   14816       181532 :   type = SymbolTable_GetSType (sym);
   14817       181532 :   if (SymbolTable_IsUnknown (sym))
   14818              :     {
   14819              :       /* Spellcheck.  */
   14820           12 :       M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1EUad} has not been declared {%1&s}", 37, sym);
   14821           12 :       SymbolTable_UnknownReported (sym);
   14822              :     }
   14823       181520 :   else if ((M2System_IsPseudoSystemFunction (sym)) || (M2Base_IsPseudoBaseFunction (sym)))
   14824              :     {
   14825              :       /* avoid dangling else.  */
   14826            6 :       M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1Ead} expected a variable, procedure, constant or expression, not an intrinsic procedure function", 99, sym);
   14827              :     }
   14828       181514 :   else if (((((! (SymbolTable_IsConst (sym))) && (! (SymbolTable_IsVar (sym)))) && (! (SymbolTable_IsProcedure (sym)))) && (! (SymbolTable_IsTemporary (sym)))) && ! MustNotCheckBounds)
   14829              :     {
   14830              :       /* avoid dangling else.  */
   14831            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);
   14832              :     }
   14833       181514 :   else if ((type != SymbolTable_NulSym) && (SymbolTable_IsArray (type)))
   14834              :     {
   14835              :       /* avoid dangling else.  */
   14836            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);
   14837              :     }
   14838       181514 :   else if (((SymbolTable_IsConstString (sym)) && (SymbolTable_IsConstStringKnown (sym))) && ((SymbolTable_GetStringLength (tokpos, sym)) > 1))
   14839              :     {
   14840              :       /* avoid dangling else.  */
   14841            0 :       M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1EU} not expecting a string constant as an operand for either comparison or binary operation", 94, sym);
   14842              :     }
   14843       181532 : }
   14844              : 
   14845              : 
   14846              : /*
   14847              :    MakeOp - returns the equalent quadruple operator to a token, t.
   14848              : */
   14849              : 
   14850       169064 : static M2Quads_QuadOperator MakeOp (NameKey_Name t)
   14851              : {
   14852       169064 :   if (t == ArithPlusTok)
   14853              :     {
   14854              :       return M2Quads_ArithAddOp;
   14855              :     }
   14856       169064 :   else if (t == M2Reserved_PlusTok)
   14857              :     {
   14858              :       /* avoid dangling else.  */
   14859              :       return M2Quads_AddOp;
   14860              :     }
   14861       144581 :   else if (t == M2Reserved_MinusTok)
   14862              :     {
   14863              :       /* avoid dangling else.  */
   14864              :       return M2Quads_SubOp;
   14865              :     }
   14866       121837 :   else if (t == M2Reserved_DivTok)
   14867              :     {
   14868              :       /* avoid dangling else.  */
   14869              :       return M2Quads_DivM2Op;
   14870              :     }
   14871       115051 :   else if (t == M2Reserved_DivideTok)
   14872              :     {
   14873              :       /* avoid dangling else.  */
   14874              :       return M2Quads_DivTruncOp;
   14875              :     }
   14876       112593 :   else if (t == M2Reserved_RemTok)
   14877              :     {
   14878              :       /* avoid dangling else.  */
   14879              :       return M2Quads_ModTruncOp;
   14880              :     }
   14881       112497 :   else if (t == M2Reserved_ModTok)
   14882              :     {
   14883              :       /* avoid dangling else.  */
   14884              :       return M2Quads_ModM2Op;
   14885              :     }
   14886       110137 :   else if (t == M2Reserved_TimesTok)
   14887              :     {
   14888              :       /* avoid dangling else.  */
   14889              :       return M2Quads_MultOp;
   14890              :     }
   14891        92196 :   else if (t == M2Reserved_HashTok)
   14892              :     {
   14893              :       /* avoid dangling else.  */
   14894              :       return M2Quads_IfNotEquOp;
   14895              :     }
   14896        79739 :   else if (t == M2Reserved_LessGreaterTok)
   14897              :     {
   14898              :       /* avoid dangling else.  */
   14899              :       return M2Quads_IfNotEquOp;
   14900              :     }
   14901        79655 :   else if (t == M2Reserved_GreaterEqualTok)
   14902              :     {
   14903              :       /* avoid dangling else.  */
   14904              :       return M2Quads_IfGreEquOp;
   14905              :     }
   14906        69173 :   else if (t == M2Reserved_LessEqualTok)
   14907              :     {
   14908              :       /* avoid dangling else.  */
   14909              :       return M2Quads_IfLessEquOp;
   14910              :     }
   14911        64427 :   else if (t == M2Reserved_EqualTok)
   14912              :     {
   14913              :       /* avoid dangling else.  */
   14914              :       return M2Quads_IfEquOp;
   14915              :     }
   14916        17473 :   else if (t == M2Reserved_LessTok)
   14917              :     {
   14918              :       /* avoid dangling else.  */
   14919              :       return M2Quads_IfLessOp;
   14920              :     }
   14921         9916 :   else if (t == M2Reserved_GreaterTok)
   14922              :     {
   14923              :       /* avoid dangling else.  */
   14924              :       return M2Quads_IfGreOp;
   14925              :     }
   14926         3876 :   else if (t == M2Reserved_InTok)
   14927              :     {
   14928              :       /* avoid dangling else.  */
   14929              :       return M2Quads_IfInOp;
   14930              :     }
   14931         1430 :   else if (t == LogicalOrTok)
   14932              :     {
   14933              :       /* avoid dangling else.  */
   14934              :       return M2Quads_LogicalOrOp;
   14935              :     }
   14936          474 :   else if (t == LogicalAndTok)
   14937              :     {
   14938              :       /* avoid dangling else.  */
   14939              :       return M2Quads_LogicalAndOp;
   14940              :     }
   14941          190 :   else if (t == LogicalXorTok)
   14942              :     {
   14943              :       /* avoid dangling else.  */
   14944              :       return M2Quads_LogicalXorOp;
   14945              :     }
   14946           66 :   else if (t == LogicalDifferenceTok)
   14947              :     {
   14948              :       /* avoid dangling else.  */
   14949              :       return M2Quads_LogicalDiffOp;
   14950              :     }
   14951              :   else
   14952              :     {
   14953              :       /* avoid dangling else.  */
   14954            0 :       M2Error_InternalError ((const char *) "binary operation not implemented yet", 36);
   14955              :     }
   14956              :   ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
   14957              :   __builtin_unreachable ();
   14958              : }
   14959              : 
   14960              : 
   14961              : /*
   14962              :    GenQuadO - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
   14963              : */
   14964              : 
   14965      5406988 : static void GenQuadO (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow)
   14966              : {
   14967      1200539 :   GenQuadOTrash (TokPos, Operation, Op1, Op2, Op3, overflow, SymbolTable_NulSym);
   14968            0 : }
   14969              : 
   14970              : 
   14971              : /*
   14972              :    GenQuadOTrash - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
   14973              : */
   14974              : 
   14975      5408826 : static void GenQuadOTrash (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow, unsigned int trash)
   14976              : {
   14977      5408826 :   M2Quads_QuadFrame f;
   14978              : 
   14979              :   /* WriteString('Potential Quad: ') ;  */
   14980      5408826 :   if (QuadrupleGeneration)
   14981              :     {
   14982      5406581 :       if (NextQuad != Head)
   14983              :         {
   14984      5391514 :           f = GetQF (NextQuad-1);
   14985      5391514 :           f->Next = NextQuad;
   14986              :         }
   14987      5406581 :       PutQuadO (NextQuad, Operation, Op1, Op2, Op3, overflow);
   14988      5406581 :       f = GetQF (NextQuad);
   14989      5406581 :       f->Trash = trash;
   14990      5406581 :       f->Next = 0;
   14991      5406581 :       f->LineNo = M2LexBuf_GetLineNo ();
   14992      5406581 :       if (TokPos == M2LexBuf_UnknownTokenNo)
   14993              :         {
   14994      3236541 :           f->TokenNo = M2LexBuf_GetTokenNo ();
   14995              :         }
   14996              :       else
   14997              :         {
   14998      2170040 :           f->TokenNo = TokPos;
   14999              :         }
   15000      5406581 :       if (M2Options_GetDebugTraceQuad ())
   15001              :         {
   15002            0 :           M2Printf_printf0 ((const char *) "generating: ", 12);
   15003            0 :           M2Quads_DisplayQuad (NextQuad);
   15004              :         }
   15005              :       /* MetaErrorT1 (TokenNo, '{%1On}', NextQuad)  */
   15006      5406581 :       CheckBreak (NextQuad);
   15007      5406581 :       NewQuad (&NextQuad);
   15008              :     }
   15009      5408826 : }
   15010              : 
   15011              : 
   15012              : /*
   15013              :    GenQuad - Generate a quadruple with Operation, Op1, Op2, Op3.
   15014              : */
   15015              : 
   15016      3166350 : static void GenQuad (M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3)
   15017              : {
   15018      2181284 :   GenQuadO (M2LexBuf_UnknownTokenNo, Operation, Op1, Op2, Op3, true);
   15019            0 : }
   15020              : 
   15021              : 
   15022              : /*
   15023              :    GenQuadOtok - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
   15024              : */
   15025              : 
   15026       572414 : 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)
   15027              : {
   15028       481648 :   GenQuadOTypetok (TokPos, Operation, Op1, Op2, Op3, overflow, true, Op1Pos, Op2Pos, Op3Pos);
   15029            0 : }
   15030              : 
   15031              : 
   15032              : /*
   15033              :    GenQuadOTypetok - assigns the fields of the quadruple with
   15034              :                      the parameters.
   15035              : */
   15036              : 
   15037       876087 : 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)
   15038              : {
   15039       876087 :   M2Quads_QuadFrame f;
   15040              : 
   15041              :   /* WriteString('Potential Quad: ') ;  */
   15042       876087 :   if (QuadrupleGeneration)
   15043              :     {
   15044       875396 :       if (NextQuad != Head)
   15045              :         {
   15046       875396 :           f = GetQF (NextQuad-1);
   15047       875396 :           f->Next = NextQuad;
   15048              :         }
   15049       875396 :       PutQuadOType (NextQuad, Operation, Op1, Op2, Op3, overflow, typecheck);
   15050       875396 :       f = GetQF (NextQuad);
   15051       875396 :       f->Next = 0;
   15052       875396 :       f->LineNo = M2LexBuf_GetLineNo ();
   15053       875396 :       if (TokPos == M2LexBuf_UnknownTokenNo)
   15054              :         {
   15055            0 :           f->TokenNo = M2LexBuf_GetTokenNo ();
   15056              :         }
   15057              :       else
   15058              :         {
   15059       875396 :           f->TokenNo = TokPos;
   15060              :         }
   15061       875396 :       f->op1pos = Op1Pos;
   15062       875396 :       f->op2pos = Op2Pos;
   15063       875396 :       f->op3pos = Op3Pos;
   15064       875396 :       if (M2Options_GetDebugTraceQuad ())
   15065              :         {
   15066            0 :           M2Printf_printf0 ((const char *) "generating: ", 12);
   15067            0 :           M2Quads_DisplayQuad (NextQuad);
   15068              :         }
   15069              :       /* MetaErrorT1 (TokenNo, '{%1On}', NextQuad)  */
   15070       875396 :       CheckBreak (NextQuad);
   15071       875396 :       NewQuad (&NextQuad);
   15072              :     }
   15073       876087 : }
   15074              : 
   15075              : 
   15076              : /*
   15077              :    DumpUntil - dump all quadruples until we seen the ending quadruple
   15078              :                with procsym in the third operand.
   15079              :                Return the quad number containing the match.
   15080              : */
   15081              : 
   15082            0 : static unsigned int DumpUntil (M2Quads_QuadOperator ending, unsigned int procsym, unsigned int quad)
   15083              : {
   15084            0 :   M2Quads_QuadOperator op;
   15085            0 :   unsigned int op1;
   15086            0 :   unsigned int op2;
   15087            0 :   unsigned int op3;
   15088            0 :   M2Quads_QuadFrame f;
   15089              : 
   15090            0 :   M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "\\n...\\n\\n", 9);
   15091            0 :   do {
   15092            0 :     M2Quads_GetQuad (quad, &op, &op1, &op2, &op3);
   15093            0 :     M2Quads_DisplayQuad (quad);
   15094            0 :     f = GetQF (quad);
   15095            0 :     quad = f->Next;
   15096            0 :   } while (! ((op == ending) && (op3 == procsym)));
   15097            0 :   return quad;
   15098              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15099              :   __builtin_unreachable ();
   15100              : }
   15101              : 
   15102              : 
   15103              : /*
   15104              :    GetCtorInit - return the init procedure for the module.
   15105              : */
   15106              : 
   15107            0 : static unsigned int GetCtorInit (unsigned int sym)
   15108              : {
   15109            0 :   unsigned int ctor;
   15110            0 :   unsigned int init;
   15111            0 :   unsigned int fini;
   15112            0 :   unsigned int dep;
   15113              : 
   15114            0 :   SymbolTable_GetModuleCtors (sym, &ctor, &init, &fini, &dep);
   15115            0 :   return init;
   15116              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15117              :   __builtin_unreachable ();
   15118              : }
   15119              : 
   15120              : 
   15121              : /*
   15122              :    GetCtorFini - return the fini procedure for the module.
   15123              : */
   15124              : 
   15125            0 : static unsigned int GetCtorFini (unsigned int sym)
   15126              : {
   15127            0 :   unsigned int ctor;
   15128            0 :   unsigned int init;
   15129            0 :   unsigned int fini;
   15130            0 :   unsigned int dep;
   15131              : 
   15132            0 :   SymbolTable_GetModuleCtors (sym, &ctor, &init, &fini, &dep);
   15133            0 :   return fini;
   15134              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15135              :   __builtin_unreachable ();
   15136              : }
   15137              : 
   15138              : 
   15139              : /*
   15140              :    DumpQuadrupleFilter -
   15141              : */
   15142              : 
   15143            0 : static void DumpQuadrupleFilter (void)
   15144              : {
   15145            0 :   M2Quads_QuadFrame f;
   15146            0 :   unsigned int i;
   15147            0 :   M2Quads_QuadOperator op;
   15148            0 :   unsigned int op1;
   15149            0 :   unsigned int op2;
   15150            0 :   unsigned int op3;
   15151              : 
   15152            0 :   i = Head;
   15153            0 :   while (i != 0)
   15154              :     {
   15155            0 :       M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
   15156            0 :       if ((op == M2Quads_ProcedureScopeOp) && (M2LangDump_IsDumpRequired (op3, true)))
   15157              :         {
   15158            0 :           i = DumpUntil (M2Quads_KillLocalVarOp, op3, i);
   15159              :         }
   15160            0 :       else if ((op == M2Quads_InitStartOp) && (M2LangDump_IsDumpRequired (GetCtorInit (op3), true)))
   15161              :         {
   15162              :           /* avoid dangling else.  */
   15163            0 :           i = DumpUntil (M2Quads_InitEndOp, op3, i);
   15164              :         }
   15165            0 :       else if ((op == M2Quads_FinallyStartOp) && (M2LangDump_IsDumpRequired (GetCtorFini (op3), true)))
   15166              :         {
   15167              :           /* avoid dangling else.  */
   15168            0 :           i = DumpUntil (M2Quads_FinallyEndOp, op3, i);
   15169              :         }
   15170              :       else
   15171              :         {
   15172              :           /* avoid dangling else.  */
   15173            0 :           f = GetQF (i);
   15174            0 :           i = f->Next;
   15175              :         }
   15176              :     }
   15177            0 : }
   15178              : 
   15179              : 
   15180              : /*
   15181              :    DumpQuadrupleAll - dump all quadruples.
   15182              : */
   15183              : 
   15184            0 : static void DumpQuadrupleAll (void)
   15185              : {
   15186            0 :   M2Quads_QuadFrame f;
   15187            0 :   unsigned int i;
   15188              : 
   15189            0 :   i = Head;
   15190            0 :   while (i != 0)
   15191              :     {
   15192            0 :       M2Quads_DisplayQuad (i);
   15193            0 :       f = GetQF (i);
   15194            0 :       i = f->Next;
   15195              :     }
   15196            0 : }
   15197              : 
   15198              : 
   15199              : /*
   15200              :    BackPatch - Makes each of the quadruples on the list pointed to by
   15201              :                QuadNo take quadruple Value as a target.
   15202              : */
   15203              : 
   15204       416214 : static void BackPatch (unsigned int QuadNo, unsigned int Value)
   15205              : {
   15206       416214 :   unsigned int i;
   15207       416214 :   M2Quads_QuadFrame f;
   15208              : 
   15209       416214 :   if (QuadrupleGeneration)
   15210              :     {
   15211       661626 :       while (QuadNo != 0)
   15212              :         {
   15213       245429 :           f = GetQF (QuadNo);
   15214       245429 :           i = f->Operand3;  /* Next Link along the BackPatch  */
   15215       245429 :           ManipulateReference (QuadNo, Value);  /* Filling in the BackPatch.  */
   15216       245429 :           QuadNo = i;
   15217              :         }
   15218              :     }
   15219       416214 : }
   15220              : 
   15221              : 
   15222              : /*
   15223              :    Merge - joins two quad lists, QuadList2 to the end of QuadList1.
   15224              :            A QuadList of value zero is a nul list.
   15225              : */
   15226              : 
   15227        53920 : static unsigned int Merge (unsigned int QuadList1, unsigned int QuadList2)
   15228              : {
   15229        53920 :   unsigned int i;
   15230        53920 :   unsigned int j;
   15231        53920 :   M2Quads_QuadFrame f;
   15232              : 
   15233        53920 :   if (QuadList1 == 0)
   15234              :     {
   15235              :       return QuadList2;
   15236              :     }
   15237        26430 :   else if (QuadList2 == 0)
   15238              :     {
   15239              :       /* avoid dangling else.  */
   15240              :       return QuadList1;
   15241              :     }
   15242              :   else
   15243              :     {
   15244              :       /* avoid dangling else.  */
   15245              :       i = QuadList1;
   15246        51806 :       do {
   15247        51806 :         j = i;
   15248        51806 :         f = GetQF (i);
   15249        51806 :         i = f->Operand3;
   15250        51806 :       } while (! (i == 0));
   15251        23224 :       ManipulateReference (j, QuadList2);
   15252        23224 :       return QuadList1;
   15253              :     }
   15254              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15255              :   __builtin_unreachable ();
   15256              : }
   15257              : 
   15258              : 
   15259              : /*
   15260              :    DisplayProcedureAttributes -
   15261              : */
   15262              : 
   15263            0 : static void DisplayProcedureAttributes (unsigned int proc)
   15264              : {
   15265            0 :   if (SymbolTable_IsCtor (proc))
   15266              :     {
   15267            0 :       M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (ctor)", 7);
   15268              :     }
   15269            0 :   if (SymbolTable_IsPublic (proc))
   15270              :     {
   15271            0 :       M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (public)", 9);
   15272              :     }
   15273            0 :   if (SymbolTable_IsExtern (proc))
   15274              :     {
   15275            0 :       M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (extern)", 9);
   15276              :     }
   15277            0 :   if (SymbolTable_IsMonoName (proc))
   15278              :     {
   15279            0 :       M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (mononame)", 11);
   15280              :     }
   15281            0 : }
   15282              : 
   15283              : 
   15284              : /*
   15285              :    WriteQuad - Writes out the Quad BufferQuad.
   15286              : */
   15287              : 
   15288            0 : static void WriteQuad (unsigned int BufferQuad)
   15289              : {
   15290            0 :   NameKey_Name n1;
   15291            0 :   NameKey_Name n2;
   15292            0 :   M2Quads_QuadFrame f;
   15293            0 :   NameKey_Name n;
   15294            0 :   unsigned int l;
   15295              : 
   15296            0 :   f = GetQF (BufferQuad);
   15297            0 :   M2Quads_WriteOperator (f->Operator);
   15298            0 :   M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " [%d]", 5, (const unsigned char *) &f->NoOfTimesReferenced, (sizeof (f->NoOfTimesReferenced)-1));
   15299            0 :   if (f->ConstExpr)
   15300              :     {
   15301            0 :       M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " const ", 7);
   15302              :     }
   15303              :   else
   15304              :     {
   15305            0 :       M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "       ", 7);
   15306              :     }
   15307            0 :   switch (f->Operator)
   15308              :     {
   15309            0 :       case M2Quads_LastForIteratorOp:
   15310            0 :         M2Quads_WriteOperand (f->Operand1);
   15311            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15312            0 :         M2Quads_WriteOperand (f->Operand2);
   15313            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15314            0 :         M2Quads_WriteOperand (f->Operand3);
   15315            0 :         break;
   15316              : 
   15317            0 :       case M2Quads_HighOp:
   15318            0 :         M2Quads_WriteOperand (f->Operand1);
   15319            0 :         M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "  %4d  ", 7, (const unsigned char *) &f->Operand2, (sizeof (f->Operand2)-1));
   15320            0 :         M2Quads_WriteOperand (f->Operand3);
   15321            0 :         break;
   15322              : 
   15323            0 :       case M2Quads_InitAddressOp:
   15324            0 :       case M2Quads_SavePriorityOp:
   15325            0 :       case M2Quads_RestorePriorityOp:
   15326            0 :       case M2Quads_SubrangeLowOp:
   15327            0 :       case M2Quads_SubrangeHighOp:
   15328            0 :       case M2Quads_BecomesOp:
   15329            0 :       case M2Quads_InclOp:
   15330            0 :       case M2Quads_ExclOp:
   15331            0 :       case M2Quads_UnboundedOp:
   15332            0 :       case M2Quads_ReturnValueOp:
   15333            0 :       case M2Quads_FunctValueOp:
   15334            0 :       case M2Quads_NegateOp:
   15335            0 :       case M2Quads_AddrOp:
   15336            0 :       case M2Quads_StringConvertCnulOp:
   15337            0 :       case M2Quads_StringConvertM2nulOp:
   15338            0 :       case M2Quads_StringLengthOp:
   15339            0 :         M2Quads_WriteOperand (f->Operand1);
   15340            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15341            0 :         M2Quads_WriteOperand (f->Operand3);
   15342            0 :         break;
   15343              : 
   15344            0 :       case M2Quads_ElementSizeOp:
   15345            0 :       case M2Quads_IfInOp:
   15346            0 :       case M2Quads_IfNotInOp:
   15347            0 :       case M2Quads_IfNotEquOp:
   15348            0 :       case M2Quads_IfEquOp:
   15349            0 :       case M2Quads_IfLessOp:
   15350            0 :       case M2Quads_IfGreOp:
   15351            0 :       case M2Quads_IfLessEquOp:
   15352            0 :       case M2Quads_IfGreEquOp:
   15353            0 :         M2Quads_WriteOperand (f->Operand1);
   15354            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15355            0 :         M2Quads_WriteOperand (f->Operand2);
   15356            0 :         M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "  %4d", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
   15357            0 :         break;
   15358              : 
   15359            0 :       case M2Quads_InlineOp:
   15360            0 :       case M2Quads_RetryOp:
   15361            0 :       case M2Quads_TryOp:
   15362            0 :       case M2Quads_GotoOp:
   15363            0 :         M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d", 3, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
   15364            0 :         break;
   15365              : 
   15366            0 :       case M2Quads_StatementNoteOp:
   15367            0 :         l = M2LexBuf_TokenToLineNo (f->Operand3, 0);
   15368            0 :         n = M2LexBuf_GetTokenName (f->Operand3);
   15369            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));
   15370            0 :         break;
   15371              : 
   15372            0 :       case M2Quads_LineNumberOp:
   15373            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));
   15374            0 :         break;
   15375              : 
   15376            0 :       case M2Quads_EndFileOp:
   15377            0 :         n1 = SymbolTable_GetSymName (f->Operand3);
   15378            0 :         M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%a", 2, (const unsigned char *) &n1, (sizeof (n1)-1));
   15379            0 :         break;
   15380              : 
   15381            0 :       case M2Quads_ThrowOp:
   15382            0 :       case M2Quads_ReturnOp:
   15383            0 :       case M2Quads_CallOp:
   15384            0 :       case M2Quads_KillLocalVarOp:
   15385            0 :         M2Quads_WriteOperand (f->Operand3);
   15386            0 :         break;
   15387              : 
   15388            0 :       case M2Quads_ProcedureScopeOp:
   15389            0 :         n1 = SymbolTable_GetSymName (f->Operand2);
   15390            0 :         n2 = SymbolTable_GetSymName (f->Operand3);
   15391            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));
   15392            0 :         DisplayProcedureAttributes (f->Operand3);
   15393            0 :         break;
   15394              : 
   15395            0 :       case M2Quads_NewLocalVarOp:
   15396            0 :       case M2Quads_FinallyStartOp:
   15397            0 :       case M2Quads_FinallyEndOp:
   15398            0 :       case M2Quads_InitEndOp:
   15399            0 :       case M2Quads_InitStartOp:
   15400            0 :         n1 = SymbolTable_GetSymName (f->Operand2);
   15401            0 :         n2 = SymbolTable_GetSymName (f->Operand3);
   15402            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));
   15403            0 :         break;
   15404              : 
   15405            0 :       case M2Quads_ModuleScopeOp:
   15406            0 :       case M2Quads_StartModFileOp:
   15407            0 :         n1 = SymbolTable_GetSymName (f->Operand3);
   15408            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));
   15409            0 :         break;
   15410              : 
   15411            0 :       case M2Quads_StartDefFileOp:
   15412            0 :         n1 = SymbolTable_GetSymName (f->Operand3);
   15413            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));
   15414            0 :         break;
   15415              : 
   15416            0 :       case M2Quads_OptParamOp:
   15417            0 :       case M2Quads_ParamOp:
   15418            0 :         M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d  ", 5, (const unsigned char *) &f->Operand1, (sizeof (f->Operand1)-1));
   15419            0 :         M2Quads_WriteOperand (f->Operand2);
   15420            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15421            0 :         M2Quads_WriteOperand (f->Operand3);
   15422            0 :         break;
   15423              : 
   15424            0 :       case M2Quads_SizeOp:
   15425            0 :       case M2Quads_RecordFieldOp:
   15426            0 :       case M2Quads_IndrXOp:
   15427            0 :       case M2Quads_XIndrOp:
   15428            0 :       case M2Quads_ArrayOp:
   15429            0 :       case M2Quads_LogicalShiftOp:
   15430            0 :       case M2Quads_LogicalRotateOp:
   15431            0 :       case M2Quads_LogicalOrOp:
   15432            0 :       case M2Quads_LogicalAndOp:
   15433            0 :       case M2Quads_LogicalXorOp:
   15434            0 :       case M2Quads_LogicalDiffOp:
   15435            0 :       case M2Quads_ArithAddOp:
   15436            0 :       case M2Quads_CoerceOp:
   15437            0 :       case M2Quads_ConvertOp:
   15438            0 :       case M2Quads_CastOp:
   15439            0 :       case M2Quads_AddOp:
   15440            0 :       case M2Quads_SubOp:
   15441            0 :       case M2Quads_MultOp:
   15442            0 :       case M2Quads_DivM2Op:
   15443            0 :       case M2Quads_ModM2Op:
   15444            0 :       case M2Quads_ModFloorOp:
   15445            0 :       case M2Quads_DivCeilOp:
   15446            0 :       case M2Quads_ModCeilOp:
   15447            0 :       case M2Quads_DivFloorOp:
   15448            0 :       case M2Quads_ModTruncOp:
   15449            0 :       case M2Quads_DivTruncOp:
   15450            0 :         M2Quads_WriteOperand (f->Operand1);
   15451            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15452            0 :         M2Quads_WriteOperand (f->Operand2);
   15453            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15454            0 :         M2Quads_WriteOperand (f->Operand3);
   15455            0 :         break;
   15456              : 
   15457              :       case M2Quads_DummyOp:
   15458              :       case M2Quads_CodeOnOp:
   15459              :       case M2Quads_CodeOffOp:
   15460              :       case M2Quads_ProfileOnOp:
   15461              :       case M2Quads_ProfileOffOp:
   15462              :       case M2Quads_OptimizeOnOp:
   15463              :       case M2Quads_OptimizeOffOp:
   15464              :         break;
   15465              : 
   15466            0 :       case M2Quads_BuiltinConstOp:
   15467            0 :         M2Quads_WriteOperand (f->Operand1);
   15468            0 :         M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "   %a", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
   15469            0 :         break;
   15470              : 
   15471            0 :       case M2Quads_BuiltinTypeInfoOp:
   15472            0 :         M2Quads_WriteOperand (f->Operand1);
   15473            0 :         M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "   %a", 5, (const unsigned char *) &f->Operand2, (sizeof (f->Operand2)-1));
   15474            0 :         M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "   %a", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
   15475            0 :         break;
   15476              : 
   15477            0 :       case M2Quads_StandardFunctionOp:
   15478            0 :         M2Quads_WriteOperand (f->Operand1);
   15479            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15480            0 :         M2Quads_WriteOperand (f->Operand2);
   15481            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15482            0 :         M2Quads_WriteOperand (f->Operand3);
   15483            0 :         break;
   15484              : 
   15485              :       case M2Quads_CatchBeginOp:
   15486              :       case M2Quads_CatchEndOp:
   15487              :         break;
   15488              : 
   15489            0 :       case M2Quads_RangeCheckOp:
   15490            0 :       case M2Quads_ErrorOp:
   15491            0 :         M2Range_WriteRangeCheck (f->Operand3);
   15492            0 :         break;
   15493              : 
   15494            0 :       case M2Quads_SaveExceptionOp:
   15495            0 :       case M2Quads_RestoreExceptionOp:
   15496            0 :         M2Quads_WriteOperand (f->Operand1);
   15497            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "  ", 2);
   15498            0 :         M2Quads_WriteOperand (f->Operand3);
   15499            0 :         break;
   15500              : 
   15501              : 
   15502            0 :       default:
   15503            0 :         M2Error_InternalError ((const char *) "quadruple not recognised", 24);
   15504            0 :         break;
   15505              :     }
   15506            0 : }
   15507              : 
   15508              : 
   15509              : /*
   15510              :    WriteOperand - displays the operands name, symbol id and mode of addressing.
   15511              : */
   15512              : 
   15513            0 : static void WriteMode (SymbolTable_ModeOfAddr Mode)
   15514              : {
   15515            0 :   switch (Mode)
   15516              :     {
   15517            0 :       case SymbolTable_ImmediateValue:
   15518            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "i", 1);
   15519            0 :         break;
   15520              : 
   15521            0 :       case SymbolTable_NoValue:
   15522            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "n", 1);
   15523            0 :         break;
   15524              : 
   15525            0 :       case SymbolTable_RightValue:
   15526            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "r", 1);
   15527            0 :         break;
   15528              : 
   15529            0 :       case SymbolTable_LeftValue:
   15530            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "l", 1);
   15531            0 :         break;
   15532              : 
   15533              : 
   15534            0 :       default:
   15535            0 :         M2Error_InternalError ((const char *) "unrecognised mode", 17);
   15536            0 :         break;
   15537              :     }
   15538            0 : }
   15539              : 
   15540              : 
   15541              : /*
   15542              :    PushExit - pushes the exit value onto the EXIT stack.
   15543              : */
   15544              : 
   15545          603 : static void PushExit (unsigned int Exit)
   15546              : {
   15547            0 :   M2StackWord_PushWord (ExitStack, Exit);
   15548            0 : }
   15549              : 
   15550              : 
   15551              : /*
   15552              :    PopExit - pops the exit value from the EXIT stack.
   15553              : */
   15554              : 
   15555          603 : static unsigned int PopExit (void)
   15556              : {
   15557            0 :   return M2StackWord_PopWord (ExitStack);
   15558              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15559              :   __builtin_unreachable ();
   15560              : }
   15561              : 
   15562              : 
   15563              : /*
   15564              :    PushFor - pushes the exit value onto the FOR stack.
   15565              : */
   15566              : 
   15567        10286 : static void PushFor (unsigned int Exit)
   15568              : {
   15569            0 :   M2StackWord_PushWord (ForStack, Exit);
   15570            0 : }
   15571              : 
   15572              : 
   15573              : /*
   15574              :    PopFor - pops the exit value from the FOR stack.
   15575              : */
   15576              : 
   15577        10280 : static unsigned int PopFor (void)
   15578              : {
   15579            0 :   return M2StackWord_PopWord (ForStack);
   15580              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15581              :   __builtin_unreachable ();
   15582              : }
   15583              : 
   15584              : 
   15585              : /*
   15586              :    OperandTno - returns the ident operand stored in the true position
   15587              :                 on the boolean stack.  This is exactly the same as
   15588              :                 OperandT but it has no IsBoolean checking.
   15589              : */
   15590              : 
   15591    214826127 : static unsigned int OperandTno (unsigned int pos)
   15592              : {
   15593    214826127 :   M2Quads_BoolFrame f;
   15594              : 
   15595    214826127 :   M2Debug_Assert (pos > 0);
   15596    214826127 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   15597    214826127 :   return static_cast<unsigned int> (f->TrueExit);
   15598              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15599              :   __builtin_unreachable ();
   15600              : }
   15601              : 
   15602              : 
   15603              : /*
   15604              :    OperandFno - returns the ident operand stored in the false position
   15605              :                 on the boolean stack.  This is exactly the same as
   15606              :                 OperandF but it has no IsBoolean checking.
   15607              : */
   15608              : 
   15609       176325 : static unsigned int OperandFno (unsigned int pos)
   15610              : {
   15611       176325 :   M2Quads_BoolFrame f;
   15612              : 
   15613       176325 :   M2Debug_Assert (pos > 0);
   15614       176325 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   15615       176325 :   return static_cast<unsigned int> (f->FalseExit);
   15616              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15617              :   __builtin_unreachable ();
   15618              : }
   15619              : 
   15620              : 
   15621              : /*
   15622              :    OperandTtok - returns the token associated with the position, pos
   15623              :                  on the boolean stack.
   15624              : */
   15625              : 
   15626     58852536 : static unsigned int OperandTtok (unsigned int pos)
   15627              : {
   15628     58852536 :   M2Quads_BoolFrame f;
   15629              : 
   15630     58852536 :   M2Debug_Assert (pos > 0);
   15631     58852536 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   15632     58852536 :   return f->tokenno;
   15633              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15634              :   __builtin_unreachable ();
   15635              : }
   15636              : 
   15637              : 
   15638              : /*
   15639              :    PopBooltok - Pops a True and a False exit quad number from the True/False
   15640              :                 stack.
   15641              : */
   15642              : 
   15643       223263 : static void PopBooltok (unsigned int *True, unsigned int *False, unsigned int *tokno)
   15644              : {
   15645       223263 :   M2Quads_BoolFrame f;
   15646              : 
   15647       223263 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   15648       223263 :   (*True) = f->TrueExit;
   15649       223263 :   (*False) = f->FalseExit;
   15650       223263 :   (*tokno) = f->tokenno;
   15651       223263 :   M2Debug_Assert (f->BooleanOp);
   15652       223263 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   15653       223263 : }
   15654              : 
   15655              : 
   15656              : /*
   15657              :    PushBooltok - Push a True and a False exit quad numbers onto the
   15658              :                  True/False stack.
   15659              : */
   15660              : 
   15661       230607 : static void PushBooltok (unsigned int True, unsigned int False, unsigned int tokno)
   15662              : {
   15663       230607 :   M2Quads_BoolFrame f;
   15664              : 
   15665       230607 :   M2Debug_Assert (True <= NextQuad);
   15666       230607 :   M2Debug_Assert (False <= NextQuad);
   15667       230607 :   f = newBoolFrame ();
   15668       230607 :   f->TrueExit = True;
   15669       230607 :   f->FalseExit = False;
   15670       230607 :   f->BooleanOp = true;
   15671       230607 :   f->tokenno = tokno;
   15672       230607 :   f->Annotation = static_cast<DynamicStrings_String> (NULL);
   15673       230607 :   f->RangeDep = 0;
   15674       230607 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   15675       230607 :   M2Quads_Annotate ((const char *) "<q%1d>|<q%2d>||true quad|false quad", 35);
   15676       230607 : }
   15677              : 
   15678              : 
   15679              : /*
   15680              :    PopBool - Pops a True and a False exit quad number from the True/False
   15681              :              stack.
   15682              : */
   15683              : 
   15684       190279 : static void PopBool (unsigned int *True, unsigned int *False)
   15685              : {
   15686       190279 :   unsigned int tokno;
   15687              : 
   15688         9963 :   PopBooltok (True, False, &tokno);
   15689            0 : }
   15690              : 
   15691              : 
   15692              : /*
   15693              :    PushBool - Push a True and a False exit quad numbers onto the
   15694              :               True/False stack.
   15695              : */
   15696              : 
   15697       120029 : static void PushBool (unsigned int True, unsigned int False)
   15698              : {
   15699         7344 :   PushBooltok (True, False, M2LexBuf_UnknownTokenNo);
   15700            0 : }
   15701              : 
   15702              : 
   15703              : /*
   15704              :    IsBoolean - returns true is the Stack position pos contains a Boolean
   15705              :                Exit. False is returned if an Ident is stored.
   15706              : */
   15707              : 
   15708    277624557 : static bool IsBoolean (unsigned int pos)
   15709              : {
   15710    277624557 :   M2Quads_BoolFrame f;
   15711              : 
   15712    277624557 :   M2Debug_Assert (pos > 0);
   15713    277624557 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   15714    277624557 :   return f->BooleanOp;
   15715              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15716              :   __builtin_unreachable ();
   15717              : }
   15718              : 
   15719              : 
   15720              : /*
   15721              :    OperandD - returns possible array dimension associated with the ident
   15722              :               operand stored on the boolean stack.
   15723              : */
   15724              : 
   15725       682279 : static unsigned int OperandD (unsigned int pos)
   15726              : {
   15727       682279 :   M2Quads_BoolFrame f;
   15728              : 
   15729       682279 :   M2Debug_Assert (pos > 0);
   15730       682279 :   M2Debug_Assert (! (IsBoolean (pos)));
   15731       682279 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   15732       682279 :   return static_cast<unsigned int> (f->Dimension);
   15733              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15734              :   __builtin_unreachable ();
   15735              : }
   15736              : 
   15737              : 
   15738              : /*
   15739              :    OperandRW - returns the rw operand stored on the boolean stack.
   15740              : */
   15741              : 
   15742       744485 : static unsigned int OperandRW (unsigned int pos)
   15743              : {
   15744       744485 :   M2Quads_BoolFrame f;
   15745              : 
   15746       744485 :   M2Debug_Assert (pos > 0);
   15747       744485 :   M2Debug_Assert (! (IsBoolean (pos)));
   15748       744485 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   15749       744485 :   return static_cast<unsigned int> (f->ReadWrite);
   15750              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15751              :   __builtin_unreachable ();
   15752              : }
   15753              : 
   15754              : 
   15755              : /*
   15756              :    OperandMergeRW - returns the rw operand if not NulSym else it
   15757              :                     returns True.
   15758              : */
   15759              : 
   15760       720691 : static unsigned int OperandMergeRW (unsigned int pos)
   15761              : {
   15762       720691 :   if ((OperandRW (pos)) == SymbolTable_NulSym)
   15763              :     {
   15764       699266 :       return M2Quads_OperandT (pos);
   15765              :     }
   15766              :   else
   15767              :     {
   15768        21425 :       return OperandRW (pos);
   15769              :     }
   15770              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15771              :   __builtin_unreachable ();
   15772              : }
   15773              : 
   15774              : 
   15775              : /*
   15776              :    OperandRangeDep - return the range dependant associated with the quad stack.
   15777              : */
   15778              : 
   15779       140251 : static unsigned int OperandRangeDep (unsigned int pos)
   15780              : {
   15781       140251 :   M2Quads_BoolFrame f;
   15782              : 
   15783       140251 :   M2Debug_Assert (! (IsBoolean (pos)));
   15784       140251 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   15785       140251 :   return f->RangeDep;
   15786              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15787              :   __builtin_unreachable ();
   15788              : }
   15789              : 
   15790              : 
   15791              : /*
   15792              :    PutRangeDep - assigns the quad stack pos RangeDep to dep.
   15793              : */
   15794              : 
   15795       534556 : static void PutRangeDep (unsigned int pos, unsigned int dep)
   15796              : {
   15797       534556 :   M2Quads_BoolFrame f;
   15798              : 
   15799       534556 :   M2Debug_Assert (! (IsBoolean (pos)));
   15800       534556 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   15801       534556 :   f->RangeDep = dep;
   15802       534556 : }
   15803              : 
   15804              : 
   15805              : /*
   15806              :    UseLineNote - uses the line note and returns it to the free list.
   15807              : */
   15808              : 
   15809         5152 : static void UseLineNote (M2Quads_LineNote l)
   15810              : {
   15811         5152 :   M2Quads_QuadFrame f;
   15812              : 
   15813         5152 :   f = GetQF (NextQuad-1);
   15814         5152 :   if ((f->Operator == M2Quads_LineNumberOp) && (f->Operand1 == ((unsigned int ) (l->File))))
   15815              :     {}  /* empty.  */
   15816              :   else
   15817              :     {
   15818              :       /* do nothing  */
   15819              :       if (false)
   15820              :         {
   15821              :           GenQuad (M2Quads_LineNumberOp, (unsigned int ) (l->File), SymbolTable_NulSym, (unsigned int ) (l->Line));
   15822              :         }
   15823              :     }
   15824         5152 :   l->Next = FreeLineList;
   15825         5152 :   FreeLineList = l;
   15826         5152 : }
   15827              : 
   15828              : 
   15829              : /*
   15830              :    PopLineNo - pops a line note from the line stack.
   15831              : */
   15832              : 
   15833         5152 : static M2Quads_LineNote PopLineNo (void)
   15834              : {
   15835         5152 :   M2Quads_LineNote l;
   15836              : 
   15837         5152 :   l = static_cast<M2Quads_LineNote> (M2StackAddress_PopAddress (LineStack));
   15838         5152 :   if (l == NULL)
   15839              :     {
   15840            0 :       M2Error_InternalError ((const char *) "no line note available", 22);
   15841              :     }
   15842         5152 :   return l;
   15843              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15844              :   __builtin_unreachable ();
   15845              : }
   15846              : 
   15847              : 
   15848              : /*
   15849              :    InitLineNote - creates a line note and initializes it to
   15850              :                   contain, file, line.
   15851              : */
   15852              : 
   15853         5152 : static M2Quads_LineNote InitLineNote (NameKey_Name file, unsigned int line)
   15854              : {
   15855         5152 :   M2Quads_LineNote l;
   15856              : 
   15857         5152 :   if (FreeLineList == NULL)
   15858              :     {
   15859         2396 :       Storage_ALLOCATE ((void **) &l, sizeof (M2Quads__T6));
   15860              :     }
   15861              :   else
   15862              :     {
   15863         2756 :       l = FreeLineList;
   15864         2756 :       FreeLineList = FreeLineList->Next;
   15865              :     }
   15866         5152 :   l->File = file;
   15867         5152 :   l->Line = line;
   15868         5152 :   return l;
   15869              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15870              :   __builtin_unreachable ();
   15871              : }
   15872              : 
   15873              : 
   15874              : /*
   15875              :    PushLineNote -
   15876              : */
   15877              : 
   15878         5152 : static void PushLineNote (M2Quads_LineNote l)
   15879              : {
   15880            0 :   M2StackAddress_PushAddress (LineStack, reinterpret_cast <void *> (l));
   15881            0 : }
   15882              : 
   15883              : 
   15884              : /*
   15885              :    BuildStmtNoteTok - adds a nop (with an assigned tokenno location) to the code.
   15886              : */
   15887              : 
   15888       548247 : static void BuildStmtNoteTok (unsigned int tokenno)
   15889              : {
   15890       548247 :   NameKey_Name filename;
   15891       548247 :   M2Quads_QuadFrame f;
   15892              : 
   15893       548247 :   f = GetQF (NextQuad-1);
   15894              :   /* no need to have multiple notes at the same position.  */
   15895       548247 :   if ((f->Operator != M2Quads_StatementNoteOp) || (f->Operand3 != tokenno))
   15896              :     {
   15897       540872 :       filename = NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()));
   15898       540872 :       GenQuad (M2Quads_StatementNoteOp, (unsigned int ) (filename), SymbolTable_NulSym, tokenno);
   15899              :     }
   15900       548247 : }
   15901              : 
   15902              : 
   15903              : /*
   15904              :    GetRecordOrField -
   15905              : */
   15906              : 
   15907        12330 : static unsigned int GetRecordOrField (void)
   15908              : {
   15909        12330 :   unsigned int f;
   15910              : 
   15911        12330 :   VarientFieldNo += 1;
   15912        12330 :   f = static_cast<unsigned int> (Lists_GetItemFromList (VarientFields, VarientFieldNo));
   15913        12330 :   if (DebugVarients)
   15914              :     {
   15915              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   15916              :       if (SymbolTable_IsRecord (f))
   15917              :         {
   15918              :           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));
   15919              :         }
   15920              :       else
   15921              :         {
   15922              :           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));
   15923              :         }
   15924              :     }
   15925        12330 :   return f;
   15926              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   15927              :   __builtin_unreachable ();
   15928              : }
   15929              : 
   15930              : 
   15931              : /*
   15932              :    PushTFAD - Push True, False, Array, Dim, numbers onto the
   15933              :               True/False stack.  True and False are assumed to
   15934              :               contain Symbols or Ident etc.
   15935              : */
   15936              : 
   15937          384 : static void PushTFAD (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim)
   15938              : {
   15939          384 :   M2Quads_BoolFrame f;
   15940              : 
   15941          384 :   f = newBoolFrame ();
   15942          384 :   f->TrueExit = static_cast<unsigned int> (True);
   15943          384 :   f->FalseExit = static_cast<unsigned int> (False);
   15944          384 :   f->Unbounded = static_cast<unsigned int> (Array);
   15945          384 :   f->Dimension = static_cast<unsigned int> (Dim);
   15946          384 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   15947          384 : }
   15948              : 
   15949              : 
   15950              : /*
   15951              :    PushTFADtok - Push True, False, Array, Dim, numbers onto the
   15952              :                  True/False stack.  True and False are assumed to
   15953              :                  contain Symbols or Ident etc.
   15954              : */
   15955              : 
   15956         2957 : static void PushTFADtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int tokno)
   15957              : {
   15958         2957 :   M2Quads_BoolFrame f;
   15959              : 
   15960         2957 :   f = newBoolFrame ();
   15961         2957 :   f->TrueExit = static_cast<unsigned int> (True);
   15962         2957 :   f->FalseExit = static_cast<unsigned int> (False);
   15963         2957 :   f->Unbounded = static_cast<unsigned int> (Array);
   15964         2957 :   f->Dimension = static_cast<unsigned int> (Dim);
   15965         2957 :   f->tokenno = tokno;
   15966         2957 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   15967         2957 : }
   15968              : 
   15969              : 
   15970              : /*
   15971              :    PushTFADrwtok - Push True, False, Array, Dim, rw, numbers onto the
   15972              :                    True/False stack.  True and False are assumed to
   15973              :                    contain Symbols or Ident etc.
   15974              : */
   15975              : 
   15976         8980 : static void PushTFADrwtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int rw, unsigned int Tok)
   15977              : {
   15978         8980 :   M2Quads_BoolFrame f;
   15979              : 
   15980         8980 :   f = newBoolFrame ();
   15981         8980 :   f->TrueExit = static_cast<unsigned int> (True);
   15982         8980 :   f->FalseExit = static_cast<unsigned int> (False);
   15983         8980 :   f->Unbounded = static_cast<unsigned int> (Array);
   15984         8980 :   f->Dimension = static_cast<unsigned int> (Dim);
   15985         8980 :   f->ReadWrite = static_cast<unsigned int> (rw);
   15986         8980 :   f->tokenno = Tok;
   15987         8980 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   15988         8980 : }
   15989              : 
   15990              : 
   15991              : /*
   15992              :    PopTFrwtok - Pop a True and False number from the True/False stack.
   15993              :                 True and False are assumed to contain Symbols or Ident etc.
   15994              : */
   15995              : 
   15996       309422 : static void PopTFrwtok (unsigned int *True, unsigned int *False, unsigned int *rw, unsigned int *tokno)
   15997              : {
   15998       309422 :   M2Quads_BoolFrame f;
   15999              : 
   16000       309422 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   16001       309422 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   16002       309422 :   (*False) = static_cast<unsigned int> (f->FalseExit);
   16003       309422 :   M2Debug_Assert (! f->BooleanOp);
   16004       309422 :   (*rw) = static_cast<unsigned int> (f->ReadWrite);
   16005       309422 :   (*tokno) = f->tokenno;
   16006       309422 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   16007       309422 : }
   16008              : 
   16009              : 
   16010              : /*
   16011              :    PushTFrwtok - Push an item onto the stack in the T (true) position,
   16012              :                  it is assummed to be a token and its token location is recorded.
   16013              : */
   16014              : 
   16015       341117 : static void PushTFrwtok (unsigned int True, unsigned int False, unsigned int rw, unsigned int tokno)
   16016              : {
   16017       341117 :   M2Quads_BoolFrame f;
   16018              : 
   16019       341117 :   f = newBoolFrame ();
   16020       341117 :   f->TrueExit = static_cast<unsigned int> (True);
   16021       341117 :   f->FalseExit = static_cast<unsigned int> (False);
   16022       341117 :   f->ReadWrite = static_cast<unsigned int> (rw);
   16023       341117 :   f->tokenno = tokno;
   16024       341117 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   16025       341117 : }
   16026              : 
   16027              : 
   16028              : /*
   16029              :    PushTFDtok - Push True, False, Dim, numbers onto the
   16030              :                 True/False stack.  True and False are assumed to
   16031              :                 contain Symbols or Ident etc.
   16032              : */
   16033              : 
   16034          258 : static void PushTFDtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int Tok)
   16035              : {
   16036          258 :   M2Quads_BoolFrame f;
   16037              : 
   16038          258 :   f = newBoolFrame ();
   16039          258 :   f->TrueExit = static_cast<unsigned int> (True);
   16040          258 :   f->FalseExit = static_cast<unsigned int> (False);
   16041          258 :   f->Dimension = static_cast<unsigned int> (Dim);
   16042          258 :   f->tokenno = Tok;
   16043          258 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   16044          258 : }
   16045              : 
   16046              : 
   16047              : /*
   16048              :    PopTFDtok - Pop a True, False, Dim number from the True/False stack.
   16049              :                True and False are assumed to contain Symbols or Ident etc.
   16050              : */
   16051              : 
   16052          258 : static void PopTFDtok (unsigned int *True, unsigned int *False, unsigned int *Dim, unsigned int *Tok)
   16053              : {
   16054          258 :   M2Quads_BoolFrame f;
   16055              : 
   16056          258 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   16057          258 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   16058          258 :   (*False) = static_cast<unsigned int> (f->FalseExit);
   16059          258 :   (*Dim) = static_cast<unsigned int> (f->Dimension);
   16060          258 :   (*Tok) = f->tokenno;
   16061          258 :   M2Debug_Assert (! f->BooleanOp);
   16062          258 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   16063          258 : }
   16064              : 
   16065              : 
   16066              : /*
   16067              :    PushTFDrwtok - Push True, False, Dim, numbers onto the
   16068              :                   True/False stack.  True and False are assumed to
   16069              :                   contain Symbols or Ident etc.
   16070              : */
   16071              : 
   16072        47464 : static void PushTFDrwtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int rw, unsigned int Tok)
   16073              : {
   16074        47464 :   M2Quads_BoolFrame f;
   16075              : 
   16076        47464 :   f = newBoolFrame ();
   16077        47464 :   f->TrueExit = static_cast<unsigned int> (True);
   16078        47464 :   f->FalseExit = static_cast<unsigned int> (False);
   16079        47464 :   f->Dimension = static_cast<unsigned int> (Dim);
   16080        47464 :   f->ReadWrite = static_cast<unsigned int> (rw);
   16081        47464 :   f->tokenno = Tok;
   16082        47464 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   16083        47464 : }
   16084              : 
   16085              : 
   16086              : /*
   16087              :    PushTFrw - Push a True and False numbers onto the True/False stack.
   16088              :               True and False are assumed to contain Symbols or Ident etc.
   16089              :               It also pushes the higher level symbol which is associated
   16090              :               with the True symbol.  Eg record variable or array variable.
   16091              : */
   16092              : 
   16093         2369 : static void PushTFrw (unsigned int True, unsigned int False, unsigned int rw)
   16094              : {
   16095         2369 :   M2Quads_BoolFrame f;
   16096              : 
   16097         2369 :   f = newBoolFrame ();
   16098         2369 :   f->TrueExit = static_cast<unsigned int> (True);
   16099         2369 :   f->FalseExit = static_cast<unsigned int> (False);
   16100         2369 :   f->ReadWrite = rw;
   16101         2369 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   16102         2369 : }
   16103              : 
   16104              : 
   16105              : /*
   16106              :    PopTFrw - Pop a True and False number from the True/False stack.
   16107              :              True and False are assumed to contain Symbols or Ident etc.
   16108              : */
   16109              : 
   16110        30024 : static void PopTFrw (unsigned int *True, unsigned int *False, unsigned int *rw)
   16111              : {
   16112        30024 :   M2Quads_BoolFrame f;
   16113              : 
   16114        30024 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   16115        30024 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   16116        30024 :   (*False) = static_cast<unsigned int> (f->FalseExit);
   16117        30024 :   M2Debug_Assert (! f->BooleanOp);
   16118        30024 :   (*rw) = static_cast<unsigned int> (f->ReadWrite);
   16119        30024 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   16120        30024 : }
   16121              : 
   16122              : 
   16123              : /*
   16124              :    newBoolFrame - creates a new BoolFrame with all fields initialised to their defaults.
   16125              : */
   16126              : 
   16127    353202921 : static M2Quads_BoolFrame newBoolFrame (void)
   16128              : {
   16129    353202921 :   M2Quads_BoolFrame f;
   16130              : 
   16131    353202921 :   Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   16132    353202921 :   f->TrueExit = 0;
   16133    353202921 :   f->FalseExit = 0;
   16134    353202921 :   f->Unbounded = SymbolTable_NulSym;
   16135    353202921 :   f->BooleanOp = false;
   16136    353202921 :   f->Dimension = 0;
   16137    353202921 :   f->ReadWrite = SymbolTable_NulSym;
   16138    353202921 :   f->name = SymbolTable_NulSym;
   16139    353202921 :   f->Annotation = static_cast<DynamicStrings_String> (NULL);
   16140    353202921 :   f->tokenno = M2LexBuf_UnknownTokenNo;
   16141    353202921 :   return f;
   16142              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16143              :   __builtin_unreachable ();
   16144              : }
   16145              : 
   16146              : 
   16147              : /*
   16148              :    PushTrwtok - Push an item onto the True/False stack. The False value will be zero.
   16149              : */
   16150              : 
   16151          156 : static void PushTrwtok (unsigned int True, unsigned int rw, unsigned int tok)
   16152              : {
   16153          156 :   M2Quads_BoolFrame f;
   16154              : 
   16155          156 :   f = newBoolFrame ();
   16156          156 :   f->TrueExit = static_cast<unsigned int> (True);
   16157          156 :   f->ReadWrite = static_cast<unsigned int> (rw);
   16158          156 :   f->tokenno = tok;
   16159          156 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   16160          156 : }
   16161              : 
   16162              : 
   16163              : /*
   16164              :    PopTrw - Pop a True field and rw symbol from the stack.
   16165              : */
   16166              : 
   16167         2369 : static void PopTrw (unsigned int *True, unsigned int *rw)
   16168              : {
   16169         2369 :   M2Quads_BoolFrame f;
   16170              : 
   16171         2369 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   16172         2369 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   16173         2369 :   M2Debug_Assert (! f->BooleanOp);
   16174         2369 :   (*rw) = static_cast<unsigned int> (f->ReadWrite);
   16175         2369 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   16176         2369 : }
   16177              : 
   16178              : 
   16179              : /*
   16180              :    PopTrwtok - Pop a True field and rw symbol from the stack.
   16181              : */
   16182              : 
   16183      1084269 : static void PopTrwtok (unsigned int *True, unsigned int *rw, unsigned int *tok)
   16184              : {
   16185      1084269 :   M2Quads_BoolFrame f;
   16186              : 
   16187      1084269 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   16188      1084269 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   16189      1084269 :   M2Debug_Assert (! f->BooleanOp);
   16190      1084269 :   (*rw) = static_cast<unsigned int> (f->ReadWrite);
   16191      1084269 :   (*tok) = f->tokenno;
   16192      1084269 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   16193      1084269 : }
   16194              : 
   16195              : 
   16196              : /*
   16197              :    PopTntok - Pop a True/number/tok from the True/False stack.
   16198              :               True and False are assumed to contain Symbols.
   16199              :               The number is word sized.
   16200              : */
   16201              : 
   16202        37185 : static void PopTntok (unsigned int *True, unsigned int *n, unsigned int *tokno)
   16203              : {
   16204        37185 :   M2Quads_BoolFrame f;
   16205              : 
   16206        37185 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   16207        37185 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   16208        37185 :   (*n) = static_cast<unsigned int> (f->name);
   16209        37185 :   (*tokno) = f->tokenno;
   16210        37185 :   M2Debug_Assert (! f->BooleanOp);
   16211        37185 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   16212        37185 : }
   16213              : 
   16214              : 
   16215              : /*
   16216              :    gdbhook - a debugger convenience hook.
   16217              : */
   16218              : 
   16219            0 : static void gdbhook (void)
   16220              : {
   16221            0 : }
   16222              : 
   16223              : 
   16224              : /*
   16225              :    BreakWhenQuadCreated - to be called interactively by gdb.
   16226              : */
   16227              : 
   16228        15451 : static void BreakWhenQuadCreated (unsigned int quad)
   16229              : {
   16230        15451 :   BreakQuad = quad;
   16231            0 : }
   16232              : 
   16233              : 
   16234              : /*
   16235              :    CheckBreak - if quad = BreakQuad then call gdbhook.
   16236              : */
   16237              : 
   16238            0 : static void CheckBreak (unsigned int quad)
   16239              : {
   16240            0 :   if (quad == BreakQuad)
   16241              :     {
   16242            0 :       gdbhook ();
   16243              :     }
   16244            0 : }
   16245              : 
   16246              : 
   16247              : /*
   16248              :    Init - initialize the M2Quads module, all the stacks, all the lists
   16249              :           and the quads list.
   16250              : */
   16251              : 
   16252        15451 : static void Init (void)
   16253              : {
   16254        15451 :   BreakWhenQuadCreated (0);  /* Disable the intereactive quad watch.  */
   16255              :   /* To examine the quad table when a quad is created run cc1gm2 from gdb
   16256              :       and set a break point on gdbhook.
   16257              :       (gdb) break gdbhook
   16258              :       (gdb) run
   16259              :       Now below interactively call BreakWhenQuadCreated with the quad
   16260              :       under investigation.  */
   16261        15451 :   gdbhook ();
   16262              :   /* Now is the time to interactively call gdb, for example:
   16263              :       (gdb) print BreakWhenQuadCreated (1234)
   16264              :       (gdb) cont
   16265              :       and you will arrive at gdbhook when this quad is created.  */
   16266        15451 :   LogicalOrTok = NameKey_MakeKey ((const char *) "_LOR", 4);
   16267        15451 :   LogicalAndTok = NameKey_MakeKey ((const char *) "_LAND", 5);
   16268        15451 :   LogicalXorTok = NameKey_MakeKey ((const char *) "_LXOR", 5);
   16269        15451 :   LogicalDifferenceTok = NameKey_MakeKey ((const char *) "_LDIFF", 6);
   16270        15451 :   ArithPlusTok = NameKey_MakeKey ((const char *) "_ARITH_+", 8);
   16271        15451 :   QuadArray = Indexing_InitIndexTuned (1, (1024*1024) / 16, 16);
   16272        15451 :   FreeList = 1;
   16273        15451 :   NewQuad (&NextQuad);
   16274        15451 :   M2Debug_Assert (NextQuad == 1);
   16275        15451 :   BoolStack = M2StackAddress_InitStackAddress ();
   16276        15451 :   ExitStack = M2StackWord_InitStackWord ();
   16277        15451 :   RepeatStack = M2StackWord_InitStackWord ();
   16278        15451 :   WhileStack = M2StackWord_InitStackWord ();
   16279        15451 :   ForStack = M2StackWord_InitStackWord ();
   16280        15451 :   WithStack = M2StackAddress_InitStackAddress ();
   16281        15451 :   ReturnStack = M2StackWord_InitStackWord ();
   16282        15451 :   LineStack = M2StackAddress_InitStackAddress ();
   16283        15451 :   PriorityStack = M2StackWord_InitStackWord ();
   16284        15451 :   TryStack = M2StackWord_InitStackWord ();
   16285        15451 :   CatchStack = M2StackWord_InitStackWord ();
   16286        15451 :   ExceptStack = M2StackWord_InitStackWord ();
   16287        15451 :   ConstructorStack = M2StackAddress_InitStackAddress ();
   16288        15451 :   ConstParamStack = M2StackWord_InitStackWord ();
   16289        15451 :   ConstExprStack = M2StackWord_InitStackWord ();
   16290              :   /* StressStack ;  */
   16291        15451 :   SuppressWith = false;
   16292        15451 :   Head = 1;
   16293        15451 :   LastQuadNo = 0;
   16294        15451 :   MustNotCheckBounds = false;
   16295        15451 :   InitQuad = 0;
   16296        15451 :   GrowInitialization = 0;
   16297        15451 :   ForInfo = Indexing_InitIndex (1);
   16298        15451 :   QuadrupleGeneration = true;
   16299        15451 :   BuildingHigh = false;
   16300        15451 :   BuildingSize = false;
   16301        15451 :   AutoStack = M2StackWord_InitStackWord ();
   16302        15451 :   IsAutoOn = true;
   16303        15451 :   InConstExpression = false;
   16304        15451 :   InConstParameters = false;
   16305        15451 :   FreeLineList = NULL;
   16306        15451 :   Lists_InitList (&VarientFields);
   16307        15451 :   VarientFieldNo = 0;
   16308        15451 :   NoOfQuads = 0;
   16309        15451 :   QuadMemDiag = M2Diagnostic_InitMemDiagnostic ((const char *) "M2Quad:Quadruples", 17, (const char *) "{0N} total quadruples {1d} consuming {2M} ram {0M} ({2P})", 57);
   16310        15451 : }
   16311              : 
   16312              : 
   16313              : /*
   16314              :    SetOptionCoding - builds a code quadruple if the profiling
   16315              :                      option was given to the compiler.
   16316              : */
   16317              : 
   16318            0 : extern "C" void M2Quads_SetOptionCoding (bool b)
   16319              : {
   16320            0 :   if (b != M2Options_Coding)
   16321              :     {
   16322            0 :       if (b)
   16323              :         {
   16324            0 :           M2Quads_BuildCodeOn ();
   16325              :         }
   16326              :       else
   16327              :         {
   16328            0 :           M2Quads_BuildCodeOff ();
   16329              :         }
   16330            0 :       M2Options_Coding = b;
   16331              :     }
   16332            0 : }
   16333              : 
   16334              : 
   16335              : /*
   16336              :    SetOptionProfiling - builds a profile quadruple if the profiling
   16337              :                         option was given to the compiler.
   16338              : */
   16339              : 
   16340            0 : extern "C" void M2Quads_SetOptionProfiling (bool b)
   16341              : {
   16342            0 :   if (b != M2Options_Profiling)
   16343              :     {
   16344            0 :       if (b)
   16345              :         {
   16346            0 :           M2Quads_BuildProfileOn ();
   16347              :         }
   16348              :       else
   16349              :         {
   16350            0 :           M2Quads_BuildProfileOff ();
   16351              :         }
   16352            0 :       M2Options_Profiling = b;
   16353              :     }
   16354            0 : }
   16355              : 
   16356              : 
   16357              : /*
   16358              :    SetOptionOptimizing - builds a quadruple to say that the optimization option
   16359              :                          has been found in a comment.
   16360              : */
   16361              : 
   16362            0 : extern "C" void M2Quads_SetOptionOptimizing (bool b)
   16363              : {
   16364            0 :   if (b)
   16365              :     {
   16366            0 :       M2Quads_BuildOptimizeOn ();
   16367              :     }
   16368              :   else
   16369              :     {
   16370            0 :       M2Quads_BuildOptimizeOff ();
   16371              :     }
   16372            0 : }
   16373              : 
   16374              : 
   16375              : /*
   16376              :    Opposite - returns the opposite comparison operator.
   16377              : */
   16378              : 
   16379        80861 : extern "C" M2Quads_QuadOperator M2Quads_Opposite (M2Quads_QuadOperator Operator)
   16380              : {
   16381        80861 :   M2Quads_QuadOperator Op;
   16382              : 
   16383        80861 :   switch (Operator)
   16384              :     {
   16385              :       case M2Quads_IfNotEquOp:
   16386              :         Op = M2Quads_IfEquOp;
   16387              :         break;
   16388              : 
   16389              :       case M2Quads_IfEquOp:
   16390              :         Op = M2Quads_IfNotEquOp;
   16391              :         break;
   16392              : 
   16393              :       case M2Quads_IfLessEquOp:
   16394              :         Op = M2Quads_IfGreOp;
   16395              :         break;
   16396              : 
   16397              :       case M2Quads_IfGreOp:
   16398              :         Op = M2Quads_IfLessEquOp;
   16399              :         break;
   16400              : 
   16401              :       case M2Quads_IfGreEquOp:
   16402              :         Op = M2Quads_IfLessOp;
   16403              :         break;
   16404              : 
   16405              :       case M2Quads_IfLessOp:
   16406              :         Op = M2Quads_IfGreEquOp;
   16407              :         break;
   16408              : 
   16409              :       case M2Quads_IfInOp:
   16410              :         Op = M2Quads_IfNotInOp;
   16411              :         break;
   16412              : 
   16413              :       case M2Quads_IfNotInOp:
   16414              :         Op = M2Quads_IfInOp;
   16415              :         break;
   16416              : 
   16417              : 
   16418            0 :       default:
   16419            0 :         M2Error_InternalError ((const char *) "unexpected operator", 19);
   16420        80861 :         break;
   16421              :     }
   16422        80861 :   return Op;
   16423              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16424              :   __builtin_unreachable ();
   16425              : }
   16426              : 
   16427              : 
   16428              : /*
   16429              :    IsReferenced - returns true if QuadNo is referenced by another quadruple.
   16430              : */
   16431              : 
   16432    259659258 : extern "C" bool M2Quads_IsReferenced (unsigned int QuadNo)
   16433              : {
   16434    259659258 :   M2Quads_QuadFrame f;
   16435              : 
   16436    259659258 :   f = GetQF (QuadNo);
   16437    259659258 :   return ((f->Operator == M2Quads_ProcedureScopeOp) || (f->Operator == M2Quads_NewLocalVarOp)) || (f->NoOfTimesReferenced > 0);
   16438              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16439              :   __builtin_unreachable ();
   16440              : }
   16441              : 
   16442              : 
   16443              : /*
   16444              :    IsBackReference - returns TRUE if quadruple, q, is referenced from a quad further on.
   16445              : */
   16446              : 
   16447        97601 : extern "C" bool M2Quads_IsBackReference (unsigned int q)
   16448              : {
   16449        97601 :   unsigned int i;
   16450        97601 :   M2Quads_QuadOperator op;
   16451        97601 :   unsigned int op1;
   16452        97601 :   unsigned int op2;
   16453        97601 :   unsigned int op3;
   16454              : 
   16455        97601 :   i = q;
   16456      3822488 :   while (i != 0)
   16457              :     {
   16458      3822488 :       M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
   16459      3822488 :       switch (op)
   16460              :         {
   16461              :           case M2Quads_NewLocalVarOp:
   16462              :           case M2Quads_KillLocalVarOp:
   16463              :           case M2Quads_FinallyStartOp:
   16464              :           case M2Quads_FinallyEndOp:
   16465              :           case M2Quads_InitEndOp:
   16466              :           case M2Quads_InitStartOp:
   16467              :           case M2Quads_EndFileOp:
   16468              :           case M2Quads_StartDefFileOp:
   16469              :           case M2Quads_StartModFileOp:
   16470              :             return false;  /* run into end of procedure or module  */
   16471       169184 :             break;
   16472              : 
   16473       169184 :           case M2Quads_GotoOp:
   16474       169184 :           case M2Quads_IfEquOp:
   16475       169184 :           case M2Quads_IfLessEquOp:
   16476       169184 :           case M2Quads_IfGreEquOp:
   16477       169184 :           case M2Quads_IfGreOp:
   16478       169184 :           case M2Quads_IfLessOp:
   16479       169184 :           case M2Quads_IfNotEquOp:
   16480       169184 :           case M2Quads_IfInOp:
   16481       169184 :           case M2Quads_IfNotInOp:
   16482       169184 :             if (op3 == q)  /* run into end of procedure or module  */
   16483              :               {
   16484              :                 return true;
   16485              :               }
   16486              :             break;
   16487              : 
   16488              : 
   16489              :           default:
   16490              :             break;
   16491              :         }
   16492      3724887 :       i = M2Quads_GetNextQuad (i);
   16493              :     }
   16494            0 :   M2Error_InternalError ((const char *) "fix this for the sake of efficiency..", 37);
   16495              :   ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
   16496              :   __builtin_unreachable ();
   16497              : }
   16498              : 
   16499              : 
   16500              : /*
   16501              :    IsUnConditional - returns true if QuadNo is an unconditional jump.
   16502              : */
   16503              : 
   16504    528447391 : extern "C" bool M2Quads_IsUnConditional (unsigned int QuadNo)
   16505              : {
   16506    528447391 :   M2Quads_QuadFrame f;
   16507              : 
   16508    528447391 :   f = GetQF (QuadNo);
   16509    528447391 :   switch (f->Operator)
   16510              :     {
   16511              :       case M2Quads_ThrowOp:
   16512              :       case M2Quads_RetryOp:
   16513              :       case M2Quads_CallOp:
   16514              :       case M2Quads_ReturnOp:
   16515              :       case M2Quads_GotoOp:
   16516              :         return true;
   16517    507896200 :         break;
   16518              : 
   16519              : 
   16520    507896200 :       default:
   16521    507896200 :         return false;
   16522              :         break;
   16523              :     }
   16524              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16525              :   __builtin_unreachable ();
   16526              : }
   16527              : 
   16528              : 
   16529              : /*
   16530              :    IsConditional - returns true if QuadNo is a conditional jump.
   16531              : */
   16532              : 
   16533    528555366 : extern "C" bool M2Quads_IsConditional (unsigned int QuadNo)
   16534              : {
   16535    528555366 :   M2Quads_QuadFrame f;
   16536              : 
   16537    528555366 :   f = GetQF (QuadNo);
   16538    528555366 :   switch (f->Operator)
   16539              :     {
   16540              :       case M2Quads_IfInOp:
   16541              :       case M2Quads_IfNotInOp:
   16542              :       case M2Quads_IfEquOp:
   16543              :       case M2Quads_IfNotEquOp:
   16544              :       case M2Quads_IfLessOp:
   16545              :       case M2Quads_IfLessEquOp:
   16546              :       case M2Quads_IfGreOp:
   16547              :       case M2Quads_IfGreEquOp:
   16548              :         return true;
   16549    524602120 :         break;
   16550              : 
   16551              : 
   16552    524602120 :       default:
   16553    524602120 :         return false;
   16554              :         break;
   16555              :     }
   16556              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16557              :   __builtin_unreachable ();
   16558              : }
   16559              : 
   16560              : 
   16561              : /*
   16562              :    IsBackReferenceConditional - returns TRUE if quadruple, q, is referenced from
   16563              :                                 a conditional quad further on.
   16564              : */
   16565              : 
   16566            0 : extern "C" bool M2Quads_IsBackReferenceConditional (unsigned int q)
   16567              : {
   16568            0 :   unsigned int i;
   16569            0 :   M2Quads_QuadOperator op;
   16570            0 :   unsigned int op1;
   16571            0 :   unsigned int op2;
   16572            0 :   unsigned int op3;
   16573              : 
   16574            0 :   i = q;
   16575            0 :   while (i != 0)
   16576              :     {
   16577            0 :       M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
   16578            0 :       switch (op)
   16579              :         {
   16580              :           case M2Quads_NewLocalVarOp:
   16581              :           case M2Quads_KillLocalVarOp:
   16582              :           case M2Quads_FinallyStartOp:
   16583              :           case M2Quads_FinallyEndOp:
   16584              :           case M2Quads_InitEndOp:
   16585              :           case M2Quads_InitStartOp:
   16586              :           case M2Quads_EndFileOp:
   16587              :           case M2Quads_StartDefFileOp:
   16588              :           case M2Quads_StartModFileOp:
   16589              :             return false;  /* run into end of procedure or module  */
   16590            0 :             break;
   16591              : 
   16592            0 :           case M2Quads_TryOp:
   16593            0 :           case M2Quads_RetryOp:
   16594            0 :           case M2Quads_GotoOp:
   16595            0 :           case M2Quads_IfEquOp:
   16596            0 :           case M2Quads_IfLessEquOp:
   16597            0 :           case M2Quads_IfGreEquOp:
   16598            0 :           case M2Quads_IfGreOp:
   16599            0 :           case M2Quads_IfLessOp:
   16600            0 :           case M2Quads_IfNotEquOp:
   16601            0 :           case M2Quads_IfInOp:
   16602            0 :           case M2Quads_IfNotInOp:
   16603            0 :             if ((op3 == q) && (M2Quads_IsConditional (q)))  /* run into end of procedure or module  */
   16604              :               {
   16605              :                 return true;
   16606              :               }
   16607            0 :             break;
   16608              : 
   16609              : 
   16610              :           default:
   16611              :             return false;
   16612            0 :             break;
   16613              :         }
   16614            0 :       i = M2Quads_GetNextQuad (i);
   16615              :     }
   16616            0 :   M2Error_InternalError ((const char *) "fix this for the sake of efficiency..", 37);
   16617              :   ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
   16618              :   __builtin_unreachable ();
   16619              : }
   16620              : 
   16621              : 
   16622              : /*
   16623              :    IsGoto - returns true if QuadNo is a goto operation.
   16624              : */
   16625              : 
   16626        97601 : extern "C" bool M2Quads_IsGoto (unsigned int QuadNo)
   16627              : {
   16628        97601 :   return IsQuadA (QuadNo, M2Quads_GotoOp);
   16629              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16630              :   __builtin_unreachable ();
   16631              : }
   16632              : 
   16633              : 
   16634              : /*
   16635              :    IsCall - returns true if QuadNo is a call operation.
   16636              : */
   16637              : 
   16638    528544992 : extern "C" bool M2Quads_IsCall (unsigned int QuadNo)
   16639              : {
   16640    528544992 :   return IsQuadA (QuadNo, M2Quads_CallOp);
   16641              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16642              :   __builtin_unreachable ();
   16643              : }
   16644              : 
   16645              : 
   16646              : /*
   16647              :    IsReturn - returns true if QuadNo is a return operation.
   16648              : */
   16649              : 
   16650    528710518 : extern "C" bool M2Quads_IsReturn (unsigned int QuadNo)
   16651              : {
   16652    528710518 :   return IsQuadA (QuadNo, M2Quads_ReturnOp);
   16653              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16654              :   __builtin_unreachable ();
   16655              : }
   16656              : 
   16657              : 
   16658              : /*
   16659              :    IsProcedureScope - returns true if QuadNo is a ProcedureScope operation.
   16660              : */
   16661              : 
   16662            0 : extern "C" bool M2Quads_IsProcedureScope (unsigned int QuadNo)
   16663              : {
   16664            0 :   return IsQuadA (QuadNo, M2Quads_ProcedureScopeOp);
   16665              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16666              :   __builtin_unreachable ();
   16667              : }
   16668              : 
   16669              : 
   16670              : /*
   16671              :    IsNewLocalVar - returns true if QuadNo is a NewLocalVar operation.
   16672              : */
   16673              : 
   16674            0 : extern "C" bool M2Quads_IsNewLocalVar (unsigned int QuadNo)
   16675              : {
   16676            0 :   return IsQuadA (QuadNo, M2Quads_NewLocalVarOp);
   16677              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16678              :   __builtin_unreachable ();
   16679              : }
   16680              : 
   16681              : 
   16682              : /*
   16683              :    IsKillLocalVar - returns true if QuadNo is a KillLocalVar operation.
   16684              : */
   16685              : 
   16686       259110 : extern "C" bool M2Quads_IsKillLocalVar (unsigned int QuadNo)
   16687              : {
   16688       259110 :   return IsQuadA (QuadNo, M2Quads_KillLocalVarOp);
   16689              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16690              :   __builtin_unreachable ();
   16691              : }
   16692              : 
   16693              : 
   16694              : /*
   16695              :    IsCatchBegin - returns true if QuadNo is a catch begin quad.
   16696              : */
   16697              : 
   16698       140884 : extern "C" bool M2Quads_IsCatchBegin (unsigned int QuadNo)
   16699              : {
   16700       140884 :   return IsQuadA (QuadNo, M2Quads_CatchBeginOp);
   16701              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16702              :   __builtin_unreachable ();
   16703              : }
   16704              : 
   16705              : 
   16706              : /*
   16707              :    IsCatchEnd - returns true if QuadNo is a catch end quad.
   16708              : */
   16709              : 
   16710       157492 : extern "C" bool M2Quads_IsCatchEnd (unsigned int QuadNo)
   16711              : {
   16712       157492 :   return IsQuadA (QuadNo, M2Quads_CatchEndOp);
   16713              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16714              :   __builtin_unreachable ();
   16715              : }
   16716              : 
   16717              : 
   16718              : /*
   16719              :    IsInitStart - returns true if QuadNo is a init start quad.
   16720              : */
   16721              : 
   16722       140884 : extern "C" bool M2Quads_IsInitStart (unsigned int QuadNo)
   16723              : {
   16724       140884 :   return IsQuadA (QuadNo, M2Quads_InitStartOp);
   16725              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16726              :   __builtin_unreachable ();
   16727              : }
   16728              : 
   16729              : 
   16730              : /*
   16731              :    IsInitEnd - returns true if QuadNo is a init end quad.
   16732              : */
   16733              : 
   16734       140884 : extern "C" bool M2Quads_IsInitEnd (unsigned int QuadNo)
   16735              : {
   16736       140884 :   return IsQuadA (QuadNo, M2Quads_InitEndOp);
   16737              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16738              :   __builtin_unreachable ();
   16739              : }
   16740              : 
   16741              : 
   16742              : /*
   16743              :    IsFinallyStart - returns true if QuadNo is a finally start quad.
   16744              : */
   16745              : 
   16746       135430 : extern "C" bool M2Quads_IsFinallyStart (unsigned int QuadNo)
   16747              : {
   16748       135430 :   return IsQuadA (QuadNo, M2Quads_FinallyStartOp);
   16749              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16750              :   __builtin_unreachable ();
   16751              : }
   16752              : 
   16753              : 
   16754              : /*
   16755              :    IsFinallyEnd - returns true if QuadNo is a finally end quad.
   16756              : */
   16757              : 
   16758       129976 : extern "C" bool M2Quads_IsFinallyEnd (unsigned int QuadNo)
   16759              : {
   16760       129976 :   return IsQuadA (QuadNo, M2Quads_FinallyEndOp);
   16761              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16762              :   __builtin_unreachable ();
   16763              : }
   16764              : 
   16765              : 
   16766              : /*
   16767              :    IsBecomes - return TRUE if QuadNo is a BecomesOp.
   16768              : */
   16769              : 
   16770            0 : extern "C" bool M2Quads_IsBecomes (unsigned int QuadNo)
   16771              : {
   16772            0 :   return IsQuadA (QuadNo, M2Quads_BecomesOp);
   16773              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16774              :   __builtin_unreachable ();
   16775              : }
   16776              : 
   16777              : 
   16778              : /*
   16779              :    IsDummy - return TRUE if QuadNo is a DummyOp.
   16780              : */
   16781              : 
   16782            0 : extern "C" bool M2Quads_IsDummy (unsigned int QuadNo)
   16783              : {
   16784            0 :   return IsQuadA (QuadNo, M2Quads_DummyOp);
   16785              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16786              :   __builtin_unreachable ();
   16787              : }
   16788              : 
   16789              : 
   16790              : /*
   16791              :    IsQuadConstExpr - returns TRUE if QuadNo is part of a constant expression.
   16792              : */
   16793              : 
   16794            0 : extern "C" bool M2Quads_IsQuadConstExpr (unsigned int QuadNo)
   16795              : {
   16796            0 :   M2Quads_QuadFrame f;
   16797              : 
   16798            0 :   f = GetQF (QuadNo);
   16799            0 :   return f->ConstExpr;
   16800              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16801              :   __builtin_unreachable ();
   16802              : }
   16803              : 
   16804              : 
   16805              : /*
   16806              :    SetQuadConstExpr - sets the constexpr field to value.
   16807              : */
   16808              : 
   16809            0 : extern "C" void M2Quads_SetQuadConstExpr (unsigned int QuadNo, bool value)
   16810              : {
   16811            0 :   M2Quads_QuadFrame f;
   16812              : 
   16813            0 :   f = GetQF (QuadNo);
   16814            0 :   f->ConstExpr = value;
   16815            0 : }
   16816              : 
   16817              : 
   16818              : /*
   16819              :    GetQuadDest - returns the jump destination associated with quad.
   16820              : */
   16821              : 
   16822            0 : extern "C" unsigned int M2Quads_GetQuadDest (unsigned int QuadNo)
   16823              : {
   16824            0 :   return M2Quads_GetQuadOp3 (QuadNo);
   16825              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16826              :   __builtin_unreachable ();
   16827              : }
   16828              : 
   16829              : 
   16830              : /*
   16831              :    GetQuadOp1 - returns the 1st operand associated with quad.
   16832              : */
   16833              : 
   16834            0 : extern "C" unsigned int M2Quads_GetQuadOp1 (unsigned int QuadNo)
   16835              : {
   16836            0 :   M2Quads_QuadFrame f;
   16837              : 
   16838            0 :   f = GetQF (QuadNo);
   16839            0 :   return f->Operand1;
   16840              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16841              :   __builtin_unreachable ();
   16842              : }
   16843              : 
   16844              : 
   16845              : /*
   16846              :    GetQuadOp2 - returns the 2nd operand associated with quad.
   16847              : */
   16848              : 
   16849            0 : extern "C" unsigned int M2Quads_GetQuadOp2 (unsigned int QuadNo)
   16850              : {
   16851            0 :   M2Quads_QuadFrame f;
   16852              : 
   16853            0 :   f = GetQF (QuadNo);
   16854            0 :   return f->Operand2;
   16855              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16856              :   __builtin_unreachable ();
   16857              : }
   16858              : 
   16859              : 
   16860              : /*
   16861              :    GetQuadOp3 - returns the 3rd operand associated with quad.
   16862              : */
   16863              : 
   16864            0 : extern "C" unsigned int M2Quads_GetQuadOp3 (unsigned int QuadNo)
   16865              : {
   16866            0 :   M2Quads_QuadFrame f;
   16867              : 
   16868            0 :   f = GetQF (QuadNo);
   16869            0 :   return f->Operand3;
   16870              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16871              :   __builtin_unreachable ();
   16872              : }
   16873              : 
   16874              : 
   16875              : /*
   16876              :    IsInitialisingConst - returns TRUE if the quadruple is setting
   16877              :                          a const (op1) with a value.
   16878              : */
   16879              : 
   16880            0 : extern "C" bool M2Quads_IsInitialisingConst (unsigned int QuadNo)
   16881              : {
   16882            0 :   M2Quads_QuadOperator op;
   16883            0 :   unsigned int op1;
   16884            0 :   unsigned int op2;
   16885            0 :   unsigned int op3;
   16886              : 
   16887            0 :   M2Quads_GetQuad (QuadNo, &op, &op1, &op2, &op3);
   16888            0 :   return (OpUsesOp1 (op)) && (SymbolTable_IsConst (op1));
   16889              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16890              :   __builtin_unreachable ();
   16891              : }
   16892              : 
   16893              : 
   16894              : /*
   16895              :    IsConstQuad - return TRUE if the quadruple is marked as a constexpr.
   16896              : */
   16897              : 
   16898            0 : extern "C" bool M2Quads_IsConstQuad (unsigned int quad)
   16899              : {
   16900            0 :   M2Quads_QuadFrame f;
   16901              : 
   16902            0 :   f = GetQF (quad);
   16903            0 :   return f->ConstExpr;
   16904              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16905              :   __builtin_unreachable ();
   16906              : }
   16907              : 
   16908              : 
   16909              : /*
   16910              :    IsConditionalBooleanQuad - return TRUE if operand 1 is a boolean result.
   16911              : */
   16912              : 
   16913       428763 : extern "C" bool M2Quads_IsConditionalBooleanQuad (unsigned int quad)
   16914              : {
   16915       428763 :   M2Quads_QuadFrame f;
   16916              : 
   16917       428763 :   f = GetQF (quad);
   16918       428763 :   return ((OpUsesOp1 (f->Operator)) && ((SymbolTable_IsVar (f->Operand1)) || (SymbolTable_IsConst (f->Operand1)))) && (SymbolTable_IsVarConditional (f->Operand1));
   16919              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16920              :   __builtin_unreachable ();
   16921              : }
   16922              : 
   16923              : 
   16924              : /*
   16925              :    IsOptimizeOn - returns true if the Optimize flag was true at QuadNo.
   16926              : */
   16927              : 
   16928            0 : extern "C" bool M2Quads_IsOptimizeOn (unsigned int QuadNo)
   16929              : {
   16930            0 :   M2Quads_QuadFrame f;
   16931            0 :   unsigned int n;
   16932            0 :   unsigned int q;
   16933            0 :   bool On;
   16934              : 
   16935            0 :   On = M2Options_Optimizing;
   16936            0 :   q = Head;
   16937            0 :   while ((q != 0) && (q != QuadNo))
   16938              :     {
   16939            0 :       f = GetQF (q);
   16940            0 :       if (f->Operator == M2Quads_OptimizeOnOp)
   16941              :         {
   16942              :           On = true;
   16943              :         }
   16944            0 :       else if (f->Operator == M2Quads_OptimizeOffOp)
   16945              :         {
   16946              :           /* avoid dangling else.  */
   16947            0 :           On = false;
   16948              :         }
   16949            0 :       n = f->Next;
   16950            0 :       q = n;
   16951              :     }
   16952            0 :   return On;
   16953              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16954              :   __builtin_unreachable ();
   16955              : }
   16956              : 
   16957              : 
   16958              : /*
   16959              :    IsProfileOn - returns true if the Profile flag was true at QuadNo.
   16960              : */
   16961              : 
   16962            0 : extern "C" bool M2Quads_IsProfileOn (unsigned int QuadNo)
   16963              : {
   16964            0 :   M2Quads_QuadFrame f;
   16965            0 :   unsigned int n;
   16966            0 :   unsigned int q;
   16967            0 :   bool On;
   16968              : 
   16969            0 :   On = M2Options_Profiling;
   16970            0 :   q = Head;
   16971            0 :   while ((q != 0) && (q != QuadNo))
   16972              :     {
   16973            0 :       f = GetQF (q);
   16974            0 :       if (f->Operator == M2Quads_ProfileOnOp)
   16975              :         {
   16976              :           On = true;
   16977              :         }
   16978            0 :       else if (f->Operator == M2Quads_ProfileOffOp)
   16979              :         {
   16980              :           /* avoid dangling else.  */
   16981            0 :           On = false;
   16982              :         }
   16983            0 :       n = f->Next;
   16984            0 :       q = n;
   16985              :     }
   16986            0 :   return On;
   16987              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   16988              :   __builtin_unreachable ();
   16989              : }
   16990              : 
   16991              : 
   16992              : /*
   16993              :    IsCodeOn - returns true if the Code flag was true at QuadNo.
   16994              : */
   16995              : 
   16996            0 : extern "C" bool M2Quads_IsCodeOn (unsigned int QuadNo)
   16997              : {
   16998            0 :   M2Quads_QuadFrame f;
   16999            0 :   unsigned int n;
   17000            0 :   unsigned int q;
   17001            0 :   bool On;
   17002              : 
   17003            0 :   On = M2Options_Coding;
   17004            0 :   q = Head;
   17005            0 :   while ((q != 0) && (q != QuadNo))
   17006              :     {
   17007            0 :       f = GetQF (q);
   17008            0 :       if (f->Operator == M2Quads_CodeOnOp)
   17009              :         {
   17010              :           On = true;
   17011              :         }
   17012            0 :       else if (f->Operator == M2Quads_CodeOffOp)
   17013              :         {
   17014              :           /* avoid dangling else.  */
   17015            0 :           On = false;
   17016              :         }
   17017            0 :       n = f->Next;
   17018            0 :       q = n;
   17019              :     }
   17020            0 :   return On;
   17021              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17022              :   __builtin_unreachable ();
   17023              : }
   17024              : 
   17025              : 
   17026              : /*
   17027              :    IsPseudoQuad - returns true if QuadNo is a compiler directive.
   17028              :                   ie code, profile and optimize.
   17029              :                      StartFile, EndFile,
   17030              : */
   17031              : 
   17032     23164398 : extern "C" bool M2Quads_IsPseudoQuad (unsigned int QuadNo)
   17033              : {
   17034     23164398 :   M2Quads_QuadFrame f;
   17035              : 
   17036     23164398 :   f = GetQF (QuadNo);
   17037     23164398 :   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);
   17038              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17039              :   __builtin_unreachable ();
   17040              : }
   17041              : 
   17042              : 
   17043              : /*
   17044              :    IsDefOrModFile - returns TRUE if QuadNo is a start of Module or Def file
   17045              :                     directive.
   17046              : */
   17047              : 
   17048    528447391 : extern "C" bool M2Quads_IsDefOrModFile (unsigned int QuadNo)
   17049              : {
   17050    528447391 :   M2Quads_QuadFrame f;
   17051              : 
   17052    528447391 :   f = GetQF (QuadNo);
   17053    528447391 :   return (f->Operator == M2Quads_StartDefFileOp) || (f->Operator == M2Quads_StartModFileOp);
   17054              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17055              :   __builtin_unreachable ();
   17056              : }
   17057              : 
   17058              : 
   17059              : /*
   17060              :    DumpQuadruples - dump all quadruples providing the -fq, -fdump-lang-quad,
   17061              :                     -fdump-lang-quad= or -fdump-lang-all were issued to the
   17062              :                     command line.
   17063              : */
   17064              : 
   17065        71837 : extern "C" void M2Quads_DumpQuadruples (const char *title_, unsigned int _title_high)
   17066              : {
   17067        71837 :   char title[_title_high+1];
   17068              : 
   17069              :   /* make a local copy of each unbounded array.  */
   17070        71837 :   memcpy (title, title_, _title_high+1);
   17071              : 
   17072        71837 :   if (M2Options_GetDumpQuad ())
   17073              :     {
   17074            0 :       M2LangDump_CreateDumpQuad ((const char *) title, _title_high);
   17075            0 :       if ((M2Options_GetM2DumpFilter ()) == NULL)
   17076              :         {
   17077            0 :           DumpQuadrupleAll ();
   17078              :         }
   17079              :       else
   17080              :         {
   17081            0 :           DumpQuadrupleFilter ();
   17082              :         }
   17083            0 :       M2LangDump_CloseDumpQuad ();
   17084              :     }
   17085        71837 : }
   17086              : 
   17087              : 
   17088              : /*
   17089              :    DisplayQuadRange - displays all quads in list range, start..end.
   17090              : */
   17091              : 
   17092            0 : extern "C" void M2Quads_DisplayQuadRange (unsigned int scope, unsigned int start, unsigned int end)
   17093              : {
   17094            0 :   M2Quads_QuadFrame f;
   17095              : 
   17096            0 :   M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "Quadruples for scope: %d\\n", 26, (const unsigned char *) &scope, (sizeof (scope)-1));
   17097            0 :   while ((start <= end) && (start != 0))
   17098              :     {
   17099            0 :       M2Quads_DisplayQuad (start);
   17100            0 :       f = GetQF (start);
   17101            0 :       start = f->Next;
   17102              :     }
   17103            0 : }
   17104              : 
   17105              : 
   17106              : /*
   17107              :    DisplayQuad - displays a quadruple, QuadNo.
   17108              : */
   17109              : 
   17110            0 : extern "C" void M2Quads_DisplayQuad (unsigned int QuadNo)
   17111              : {
   17112            0 :   if (QuadNo != 0)
   17113              :     {
   17114            0 :       DSdbEnter ();
   17115            0 :       M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d  ", 5, (const unsigned char *) &QuadNo, (sizeof (QuadNo)-1));
   17116            0 :       WriteQuad (QuadNo);
   17117            0 :       M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "\\n", 2);
   17118            0 :       DSdbExit ();
   17119              :     }
   17120            0 : }
   17121              : 
   17122              : 
   17123              : /*
   17124              :    GetLastFileQuad - returns the Quadruple number of the last StartDefFile or
   17125              :                      StartModFile quadruple.
   17126              : */
   17127              : 
   17128            0 : extern "C" unsigned int M2Quads_GetLastFileQuad (unsigned int QuadNo)
   17129              : {
   17130            0 :   M2Quads_QuadFrame f;
   17131            0 :   unsigned int q;
   17132            0 :   unsigned int i;
   17133            0 :   unsigned int FileQuad;
   17134              : 
   17135            0 :   q = Head;
   17136            0 :   FileQuad = 0;
   17137            0 :   do {
   17138            0 :     f = GetQF (q);
   17139            0 :     if ((f->Operator == M2Quads_StartModFileOp) || (f->Operator == M2Quads_StartDefFileOp))
   17140              :       {
   17141            0 :         FileQuad = q;
   17142              :       }
   17143            0 :     i = f->Next;
   17144            0 :     q = i;
   17145            0 :   } while (! ((i == QuadNo) || (i == 0)));
   17146            0 :   M2Debug_Assert (i != 0);
   17147            0 :   M2Debug_Assert (FileQuad != 0);
   17148            0 :   return FileQuad;
   17149              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17150              :   __builtin_unreachable ();
   17151              : }
   17152              : 
   17153              : 
   17154              : /*
   17155              :    GetLastQuadNo - returns the last quadruple number referenced
   17156              :                    by a GetQuad.
   17157              : */
   17158              : 
   17159            0 : extern "C" unsigned int M2Quads_GetLastQuadNo (void)
   17160              : {
   17161            0 :   return LastQuadNo;
   17162              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17163              :   __builtin_unreachable ();
   17164              : }
   17165              : 
   17166              : 
   17167              : /*
   17168              :    QuadToTokenNo - Converts a QuadNo into the approprate token number of the
   17169              :                    source file, the line number is returned.
   17170              : 
   17171              :                    This may be used to yield an idea where abouts in the
   17172              :                    source file the code generetion is
   17173              :                    processing.
   17174              : */
   17175              : 
   17176      7348650 : extern "C" unsigned int M2Quads_QuadToTokenNo (unsigned int QuadNo)
   17177              : {
   17178      7348650 :   M2Quads_QuadFrame f;
   17179              : 
   17180      7348650 :   if ((((LastQuadNo == 0) && (! (M2Pass_IsNoPass ()))) && (! (M2Pass_IsPassCodeGeneration ()))) || (! (Indexing_InBounds (QuadArray, QuadNo))))
   17181              :     {
   17182              :       return 0;
   17183              :     }
   17184              :   else
   17185              :     {
   17186      7348650 :       f = GetQF (QuadNo);
   17187      7348650 :       return f->TokenNo;
   17188              :     }
   17189              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17190              :   __builtin_unreachable ();
   17191              : }
   17192              : 
   17193              : 
   17194              : /*
   17195              :    QuadToLineNo - Converts a QuadNo into the approprate line number of the
   17196              :                   source file, the line number is returned.
   17197              : 
   17198              :                   This may be used to yield an idea where abouts in the
   17199              :                   source file the code generetion is
   17200              :                   processing.
   17201              : */
   17202              : 
   17203            0 : extern "C" unsigned int M2Quads_QuadToLineNo (unsigned int QuadNo)
   17204              : {
   17205            0 :   M2Quads_QuadFrame f;
   17206              : 
   17207            0 :   if ((((LastQuadNo == 0) && (! (M2Pass_IsNoPass ()))) && (! (M2Pass_IsPassCodeGeneration ()))) || (! (Indexing_InBounds (QuadArray, QuadNo))))
   17208              :     {
   17209              :       return 0;
   17210              :     }
   17211              :   else
   17212              :     {
   17213            0 :       f = GetQF (QuadNo);
   17214            0 :       return f->LineNo;
   17215              :     }
   17216              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17217              :   __builtin_unreachable ();
   17218              : }
   17219              : 
   17220              : 
   17221              : /*
   17222              :    GetQuad - returns the Quadruple QuadNo.
   17223              : */
   17224              : 
   17225   2685160747 : extern "C" void M2Quads_GetQuad (unsigned int QuadNo, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3)
   17226              : {
   17227   2685160747 :   M2Quads_QuadFrame f;
   17228              : 
   17229   2685160747 :   f = GetQF (QuadNo);
   17230   2685160747 :   LastQuadNo = QuadNo;
   17231   2685160747 :   (*Op) = f->Operator;
   17232   2685160747 :   (*Oper1) = f->Operand1;
   17233   2685160747 :   (*Oper2) = f->Operand2;
   17234   2685160747 :   (*Oper3) = f->Operand3;
   17235   2685160747 : }
   17236              : 
   17237              : 
   17238              : /*
   17239              :    GetQuadOp - returns the operator for quad.
   17240              : */
   17241              : 
   17242           24 : extern "C" M2Quads_QuadOperator M2Quads_GetQuadOp (unsigned int quad)
   17243              : {
   17244           24 :   M2Quads_QuadFrame f;
   17245              : 
   17246           24 :   f = GetQF (quad);
   17247           24 :   return f->Operator;
   17248              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17249              :   __builtin_unreachable ();
   17250              : }
   17251              : 
   17252              : 
   17253              : /*
   17254              :    GetM2OperatorDesc - returns the Modula-2 string associated with the quad operator
   17255              :                        (if possible).  It returns NIL if no there is not an obvious match
   17256              :                        in Modula-2.  It is assummed that the string will be used during
   17257              :                        construction of error messages and therefore keywords are
   17258              :                        wrapped with a format specifier.
   17259              : */
   17260              : 
   17261           31 : extern "C" DynamicStrings_String M2Quads_GetM2OperatorDesc (M2Quads_QuadOperator op)
   17262              : {
   17263           31 :   switch (op)
   17264              :     {
   17265            6 :       case M2Quads_NegateOp:
   17266            6 :         return DynamicStrings_InitString ((const char *) "-", 1);
   17267           18 :         break;
   17268              : 
   17269           18 :       case M2Quads_AddOp:
   17270           18 :         return DynamicStrings_InitString ((const char *) "+", 1);
   17271            0 :         break;
   17272              : 
   17273            0 :       case M2Quads_SubOp:
   17274            0 :         return DynamicStrings_InitString ((const char *) "-", 1);
   17275            0 :         break;
   17276              : 
   17277            0 :       case M2Quads_MultOp:
   17278            0 :         return DynamicStrings_InitString ((const char *) "*", 1);
   17279            0 :         break;
   17280              : 
   17281            0 :       case M2Quads_DivM2Op:
   17282            0 :       case M2Quads_DivCeilOp:
   17283            0 :       case M2Quads_DivFloorOp:
   17284            0 :       case M2Quads_DivTruncOp:
   17285            0 :         return DynamicStrings_InitString ((const char *) "{%kDIV}", 7);
   17286            0 :         break;
   17287              : 
   17288            0 :       case M2Quads_ModM2Op:
   17289            0 :       case M2Quads_ModCeilOp:
   17290            0 :       case M2Quads_ModFloorOp:
   17291            0 :         return DynamicStrings_InitString ((const char *) "{%kMOD}", 7);
   17292            0 :         break;
   17293              : 
   17294            0 :       case M2Quads_ModTruncOp:
   17295            0 :         return DynamicStrings_InitString ((const char *) "{%kREM}", 7);
   17296            0 :         break;
   17297              : 
   17298            0 :       case M2Quads_LogicalOrOp:
   17299            0 :         return DynamicStrings_InitString ((const char *) "{%kOR}", 6);
   17300            0 :         break;
   17301              : 
   17302            0 :       case M2Quads_LogicalAndOp:
   17303            0 :         return DynamicStrings_InitString ((const char *) "{%kAND}", 7);
   17304            0 :         break;
   17305              : 
   17306            0 :       case M2Quads_InclOp:
   17307            0 :         return DynamicStrings_InitString ((const char *) "{%kINCL}", 8);
   17308            0 :         break;
   17309              : 
   17310            0 :       case M2Quads_ExclOp:
   17311            0 :         return DynamicStrings_InitString ((const char *) "{%kEXCL}", 8);
   17312            7 :         break;
   17313              : 
   17314            7 :       case M2Quads_IfEquOp:
   17315            7 :         return DynamicStrings_InitString ((const char *) "=", 1);
   17316            0 :         break;
   17317              : 
   17318            0 :       case M2Quads_IfLessEquOp:
   17319            0 :         return DynamicStrings_InitString ((const char *) "<=", 2);
   17320            0 :         break;
   17321              : 
   17322            0 :       case M2Quads_IfGreEquOp:
   17323            0 :         return DynamicStrings_InitString ((const char *) ">=", 2);
   17324            0 :         break;
   17325              : 
   17326            0 :       case M2Quads_IfGreOp:
   17327            0 :         return DynamicStrings_InitString ((const char *) ">", 1);
   17328            0 :         break;
   17329              : 
   17330            0 :       case M2Quads_IfLessOp:
   17331            0 :         return DynamicStrings_InitString ((const char *) "<", 1);
   17332            0 :         break;
   17333              : 
   17334            0 :       case M2Quads_IfNotEquOp:
   17335            0 :         return DynamicStrings_InitString ((const char *) "#", 1);
   17336            0 :         break;
   17337              : 
   17338            0 :       case M2Quads_IfInOp:
   17339            0 :         return DynamicStrings_InitString ((const char *) "IN", 2);
   17340            0 :         break;
   17341              : 
   17342            0 :       case M2Quads_IfNotInOp:
   17343            0 :         return DynamicStrings_InitString ((const char *) "NOT IN", 6);
   17344              :         break;
   17345              : 
   17346              : 
   17347              :       default:
   17348              :         return static_cast<DynamicStrings_String> (NULL);
   17349              :         break;
   17350              :     }
   17351              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17352              :   __builtin_unreachable ();
   17353              : }
   17354              : 
   17355              : 
   17356              : /*
   17357              :    GetQuadtok - returns the Quadruple QuadNo.
   17358              : */
   17359              : 
   17360    173441259 : 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)
   17361              : {
   17362    173441259 :   M2Quads_QuadFrame f;
   17363              : 
   17364    173441259 :   f = GetQF (QuadNo);
   17365    173441259 :   LastQuadNo = QuadNo;
   17366    173441259 :   (*Op) = f->Operator;
   17367    173441259 :   (*Oper1) = f->Operand1;
   17368    173441259 :   (*Oper2) = f->Operand2;
   17369    173441259 :   (*Oper3) = f->Operand3;
   17370    173441259 :   (*Op1Pos) = f->op1pos;
   17371    173441259 :   (*Op2Pos) = f->op2pos;
   17372    173441259 :   (*Op3Pos) = f->op3pos;
   17373    173441259 : }
   17374              : 
   17375              : 
   17376              : /*
   17377              :    GetQuadOtok - returns the Quadruple QuadNo.
   17378              : */
   17379              : 
   17380      6962897 : 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)
   17381              : {
   17382      6962897 :   M2Quads_QuadFrame f;
   17383              : 
   17384      6962897 :   f = GetQF (QuadNo);
   17385      6962897 :   LastQuadNo = QuadNo;
   17386      6962897 :   (*Op) = f->Operator;
   17387      6962897 :   (*Oper1) = f->Operand1;
   17388      6962897 :   (*Oper2) = f->Operand2;
   17389      6962897 :   (*Oper3) = f->Operand3;
   17390      6962897 :   (*Op1Pos) = f->op1pos;
   17391      6962897 :   (*Op2Pos) = f->op2pos;
   17392      6962897 :   (*Op3Pos) = f->op3pos;
   17393      6962897 :   (*tok) = f->TokenNo;
   17394      6962897 :   (*overflowChecking) = f->CheckOverflow;
   17395      6962897 :   (*constExpr) = f->ConstExpr;
   17396      6962897 : }
   17397              : 
   17398              : 
   17399              : /*
   17400              :    GetQuadOTypetok - returns the fields associated with quadruple QuadNo.
   17401              : */
   17402              : 
   17403         6456 : 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)
   17404              : {
   17405         6456 :   M2Quads_QuadFrame f;
   17406              : 
   17407         6456 :   f = GetQF (QuadNo);
   17408         6456 :   LastQuadNo = QuadNo;
   17409         6456 :   (*Op) = f->Operator;
   17410         6456 :   (*Oper1) = f->Operand1;
   17411         6456 :   (*Oper2) = f->Operand2;
   17412         6456 :   (*Oper3) = f->Operand3;
   17413         6456 :   (*Op1Pos) = f->op1pos;
   17414         6456 :   (*Op2Pos) = f->op2pos;
   17415         6456 :   (*Op3Pos) = f->op3pos;
   17416         6456 :   (*tok) = f->TokenNo;
   17417         6456 :   (*overflowChecking) = f->CheckOverflow;
   17418         6456 :   (*typeChecking) = f->CheckType;
   17419         6456 :   (*constExpr) = f->ConstExpr;
   17420         6456 : }
   17421              : 
   17422              : 
   17423              : /*
   17424              :    PutQuadOtok - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
   17425              :                  sets a boolean to determinine whether overflow should be checked.
   17426              : */
   17427              : 
   17428        80854 : 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)
   17429              : {
   17430        80854 :   M2Quads_QuadFrame f;
   17431              : 
   17432        80854 :   if (QuadrupleGeneration)
   17433              :     {
   17434        80854 :       M2Quads_EraseQuad (QuadNo);
   17435        80854 :       AddQuadInformation (QuadNo, Op, Oper1, Oper2, Oper3);
   17436        80854 :       f = GetQF (QuadNo);
   17437        80854 :       f->Operator = Op;
   17438        80854 :       f->Operand1 = Oper1;
   17439        80854 :       f->Operand2 = Oper2;
   17440        80854 :       f->Operand3 = Oper3;
   17441        80854 :       f->CheckOverflow = overflowChecking;
   17442        80854 :       f->op1pos = Op1Pos;
   17443        80854 :       f->op2pos = Op2Pos;
   17444        80854 :       f->op3pos = Op3Pos;
   17445        80854 :       f->TokenNo = tok;
   17446        80854 :       f->ConstExpr = constExpr;
   17447              :     }
   17448        80854 : }
   17449              : 
   17450              : 
   17451              : /*
   17452              :    PutQuad - overwrites a quadruple QuadNo with Op, Oper1, Oper2, Oper3
   17453              : */
   17454              : 
   17455        14653 : extern "C" void M2Quads_PutQuad (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
   17456              : {
   17457        14653 :   PutQuadO (QuadNo, Op, Oper1, Oper2, Oper3, true);
   17458        14653 : }
   17459              : 
   17460              : 
   17461              : /*
   17462              :    GetFirstQuad - returns the first quadruple.
   17463              : */
   17464              : 
   17465       798769 : extern "C" unsigned int M2Quads_GetFirstQuad (void)
   17466              : {
   17467       798769 :   return Head;
   17468              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17469              :   __builtin_unreachable ();
   17470              : }
   17471              : 
   17472              : 
   17473              : /*
   17474              :    GetNextQuad - returns the Quadruple number following QuadNo.
   17475              : */
   17476              : 
   17477   3387595096 : extern "C" unsigned int M2Quads_GetNextQuad (unsigned int QuadNo)
   17478              : {
   17479   3387595096 :   M2Quads_QuadFrame f;
   17480              : 
   17481   3387595096 :   f = GetQF (QuadNo);
   17482   3387595096 :   return f->Next;
   17483              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17484              :   __builtin_unreachable ();
   17485              : }
   17486              : 
   17487              : 
   17488              : /*
   17489              :    GetRealQuad - returns the Quadruple number of the real quadruple
   17490              :                  at QuadNo or beyond.
   17491              : */
   17492              : 
   17493     15211840 : extern "C" unsigned int M2Quads_GetRealQuad (unsigned int QuadNo)
   17494              : {
   17495     15211840 :   M2Quads_QuadFrame f;
   17496              : 
   17497     23077222 :   while (QuadNo != 0)
   17498              :     {
   17499     23077222 :       if (Indexing_InBounds (QuadArray, QuadNo))
   17500              :         {
   17501     22993418 :           f = GetQF (QuadNo);
   17502     22993418 :           if ((((! (M2Quads_IsPseudoQuad (QuadNo))) && (f->Operator != M2Quads_DummyOp)) && (f->Operator != M2Quads_LineNumberOp)) && (f->Operator != M2Quads_StatementNoteOp))
   17503              :             {
   17504              :               return QuadNo;
   17505              :             }
   17506      7865382 :           QuadNo += 1;
   17507              :         }
   17508              :       else
   17509              :         {
   17510              :           return 0;
   17511              :         }
   17512              :     }
   17513              :   return 0;
   17514              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17515              :   __builtin_unreachable ();
   17516              : }
   17517              : 
   17518              : 
   17519              : /*
   17520              :    SubQuad - subtracts a quadruple QuadNo from a list Head.
   17521              : */
   17522              : 
   17523      1926117 : extern "C" void M2Quads_SubQuad (unsigned int QuadNo)
   17524              : {
   17525      1926117 :   unsigned int i;
   17526      1926117 :   M2Quads_QuadFrame f;
   17527      1926117 :   M2Quads_QuadFrame g;
   17528              : 
   17529      1926117 :   CheckBreak (QuadNo);
   17530      1926117 :   f = GetQF (QuadNo);
   17531      1926117 :   AlterReference (Head, QuadNo, f->Next);
   17532      1926117 :   UndoReadWriteInfo (QuadNo, f->Operator, f->Operand1, f->Operand2, f->Operand3);
   17533      1926117 :   if (Head == QuadNo)
   17534              :     {
   17535            0 :       Head = f->Next;
   17536              :     }
   17537              :   else
   17538              :     {
   17539      1926117 :       i = Head;
   17540      1926117 :       g = GetQF (i);
   17541   5043237402 :       while (g->Next != QuadNo)
   17542              :         {
   17543   5039385168 :           i = g->Next;
   17544   5039385168 :           g = GetQF (i);
   17545              :         }
   17546      1926117 :       g->Next = f->Next;
   17547              :     }
   17548      1926117 :   f->Operator = M2Quads_DummyOp;
   17549      1926117 :   NoOfQuads -= 1;
   17550      1926117 : }
   17551              : 
   17552              : 
   17553              : /*
   17554              :    EraseQuad - erases a quadruple QuadNo, the quadruple is still in the list
   17555              :                but wiped clean.
   17556              : */
   17557              : 
   17558      6377484 : extern "C" void M2Quads_EraseQuad (unsigned int QuadNo)
   17559              : {
   17560      6377484 :   M2Quads_QuadFrame f;
   17561              : 
   17562      6377484 :   CheckBreak (QuadNo);
   17563      6377484 :   f = GetQF (QuadNo);
   17564      6377484 :   UndoReadWriteInfo (QuadNo, f->Operator, f->Operand1, f->Operand2, f->Operand3);
   17565      6377484 :   f->Operator = M2Quads_DummyOp;  /* finally blank it out  */
   17566      6377484 :   f->Operand1 = 0;  /* finally blank it out  */
   17567      6377484 :   f->Operand2 = 0;
   17568      6377484 :   f->Operand3 = 0;
   17569      6377484 :   f->Trash = 0;
   17570      6377484 :   f->op1pos = M2LexBuf_UnknownTokenNo;
   17571      6377484 :   f->op2pos = M2LexBuf_UnknownTokenNo;
   17572      6377484 :   f->op3pos = M2LexBuf_UnknownTokenNo;
   17573      6377484 :   f->ConstExpr = false;
   17574      6377484 : }
   17575              : 
   17576              : 
   17577              : /*
   17578              :    CountQuads - returns the number of quadruples.
   17579              : */
   17580              : 
   17581      9228580 : extern "C" unsigned int M2Quads_CountQuads (void)
   17582              : {
   17583      9228580 :   return NoOfQuads;
   17584              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   17585              :   __builtin_unreachable ();
   17586              : }
   17587              : 
   17588              : 
   17589              : /*
   17590              :    BuildScaffold - generate the main, init, finish functions if
   17591              :                    no -c and this is the application module.
   17592              : */
   17593              : 
   17594        15595 : extern "C" void M2Quads_BuildScaffold (unsigned int tok, unsigned int moduleSym)
   17595              : {
   17596        15595 :   if ((SymbolTable_GetMainModule ()) == moduleSym)
   17597              :     {
   17598        15067 :       M2Scaffold_DeclareScaffold (tok);
   17599        15067 :       if (M2Options_ScaffoldMain || ! M2Options_cflag)
   17600              :         {
   17601              :           /* There are module init/fini functions and
   17602              :             application init/fini functions.
   17603              :             Here we create the application pair.  */
   17604         2823 :           BuildM2LinkFunction (tok);
   17605         2823 :           BuildM2MainFunction (tok);
   17606         2823 :           BuildM2InitFunction (tok, moduleSym);  /* Application init.  */
   17607         2823 :           BuildM2FiniFunction (tok, moduleSym);  /* Application fini.  */
   17608              :         }
   17609              :        /* Application fini.  */
   17610        15067 :       BuildM2DepFunction (tok, moduleSym);  /* Per module dependency.  */
   17611              :       /* Each module needs a ctor to register the module
   17612              :          init/finish/dep with M2RTS.  */
   17613        15067 :       BuildM2CtorFunction (tok, moduleSym);
   17614              :     }
   17615          528 :   else if (M2Options_WholeProgram)
   17616              :     {
   17617              :       /* avoid dangling else.  */
   17618          528 :       M2Scaffold_DeclareScaffold (tok);
   17619          528 :       BuildM2DepFunction (tok, moduleSym);  /* Per module dependency.  */
   17620              :       /* Each module needs a ctor to register the module
   17621              :          init/finish/dep with M2RTS.  */
   17622          528 :       BuildM2CtorFunction (tok, moduleSym);
   17623              :     }
   17624        15595 : }
   17625              : 
   17626              : 
   17627              : /*
   17628              :    StartBuildDefFile - generates a StartFileDefOp quadruple indicating the file
   17629              :                        that has produced the subsequent quadruples.
   17630              :                        The code generator uses the StartDefFileOp quadruples
   17631              :                        to relate any error to the appropriate file.
   17632              : 
   17633              : 
   17634              :                        Entry                   Exit
   17635              :                        =====                   ====
   17636              : 
   17637              : 
   17638              :                 Ptr ->                                        <- Ptr
   17639              :                        +------------+          +------------+
   17640              :                        | ModuleName |          | ModuleName |
   17641              :                        |------------|          |------------|
   17642              : 
   17643              : 
   17644              :                        Quadruples Produced
   17645              : 
   17646              :                        q     StartDefFileOp  _  _  ModuleSym
   17647              : */
   17648              : 
   17649       164816 : extern "C" void M2Quads_StartBuildDefFile (unsigned int tok)
   17650              : {
   17651       164816 :   NameKey_Name ModuleName;
   17652              : 
   17653       164816 :   M2Quads_PopT (&ModuleName);
   17654       164816 :   M2Quads_PushT (ModuleName);
   17655       164816 :   GenQuadO (tok, M2Quads_StartDefFileOp, tok, SymbolTable_NulSym, SymbolTable_GetModule (ModuleName), false);
   17656       164816 : }
   17657              : 
   17658              : 
   17659              : /*
   17660              :    StartBuildModFile - generates a StartModFileOp quadruple indicating the file
   17661              :                        that has produced the subsequent quadruples.
   17662              :                        The code generator uses the StartModFileOp quadruples
   17663              :                        to relate any error to the appropriate file.
   17664              : 
   17665              : 
   17666              :                        Entry                   Exit
   17667              :                        =====                   ====
   17668              : 
   17669              : 
   17670              :                 Ptr ->                                        <- Ptr
   17671              :                        +------------+          +------------+
   17672              :                        | ModuleName |          | ModuleName |
   17673              :                        |------------|          |------------|
   17674              : 
   17675              : 
   17676              :                        Quadruples Produced
   17677              : 
   17678              :                        q     StartModFileOp  lineno  filename  ModuleSym
   17679              : */
   17680              : 
   17681        84373 : extern "C" void M2Quads_StartBuildModFile (unsigned int tok)
   17682              : {
   17683        84373 :   GenQuadO (tok, M2Quads_StartModFileOp, tok, (unsigned int ) (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()))), SymbolTable_GetFileModule (), false);
   17684        84373 : }
   17685              : 
   17686              : 
   17687              : /*
   17688              :    EndBuildFile - generates an EndFileOp quadruple indicating the file
   17689              :                   that has produced the previous quadruples has ended.
   17690              : 
   17691              :                   Entry                   Exit
   17692              :                   =====                   ====
   17693              : 
   17694              : 
   17695              :            Ptr ->                                        <- Ptr
   17696              :                   +------------+          +------------+
   17697              :                   | ModuleName |          | ModuleName |
   17698              :                   |------------|          |------------|
   17699              : 
   17700              : 
   17701              :                   Quadruples Produced
   17702              : 
   17703              :                   q     EndFileOp  _  _  ModuleSym
   17704              : */
   17705              : 
   17706       248970 : extern "C" void M2Quads_EndBuildFile (unsigned int tok)
   17707              : {
   17708       248970 :   NameKey_Name ModuleName;
   17709              : 
   17710       248970 :   ModuleName = static_cast<NameKey_Name> (M2Quads_OperandT (1));
   17711       248970 :   GenQuadO (tok, M2Quads_EndFileOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_GetModule (ModuleName), false);
   17712       248970 : }
   17713              : 
   17714              : 
   17715              : /*
   17716              :    StartBuildInit - Sets the start of initialization code of the
   17717              :                     current module to the next quadruple.
   17718              : */
   17719              : 
   17720        84749 : extern "C" void M2Quads_StartBuildInit (unsigned int tok)
   17721              : {
   17722        84749 :   NameKey_Name name;
   17723        84749 :   unsigned int ModuleSym;
   17724              : 
   17725        84749 :   M2Quads_PopT (&name);
   17726        84749 :   ModuleSym = SymbolTable_GetCurrentModule ();
   17727       169498 :   M2Debug_Assert ((SymbolTable_IsModule (ModuleSym)) || (SymbolTable_IsDefImp (ModuleSym)));
   17728        84749 :   M2Debug_Assert ((SymbolTable_GetSymName (ModuleSym)) == name);
   17729        84743 :   SymbolTable_PutModuleStartQuad (ModuleSym, NextQuad);
   17730        84743 :   GenQuad (M2Quads_InitStartOp, tok, SymbolTable_GetFileModule (), ModuleSym);
   17731        84743 :   M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
   17732        84743 :   M2Quads_PushT (name);
   17733        84743 :   CheckVariablesAt (ModuleSym);
   17734        84743 :   CheckNeedPriorityBegin (tok, ModuleSym, ModuleSym);
   17735        84743 :   M2StackWord_PushWord (TryStack, NextQuad);
   17736        84743 :   M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
   17737        84743 :   if (SymbolTable_HasExceptionBlock (ModuleSym))
   17738              :     {
   17739           54 :       GenQuad (M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
   17740              :     }
   17741        84743 : }
   17742              : 
   17743              : 
   17744              : /*
   17745              :    EndBuildInit - Sets the end initialization code of a module.
   17746              : */
   17747              : 
   17748        84592 : extern "C" void M2Quads_EndBuildInit (unsigned int tok)
   17749              : {
   17750        84592 :   if (SymbolTable_HasExceptionBlock (SymbolTable_GetCurrentModule ()))
   17751              :     {
   17752           54 :       BuildRTExceptLeave (tok, true);
   17753           54 :       GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
   17754              :     }
   17755        84592 :   BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
   17756        84592 :   CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
   17757        84592 :   SymbolTable_PutModuleEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
   17758        84592 :   CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
   17759        84592 :   GenQuadO (tok, M2Quads_InitEndOp, tok, SymbolTable_GetFileModule (), SymbolTable_GetCurrentModule (), false);
   17760        84592 : }
   17761              : 
   17762              : 
   17763              : /*
   17764              :    StartBuildFinally - Sets the start of finalization code of the
   17765              :                        current module to the next quadruple.
   17766              : */
   17767              : 
   17768        15814 : extern "C" void M2Quads_StartBuildFinally (unsigned int tok)
   17769              : {
   17770        15814 :   NameKey_Name name;
   17771        15814 :   unsigned int ModuleSym;
   17772              : 
   17773        15814 :   M2Quads_PopT (&name);
   17774        15808 :   ModuleSym = SymbolTable_GetCurrentModule ();
   17775        31616 :   M2Debug_Assert ((SymbolTable_IsModule (ModuleSym)) || (SymbolTable_IsDefImp (ModuleSym)));
   17776        15808 :   M2Debug_Assert ((SymbolTable_GetSymName (ModuleSym)) == name);
   17777        15808 :   SymbolTable_PutModuleFinallyStartQuad (ModuleSym, NextQuad);
   17778        15808 :   GenQuadO (tok, M2Quads_FinallyStartOp, tok, SymbolTable_GetFileModule (), ModuleSym, false);
   17779        15808 :   M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
   17780        15808 :   M2Quads_PushT (name);
   17781              :   /* CheckVariablesAt(ModuleSym) ;  */
   17782        15808 :   CheckNeedPriorityBegin (tok, ModuleSym, ModuleSym);
   17783        15808 :   M2StackWord_PushWord (TryStack, NextQuad);
   17784        15808 :   M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
   17785        15808 :   if (SymbolTable_HasExceptionFinally (ModuleSym))
   17786              :     {
   17787            0 :       GenQuadO (tok, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
   17788              :     }
   17789        15808 : }
   17790              : 
   17791              : 
   17792              : /*
   17793              :    EndBuildFinally - Sets the end finalization code of a module.
   17794              : */
   17795              : 
   17796        15808 : extern "C" void M2Quads_EndBuildFinally (unsigned int tok)
   17797              : {
   17798        15808 :   if (SymbolTable_HasExceptionFinally (SymbolTable_GetCurrentModule ()))
   17799              :     {
   17800            0 :       BuildRTExceptLeave (tok, true);
   17801            0 :       GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
   17802              :     }
   17803        15808 :   BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
   17804        15808 :   CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
   17805        15808 :   SymbolTable_PutModuleFinallyEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
   17806        15808 :   CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
   17807        15808 :   GenQuadO (tok, M2Quads_FinallyEndOp, tok, SymbolTable_GetFileModule (), SymbolTable_GetCurrentModule (), false);
   17808        15808 : }
   17809              : 
   17810              : 
   17811              : /*
   17812              :    BuildExceptInitial - adds an CatchBeginOp, CatchEndOp quadruple
   17813              :                         in the current block.
   17814              : */
   17815              : 
   17816         2977 : extern "C" void M2Quads_BuildExceptInitial (unsigned int tok)
   17817              : {
   17818         2977 :   unsigned int previous;
   17819              : 
   17820              :   /* we have finished the 'try' block, so now goto the return
   17821              :       section which will tidy up (any) priorities before returning.
   17822              :   */
   17823         2977 :   GenQuadO (tok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PopWord (ReturnStack), false);
   17824         2977 :   M2StackWord_PushWord (ReturnStack, NextQuad-1);
   17825              :   /* 
   17826              :       this is the 'catch' block.
   17827              :   */
   17828         2977 :   BackPatch (M2StackWord_PeepWord (TryStack, 1), NextQuad);
   17829         2977 :   GenQuadO (tok, M2Quads_CatchBeginOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
   17830         2977 :   previous = static_cast<unsigned int> (M2StackWord_PopWord (CatchStack));
   17831         2977 :   if (previous != 0)
   17832              :     {
   17833            0 :       M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}only allowed one EXCEPT statement in a procedure or module", 62);
   17834              :     }
   17835         2977 :   M2StackWord_PushWord (CatchStack, NextQuad-1);
   17836         2977 :   BuildRTExceptEnter (tok);
   17837         2977 : }
   17838              : 
   17839              : 
   17840              : /*
   17841              :    BuildExceptFinally - adds an ExceptOp quadruple in a modules
   17842              :                         finally block.
   17843              : */
   17844              : 
   17845            0 : extern "C" void M2Quads_BuildExceptFinally (unsigned int tok)
   17846              : {
   17847            0 :   M2Quads_BuildExceptInitial (tok);
   17848            0 : }
   17849              : 
   17850              : 
   17851              : /*
   17852              :    BuildExceptProcedure - adds an ExceptOp quadruple in a procedure
   17853              :                           block.
   17854              : */
   17855              : 
   17856          168 : extern "C" void M2Quads_BuildExceptProcedure (unsigned int tok)
   17857              : {
   17858          168 :   M2Quads_BuildExceptInitial (tok);
   17859          168 : }
   17860              : 
   17861              : 
   17862              : /*
   17863              :    BuildRetry - adds an RetryOp quadruple.
   17864              : */
   17865              : 
   17866          168 : extern "C" void M2Quads_BuildRetry (unsigned int tok)
   17867              : {
   17868          168 :   if ((M2StackWord_PeepWord (CatchStack, 1)) == 0)
   17869              :     {
   17870            6 :       M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}the {%kRETRY} statement must occur after an {%kEXCEPT} statement in the same module or procedure block", 106);
   17871              :     }
   17872              :   else
   17873              :     {
   17874          162 :       BuildRTExceptLeave (tok, false);
   17875          162 :       GenQuadO (tok, M2Quads_RetryOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PeepWord (TryStack, 1), false);
   17876              :     }
   17877          168 : }
   17878              : 
   17879              : 
   17880              : /*
   17881              :    BuildReThrow - creates a ThrowOp _ _ NulSym, indicating that
   17882              :                   the exception needs to be rethrown.  The stack
   17883              :                   is unaltered.
   17884              : */
   17885              : 
   17886          222 : extern "C" void M2Quads_BuildReThrow (unsigned int tokenno)
   17887              : {
   17888          222 :   GenQuadO (tokenno, M2Quads_ThrowOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
   17889          222 : }
   17890              : 
   17891              : 
   17892              : /*
   17893              :    StartBuildInnerInit - Sets the start of initialization code of the
   17894              :                          inner module to the next quadruple.
   17895              : */
   17896              : 
   17897            0 : extern "C" void M2Quads_StartBuildInnerInit (unsigned int tok)
   17898              : {
   17899            0 :   SymbolTable_PutModuleStartQuad (SymbolTable_GetCurrentModule (), NextQuad);
   17900            0 :   GenQuadO (tok, M2Quads_InitStartOp, tok, SymbolTable_NulSym, SymbolTable_GetCurrentModule (), false);
   17901            0 :   M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
   17902            0 :   CheckNeedPriorityBegin (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
   17903            0 :   M2StackWord_PushWord (TryStack, NextQuad);
   17904            0 :   M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
   17905            0 :   if (SymbolTable_HasExceptionFinally (SymbolTable_GetCurrentModule ()))
   17906              :     {
   17907            0 :       GenQuadO (tok, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
   17908              :     }
   17909            0 : }
   17910              : 
   17911              : 
   17912              : /*
   17913              :    EndBuildInnerInit - Sets the end initialization code of a module.
   17914              : */
   17915              : 
   17916            0 : extern "C" void M2Quads_EndBuildInnerInit (unsigned int tok)
   17917              : {
   17918            0 :   if (SymbolTable_HasExceptionBlock (SymbolTable_GetCurrentModule ()))
   17919              :     {
   17920            0 :       BuildRTExceptLeave (tok, true);
   17921            0 :       GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
   17922              :     }
   17923            0 :   SymbolTable_PutModuleEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
   17924            0 :   CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
   17925            0 :   BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
   17926            0 :   CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
   17927            0 :   GenQuadO (tok, M2Quads_InitEndOp, tok, SymbolTable_NulSym, SymbolTable_GetCurrentModule (), false);
   17928            0 : }
   17929              : 
   17930              : 
   17931              : /*
   17932              :    BuildBuiltinConst - makes reference to a builtin constant within gm2.
   17933              : 
   17934              :                               Entry                 Exit
   17935              : 
   17936              :                        Ptr ->
   17937              :                               +------------+        +------------+
   17938              :                               | Ident      |        | Sym        |
   17939              :                               |------------|        |------------|
   17940              : 
   17941              :                        Quadruple produced:
   17942              : 
   17943              :                        q    Sym  BuiltinConstOp  Ident
   17944              : */
   17945              : 
   17946        29742 : extern "C" void M2Quads_BuildBuiltinConst (void)
   17947              : {
   17948        29742 :   unsigned int idtok;
   17949        29742 :   unsigned int Id;
   17950        29742 :   unsigned int Sym;
   17951              : 
   17952        29742 :   M2Quads_PopTtok (&Id, &idtok);
   17953        29742 :   Sym = SymbolTable_MakeTemporary (idtok, SymbolTable_ImmediateValue);
   17954        29742 :   SymbolTable_PutVar (Sym, M2Base_Integer);
   17955              :   /* 
   17956              :    CASE GetBuiltinConstType(KeyToCharStar(Name(Id))) OF
   17957              : 
   17958              :    0:  ErrorFormat1(NewError(GetTokenNo()),
   17959              :                     '%a unrecognised builtin constant', Id) |
   17960              :    1:  PutVar(Sym, Integer) |
   17961              :    2:  PutVar(Sym, Real)
   17962              : 
   17963              :    ELSE
   17964              :       InternalError ('unrecognised value')
   17965              :    END ;
   17966              :   */
   17967        29742 :   GenQuadO (idtok, M2Quads_BuiltinConstOp, Sym, SymbolTable_NulSym, Id, false);
   17968        29742 :   M2Quads_PushTtok (Sym, idtok);
   17969        29742 : }
   17970              : 
   17971              : 
   17972              : /*
   17973              :    BuildBuiltinTypeInfo - make reference to a builtin typeinfo function
   17974              :                           within gm2.
   17975              : 
   17976              :                                  Entry                 Exit
   17977              : 
   17978              :                           Ptr ->
   17979              :                                  +-------------+
   17980              :                                  | Type        |
   17981              :                                  |-------------|       +------------+
   17982              :                                  | Ident       |       | Sym        |
   17983              :                                  |-------------|       |------------|
   17984              : 
   17985              :                           Quadruple produced:
   17986              : 
   17987              :                           q    Sym  BuiltinTypeInfoOp  Type Ident
   17988              : */
   17989              : 
   17990          360 : extern "C" void M2Quads_BuildBuiltinTypeInfo (void)
   17991              : {
   17992          360 :   unsigned int idtok;
   17993          360 :   unsigned int Ident;
   17994          360 :   unsigned int Type;
   17995          360 :   unsigned int Sym;
   17996              : 
   17997          360 :   M2Quads_PopTtok (&Ident, &idtok);
   17998          360 :   M2Quads_PopT (&Type);
   17999          360 :   Sym = SymbolTable_MakeTemporary (M2LexBuf_BuiltinTokenNo, SymbolTable_ImmediateValue);
   18000          360 :   switch (m2builtins_GetBuiltinTypeInfoType (const_cast <const char * > (static_cast <char * > (NameKey_KeyToCharStar ((NameKey_Name) (Ident))))))
   18001              :     {
   18002            0 :       case 0:
   18003            0 :         M2Error_ErrorFormat1 (M2Error_NewError (idtok), (const char *) "%a unrecognised builtin constant", 32, (const unsigned char *) &Ident, (sizeof (Ident)-1));
   18004            0 :         break;
   18005              : 
   18006          192 :       case 1:
   18007          192 :         SymbolTable_PutVar (Sym, M2Base_Boolean);
   18008          192 :         break;
   18009              : 
   18010          120 :       case 2:
   18011          120 :         SymbolTable_PutVar (Sym, M2Base_ZType);
   18012          120 :         break;
   18013              : 
   18014           48 :       case 3:
   18015           48 :         SymbolTable_PutVar (Sym, M2Base_RType);
   18016           48 :         break;
   18017              : 
   18018              : 
   18019            0 :       default:
   18020            0 :         M2Error_InternalError ((const char *) "unrecognised value", 18);
   18021          360 :         break;
   18022              :     }
   18023          360 :   GenQuadO (idtok, M2Quads_BuiltinTypeInfoOp, Sym, Type, Ident, false);
   18024          360 :   M2Quads_PushTtok (Sym, idtok);
   18025          360 : }
   18026              : 
   18027              : 
   18028              : /*
   18029              :    BuildAssignment - Builds an assignment from the values given on the
   18030              :                      quad stack. Either an assignment to an
   18031              :                      arithmetic expression or an assignment to a
   18032              :                      boolean expression.  This procedure should not
   18033              :                      be called in CONST declarations.
   18034              :                      The Stack is expected to contain:
   18035              : 
   18036              : 
   18037              :        Either
   18038              : 
   18039              :                      Entry                   Exit
   18040              :                      =====                   ====
   18041              : 
   18042              :               Ptr ->
   18043              :                      +------------+
   18044              :                      | Expression |
   18045              :                      |------------|
   18046              :                      | Designator |
   18047              :                      |------------|          +------------+
   18048              :                      |            |          |            |  <- Ptr
   18049              :                      |------------|          |------------|
   18050              : 
   18051              : 
   18052              :                      Quadruples Produced
   18053              : 
   18054              :                      q     BecomesOp  Designator  _  Expression
   18055              : 
   18056              :        OR
   18057              : 
   18058              :                      Entry                   Exit
   18059              :                      =====                   ====
   18060              : 
   18061              :               Ptr ->
   18062              :                      +------------+
   18063              :                      | True |False|
   18064              :                      |------------|
   18065              :                      | Designator |
   18066              :                      |------------|          +------------+
   18067              :                      |            |          |            |  <- Ptr
   18068              :                      |------------|          |------------|
   18069              : 
   18070              : 
   18071              :                      Quadruples Produced
   18072              : 
   18073              :                      q     BecomesOp  Designator  _  TRUE
   18074              :                      q+1   GotoOp                    q+3
   18075              :                      q+2   BecomesOp  Designator  _  FALSE
   18076              : 
   18077              : */
   18078              : 
   18079       126760 : extern "C" void M2Quads_BuildAssignment (unsigned int becomesTokNo)
   18080              : {
   18081       126760 :   unsigned int des;
   18082       126760 :   unsigned int exp;
   18083       126760 :   unsigned int destok;
   18084       126760 :   unsigned int exptok;
   18085       126760 :   unsigned int combinedtok;
   18086              : 
   18087       126760 :   des = static_cast<unsigned int> (M2Quads_OperandT (2));
   18088       126760 :   if (IsReadOnly (des))
   18089              :     {
   18090           36 :       destok = static_cast<unsigned int> (M2Quads_OperandTok (2));
   18091           36 :       exptok = static_cast<unsigned int> (M2Quads_OperandTok (1));
   18092           36 :       exp = static_cast<unsigned int> (M2Quads_OperandT (1));
   18093           36 :       if (DebugTokPos)
   18094              :         {
   18095              :           M2MetaError_MetaErrorT1 (destok, (const char *) "destok {%1Ead}", 14, des);
   18096              :           M2MetaError_MetaErrorT1 (exptok, (const char *) "exptok {%1Ead}", 14, exp);
   18097              :         }
   18098           36 :       combinedtok = M2LexBuf_MakeVirtualTok (becomesTokNo, destok, exptok);
   18099           36 :       if (DebugTokPos)
   18100              :         {
   18101              :           M2MetaError_MetaErrorT1 (combinedtok, (const char *) "combined {%1Ead}", 16, des);
   18102              :         }
   18103           36 :       if (IsBoolean (1))
   18104              :         {
   18105            0 :           M2MetaError_MetaErrorT1 (combinedtok, (const char *) "cannot assign expression to a constant designator {%1Ead}", 57, des);
   18106              :         }
   18107              :       else
   18108              :         {
   18109           36 :           exp = static_cast<unsigned int> (M2Quads_OperandT (1));
   18110           36 :           M2MetaError_MetaErrorT2 (combinedtok, (const char *) "cannot assign a constant designator {%1Ead} with an expression {%2Ead}", 70, des, exp);
   18111              :         }
   18112           36 :       M2Quads_PopN (2);  /* Remove both parameters.  */
   18113              :     }
   18114       126724 :   else if (SymbolTable_IsError (des))
   18115              :     {
   18116              :       /* avoid dangling else.  */
   18117           25 :       M2Quads_PopN (2);  /* Remove both parameters.  */
   18118              :     }
   18119              :   else
   18120              :     {
   18121              :       /* avoid dangling else.  */
   18122       126699 :       doBuildAssignment (becomesTokNo, true, true);
   18123              :     }
   18124       126754 : }
   18125              : 
   18126              : 
   18127              : /*
   18128              :    BuildAssignConstant - used to create constant in the CONST declaration.
   18129              :                          The stack is expected to contain:
   18130              : 
   18131              :        Either
   18132              : 
   18133              :                      Entry                   Exit
   18134              :                      =====                   ====
   18135              : 
   18136              :               Ptr ->
   18137              :                      +------------+
   18138              :                      | Expression |
   18139              :                      |------------|
   18140              :                      | Designator |
   18141              :                      |------------|          +------------+
   18142              :                      |            |          |            |  <- Ptr
   18143              :                      |------------|          |------------|
   18144              : 
   18145              : 
   18146              :                      Quadruples Produced
   18147              : 
   18148              :                      q     BecomesOp  Designator  _  Expression
   18149              : 
   18150              :        OR
   18151              : 
   18152              :                      Entry                   Exit
   18153              :                      =====                   ====
   18154              : 
   18155              :               Ptr ->
   18156              :                      +------------+
   18157              :                      | True |False|
   18158              :                      |------------|
   18159              :                      | Designator |
   18160              :                      |------------|          +------------+
   18161              :                      |            |          |            |  <- Ptr
   18162              :                      |------------|          |------------|
   18163              : 
   18164              : 
   18165              :                      Quadruples Produced
   18166              : 
   18167              :                      q     BecomesOp  Designator  _  TRUE
   18168              :                      q+1   GotoOp                    q+3
   18169              :                      q+2   BecomesOp  Designator  _  FALSE
   18170              : */
   18171              : 
   18172       299566 : extern "C" void M2Quads_BuildAssignConstant (unsigned int equalsTokNo)
   18173              : {
   18174       299566 :   doBuildAssignment (equalsTokNo, true, true);
   18175       299566 : }
   18176              : 
   18177              : 
   18178              : /*
   18179              :    BuildAlignment - builds an assignment to an alignment constant.
   18180              : 
   18181              :                     The Stack is expected to contain:
   18182              : 
   18183              : 
   18184              :                             Entry                   Exit
   18185              :                             =====                   ====
   18186              : 
   18187              :                     Ptr ->
   18188              :                             +---------------+
   18189              :                             | Expression    |
   18190              :                             |---------------|
   18191              :                             | bytealignment |
   18192              :                             |---------------|       empty
   18193              : */
   18194              : 
   18195           72 : extern "C" void M2Quads_BuildAlignment (unsigned int tokno)
   18196              : {
   18197           72 :   NameKey_Name name;
   18198           72 :   unsigned int expr;
   18199           72 :   unsigned int align;
   18200              : 
   18201           72 :   M2Quads_PopT (&expr);
   18202           72 :   M2Quads_PopT (&name);
   18203           72 :   if (name != (NameKey_MakeKey ((const char *) "bytealignment", 13)))
   18204              :     {
   18205            0 :       M2MetaError_MetaError1 ((const char *) "expecting bytealignment identifier, rather than {%1Ea}", 54, SymbolTable_MakeError (tokno, name));
   18206              :     }
   18207           72 :   FifoQueue_GetConstFromFifoQueue (&align);
   18208           72 :   M2Quads_PushT (align);
   18209           72 :   M2Quads_PushT (expr);
   18210           72 :   M2Quads_BuildAssignConstant (tokno);
   18211           72 : }
   18212              : 
   18213              : 
   18214              : /*
   18215              :    BuildBitLength - builds an assignment to a bit length constant.
   18216              : 
   18217              :                     The Stack is expected to contain:
   18218              : 
   18219              : 
   18220              :                            Entry                   Exit
   18221              :                            =====                   ====
   18222              : 
   18223              :                     Ptr ->
   18224              :                            +------------+
   18225              :                            | Expression |
   18226              :                            |------------|          empty
   18227              : */
   18228              : 
   18229            0 : extern "C" void M2Quads_BuildBitLength (unsigned int tokno)
   18230              : {
   18231            0 :   unsigned int expr;
   18232            0 :   unsigned int length;
   18233              : 
   18234            0 :   M2Quads_PopT (&expr);
   18235            0 :   FifoQueue_GetConstFromFifoQueue (&length);
   18236            0 :   M2Quads_PushT (length);
   18237            0 :   M2Quads_PushT (expr);
   18238            0 :   M2Quads_BuildAssignConstant (tokno);
   18239            0 : }
   18240              : 
   18241              : 
   18242              : /*
   18243              :    BuildPragmaField - builds an assignment to an alignment constant.
   18244              : 
   18245              :                       The Stack is expected to contain:
   18246              : 
   18247              : 
   18248              :                       Entry                   Exit
   18249              :                       =====                   ====
   18250              : 
   18251              :                Ptr ->
   18252              :                       +------------+
   18253              :                       | Expression |
   18254              :                       |------------|          empty
   18255              : */
   18256              : 
   18257           12 : extern "C" void M2Quads_BuildPragmaField (void)
   18258              : {
   18259           12 :   unsigned int expr;
   18260           12 :   unsigned int const_;
   18261           12 :   NameKey_Name name;
   18262              : 
   18263           12 :   M2Quads_PopT (&expr);
   18264           12 :   M2Quads_PopT (&name);
   18265           12 :   if ((name != (NameKey_MakeKey ((const char *) "unused", 6))) && (name != (NameKey_MakeKey ((const char *) "bytealignment", 13))))
   18266              :     {
   18267            0 :       M2MetaError_MetaError0 ((const char *) "only allowed to use the attribute {%Ekbytealignment} in the default record field alignment pragma", 97);
   18268              :     }
   18269           12 :   if (expr != SymbolTable_NulSym)
   18270              :     {
   18271           12 :       FifoQueue_GetConstFromFifoQueue (&const_);
   18272           12 :       M2Quads_PushT (const_);
   18273           12 :       M2Quads_PushT (expr);
   18274           12 :       M2Quads_BuildAssignConstant (M2LexBuf_GetTokenNo ());
   18275              :     }
   18276           12 : }
   18277              : 
   18278              : 
   18279              : /*
   18280              :    BuildDefaultFieldAlignment - builds an assignment to an alignment constant.
   18281              : 
   18282              :                                 The Stack is expected to contain:
   18283              : 
   18284              : 
   18285              :                                        Entry                   Exit
   18286              :                                        =====                   ====
   18287              : 
   18288              :                                 Ptr ->
   18289              :                                        +------------+
   18290              :                                        | Expression |
   18291              :                                        |------------|          empty
   18292              : */
   18293              : 
   18294           36 : extern "C" void M2Quads_BuildDefaultFieldAlignment (void)
   18295              : {
   18296           36 :   unsigned int expr;
   18297           36 :   unsigned int align;
   18298           36 :   NameKey_Name name;
   18299              : 
   18300           36 :   M2Quads_PopT (&expr);
   18301           36 :   M2Quads_PopT (&name);
   18302           36 :   if (name != (NameKey_MakeKey ((const char *) "bytealignment", 13)))
   18303              :     {
   18304            0 :       M2MetaError_MetaError0 ((const char *) "{%E}only allowed to use the attribute {%kbytealignment} in the default record field alignment pragma", 100);
   18305              :     }
   18306           36 :   FifoQueue_GetConstFromFifoQueue (&align);
   18307           36 :   M2Quads_PushT (align);
   18308           36 :   M2Quads_PushT (expr);
   18309           36 :   M2Quads_BuildAssignConstant (M2LexBuf_GetTokenNo ());
   18310           36 : }
   18311              : 
   18312              : 
   18313              : /*
   18314              :    BuildRepeat - Builds the repeat statement from the quad stack.
   18315              :                  The Stack is expected to contain:
   18316              : 
   18317              : 
   18318              :                  Entry                   Exit
   18319              :                  =====                   ====
   18320              : 
   18321              : 
   18322              :                  Empty
   18323              :                                                         <- Ptr
   18324              :                                          +------------+
   18325              :                                          | RepeatQuad |
   18326              :                                          |------------|
   18327              : 
   18328              : */
   18329              : 
   18330         1381 : extern "C" void M2Quads_BuildRepeat (void)
   18331              : {
   18332         1381 :   M2Quads_PushT (NextQuad);
   18333         1381 : }
   18334              : 
   18335              : 
   18336              : /*
   18337              :    BuildUntil - Builds the until part of the repeat statement
   18338              :                 from the quad stack.
   18339              :                 The Stack is expected to contain:
   18340              : 
   18341              : 
   18342              :                 Entry                   Exit
   18343              :                 =====                   ====
   18344              : 
   18345              :         Ptr ->
   18346              :                 +------------+
   18347              :                 | t   | f    |
   18348              :                 |------------|
   18349              :                 | RepeatQuad |          Empty
   18350              :                 |------------|
   18351              : */
   18352              : 
   18353         1381 : extern "C" void M2Quads_BuildUntil (void)
   18354              : {
   18355         1381 :   unsigned int t;
   18356         1381 :   unsigned int f;
   18357         1381 :   unsigned int Repeat;
   18358              : 
   18359         1381 :   CheckBooleanId ();
   18360         1381 :   PopBool (&t, &f);
   18361         1381 :   M2Quads_PopT (&Repeat);
   18362         1381 :   BackPatch (f, Repeat);  /* If False then keep on repeating  */
   18363         1381 :   BackPatch (t, NextQuad);  /* If True then exit repeat  */
   18364         1381 : }
   18365              : 
   18366              : 
   18367              : /*
   18368              :    BuildWhile - Builds the While part of the While statement
   18369              :                 from the quad stack.
   18370              :                 The Stack is expected to contain:
   18371              : 
   18372              : 
   18373              :                 Entry                   Exit
   18374              :                 =====                   ====
   18375              : 
   18376              :                                                        <- Ptr
   18377              :                                         |------------|
   18378              :                 Empty                   | WhileQuad  |
   18379              :                                         |------------|
   18380              : */
   18381              : 
   18382         7639 : extern "C" void M2Quads_BuildWhile (void)
   18383              : {
   18384         7639 :   M2Quads_PushT (NextQuad);
   18385         7639 : }
   18386              : 
   18387              : 
   18388              : /*
   18389              :    BuildDoWhile - Builds the Do part of the while statement
   18390              :                   from the quad stack.
   18391              :                   The Stack is expected to contain:
   18392              : 
   18393              : 
   18394              :                   Entry                   Exit
   18395              :                   =====                   ====
   18396              : 
   18397              :           Ptr ->
   18398              :                   +------------+          +------------+
   18399              :                   | t   | f    |          | 0    | f   |
   18400              :                   |------------|          |------------|
   18401              :                   | WhileQuad  |          | WhileQuad  |
   18402              :                   |------------|          |------------|
   18403              : 
   18404              :                   Quadruples
   18405              : 
   18406              :                   BackPatch t exit to the NextQuad
   18407              : */
   18408              : 
   18409         7639 : extern "C" void M2Quads_BuildDoWhile (void)
   18410              : {
   18411         7639 :   unsigned int t;
   18412         7639 :   unsigned int f;
   18413              : 
   18414         7639 :   CheckBooleanId ();
   18415         7639 :   PopBool (&t, &f);
   18416         7639 :   BackPatch (t, NextQuad);
   18417         7639 :   PushBool (0, f);
   18418         7639 : }
   18419              : 
   18420              : 
   18421              : /*
   18422              :    BuildEndWhile - Builds the end part of the while statement
   18423              :                    from the quad stack.
   18424              :                    The Stack is expected to contain:
   18425              : 
   18426              : 
   18427              :                    Entry                   Exit
   18428              :                    =====                   ====
   18429              : 
   18430              :            Ptr ->
   18431              :                    +------------+
   18432              :                    | t   | f    |
   18433              :                    |------------|
   18434              :                    | WhileQuad  |          Empty
   18435              :                    |------------|
   18436              : 
   18437              :                    Quadruples
   18438              : 
   18439              :                    q    GotoOp  WhileQuad
   18440              :                    False exit is backpatched with q+1
   18441              : */
   18442              : 
   18443         7639 : extern "C" void M2Quads_BuildEndWhile (int reltokpos)
   18444              : {
   18445         7639 :   unsigned int tok;
   18446         7639 :   unsigned int While;
   18447         7639 :   unsigned int t;
   18448         7639 :   unsigned int f;
   18449              : 
   18450         7639 :   tok = M2LexBuf_GetTokenNo ();
   18451         7639 :   tok = ((int ) (tok))+reltokpos;
   18452         7639 :   PopBool (&t, &f);
   18453         7639 :   M2Debug_Assert (t == 0);
   18454         7639 :   M2Quads_PopT (&While);
   18455         7639 :   GenQuadO (tok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, While, false);
   18456         7639 :   BackPatch (f, NextQuad);
   18457         7639 : }
   18458              : 
   18459              : 
   18460              : /*
   18461              :    BuildLoop - Builds the Loop part of the Loop statement
   18462              :                from the quad stack.
   18463              :                The Stack is expected to contain:
   18464              : 
   18465              : 
   18466              :                Entry                   Exit
   18467              :                =====                   ====
   18468              : 
   18469              :                                                       <- Ptr
   18470              :                Empty                   +------------+
   18471              :                                        | LoopQuad   |
   18472              :                                        |------------|
   18473              : */
   18474              : 
   18475          509 : extern "C" void M2Quads_BuildLoop (void)
   18476              : {
   18477          509 :   M2Quads_PushT (NextQuad);
   18478          509 :   PushExit (0);  /* Seperate Exit Stack for loop end  */
   18479          509 : }
   18480              : 
   18481              : 
   18482              : /*
   18483              :    BuildExit - Builds the Exit part of the Loop statement.
   18484              : */
   18485              : 
   18486           94 : extern "C" void M2Quads_BuildExit (void)
   18487              : {
   18488           94 :   if (M2StackWord_IsEmptyWord (ExitStack))
   18489              :     {
   18490            0 :       M2MetaError_MetaError0 ((const char *) "{%EkEXIT} is only allowed in a {%kLOOP} statement", 49);
   18491              :     }
   18492              :   else
   18493              :     {
   18494           94 :       GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
   18495           94 :       PushExit (Merge (PopExit (), NextQuad-1));
   18496              :     }
   18497           94 : }
   18498              : 
   18499              : 
   18500              : /*
   18501              :    BuildEndLoop - Builds the End part of the Loop statement
   18502              :                   from the quad stack.
   18503              :                   The Stack is expected to contain:
   18504              : 
   18505              : 
   18506              :                   Entry                   Exit
   18507              :                   =====                   ====
   18508              : 
   18509              :           Ptr ->
   18510              :                   +------------+
   18511              :                   | LoopQuad   |          Empty
   18512              :                   |------------|
   18513              : 
   18514              :                   Quadruples
   18515              : 
   18516              :                   Goto  _  _  LoopQuad
   18517              : */
   18518              : 
   18519          509 : extern "C" void M2Quads_BuildEndLoop (void)
   18520              : {
   18521          509 :   unsigned int Loop;
   18522              : 
   18523          509 :   M2Quads_PopT (&Loop);
   18524          509 :   GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, Loop);
   18525          509 :   BackPatch (PopExit (), NextQuad);
   18526          509 : }
   18527              : 
   18528              : 
   18529              : /*
   18530              :    BuildThenIf - Builds the Then part of the If statement
   18531              :                  from the quad stack.
   18532              :                  The Stack is expected to contain:
   18533              : 
   18534              : 
   18535              :                  Entry                   Exit
   18536              :                  =====                   ====
   18537              : 
   18538              :          Ptr ->                                          <- Ptr
   18539              :                  +------------+          +------------+
   18540              :                  | t   | f    |          | 0    | f   |
   18541              :                  |------------|          |------------|
   18542              : 
   18543              :                  Quadruples
   18544              : 
   18545              :                  The true exit is BackPatched to point to
   18546              :                  the NextQuad.
   18547              : */
   18548              : 
   18549        44490 : extern "C" void M2Quads_BuildThenIf (void)
   18550              : {
   18551        44490 :   unsigned int t;
   18552        44490 :   unsigned int f;
   18553              : 
   18554        44490 :   CheckBooleanId ();
   18555        44490 :   PopBool (&t, &f);
   18556        44490 :   BackPatch (t, NextQuad);
   18557        44490 :   PushBool (0, f);
   18558        44490 : }
   18559              : 
   18560              : 
   18561              : /*
   18562              :    BuildElse - Builds the Else part of the If statement
   18563              :                from the quad stack.
   18564              :                The Stack is expected to contain:
   18565              : 
   18566              : 
   18567              :                Entry                   Exit
   18568              :                =====                   ====
   18569              : 
   18570              :        Ptr ->
   18571              :                +------------+          +------------+
   18572              :                | t   | f    |          | t+q  | 0   |
   18573              :                |------------|          |------------|
   18574              : 
   18575              :                Quadruples
   18576              : 
   18577              :                q    GotoOp  _  _  0
   18578              :                q+1  <- BackPatched from f
   18579              : */
   18580              : 
   18581        15059 : extern "C" void M2Quads_BuildElse (void)
   18582              : {
   18583        15059 :   unsigned int t;
   18584        15059 :   unsigned int f;
   18585              : 
   18586        15059 :   GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
   18587        15059 :   PopBool (&t, &f);
   18588        15059 :   BackPatch (f, NextQuad);
   18589        15059 :   PushBool (Merge (t, NextQuad-1), 0);  /* NextQuad-1 = Goto Quad  */
   18590        15059 : }
   18591              : 
   18592              : 
   18593              : /*
   18594              :    BuildEndIf - Builds the End part of the If statement
   18595              :                 from the quad stack.
   18596              :                 The Stack is expected to contain:
   18597              : 
   18598              : 
   18599              :                 Entry                   Exit
   18600              :                 =====                   ====
   18601              : 
   18602              :         Ptr ->
   18603              :                 +------------+
   18604              :                 | t   | f    |          Empty
   18605              :                 |------------|
   18606              : 
   18607              :                 Quadruples
   18608              : 
   18609              :                 Both t and f are backpatched to point to the NextQuad
   18610              : */
   18611              : 
   18612        41284 : extern "C" void M2Quads_BuildEndIf (void)
   18613              : {
   18614        41284 :   unsigned int t;
   18615        41284 :   unsigned int f;
   18616              : 
   18617        41284 :   PopBool (&t, &f);
   18618        41284 :   BackPatch (t, NextQuad);
   18619        41284 :   BackPatch (f, NextQuad);
   18620        41284 : }
   18621              : 
   18622              : 
   18623              : /*
   18624              :    BuildElsif1 - Builds the Elsif part of the If statement
   18625              :                  from the quad stack.
   18626              :                  The Stack is expected to contain:
   18627              : 
   18628              : 
   18629              :                  Entry                   Exit
   18630              :                  =====                   ====
   18631              : 
   18632              :          Ptr ->
   18633              :                  +------------+          +------------+
   18634              :                  | t   | f    |          | t+q  | 0   |
   18635              :                  |------------|          |------------|
   18636              : 
   18637              :                  Quadruples
   18638              : 
   18639              :                  q    GotoOp  _  _  0
   18640              :                  q+1  <- BackPatched from f
   18641              : */
   18642              : 
   18643         3206 : extern "C" void M2Quads_BuildElsif1 (void)
   18644              : {
   18645         3206 :   unsigned int t;
   18646         3206 :   unsigned int f;
   18647              : 
   18648         3206 :   GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
   18649         3206 :   PopBool (&t, &f);
   18650         3206 :   BackPatch (f, NextQuad);
   18651         3206 :   PushBool (Merge (t, NextQuad-1), 0);  /* NextQuad-1 = Goto Quad  */
   18652         3206 : }
   18653              : 
   18654              : 
   18655              : /*
   18656              :    BuildElsif2 - Builds the Elsif until part of the If statement
   18657              :                  from the quad stack.
   18658              :                  The Stack is expected to contain:
   18659              : 
   18660              : 
   18661              :                  Entry                   Exit
   18662              :                  =====                   ====
   18663              : 
   18664              :           Ptr ->
   18665              :                  +--------------+
   18666              :                  | 0    | f1    |                            <- Ptr
   18667              :                  |--------------|          +---------------+
   18668              :                  | t2   | f2    |          | t2    | f1+f2 |
   18669              :                  |--------------|          |---------------|
   18670              : */
   18671              : 
   18672         3206 : extern "C" void M2Quads_BuildElsif2 (void)
   18673              : {
   18674         3206 :   unsigned int t1;
   18675         3206 :   unsigned int f1;
   18676         3206 :   unsigned int t2;
   18677         3206 :   unsigned int f2;
   18678              : 
   18679         3206 :   PopBool (&t1, &f1);
   18680         3206 :   M2Debug_Assert (t1 == 0);
   18681         3206 :   PopBool (&t2, &f2);
   18682         3206 :   PushBool (t2, Merge (f1, f2));
   18683         3206 : }
   18684              : 
   18685              : 
   18686              : /*
   18687              :    BuildForToByDo - Builds the For To By Do part of the For statement
   18688              :                     from the quad stack.
   18689              :                     The Stack is expected to contain:
   18690              : 
   18691              : 
   18692              :                     Entry                   Exit
   18693              :                     =====                   ====
   18694              : 
   18695              :                                                                <- Ptr
   18696              :                                             +----------------+
   18697              :              Ptr ->                         | RangeId        |
   18698              :                     +----------------+      |----------------|
   18699              :                     | BySym | ByType |      | ForQuad        |
   18700              :                     |----------------|      |----------------|
   18701              :                     | e2             |      | LastValue      |
   18702              :                     |----------------|      |----------------|
   18703              :                     | e1             |      | BySym | ByType |
   18704              :                     |----------------|      |----------------|
   18705              :                     | Ident          |      | IdentSym       |
   18706              :                     |----------------|      |----------------|
   18707              : 
   18708              : 
   18709              :                     x := e1 ;
   18710              :                     Note that LASTVALUE is calculated during M2GenGCC
   18711              :                          after all the types have been resolved.
   18712              :                     LASTVALUE := ((e2-e1) DIV BySym) * BySym + e1
   18713              :                     IF BySym<0
   18714              :                     THEN
   18715              :                        IF e1<e2
   18716              :                        THEN
   18717              :                           goto exit
   18718              :                        END
   18719              :                     ELSE
   18720              :                        IF e1>e2
   18721              :                        THEN
   18722              :                           goto exit
   18723              :                        END
   18724              :                     END ;
   18725              :                     LOOP
   18726              :                        body
   18727              :                        IF x=LASTVALUE
   18728              :                        THEN
   18729              :                           goto exit
   18730              :                        END ;
   18731              :                        INC(x, BySym)
   18732              :                     END
   18733              : 
   18734              :                     Quadruples:
   18735              : 
   18736              :                     q     BecomesOp  IdentSym  _  e1
   18737              :                     q+    LastForIteratorOp  LastValue  := ((e1-e2) DIV by) * by + e1
   18738              :                     q+1   if >=      by        0  q+..2
   18739              :                     q+2   GotoOp                  q+3
   18740              :                     q+3   If >=      e1  e2       q+5
   18741              :                     q+4   GotoOp                  exit
   18742              :                     q+5   ..
   18743              :                     q+..1 Goto                    q+..5
   18744              :                     q+..2 If >=      e2  e1       q+..4
   18745              :                     q+..3 GotoOp                  exit
   18746              :                     q+..4 ..
   18747              : 
   18748              :                     The For Loop is regarded:
   18749              : 
   18750              :                     For ident := e1 To e2 By by Do
   18751              : 
   18752              :                     End
   18753              : */
   18754              : 
   18755         2576 : extern "C" void M2Quads_BuildForToByDo (void)
   18756              : {
   18757         2576 :   M2Quads_LineNote l1;
   18758         2576 :   M2Quads_LineNote l2;
   18759         2576 :   NameKey_Name e1;
   18760         2576 :   NameKey_Name e2;
   18761         2576 :   NameKey_Name Id;
   18762         2576 :   unsigned int e1tok;
   18763         2576 :   unsigned int e2tok;
   18764         2576 :   unsigned int idtok;
   18765         2576 :   unsigned int bytok;
   18766         2576 :   unsigned int LastIterator;
   18767         2576 :   unsigned int exit1;
   18768         2576 :   unsigned int IdSym;
   18769         2576 :   unsigned int BySym;
   18770         2576 :   unsigned int ByType;
   18771         2576 :   unsigned int ForLoop;
   18772         2576 :   unsigned int RangeId;
   18773         2576 :   unsigned int t;
   18774         2576 :   unsigned int f;
   18775         2576 :   unsigned int etype;
   18776         2576 :   unsigned int t1;
   18777              : 
   18778         2576 :   l2 = PopLineNo ();
   18779         2576 :   l1 = PopLineNo ();
   18780         2576 :   UseLineNote (l1);
   18781         2576 :   PushFor (0);
   18782         2576 :   M2Quads_PopTFtok (&BySym, &ByType, &bytok);
   18783         2576 :   M2Quads_PopTtok (&e2, &e2tok);
   18784         2576 :   M2Quads_PopTtok (&e1, &e1tok);
   18785         2576 :   M2Quads_PopTtok (&Id, &idtok);
   18786         2576 :   IdSym = SymbolTable_RequestSym (idtok, Id);
   18787         2576 :   RangeId = M2Range_InitForLoopBeginRangeCheck (IdSym, idtok, e1, e1tok, e2, e2tok, BySym, bytok);
   18788         2576 :   BuildRange (RangeId);
   18789         2576 :   M2Quads_PushTtok (IdSym, idtok);
   18790         2576 :   M2Quads_PushTtok (e1, e1tok);
   18791         2576 :   BuildAssignmentWithoutBounds (idtok, true, true);
   18792         2576 :   UseLineNote (l2);
   18793         3434 :   LastIterator = SymbolTable_MakeTemporary (e2tok, AreConstant (((SymbolTable_IsConst (e1)) && (SymbolTable_IsConst (e2))) && (SymbolTable_IsConst (BySym))));
   18794         2576 :   SymbolTable_PutVar (LastIterator, SymbolTable_GetSType (IdSym));
   18795         2576 :   etype = M2Base_MixTypes (SymbolTable_GetSType (e1), SymbolTable_GetSType (e2), e2tok);
   18796         2576 :   e1 = doConvert (etype, e1);
   18797         2576 :   e2 = doConvert (etype, e2);
   18798         2570 :   ForLoopLastIterator (LastIterator, e1, e2, BySym, e1tok, e2tok, bytok);
   18799              :   /* q+2 GotoOp                  q+3  */
   18800         2570 :   M2Quads_PushTFtok (BySym, ByType, bytok);  /* BuildRelOp  1st parameter.  */
   18801         2570 :   M2Quads_PushT (M2Reserved_GreaterEqualTok);  /* 2nd parameter.  */
   18802              :   /* 3rd parameter.  */
   18803         2570 :   PushZero (bytok, ByType);
   18804         2570 :   M2Quads_BuildRelOp (e2tok);  /* Choose final expression position.  */
   18805         2570 :   PopBool (&t, &f);  /* Choose final expression position.  */
   18806         2570 :   BackPatch (f, NextQuad);
   18807              :   /* q+4 GotoOp                  Exit  */
   18808         2570 :   M2Quads_PushTFtok (e1, SymbolTable_GetSType (e1), e1tok);  /* BuildRelOp  1st parameter  */
   18809         2570 :   M2Quads_PushT (M2Reserved_GreaterEqualTok);  /* 2nd parameter  */
   18810         2570 :   M2Quads_PushTFtok (e2, SymbolTable_GetSType (e2), e2tok);  /* 3rd parameter  */
   18811         2570 :   M2Quads_BuildRelOp (e2tok);  /* Choose final expression position.  */
   18812         2570 :   PopBool (&t1, &exit1);  /* Choose final expression position.  */
   18813         2570 :   BackPatch (t1, NextQuad);
   18814         2570 :   PushFor (Merge (PopFor (), exit1));  /* Merge exit1.  */
   18815         2570 :   GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);  /* Merge exit1.  */
   18816         2570 :   ForLoop = NextQuad-1;
   18817              :   /* ELSE.  */
   18818         2570 :   BackPatch (t, NextQuad);
   18819         2570 :   M2Quads_PushTFtok (e2, SymbolTable_GetSType (e2), e2tok);  /* BuildRelOp  1st parameter  */
   18820         2570 :   M2Quads_PushT (M2Reserved_GreaterEqualTok);  /* 2nd parameter  */
   18821         2570 :   M2Quads_PushTFtok (e1, SymbolTable_GetSType (e1), e1tok);  /* 3rd parameter  */
   18822         2570 :   M2Quads_BuildRelOp (e2tok);  /* 3rd parameter  */
   18823         2570 :   PopBool (&t1, &exit1);
   18824         2570 :   BackPatch (t1, NextQuad);
   18825         2570 :   PushFor (Merge (PopFor (), exit1));  /* Merge exit1.  */
   18826         2570 :   BackPatch (ForLoop, NextQuad);  /* Fixes the start of the for loop.  */
   18827         2570 :   ForLoop = NextQuad;
   18828              :   /* And set up the stack.  */
   18829         2570 :   M2Quads_PushTFtok (IdSym, SymbolTable_GetSym (IdSym), idtok);
   18830         2570 :   M2Quads_PushTFtok (BySym, ByType, bytok);
   18831         2570 :   M2Quads_PushTFtok (LastIterator, SymbolTable_GetSType (LastIterator), e2tok);
   18832         2570 :   M2Quads_PushT (ForLoop);
   18833         2570 :   M2Quads_PushT (RangeId);
   18834         2570 : }
   18835              : 
   18836              : 
   18837              : /*
   18838              :    BuildPseudoBy - Builds the Non existant part of the By
   18839              :                    clause of the For statement
   18840              :                    from the quad stack.
   18841              :                    The Stack is expected to contain:
   18842              : 
   18843              : 
   18844              :                    Entry                   Exit
   18845              :                    =====                   ====
   18846              : 
   18847              :                                                            <- Ptr
   18848              :                                            +------------+
   18849              :             Ptr ->                         | BySym | t  |
   18850              :                    +------------+          |------------|
   18851              :                    | e    | t   |          | e     | t  |
   18852              :                    |------------|          |------------|
   18853              : */
   18854              : 
   18855         2210 : extern "C" void M2Quads_BuildPseudoBy (void)
   18856              : {
   18857         2210 :   unsigned int expr;
   18858         2210 :   unsigned int type;
   18859         2210 :   unsigned int dotok;
   18860              : 
   18861              :   /* As there is no BY token this position is the DO at the end of the last expression.  */
   18862         2210 :   M2Quads_PopTFtok (&expr, &type, &dotok);
   18863         2210 :   M2Quads_PushTFtok (expr, type, dotok);
   18864         2210 :   if (type == SymbolTable_NulSym)
   18865              :     {}  /* empty.  */
   18866              :   /* Use type.  */
   18867         1990 :   else if ((SymbolTable_IsEnumeration (SymbolTable_SkipType (type))) || ((SymbolTable_SkipType (type)) == M2Base_Char))
   18868              :     {
   18869              :       /* avoid dangling else.  */
   18870              :     }
   18871         1770 :   else if (M2Base_IsOrdinalType (SymbolTable_SkipType (type)))
   18872              :     {
   18873              :       /* avoid dangling else.  */
   18874         1770 :       type = M2Base_ZType;
   18875              :     }
   18876         2210 :   PushOne (dotok, type, (const char *) "the implied {%kFOR} loop increment will cause an overflow {%1ad}", 64);
   18877         2210 : }
   18878              : 
   18879              : 
   18880              : /*
   18881              :    BuildEndFor - Builds the End part of the For statement
   18882              :                  from the quad stack.
   18883              :                  The Stack is expected to contain:
   18884              : 
   18885              : 
   18886              :                  Entry                   Exit
   18887              :                  =====                   ====
   18888              : 
   18889              :          Ptr ->
   18890              :                  +----------------+
   18891              :                  | RangeId        |
   18892              :                  |----------------|
   18893              :                  | ForQuad        |
   18894              :                  |----------------|
   18895              :                  | LastValue      |
   18896              :                  |----------------|
   18897              :                  | BySym | ByType |
   18898              :                  |----------------|
   18899              :                  | IdSym          |      Empty
   18900              :                  |----------------|
   18901              : */
   18902              : 
   18903         2570 : extern "C" void M2Quads_BuildEndFor (unsigned int endpostok)
   18904              : {
   18905         2570 :   unsigned int t;
   18906         2570 :   unsigned int f;
   18907         2570 :   unsigned int tsym;
   18908         2570 :   unsigned int RangeId;
   18909         2570 :   unsigned int IncQuad;
   18910         2570 :   unsigned int ForQuad;
   18911         2570 :   unsigned int LastSym;
   18912         2570 :   unsigned int ByType;
   18913         2570 :   unsigned int BySym;
   18914         2570 :   unsigned int bytok;
   18915         2570 :   unsigned int IdSym;
   18916         2570 :   unsigned int idtok;
   18917              : 
   18918         2570 :   M2Quads_PopT (&RangeId);
   18919         2570 :   M2Quads_PopT (&ForQuad);
   18920         2570 :   M2Quads_PopT (&LastSym);
   18921         2570 :   M2Quads_PopTFtok (&BySym, &ByType, &bytok);
   18922         2570 :   M2Quads_PopTtok (&IdSym, &idtok);
   18923              :   /* IF IdSym=LastSym THEN exit END  */
   18924         2570 :   M2Quads_PushTF (IdSym, SymbolTable_GetSType (IdSym));
   18925         2570 :   M2Quads_PushT (M2Reserved_EqualTok);
   18926         2570 :   M2Quads_PushTF (LastSym, SymbolTable_GetSType (LastSym));
   18927         2570 :   M2Quads_BuildRelOp (endpostok);
   18928         2570 :   PopBool (&t, &f);
   18929         2570 :   BackPatch (t, NextQuad);
   18930         2570 :   GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
   18931         2570 :   PushFor (Merge (PopFor (), NextQuad-1));
   18932         2570 :   BackPatch (f, NextQuad);
   18933         2570 :   if ((SymbolTable_GetMode (IdSym)) == SymbolTable_LeftValue)
   18934              :     {
   18935              :       /* index variable is a LeftValue, therefore we must dereference it  */
   18936            0 :       tsym = SymbolTable_MakeTemporary (idtok, SymbolTable_RightValue);
   18937            0 :       SymbolTable_PutVar (tsym, SymbolTable_GetSType (IdSym));
   18938            0 :       CheckPointerThroughNil (idtok, IdSym);
   18939            0 :       doIndrX (endpostok, tsym, IdSym);
   18940            0 :       BuildRange (M2Range_InitForLoopEndRangeCheck (tsym, BySym));  /* --fixme-- pass endpostok.  */
   18941            0 :       IncQuad = NextQuad;
   18942              :       /* we have explicitly checked using the above and also
   18943              :          this addition can legitimately overflow if a cardinal type
   18944              :          is counting down.  The above test will generate a more
   18945              :          precise error message, so we suppress overflow detection
   18946              :          here.  */
   18947            0 :       GenQuadOTypetok (bytok, M2Quads_AddOp, tsym, tsym, BySym, false, false, idtok, idtok, bytok);
   18948            0 :       CheckPointerThroughNil (idtok, IdSym);
   18949            0 :       GenQuadOtok (idtok, M2Quads_XIndrOp, IdSym, SymbolTable_GetSType (IdSym), tsym, false, idtok, idtok, idtok);
   18950              :     }
   18951              :   else
   18952              :     {
   18953         2570 :       BuildRange (M2Range_InitForLoopEndRangeCheck (IdSym, BySym));
   18954         2570 :       IncQuad = NextQuad;
   18955              :       /* we have explicitly checked using the above and also
   18956              :          this addition can legitimately overflow if a cardinal type
   18957              :          is counting down.  The above test will generate a more
   18958              :          precise error message, so we suppress overflow detection
   18959              :          here.
   18960              : 
   18961              :          This quadruple suppresses the generic binary op type
   18962              :          check (performed in M2GenGCC.mod) as there
   18963              :          will be a more informative/exhaustive check performed by the
   18964              :          InitForLoopBeginRangeCheck setup in BuildForToByDo and
   18965              :          performed by M2Range.mod.  */
   18966         2570 :       GenQuadOTypetok (idtok, M2Quads_AddOp, IdSym, IdSym, BySym, false, false, idtok, idtok, bytok);
   18967              :     }
   18968         2570 :   GenQuadO (endpostok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, ForQuad, false);
   18969         2570 :   BackPatch (PopFor (), NextQuad);
   18970         2570 :   AddForInfo (ForQuad, NextQuad-1, IncQuad, IdSym, idtok);
   18971         2570 :   M2Range_PutRangeForIncrement (RangeId, IncQuad);
   18972         2570 : }
   18973              : 
   18974              : 
   18975              : /*
   18976              :    BuildCaseStart - starts the case statement.
   18977              :                     It initializes a backpatch list on the compile
   18978              :                     time stack, the list is used to contain all
   18979              :                     case break points. The list is later backpatched
   18980              :                     and contains all positions of the case statement
   18981              :                     which jump to the end of the case statement.
   18982              :                     The stack also contains room for a boolean
   18983              :                     expression, this is needed to allow , operator
   18984              :                     in the CaseField alternatives.
   18985              : 
   18986              :                     The Stack is expected to contain:
   18987              : 
   18988              : 
   18989              :                     Entry                   Exit
   18990              :                     =====                   ====
   18991              : 
   18992              :                                                            <- Ptr
   18993              :                                             +------------+
   18994              :                                             | 0    | 0   |
   18995              :                                             |------------|
   18996              :                                             | 0    | 0   |
   18997              :                     +-------------+         |------------|
   18998              :                     | Expr |      |         | Expr |     |
   18999              :                     |-------------|         |------------|
   19000              : */
   19001              : 
   19002          989 : extern "C" void M2Quads_BuildCaseStart (void)
   19003              : {
   19004          989 :   BuildRange (M2Range_InitCaseBounds (M2CaseList_PushCase (SymbolTable_NulSym, SymbolTable_NulSym, M2Quads_OperandT (1))));
   19005          989 :   PushBool (0, 0);  /* BackPatch list initialized  */
   19006          989 :   PushBool (0, 0);  /* Room for a boolean expression  */
   19007          989 : }
   19008              : 
   19009              : 
   19010              : /*
   19011              :    BuildCaseStartStatementSequence - starts the statement sequence
   19012              :                                      inside a case clause.
   19013              :                                      BackPatches the true exit to the
   19014              :                                      NextQuad.
   19015              :                                      The Stack:
   19016              : 
   19017              :                                      Entry             Exit
   19018              : 
   19019              :                               Ptr ->                                  <- Ptr
   19020              :                                      +-----------+     +------------+
   19021              :                                      | t   | f   |     | 0   | f    |
   19022              :                                      |-----------|     |------------|
   19023              : */
   19024              : 
   19025         3791 : extern "C" void M2Quads_BuildCaseStartStatementSequence (void)
   19026              : {
   19027         3791 :   unsigned int t;
   19028         3791 :   unsigned int f;
   19029              : 
   19030         3791 :   PopBool (&t, &f);
   19031         3791 :   BackPatch (t, NextQuad);
   19032         3791 :   PushBool (0, f);
   19033         3791 : }
   19034              : 
   19035              : 
   19036              : /*
   19037              :    BuildCaseEndStatementSequence - ends the statement sequence
   19038              :                                    inside a case clause.
   19039              :                                    BackPatches the false exit f1 to the
   19040              :                                    NextQuad.
   19041              :                                    Asserts that t1 and f2 is 0
   19042              :                                    Pushes t2+q and 0
   19043              : 
   19044              :                                    Quadruples:
   19045              : 
   19046              :                                    q  GotoOp  _  _  0
   19047              : 
   19048              :                                    The Stack:
   19049              : 
   19050              :                                    Entry             Exit
   19051              : 
   19052              :                             Ptr ->                                  <- Ptr
   19053              :                                    +-----------+     +------------+
   19054              :                                    | t1  | f1  |     | 0    | 0   |
   19055              :                                    |-----------|     |------------|
   19056              :                                    | t2  | f2  |     | t2+q | 0   |
   19057              :                                    |-----------|     |------------|
   19058              : */
   19059              : 
   19060         3791 : extern "C" void M2Quads_BuildCaseEndStatementSequence (void)
   19061              : {
   19062         3791 :   unsigned int t1;
   19063         3791 :   unsigned int f1;
   19064         3791 :   unsigned int t2;
   19065         3791 :   unsigned int f2;
   19066              : 
   19067         3791 :   GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
   19068         3791 :   PopBool (&t1, &f1);
   19069         3791 :   PopBool (&t2, &f2);  /* t2 contains the break list for the case  */
   19070         3791 :   BackPatch (f1, NextQuad);  /* f1 no longer needed  */
   19071         3791 :   M2Debug_Assert (t1 == 0);  /* f1 no longer needed  */
   19072         3791 :   M2Debug_Assert (f2 == 0);
   19073         3791 :   PushBool (Merge (t2, NextQuad-1), 0);  /* NextQuad-1 = Goto Quad  */
   19074         3791 :   PushBool (0, 0);  /* Room for boolean expression  */
   19075         3791 : }
   19076              : 
   19077              : 
   19078              : /*
   19079              :    BuildCaseRange - builds the range testing quaruples for
   19080              :                     a case clause.
   19081              : 
   19082              :                     IF (e1>=ce1) AND (e1<=ce2)
   19083              :                     THEN
   19084              : 
   19085              :                     ELS..
   19086              : 
   19087              :                     The Stack:
   19088              : 
   19089              :                     Entry             Exit
   19090              : 
   19091              :              Ptr ->
   19092              :                     +-----------+
   19093              :                     | ce2       |                   <- Ptr
   19094              :                     |-----------|     +-----------+
   19095              :                     | ce1       |     | t   | f   |
   19096              :                     |-----------|     |-----------|
   19097              :                     | t1  | f1  |     | t1  | f1  |
   19098              :                     |-----------|     |-----------|
   19099              :                     | t2  | f2  |     | t2  | f2  |
   19100              :                     |-----------|     |-----------|
   19101              :                     | e1        |     | e1        |
   19102              :                     |-----------|     |-----------|
   19103              : */
   19104              : 
   19105          170 : extern "C" void M2Quads_BuildCaseRange (void)
   19106              : {
   19107          170 :   unsigned int ce1;
   19108          170 :   unsigned int ce2;
   19109          170 :   unsigned int combinedtok;
   19110          170 :   unsigned int ce1tok;
   19111          170 :   unsigned int ce2tok;
   19112          170 :   unsigned int e1tok;
   19113          170 :   unsigned int e1;
   19114          170 :   unsigned int t2;
   19115          170 :   unsigned int f2;
   19116          170 :   unsigned int t1;
   19117          170 :   unsigned int f1;
   19118              : 
   19119          170 :   M2Quads_PopTtok (&ce2, &ce2tok);
   19120          170 :   M2Quads_PopTtok (&ce1, &ce1tok);
   19121          170 :   combinedtok = M2LexBuf_MakeVirtualTok (ce2tok, ce2tok, ce1tok);
   19122          170 :   M2CaseList_AddRange (ce1, ce2, combinedtok);
   19123          170 :   PopBool (&t1, &f1);
   19124          170 :   PopBool (&t2, &f2);
   19125          170 :   M2Quads_PopTtok (&e1, &e1tok);
   19126          170 :   M2Quads_PushTtok (e1, e1tok);  /* leave e1 on bottom of stack when exit procedure  */
   19127          170 :   PushBool (t2, f2);  /* leave e1 on bottom of stack when exit procedure  */
   19128          170 :   PushBool (t1, f1);  /* also leave t1 and f1 on the bottom of the stack  */
   19129          170 :   M2Quads_PushTtok (e1, e1tok);  /* also leave t1 and f1 on the bottom of the stack  */
   19130          170 :   M2Quads_PushT (M2Reserved_GreaterEqualTok);
   19131          170 :   M2Quads_PushTtok (ce1, ce1tok);
   19132          170 :   M2Quads_BuildRelOp (combinedtok);
   19133          170 :   M2Quads_PushT (M2Reserved_AndTok);
   19134          170 :   M2Quads_RecordOp ();
   19135          170 :   M2Quads_PushTtok (e1, e1tok);
   19136          170 :   M2Quads_PushT (M2Reserved_LessEqualTok);
   19137          170 :   M2Quads_PushTtok (ce2, ce2tok);
   19138          170 :   M2Quads_BuildRelOp (combinedtok);
   19139          170 :   M2Quads_BuildBinaryOp ();
   19140          170 : }
   19141              : 
   19142              : 
   19143              : /*
   19144              :    BuildCaseEquality - builds the range testing quadruples for
   19145              :                        a case clause.
   19146              : 
   19147              :                        IF e1=ce1
   19148              :                        THEN
   19149              : 
   19150              :                        ELS..
   19151              : 
   19152              :                        The Stack:
   19153              : 
   19154              :                        Entry             Exit
   19155              : 
   19156              :                 Ptr ->
   19157              :                        +-----------+     +-----------+
   19158              :                        | ce1       |     | t   | f   |
   19159              :                        |-----------|     |-----------|
   19160              :                        | t1  | f1  |     | t1  | f1  |
   19161              :                        |-----------|     |-----------|
   19162              :                        | t2  | f2  |     | t2  | f2  |
   19163              :                        |-----------|     |-----------|
   19164              :                        | e1        |     | e1        |
   19165              :                        |-----------|     |-----------|
   19166              : */
   19167              : 
   19168         3671 : extern "C" void M2Quads_BuildCaseEquality (void)
   19169              : {
   19170         3671 :   unsigned int ce1tok;
   19171         3671 :   unsigned int e1tok;
   19172         3671 :   unsigned int ce1;
   19173         3671 :   unsigned int e1;
   19174         3671 :   unsigned int t2;
   19175         3671 :   unsigned int f2;
   19176         3671 :   unsigned int t1;
   19177         3671 :   unsigned int f1;
   19178              : 
   19179         3671 :   M2Quads_PopTtok (&ce1, &ce1tok);
   19180         3671 :   M2CaseList_AddRange (ce1, SymbolTable_NulSym, ce1tok);
   19181         3671 :   PopBool (&t1, &f1);
   19182         3671 :   PopBool (&t2, &f2);
   19183         3671 :   M2Quads_PopTtok (&e1, &e1tok);
   19184         3671 :   M2Quads_PushTtok (e1, e1tok);  /* leave e1 on bottom of stack when exit procedure  */
   19185         3671 :   PushBool (t2, f2);  /* also leave t2 and f2 on the bottom of the stack  */
   19186         3671 :   PushBool (t1, f1);  /* also leave t2 and f2 on the bottom of the stack  */
   19187         3671 :   M2Quads_PushTtok (e1, e1tok);
   19188         3671 :   M2Quads_PushT (M2Reserved_EqualTok);
   19189         3671 :   M2Quads_PushTtok (ce1, ce1tok);
   19190         3671 :   M2Quads_BuildRelOp (ce1tok);
   19191         3671 : }
   19192              : 
   19193              : 
   19194              : /*
   19195              :    BuildCaseList - merges two case tests into one
   19196              : 
   19197              :                    The Stack:
   19198              : 
   19199              :                    Entry             Exit
   19200              : 
   19201              :             Ptr ->
   19202              :                    +-----------+
   19203              :                    | t2  | f2  |
   19204              :                    |-----------|     +-------------+
   19205              :                    | t1  | f1  |     | t1+t2| f1+f2|
   19206              :                    |-----------|     |-------------|
   19207              : */
   19208              : 
   19209         3841 : extern "C" void M2Quads_BuildCaseList (void)
   19210              : {
   19211         3841 :   unsigned int t2;
   19212         3841 :   unsigned int f2;
   19213         3841 :   unsigned int t1;
   19214         3841 :   unsigned int f1;
   19215              : 
   19216         3841 :   PopBool (&t2, &f2);
   19217         3841 :   PopBool (&t1, &f1);
   19218         3841 :   PushBool (Merge (t1, t2), Merge (f1, f2));
   19219         3841 : }
   19220              : 
   19221              : 
   19222              : /*
   19223              :    BuildCaseOr - builds the , in the case clause.
   19224              : 
   19225              :                  The Stack:
   19226              : 
   19227              :                  Entry             Exit
   19228              : 
   19229              :           Ptr ->                                  <- Ptr
   19230              :                  +-----------+     +------------+
   19231              :                  | t   | f   |     | t    | 0   |
   19232              :                  |-----------|     |------------|
   19233              : */
   19234              : 
   19235           50 : extern "C" void M2Quads_BuildCaseOr (void)
   19236              : {
   19237           50 :   unsigned int t;
   19238           50 :   unsigned int f;
   19239              : 
   19240           50 :   PopBool (&t, &f);
   19241           50 :   BackPatch (f, NextQuad);
   19242           50 :   PushBool (t, 0);
   19243           50 : }
   19244              : 
   19245              : 
   19246              : /*
   19247              :    BuildCaseElse - builds the else of case clause.
   19248              : 
   19249              :                   The Stack:
   19250              : 
   19251              :                   Entry             Exit
   19252              : 
   19253              :            Ptr ->                                  <- Ptr
   19254              :                   +-----------+     +------------+
   19255              :                   | t   | f   |     | t    | 0   |
   19256              :                   |-----------|     |------------|
   19257              : */
   19258              : 
   19259          989 : extern "C" void M2Quads_BuildCaseElse (void)
   19260              : {
   19261          989 :   unsigned int t;
   19262          989 :   unsigned int f;
   19263              : 
   19264          989 :   PopBool (&t, &f);
   19265          989 :   BackPatch (f, NextQuad);
   19266          989 :   PushBool (t, 0);
   19267          989 : }
   19268              : 
   19269              : 
   19270              : /*
   19271              :    BuildCaseEnd - builds the end of case clause.
   19272              : 
   19273              :                   The Stack:
   19274              : 
   19275              :                   Entry             Exit
   19276              : 
   19277              :            Ptr ->
   19278              :                   +-----------+
   19279              :                   | t1  | f1  |
   19280              :                   |-----------|
   19281              :                   | t2  | f2  |
   19282              :                   |-----------|
   19283              :                   | e1        |
   19284              :                   |-----------|     Empty
   19285              : */
   19286              : 
   19287          989 : extern "C" void M2Quads_BuildCaseEnd (void)
   19288              : {
   19289          989 :   unsigned int e1;
   19290          989 :   unsigned int t;
   19291          989 :   unsigned int f;
   19292              : 
   19293          989 :   PopBool (&t, &f);
   19294          989 :   BackPatch (f, NextQuad);
   19295          989 :   BackPatch (t, NextQuad);
   19296          989 :   PopBool (&t, &f);
   19297          989 :   BackPatch (f, NextQuad);
   19298          989 :   BackPatch (t, NextQuad);
   19299          989 :   M2Quads_PopT (&e1);
   19300          989 :   M2CaseList_PopCase ();
   19301          989 : }
   19302              : 
   19303              : 
   19304              : /*
   19305              :    BuildCaseCheck - builds the case checking code to ensure that
   19306              :                     the program does not need an else clause at runtime.
   19307              :                     The stack is unaltered.
   19308              : */
   19309              : 
   19310          491 : extern "C" void M2Quads_BuildCaseCheck (void)
   19311              : {
   19312          491 :   BuildError (M2Range_InitNoElseRangeCheck ());
   19313          491 : }
   19314              : 
   19315              : 
   19316              : /*
   19317              :    BuildNulParam - Builds a nul parameter on the stack.
   19318              :                    The Stack:
   19319              : 
   19320              :                    Entry             Exit
   19321              : 
   19322              :                                                     <- Ptr
   19323              :                    Empty             +------------+
   19324              :                                      | 0          |
   19325              :                                      |------------|
   19326              : */
   19327              : 
   19328        18046 : extern "C" void M2Quads_BuildNulParam (void)
   19329              : {
   19330        18046 :   M2Quads_PushT (static_cast<unsigned int> (0));
   19331        18046 : }
   19332              : 
   19333              : 
   19334              : /*
   19335              :    BuildProcedureCall - builds a procedure call.
   19336              :                         Although this procedure does not directly
   19337              :                         destroy the procedure parameters, it calls
   19338              :                         routine which will manipulate the stack and
   19339              :                         so the entry and exit states of the stack are shown.
   19340              : 
   19341              :                         The Stack:
   19342              : 
   19343              : 
   19344              :                         Entry                      Exit
   19345              : 
   19346              :                  Ptr ->
   19347              :                         +----------------+
   19348              :                         | NoOfParam      |
   19349              :                         |----------------|
   19350              :                         | Param 1        |
   19351              :                         |----------------|
   19352              :                         | Param 2        |
   19353              :                         |----------------|
   19354              :                         .                .
   19355              :                         .                .
   19356              :                         .                .
   19357              :                         |----------------|
   19358              :                         | Param #        |
   19359              :                         |----------------|
   19360              :                         | ProcSym | Type |         Empty
   19361              :                         |----------------|
   19362              : */
   19363              : 
   19364       177513 : extern "C" void M2Quads_BuildProcedureCall (unsigned int tokno)
   19365              : {
   19366       177513 :   unsigned int NoOfParam;
   19367       177513 :   unsigned int ProcSym;
   19368              : 
   19369       177513 :   M2Quads_PopT (&NoOfParam);
   19370       177513 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   19371       177513 :   M2Quads_PushT (NoOfParam);  /* Compile time stack restored to entry state  */
   19372       177513 :   if ((M2Base_IsPseudoBaseProcedure (ProcSym)) || (M2System_IsPseudoSystemProcedure (ProcSym)))  /* Compile time stack restored to entry state  */
   19373              :     {
   19374        21047 :       M2Quads_DisplayStack ();
   19375        21047 :       ManipulatePseudoCallParameters ();
   19376        21047 :       M2Quads_DisplayStack ();
   19377        21047 :       BuildPseudoProcedureCall (tokno);
   19378        21047 :       M2Quads_DisplayStack ();
   19379              :     }
   19380       156466 :   else if (SymbolTable_IsUnknown (ProcSym))
   19381              :     {
   19382              :       /* avoid dangling else.  */
   19383              :       /* Spellcheck.  */
   19384           30 :       M2MetaError_MetaError1 ((const char *) "{%1Ua} is not recognised as a procedure {%1&s}", 46, ProcSym);
   19385           30 :       M2Quads_PopN (NoOfParam+2);
   19386           30 :       SymbolTable_UnknownReported (ProcSym);
   19387              :     }
   19388              :   else
   19389              :     {
   19390              :       /* avoid dangling else.  */
   19391       156436 :       M2Quads_DisplayStack ();
   19392       156436 :       BuildRealProcedureCall (tokno);
   19393       156430 :       M2Quads_DisplayStack ();
   19394              :     }
   19395       177507 : }
   19396              : 
   19397              : 
   19398              : /*
   19399              :    CheckBuildFunction - checks to see whether ProcSym is a function
   19400              :                         and if so it adds a TempSym value which will
   19401              :                         hold the return value once the function finishes.
   19402              :                         This procedure also generates an error message
   19403              :                         if the user is calling a function and ignoring
   19404              :                         the return result.  The additional TempSym
   19405              :                         is not created if ProcSym is a procedure
   19406              :                         and the stack is unaltered.
   19407              : 
   19408              :                         The Stack:
   19409              : 
   19410              : 
   19411              :                        Entry                      Exit
   19412              : 
   19413              :                 Ptr ->
   19414              : 
   19415              :                                                   +----------------+
   19416              :                                                   | ProcSym | Type |
   19417              :                        +----------------+         |----------------|
   19418              :                        | ProcSym | Type |         | TempSym | Type |
   19419              :                        |----------------|         |----------------|
   19420              : */
   19421              : 
   19422       105741 : extern "C" bool M2Quads_CheckBuildFunction (void)
   19423              : {
   19424       105741 :   unsigned int tokpos;
   19425       105741 :   unsigned int TempSym;
   19426       105741 :   unsigned int ProcSym;
   19427       105741 :   unsigned int Type;
   19428              : 
   19429       105741 :   M2Quads_PopTFtok (&ProcSym, &Type, &tokpos);
   19430       105741 :   if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (Type)))
   19431              :     {
   19432              :       /* avoid dangling else.  */
   19433          684 :       if ((SymbolTable_GetSType (Type)) != SymbolTable_NulSym)
   19434              :         {
   19435            0 :           TempSym = SymbolTable_MakeTemporary (tokpos, SymbolTable_RightValue);
   19436            0 :           SymbolTable_PutVar (TempSym, SymbolTable_GetSType (Type));
   19437            0 :           M2Quads_PushTFtok (TempSym, SymbolTable_GetSType (Type), tokpos);
   19438            0 :           M2Quads_PushTFtok (ProcSym, Type, tokpos);
   19439            0 :           if (! (SymbolTable_IsReturnOptionalAny (Type)))
   19440              :             {
   19441            0 :               M2MetaError_MetaErrorT1 (tokpos, (const char *) "function {%1Ea} is called but its return value is ignored", 57, ProcSym);
   19442              :             }
   19443              :           return true;
   19444              :         }
   19445              :     }
   19446       105057 :   else if ((SymbolTable_IsProcedure (ProcSym)) && (Type != SymbolTable_NulSym))
   19447              :     {
   19448              :       /* avoid dangling else.  */
   19449            0 :       TempSym = SymbolTable_MakeTemporary (tokpos, SymbolTable_RightValue);
   19450            0 :       SymbolTable_PutVar (TempSym, Type);
   19451            0 :       M2Quads_PushTFtok (TempSym, Type, tokpos);
   19452            0 :       M2Quads_PushTFtok (ProcSym, Type, tokpos);
   19453            0 :       if (! (SymbolTable_IsReturnOptionalAny (ProcSym)))
   19454              :         {
   19455            0 :           M2MetaError_MetaErrorT1 (tokpos, (const char *) "function {%1Ea} is called but its return value is ignored", 57, ProcSym);
   19456              :         }
   19457              :       return true;
   19458              :     }
   19459       105741 :   M2Quads_PushTFtok (ProcSym, Type, tokpos);
   19460       105741 :   return false;
   19461              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   19462              :   __builtin_unreachable ();
   19463              : }
   19464              : 
   19465              : 
   19466              : /*
   19467              :    BuildFunctionCall - builds a function call.
   19468              :                        The Stack:
   19469              : 
   19470              : 
   19471              :                        Entry                      Exit
   19472              : 
   19473              :                 Ptr ->
   19474              :                        +----------------+
   19475              :                        | NoOfParam      |
   19476              :                        |----------------|
   19477              :                        | Param 1        |
   19478              :                        |----------------|
   19479              :                        | Param 2        |
   19480              :                        |----------------|
   19481              :                        .                .
   19482              :                        .                .
   19483              :                        .                .
   19484              :                        |----------------|
   19485              :                        | Param #        |                        <- Ptr
   19486              :                        |----------------|         +------------+
   19487              :                        | ProcSym | Type |         | ReturnVar  |
   19488              :                        |----------------|         |------------|
   19489              : */
   19490              : 
   19491       107705 : extern "C" void M2Quads_BuildFunctionCall (bool ConstExpr)
   19492              : {
   19493       107705 :   unsigned int paramtok;
   19494       107705 :   unsigned int combinedtok;
   19495       107705 :   unsigned int functok;
   19496       107705 :   unsigned int NoOfParam;
   19497       107705 :   unsigned int ProcSym;
   19498              : 
   19499       107705 :   M2Quads_PopT (&NoOfParam);
   19500       107705 :   functok = OperandTtok (NoOfParam+1);
   19501       107705 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   19502       107705 :   ProcSym = PCSymBuild_SkipConst (ProcSym);
   19503       107705 :   M2Quads_PushT (NoOfParam);
   19504              :   /* Compile time stack restored to entry state.  */
   19505       107705 :   if (SymbolTable_IsUnknown (ProcSym))
   19506              :     {
   19507              :       /* Spellcheck.  */
   19508            6 :       paramtok = OperandTtok (1);
   19509            6 :       combinedtok = M2LexBuf_MakeVirtual2Tok (functok, paramtok);
   19510            6 :       M2MetaError_MetaErrorT1 (functok, (const char *) "procedure function {%1Ea} is undefined {%1&s}", 45, ProcSym);
   19511            6 :       SymbolTable_UnknownReported (ProcSym);
   19512            6 :       M2Quads_PopN (NoOfParam+2);
   19513              :       /* Fake return value to continue compiling.  */
   19514            6 :       M2Quads_PushT (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym));
   19515              :     }
   19516       107699 :   else if (SymbolTable_IsAModula2Type (ProcSym))
   19517              :     {
   19518              :       /* avoid dangling else.  */
   19519         2544 :       ManipulatePseudoCallParameters ();
   19520         2544 :       BuildTypeCoercion (ConstExpr);
   19521              :     }
   19522       105155 :   else if ((M2System_IsPseudoSystemFunction (ProcSym)) || (M2Base_IsPseudoBaseFunction (ProcSym)))
   19523              :     {
   19524              :       /* avoid dangling else.  */
   19525        42871 :       ManipulatePseudoCallParameters ();
   19526        42871 :       BuildPseudoFunctionCall (ConstExpr);
   19527              :     }
   19528              :   else
   19529              :     {
   19530              :       /* avoid dangling else.  */
   19531        62284 :       BuildRealFunctionCall (functok, ConstExpr);
   19532              :     }
   19533       107675 : }
   19534              : 
   19535              : 
   19536              : /*
   19537              :    BuildConstFunctionCall - builds a function call and checks that this function can be
   19538              :                             called inside a ConstExpression.
   19539              : 
   19540              :                             The Stack:
   19541              : 
   19542              : 
   19543              :                             Entry                      Exit
   19544              : 
   19545              :                      Ptr ->
   19546              :                             +----------------+
   19547              :                             | NoOfParam      |
   19548              :                             |----------------|
   19549              :                             | Param 1        |
   19550              :                             |----------------|
   19551              :                             | Param 2        |
   19552              :                             |----------------|
   19553              :                             .                .
   19554              :                             .                .
   19555              :                             .                .
   19556              :                             |----------------|
   19557              :                             | Param #        |                        <- Ptr
   19558              :                             |----------------|         +------------+
   19559              :                             | ProcSym | Type |         | ReturnVar  |
   19560              :                             |----------------|         |------------|
   19561              : 
   19562              : */
   19563              : 
   19564         7477 : extern "C" void M2Quads_BuildConstFunctionCall (void)
   19565              : {
   19566         7477 :   unsigned int functok;
   19567         7477 :   unsigned int combinedtok;
   19568         7477 :   unsigned int paramtok;
   19569         7477 :   unsigned int ConstExpression;
   19570         7477 :   unsigned int NoOfParam;
   19571         7477 :   unsigned int ProcSym;
   19572              : 
   19573         7477 :   M2Quads_DisplayStack ();
   19574         7477 :   M2Quads_PopT (&NoOfParam);
   19575         7477 :   ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   19576         7477 :   functok = OperandTtok (NoOfParam+1);
   19577         7477 :   if (M2Options_CompilerDebugging)
   19578              :     {
   19579            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));
   19580              :     }
   19581              :   /* ErrorStringAt (InitString ('constant function'), functok).  */
   19582         7477 :   M2Quads_PushT (NoOfParam);
   19583         7477 :   if ((ProcSym != M2Base_Convert) && (((M2Base_IsPseudoBaseFunction (ProcSym)) || (M2System_IsPseudoSystemFunctionConstExpression (ProcSym))) || ((SymbolTable_IsProcedure (ProcSym)) && (SymbolTable_IsProcedureBuiltin (ProcSym)))))
   19584              :     {
   19585         7345 :       M2Quads_BuildFunctionCall (true);
   19586              :     }
   19587              :   else
   19588              :     {
   19589          132 :       if (SymbolTable_IsAModula2Type (ProcSym))
   19590              :         {
   19591              :           /* Type conversion.  */
   19592          132 :           if (NoOfParam == 1)
   19593              :             {
   19594          132 :               ConstExpression = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
   19595          132 :               paramtok = OperandTtok (NoOfParam+1);
   19596          132 :               M2Quads_PopN (NoOfParam+2);
   19597              :               /* Build macro: CONVERT( ProcSym, ConstExpression ).  */
   19598          132 :               M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
   19599          132 :               M2Quads_PushTtok (ProcSym, functok);
   19600          132 :               M2Quads_PushTtok (ConstExpression, paramtok);
   19601          132 :               M2Quads_PushT (static_cast<unsigned int> (2));  /* Two parameters.  */
   19602          132 :               BuildConvertFunction (M2Base_Convert, true);  /* Two parameters.  */
   19603              :             }
   19604              :           else
   19605              :             {
   19606            0 :               M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}a constant type conversion can only have one argument", 57);
   19607              :             }
   19608              :         }
   19609              :       else
   19610              :         {
   19611              :           /* Error issue message and fake return stack.  */
   19612            0 :           if (M2Options_Iso)
   19613              :             {
   19614            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);
   19615              :             }
   19616              :           else
   19617              :             {
   19618            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);
   19619              :             }
   19620            0 :           if (NoOfParam > 0)
   19621              :             {
   19622            0 :               paramtok = OperandTtok (NoOfParam+1);
   19623            0 :               combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
   19624              :             }
   19625              :           else
   19626              :             {
   19627            0 :               combinedtok = functok;
   19628              :             }
   19629            0 :           M2Quads_PopN (NoOfParam+2);
   19630            0 :           M2Quads_PushT (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym));  /* Fake return value to continue compiling.  */
   19631              :         }
   19632              :     }
   19633         7477 : }
   19634              : 
   19635              : 
   19636              : /*
   19637              :    BuildBooleanVariable - tests to see whether top of stack is a boolean
   19638              :                           conditional and if so it converts it into a boolean
   19639              :                           variable.
   19640              : */
   19641              : 
   19642       359048 : extern "C" void M2Quads_BuildBooleanVariable (void)
   19643              : {
   19644       359048 :   if (IsBoolean (1))
   19645              :     {
   19646         7228 :       ConvertBooleanToVariable (OperandTtok (1), 1);
   19647              :     }
   19648       359048 : }
   19649              : 
   19650              : 
   19651              : /*
   19652              :    BuildModuleStart - starts current module scope.
   19653              : */
   19654              : 
   19655        84805 : extern "C" void M2Quads_BuildModuleStart (unsigned int tok)
   19656              : {
   19657        84805 :   GenQuadO (tok, M2Quads_ModuleScopeOp, tok, (unsigned int ) (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()))), SymbolTable_GetCurrentModule (), false);
   19658        84805 : }
   19659              : 
   19660              : 
   19661              : /*
   19662              :    BuildProcedureStart - Builds start of the procedure. Generates a
   19663              :                          quadruple which indicated the start of
   19664              :                          this procedure declarations scope.
   19665              :                          The Stack is expected to contain:
   19666              : 
   19667              : 
   19668              :                          Entry                   Exit
   19669              :                          =====                   ====
   19670              : 
   19671              :                  Ptr ->                                       <- Ptr
   19672              :                         +------------+          +-----------+
   19673              :                         | ProcSym    |          | ProcSym   |
   19674              :                         |------------|          |-----------|
   19675              :                         | Name       |          | Name      |
   19676              :                         |------------|          |-----------|
   19677              : 
   19678              : 
   19679              :                         Quadruples:
   19680              : 
   19681              :                         q   ProcedureScopeOp  Line#  Scope  ProcSym
   19682              : */
   19683              : 
   19684        82774 : extern "C" void M2Quads_BuildProcedureStart (void)
   19685              : {
   19686        82774 :   unsigned int ProcSym;
   19687              : 
   19688        82774 :   M2Quads_PopT (&ProcSym);
   19689        82774 :   M2Debug_Assert (SymbolTable_IsProcedure (ProcSym));
   19690        82774 :   SymbolTable_PutProcedureScopeQuad (ProcSym, NextQuad);
   19691        82774 :   GenQuad (M2Quads_ProcedureScopeOp, M2LexBuf_GetPreviousTokenLineNo (), SymbolTable_GetScope (ProcSym), ProcSym);
   19692        82774 :   M2Quads_PushT (ProcSym);
   19693        82774 : }
   19694              : 
   19695              : 
   19696              : /*
   19697              :    BuildProcedureBegin - determines the start of the BEGIN END block of
   19698              :                          the procedure.
   19699              :                          The Stack is expected to contain:
   19700              : 
   19701              : 
   19702              :                          Entry                   Exit
   19703              :                          =====                   ====
   19704              : 
   19705              :                  Ptr ->                                       <- Ptr
   19706              :                         +------------+          +-----------+
   19707              :                         | ProcSym    |          | ProcSym   |
   19708              :                         |------------|          |-----------|
   19709              :                         | Name       |          | Name      |
   19710              :                         |------------|          |-----------|
   19711              : 
   19712              : 
   19713              :                         Quadruples:
   19714              : 
   19715              :                         q   NewLocalVarOp  TokenNo(BEGIN)  _  ProcSym
   19716              : */
   19717              : 
   19718        82762 : extern "C" void M2Quads_BuildProcedureBegin (void)
   19719              : {
   19720        82762 :   unsigned int ProcSym;
   19721              : 
   19722        82762 :   M2Quads_PopT (&ProcSym);
   19723        82762 :   M2Debug_Assert (SymbolTable_IsProcedure (ProcSym));
   19724        82762 :   SymbolTable_PutProcedureStartQuad (ProcSym, NextQuad);
   19725        82762 :   SymbolTable_PutProcedureBegin (ProcSym, M2LexBuf_GetTokenNo ());
   19726        82762 :   GenQuad (M2Quads_NewLocalVarOp, M2LexBuf_GetTokenNo (), SymbolTable_GetScope (ProcSym), ProcSym);
   19727        82762 :   CurrentProc = ProcSym;
   19728        82762 :   M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
   19729        82762 :   M2Quads_PushT (ProcSym);
   19730        82762 :   CheckVariablesAt (ProcSym);
   19731        82762 :   CheckNeedPriorityBegin (M2LexBuf_GetTokenNo (), ProcSym, SymbolTable_GetCurrentModule ());
   19732        82762 :   M2StackWord_PushWord (TryStack, NextQuad);
   19733        82762 :   M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
   19734        82762 :   if (SymbolTable_HasExceptionBlock (ProcSym))
   19735              :     {
   19736          168 :       GenQuad (M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
   19737              :     }
   19738        82762 : }
   19739              : 
   19740              : 
   19741              : /*
   19742              :    BuildProcedureEnd - Builds end of the procedure. Destroys space for
   19743              :                        the local variables.
   19744              :                        The Stack is expected to contain:
   19745              : 
   19746              : 
   19747              :                        Entry                   Exit
   19748              :                        =====                   ====
   19749              : 
   19750              :                 Ptr ->                                       <- Ptr
   19751              :                        +------------+          +-----------+
   19752              :                        | ProcSym    |          | ProcSym   |
   19753              :                        |------------|          |-----------|
   19754              :                        | Name       |          | Name      |
   19755              :                        |------------|          |-----------|
   19756              : 
   19757              : 
   19758              :                        Quadruples:
   19759              : 
   19760              :                        q   KillLocalVarOp  TokenNo(END)  _  ProcSym
   19761              : */
   19762              : 
   19763        82730 : extern "C" void M2Quads_BuildProcedureEnd (void)
   19764              : {
   19765        82730 :   unsigned int tok;
   19766        82730 :   unsigned int ProcSym;
   19767              : 
   19768        82730 :   M2Quads_PopTtok (&ProcSym, &tok);
   19769        82730 :   if (SymbolTable_HasExceptionBlock (ProcSym))
   19770              :     {
   19771          168 :       BuildRTExceptLeave (tok, true);
   19772          168 :       GenQuad (M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
   19773              :     }
   19774        82730 :   if ((SymbolTable_GetSType (ProcSym)) != SymbolTable_NulSym)
   19775              :     {
   19776        20871 :       BuildError (M2Range_InitNoReturnRangeCheck ());
   19777              :     }
   19778        82730 :   BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
   19779        82730 :   CheckNeedPriorityEnd (tok, ProcSym, SymbolTable_GetCurrentModule ());
   19780        82730 :   CurrentProc = SymbolTable_NulSym;
   19781        82730 :   SymbolTable_PutProcedureEnd (ProcSym, (M2LexBuf_GetTokenNo ())-1);  /* --fixme--  */
   19782        82730 :   GenQuad (M2Quads_KillLocalVarOp, (M2LexBuf_GetTokenNo ())-1, SymbolTable_NulSym, ProcSym);  /* --fixme--  */
   19783        82730 :   SymbolTable_PutProcedureEndQuad (ProcSym, NextQuad);
   19784        82730 :   GenQuad (M2Quads_ReturnOp, SymbolTable_NulSym, SymbolTable_NulSym, ProcSym);
   19785        82730 :   CheckFunctionReturn (ProcSym);
   19786        82730 :   CheckVariablesInBlock (ProcSym);
   19787              :   /* Call PutProcedureEndQuad so that any runtime procedure will be
   19788              :       seen as defined even if it not seen during pass 2 (which will also
   19789              :       call PutProcedureEndQuad).  */
   19790        82730 :   SymbolTable_PutProcedureParametersDefined (ProcSym, SymbolTable_ProperProcedure);
   19791        82730 :   SymbolTable_PutProcedureDefined (ProcSym, SymbolTable_ProperProcedure);
   19792        82730 :   M2StackWord_RemoveTop (CatchStack);
   19793        82730 :   M2StackWord_RemoveTop (TryStack);
   19794        82730 :   M2Quads_PushT (ProcSym);
   19795        82730 : }
   19796              : 
   19797              : 
   19798              : /*
   19799              :    BuildReturn - Builds the Return part of the procedure.
   19800              :                  tokreturn is the location of the RETURN keyword.
   19801              :                  The Stack is expected to contain:
   19802              : 
   19803              : 
   19804              :                  Entry                   Exit
   19805              :                  =====                   ====
   19806              : 
   19807              :          Ptr ->
   19808              :                  +------------+
   19809              :                  | e1         |          Empty
   19810              :                  |------------|
   19811              : */
   19812              : 
   19813        30655 : extern "C" void M2Quads_BuildReturn (unsigned int tokreturn)
   19814              : {
   19815        30655 :   unsigned int tokcombined;
   19816        30655 :   unsigned int tokexpr;
   19817        30655 :   unsigned int e1;
   19818        30655 :   unsigned int t1;
   19819        30655 :   unsigned int t;
   19820        30655 :   unsigned int f;
   19821        30655 :   unsigned int Des;
   19822              : 
   19823        30655 :   if (IsBoolean (1))
   19824              :     {
   19825         1790 :       PopBooltok (&t, &f, &tokexpr);
   19826              :       /* Des will be a boolean type  */
   19827         1790 :       Des = SymbolTable_MakeTemporary (tokexpr, SymbolTable_RightValue);
   19828         1790 :       SymbolTable_PutVar (Des, M2Base_Boolean);
   19829         1790 :       M2Quads_PushTFtok (Des, M2Base_Boolean, tokexpr);
   19830         1790 :       PushBooltok (t, f, tokexpr);
   19831         1790 :       BuildAssignmentWithoutBounds (tokreturn, false, true);
   19832         1790 :       M2Quads_PushTFtok (Des, M2Base_Boolean, tokexpr);
   19833              :     }
   19834        30655 :   M2Quads_PopTFtok (&e1, &t1, &tokexpr);
   19835        30655 :   tokcombined = M2LexBuf_MakeVirtualTok (tokreturn, tokreturn, tokexpr);
   19836        30655 :   if (e1 != SymbolTable_NulSym)
   19837              :     {
   19838              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   19839              :       /* Check we are in a procedure scope and that the procedure has a return type.  */
   19840        29811 :       if (CurrentProc == SymbolTable_NulSym)
   19841              :         {
   19842            6 :           M2MetaError_MetaErrorT0 (tokcombined, (const char *) "{%1E} attempting to return a value when not in a procedure scope", 64);
   19843              :         }
   19844        29805 :       else if ((SymbolTable_GetSType (CurrentProc)) == SymbolTable_NulSym)
   19845              :         {
   19846              :           /* avoid dangling else.  */
   19847            6 :           M2MetaError_MetaErrorT1 (tokcombined, (const char *) "attempting to return a value from procedure {%1Ea} which does not have a return type", 84, CurrentProc);
   19848              :         }
   19849              :       else
   19850              :         {
   19851              :           /* avoid dangling else.  */
   19852        29799 :           BuildReturnLower (tokcombined, tokexpr, e1, t1);
   19853              :         }
   19854              :     }
   19855        30655 :   GenQuadO (tokcombined, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PopWord (ReturnStack), false);
   19856        30655 :   M2StackWord_PushWord (ReturnStack, NextQuad-1);
   19857        30655 : }
   19858              : 
   19859              : 
   19860              : /*
   19861              :    BuildModulePriority - assigns the current module with a priority
   19862              :                          from the top of stack.
   19863              : 
   19864              :                          Entry                   Exit
   19865              :                          =====                   ====
   19866              : 
   19867              : 
   19868              :                   Ptr ->                         Empty
   19869              :                          +------------+
   19870              :                          | Priority   |
   19871              :                          |------------|
   19872              : */
   19873              : 
   19874           38 : extern "C" void M2Quads_BuildModulePriority (void)
   19875              : {
   19876           38 :   unsigned int Priority;
   19877              : 
   19878           38 :   M2Quads_PopT (&Priority);
   19879           38 :   SymbolTable_PutPriority (SymbolTable_GetCurrentModule (), Priority);
   19880           38 : }
   19881              : 
   19882              : 
   19883              : /*
   19884              :    StartBuildWith - performs the with statement.
   19885              :                     The Stack:
   19886              : 
   19887              :                     Entry                    Exit
   19888              : 
   19889              :                     +------------+
   19890              :                     | Sym | Type |           Empty
   19891              :                     |------------|
   19892              : */
   19893              : 
   19894         5971 : extern "C" void M2Quads_StartBuildWith (unsigned int withTok)
   19895              : {
   19896         5971 :   unsigned int tok;
   19897         5971 :   unsigned int Sym;
   19898         5971 :   unsigned int Type;
   19899         5971 :   unsigned int Ref;
   19900              : 
   19901         5971 :   DebugLocation (static_cast<unsigned int> (M2Reserved_withtok), (const char *) "with", 4);
   19902         5971 :   BuildStmtNoteTok (withTok);
   19903         5971 :   M2Quads_DisplayStack ();
   19904         5971 :   M2Quads_PopTFtok (&Sym, &Type, &tok);
   19905         5971 :   DebugLocation (tok, (const char *) "expression", 10);
   19906         5971 :   Type = SymbolTable_SkipType (Type);
   19907         5971 :   if (Type == SymbolTable_NulSym)
   19908              :     {
   19909            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);
   19910              :     }
   19911              :   else
   19912              :     {
   19913         5965 :       Ref = SymbolTable_MakeTemporary (tok, SymbolTable_LeftValue);
   19914         5965 :       SymbolTable_PutVar (Ref, Type);
   19915         5965 :       if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
   19916              :         {
   19917              :           /* Copy LeftValue.  */
   19918         5660 :           GenQuadO (tok, M2Quads_BecomesOp, Ref, SymbolTable_NulSym, Sym, true);
   19919              :         }
   19920              :       else
   19921              :         {
   19922              :           /* Calculate the address of Sym.  */
   19923          305 :           GenQuadO (tok, M2Quads_AddrOp, Ref, SymbolTable_NulSym, Sym, true);
   19924              :         }
   19925         5965 :       PushWith (Sym, Type, Ref, tok);
   19926         5965 :       DebugLocation (tok, (const char *) "with ref", 8);
   19927         5965 :       if (! (SymbolTable_IsRecord (Type)))
   19928              :         {
   19929            0 :           M2MetaError_MetaErrorT1 (tok, (const char *) "the {%kWITH} statement requires that {%1Ea} {%1d} be of a {%kRECORD} {%1tsa:type rather than {%1tsa}}", 101, Sym);
   19930              :         }
   19931         5965 :       SymbolTable_StartScope (Type);
   19932              :     }
   19933         5965 :   M2StackSpell_Push (Type);
   19934         5965 :   M2Quads_DisplayStack ();
   19935         5965 : }
   19936              : 
   19937              : 
   19938              : /*
   19939              :    EndBuildWith - terminates the innermost with scope.
   19940              : */
   19941              : 
   19942         5965 : extern "C" void M2Quads_EndBuildWith (void)
   19943              : {
   19944         5965 :   M2Quads_DisplayStack ();
   19945         5965 :   SymbolTable_EndScope ();
   19946         5965 :   PopWith ();
   19947         5965 :   M2StackSpell_Pop ();
   19948         5965 :   M2Quads_DisplayStack ();
   19949         5965 : }
   19950              : 
   19951              : 
   19952              : /*
   19953              :    CheckWithReference - performs the with statement.
   19954              :                         The Stack:
   19955              : 
   19956              :                         Entry                    Exit
   19957              : 
   19958              :                         +------------+           +------------+
   19959              :                         | Sym | Type |           | Sym | Type |
   19960              :                         |------------|           |------------|
   19961              : */
   19962              : 
   19963       690141 : extern "C" void M2Quads_CheckWithReference (void)
   19964              : {
   19965       690141 :   M2Quads_WithFrame f;
   19966       690141 :   unsigned int tokpos;
   19967       690141 :   unsigned int i;
   19968       690141 :   unsigned int n;
   19969       690141 :   unsigned int rw;
   19970       690141 :   unsigned int Sym;
   19971       690141 :   unsigned int Type;
   19972              : 
   19973       690141 :   n = M2StackAddress_NoOfItemsInStackAddress (WithStack);
   19974       690141 :   if ((n > 0) && ! SuppressWith)
   19975              :     {
   19976       102657 :       PopTFrwtok (&Sym, &Type, &rw, &tokpos);
   19977       102657 :       M2Debug_Assert (tokpos != M2LexBuf_UnknownTokenNo);
   19978       102657 :       if (SymbolTable_IsUnknown (Sym))
   19979              :         {
   19980            6 :           M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1ad} is unknown {%1&s}", 24, Sym);
   19981            6 :           SymbolTable_UnknownReported (Sym);
   19982              :         }
   19983              :       else
   19984              :         {
   19985              :           /* Inner WITH always has precedence.  */
   19986              :           i = 1;  /* top of stack  */
   19987              :           /* WriteString('Checking for a with') ;  */
   19988       217989 :           while (i <= n)
   19989              :             {
   19990       115338 :               f = static_cast<M2Quads_WithFrame> (M2StackAddress_PeepAddress (WithStack, i));
   19991       115338 :               if ((SymbolTable_IsRecordField (Sym)) && ((SymbolTable_GetRecord (SymbolTable_GetParent (Sym))) == f->RecordType))
   19992              :                 {
   19993        30024 :                   if (SymbolTable_IsUnused (Sym))
   19994              :                     {
   19995            0 :                       M2MetaError_MetaError1 ((const char *) "record field {%1Dad} was declared as unused by a pragma", 55, Sym);
   19996              :                     }
   19997              :                   /* Fake a RecordSym.op  */
   19998        30024 :                   PushTFrwtok (f->RecordRef, f->RecordType, f->rw, f->RecordTokPos);
   19999        30024 :                   M2Quads_PushTFtok (Sym, Type, tokpos);
   20000        30024 :                   BuildAccessWithField ();
   20001        30024 :                   PopTFrw (&Sym, &Type, &f->rw);
   20002        30024 :                   i = n+1;  /* Finish loop.  */
   20003              :                 }
   20004              :               else
   20005              :                 {
   20006        85314 :                   i += 1;
   20007              :                 }
   20008              :             }
   20009              :         }
   20010       102657 :       PushTFrwtok (Sym, Type, rw, tokpos);
   20011              :     }
   20012       690141 : }
   20013              : 
   20014              : 
   20015              : /*
   20016              :    BuildDesignatorRecord - Builds the record referencing.
   20017              :                            The Stack is expected to contain:
   20018              : 
   20019              : 
   20020              :                            Entry                   Exit
   20021              :                            =====                   ====
   20022              : 
   20023              :                    Ptr ->
   20024              :                            +--------------+
   20025              :                            | n            |
   20026              :                            |--------------|
   20027              :                            | fld1 | type1 |
   20028              :                            |--------------|
   20029              :                            .              .
   20030              :                            .              .
   20031              :                            .              .
   20032              :                            |--------------|
   20033              :                            | fldn | typen |                        <- Ptr
   20034              :                            |--------------|        +-------------+
   20035              :                            | Sym  | Type  |        | S    | type1|
   20036              :                            |--------------|        |-------------|
   20037              : */
   20038              : 
   20039       115871 : extern "C" void M2Quads_BuildDesignatorRecord (unsigned int dottok)
   20040              : {
   20041       115871 :   unsigned int RecordTok;
   20042       115871 :   unsigned int FieldTok;
   20043       115871 :   unsigned int combinedtok;
   20044       115871 :   unsigned int n;
   20045       115871 :   unsigned int rw;
   20046       115871 :   unsigned int Field;
   20047       115871 :   unsigned int FieldType;
   20048       115871 :   unsigned int RecordSym;
   20049       115871 :   unsigned int Res;
   20050              : 
   20051       115871 :   M2Quads_PopT (&n);
   20052       115871 :   RecordSym = static_cast<unsigned int> (M2Quads_OperandT (n+1));
   20053              :   /* RecordType could be found by:  SkipType (OperandF (n+1)).  */
   20054       115871 :   RecordTok = static_cast<unsigned int> (M2Quads_OperandTok (n+1));
   20055       115871 :   rw = static_cast<unsigned int> (OperandMergeRW (n+1));
   20056       115871 :   M2Debug_Assert (SymbolTable_IsLegal (rw));
   20057       115871 :   Field = static_cast<unsigned int> (M2Quads_OperandT (n));
   20058       115871 :   FieldType = SymbolTable_SkipType (M2Quads_OperandF (n));
   20059       115871 :   FieldTok = static_cast<unsigned int> (M2Quads_OperandTok (n));
   20060       115871 :   combinedtok = M2LexBuf_MakeVirtualTok (dottok, RecordTok, FieldTok);
   20061       115871 :   if (n > 1)
   20062              :     {
   20063            0 :       M2Error_InternalError ((const char *) "not expecting to see n>1", 24);
   20064              :     }
   20065       115871 :   if (SymbolTable_IsUnused (Field))
   20066              :     {
   20067            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);
   20068              :     }
   20069       115871 :   Res = SymbolTable_MakeComponentRef (SymbolTable_MakeComponentRecord (combinedtok, SymbolTable_RightValue, RecordSym), Field);
   20070       115871 :   SymbolTable_PutVarConst (Res, IsReadOnly (RecordSym));
   20071       115871 :   GenQuadO (combinedtok, M2Quads_RecordFieldOp, Res, RecordSym, Field, false);
   20072       115871 :   M2Quads_PopN (n+1);
   20073       115871 :   PushTFrwtok (Res, FieldType, rw, combinedtok);
   20074       115871 : }
   20075              : 
   20076              : 
   20077              : /*
   20078              :    BuildDesignatorArray - Builds the array referencing.
   20079              :                           The purpose of this procedure is to work out
   20080              :                           whether the DesignatorArray is a constant string or
   20081              :                           dynamic array/static array and to call the appropriate
   20082              :                           BuildRoutine.
   20083              : 
   20084              :                           The Stack is expected to contain:
   20085              : 
   20086              :                           Entry                   Exit
   20087              :                           =====                   ====
   20088              : 
   20089              :                   Ptr ->
   20090              :                           +--------------+
   20091              :                           | e            |                        <- Ptr
   20092              :                           |--------------|        +------------+
   20093              :                           | Sym  | Type  |        | S    | T   |
   20094              :                           |--------------|        |------------|
   20095              : */
   20096              : 
   20097        56486 : extern "C" void M2Quads_BuildDesignatorArray (void)
   20098              : {
   20099        56486 :   if ((SymbolTable_IsConst (M2Quads_OperandT (2))) && (SymbolTable_IsConstString (M2Quads_OperandT (2))))
   20100              :     {
   20101            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));
   20102            6 :       BuildDesignatorError ((const char *) "bad array access", 16);
   20103              :     }
   20104              :   else
   20105              :     {
   20106        56480 :       BuildDesignatorArrayStaticDynamic ();
   20107              :     }
   20108        56480 : }
   20109              : 
   20110              : 
   20111              : /*
   20112              :    BuildDesignatorPointer - Builds a pointer reference.
   20113              :                             The Stack is expected to contain:
   20114              : 
   20115              : 
   20116              :                             Entry                   Exit
   20117              :                             =====                   ====
   20118              : 
   20119              :                     Ptr ->                                           <- Ptr
   20120              :                             +--------------+        +--------------+
   20121              :                             | Sym1  | Type1|        | Sym2  | Type2|
   20122              :                             |--------------|        |--------------|
   20123              : */
   20124              : 
   20125        19929 : extern "C" void M2Quads_BuildDesignatorPointer (unsigned int ptrtok)
   20126              : {
   20127        19929 :   unsigned int combinedtok;
   20128        19929 :   unsigned int destok;
   20129        19929 :   unsigned int rw;
   20130        19929 :   unsigned int Sym1;
   20131        19929 :   unsigned int Type1;
   20132        19929 :   unsigned int Sym2;
   20133        19929 :   unsigned int Type2;
   20134              : 
   20135        19929 :   PopTFrwtok (&Sym1, &Type1, &rw, &destok);
   20136        19929 :   DebugLocation (destok, (const char *) "des ptr expression", 18);
   20137        19929 :   Type1 = SymbolTable_SkipType (Type1);
   20138        19929 :   if (Type1 == SymbolTable_NulSym)
   20139              :     {
   20140            0 :       M2MetaError_MetaErrorT1 (ptrtok, (const char *) "{%1ad} has no type and therefore cannot be dereferenced by ^", 60, Sym1);
   20141              :     }
   20142        19929 :   else if (SymbolTable_IsUnknown (Sym1))
   20143              :     {
   20144              :       /* avoid dangling else.  */
   20145              :       /* Spellcheck.  */
   20146            0 :       M2MetaError_MetaError1 ((const char *) "{%1EMad} is undefined and therefore {%1ad}^ cannot be resolved {%1&s}", 69, Sym1);
   20147            0 :       SymbolTable_UnknownReported (Sym1);
   20148              :     }
   20149              :   else
   20150              :     {
   20151              :       /* avoid dangling else.  */
   20152        19929 :       combinedtok = M2LexBuf_MakeVirtual2Tok (destok, ptrtok);
   20153        19929 :       if (SymbolTable_IsPointer (Type1))
   20154              :         {
   20155        19927 :           Type2 = SymbolTable_GetSType (Type1);
   20156        19927 :           Sym2 = SymbolTable_MakeTemporary (ptrtok, SymbolTable_LeftValue);
   20157              :           /* 
   20158              :           Ok must reference by address
   20159              :           - but we contain the type of the referenced entity
   20160              :   */
   20161        19927 :           MarkAsRead (rw);
   20162        19927 :           SymbolTable_PutVarPointerCheck (Sym1, true);
   20163        19927 :           CheckPointerThroughNil (ptrtok, Sym1);
   20164        19927 :           if ((SymbolTable_GetMode (Sym1)) == SymbolTable_LeftValue)
   20165              :             {
   20166          510 :               rw = SymbolTable_NulSym;
   20167          510 :               SymbolTable_PutLeftValueFrontBackType (Sym2, Type2, Type1);
   20168          510 :               GenQuadO (ptrtok, M2Quads_IndrXOp, Sym2, Type1, Sym1, false);  /* Sym2 := *Sym1.  */
   20169              :             }
   20170              :           else
   20171              :             {
   20172        19417 :               SymbolTable_PutLeftValueFrontBackType (Sym2, Type2, SymbolTable_NulSym);
   20173        19417 :               GenQuadO (ptrtok, M2Quads_BecomesOp, Sym2, SymbolTable_NulSym, Sym1, false);  /* Sym2 :=  Sym1.  */
   20174              :             }
   20175              :           /* We should check this for Sym2 later on (pointer via NIL).  */
   20176        19927 :           SymbolTable_PutVarPointerCheck (Sym2, true);
   20177        19927 :           PushTFrwtok (Sym2, Type2, rw, combinedtok);
   20178        19927 :           DebugLocation (combinedtok, (const char *) "pointer expression", 18);
   20179              :         }
   20180            2 :       else if ((SymbolTable_IsHiddenType (Type1)) && ((SymbolTable_GetModuleScope (Type1)) != (SymbolTable_GetCurrentModuleScope ())))
   20181              :         {
   20182              :           /* avoid dangling else.  */
   20183            2 :           M2MetaError_MetaErrorT1 (ptrtok, (const char *) "{%1Ead} is declared with an opaque type from a different module and cannot be dereferenced", 90, Sym1);
   20184            2 :           MarkAsRead (rw);
   20185            2 :           BuildDesignatorPointerError (Type1, rw, combinedtok, (const char *) "bad opaque pointer dereference", 30);
   20186              :         }
   20187              :       else
   20188              :         {
   20189              :           /* avoid dangling else.  */
   20190            0 :           M2MetaError_MetaError2 ((const char *) "{%1Ead} is not a pointer type but a {%2dv}", 42, Sym1, Type1);
   20191            0 :           MarkAsRead (rw);
   20192            0 :           BuildDesignatorPointerError (Type1, rw, combinedtok, (const char *) "bad pointer dereference", 23);
   20193              :         }
   20194              :     }
   20195        19929 : }
   20196              : 
   20197              : 
   20198              : /*
   20199              :    BuildNulExpression - Builds a nul expression on the stack.
   20200              :                         The Stack:
   20201              : 
   20202              :                         Entry             Exit
   20203              : 
   20204              :                                                          <- Ptr
   20205              :                         Empty             +------------+
   20206              :                                           | NulSym     |
   20207              :                                           |------------|
   20208              :    tokpos is the position of the RETURN token.
   20209              : */
   20210              : 
   20211          844 : extern "C" void M2Quads_BuildNulExpression (unsigned int tokpos)
   20212              : {
   20213          844 :   M2Quads_PushTtok (static_cast<unsigned int> (SymbolTable_NulSym), tokpos);
   20214          844 : }
   20215              : 
   20216              : 
   20217              : /*
   20218              :    BuildSetStart - Pushes a Bitset type on the stack.
   20219              : 
   20220              :                       The Stack:
   20221              : 
   20222              :                       Entry             Exit
   20223              : 
   20224              :                Ptr ->                                        <- Ptr
   20225              : 
   20226              :                       Empty             +--------------+
   20227              :                                         | Bitset       |
   20228              :                                         |--------------|
   20229              : */
   20230              : 
   20231            0 : extern "C" void M2Quads_BuildSetStart (unsigned int tokpos)
   20232              : {
   20233            0 :   M2Quads_PushTtok (M2Bitset_Bitset, tokpos);
   20234            0 : }
   20235              : 
   20236              : 
   20237              : /*
   20238              :    BuildSetEnd - pops the set value and type from the stack
   20239              :                  and pushes the value,type pair.
   20240              : 
   20241              :                     Entry                   Exit
   20242              : 
   20243              :              Ptr ->
   20244              :                     +--------------+
   20245              :                     | Set Value    |                         <- Ptr
   20246              :                     |--------------|        +--------------+
   20247              :                     | Set Type     |        | Value | Type |
   20248              :                     |--------------|        |--------------|
   20249              : */
   20250              : 
   20251            0 : extern "C" void M2Quads_BuildSetEnd (void)
   20252              : {
   20253            0 :   unsigned int valuepos;
   20254            0 :   unsigned int typepos;
   20255            0 :   unsigned int combined;
   20256            0 :   unsigned int value;
   20257            0 :   unsigned int type;
   20258              : 
   20259            0 :   M2Quads_PopTtok (&value, &valuepos);
   20260            0 :   M2Quads_PopTtok (&type, &typepos);
   20261            0 :   combined = M2LexBuf_MakeVirtual2Tok (typepos, valuepos);
   20262            0 :   M2Quads_PushTFtok (value, type, combined);
   20263            0 :   M2Debug_Assert (SymbolTable_IsSet (type));
   20264            0 : }
   20265              : 
   20266              : 
   20267              : /*
   20268              :    BuildEmptySet - Builds an empty set on the stack.
   20269              :                    The Stack:
   20270              : 
   20271              :                    Entry             Exit
   20272              : 
   20273              :                                                      <- Ptr
   20274              :                                      +-------------+
   20275              :             Ptr ->                   | Value       |
   20276              :                    +-----------+     |-------------|
   20277              :                    | SetType   |     | SetType     |
   20278              :                    |-----------|     |-------------|
   20279              : 
   20280              :    tokpos points to the opening '{'.
   20281              : */
   20282              : 
   20283            0 : extern "C" void M2Quads_BuildEmptySet (unsigned int tokpos)
   20284              : {
   20285            0 :   NameKey_Name n;
   20286            0 :   unsigned int typepos;
   20287            0 :   unsigned int Type;
   20288            0 :   unsigned int NulSet;
   20289              : 
   20290            0 :   M2Quads_PopTtok (&Type, &typepos);  /* type of set we are building  */
   20291            0 :   if ((Type == SymbolTable_NulSym) && M2Options_Pim)
   20292              :     {
   20293              :       /* allowed generic {} in PIM Modula-2  */
   20294            0 :       typepos = tokpos;
   20295              :     }
   20296            0 :   else if (SymbolTable_IsUnknown (Type))
   20297              :     {
   20298              :       /* avoid dangling else.  */
   20299              :       /* Spellcheck.  */
   20300            0 :       M2MetaError_MetaError1 ((const char *) "set type {%1a} is undefined {%1&s}", 34, Type);
   20301            0 :       SymbolTable_UnknownReported (Type);
   20302            0 :       Type = M2Bitset_Bitset;
   20303              :     }
   20304            0 :   else if (! (SymbolTable_IsSet (SymbolTable_SkipType (Type))))
   20305              :     {
   20306              :       /* avoid dangling else.  */
   20307            0 :       M2MetaError_MetaError1 ((const char *) "expecting a set type {%1a} and not a {%1d}", 42, Type);
   20308            0 :       Type = M2Bitset_Bitset;
   20309              :     }
   20310              :   else
   20311              :     {
   20312              :       /* avoid dangling else.  */
   20313            0 :       Type = SymbolTable_SkipType (Type);
   20314            0 :       M2Debug_Assert (Type != SymbolTable_NulSym);
   20315              :     }
   20316            0 :   NulSet = SymbolTable_MakeTemporary (typepos, SymbolTable_ImmediateValue);
   20317            0 :   SymbolTable_PutVar (NulSet, Type);
   20318            0 :   SymbolTable_PutConstSet (NulSet);
   20319            0 :   if (M2Options_CompilerDebugging)
   20320              :     {
   20321            0 :       n = SymbolTable_GetSymName (Type);
   20322            0 :       M2Printf_printf1 ((const char *) "set type = %a\\n", 15, (const unsigned char *) &n, (sizeof (n)-1));
   20323              :     }
   20324            0 :   M2ALU_PushNulSet (Type);  /* onto the ALU stack  */
   20325            0 :   SymbolTable_PopValue (NulSet);  /* ALU -> symbol table  */
   20326              :   /* and now construct the M2Quads stack as defined by the comments above  */
   20327            0 :   M2Quads_PushTtok (Type, typepos);
   20328            0 :   M2Quads_PushTtok (NulSet, typepos);
   20329            0 :   if (M2Options_CompilerDebugging)
   20330              :     {
   20331            0 :       n = SymbolTable_GetSymName (Type);
   20332            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));
   20333            0 :       M2Quads_DisplayStack ();  /* Debugging info  */
   20334              :     }
   20335            0 : }
   20336              : 
   20337              : 
   20338              : /*
   20339              :    BuildInclRange - includes a set range with a set.
   20340              : 
   20341              : 
   20342              :                           Entry                   Exit
   20343              :                           =====                   ====
   20344              : 
   20345              : 
   20346              :                    Ptr ->
   20347              :                           +------------+
   20348              :                           | El2        |
   20349              :                           |------------|
   20350              :                           | El1        |                                 <- Ptr
   20351              :                           |------------|           +-------------------+
   20352              :                           | Set Value  |           | Value + {El1..El2}|
   20353              :                           |------------|           |-------------------|
   20354              : 
   20355              :                    No quadruples produced as the range info is contained within
   20356              :                    the set value.
   20357              : */
   20358              : 
   20359            0 : extern "C" void M2Quads_BuildInclRange (void)
   20360              : {
   20361            0 :   NameKey_Name n;
   20362            0 :   unsigned int el1;
   20363            0 :   unsigned int el2;
   20364            0 :   unsigned int value;
   20365              : 
   20366            0 :   M2Quads_PopT (&el2);
   20367            0 :   SafeCheckWithField ();
   20368            0 :   M2Quads_PopT (&el1);
   20369            0 :   SafeCheckWithField ();
   20370            0 :   M2Quads_PopT (&value);
   20371            0 :   if (! (SymbolTable_IsConstSet (value)))
   20372              :     {
   20373            0 :       n = SymbolTable_GetSymName (el1);
   20374            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));
   20375              :     }
   20376            0 :   if ((SymbolTable_IsConst (el1)) && (SymbolTable_IsConst (el2)))
   20377              :     {
   20378            0 :       SymbolTable_PushValue (value);  /* onto ALU stack  */
   20379            0 :       M2ALU_AddBitRange (M2LexBuf_GetTokenNo (), el1, el2);  /* onto ALU stack  */
   20380            0 :       SymbolTable_PopValue (value);  /* ALU -> symboltable  */
   20381              :     }
   20382              :   else
   20383              :     {
   20384            0 :       if (! (SymbolTable_IsConst (el1)))
   20385              :         {
   20386            0 :           n = SymbolTable_GetSymName (el1);
   20387            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));
   20388              :         }
   20389            0 :       if (! (SymbolTable_IsConst (el2)))
   20390              :         {
   20391            0 :           n = SymbolTable_GetSymName (el2);
   20392            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));
   20393              :         }
   20394              :     }
   20395            0 :   M2Quads_PushT (value);
   20396            0 : }
   20397              : 
   20398              : 
   20399              : /*
   20400              :    BuildInclBit - includes a bit into the set.
   20401              : 
   20402              :                          Entry                   Exit
   20403              :                          =====                   ====
   20404              : 
   20405              : 
   20406              :                   Ptr ->
   20407              :                          +------------+
   20408              :                          | Element    |                         <- Ptr
   20409              :                          |------------|          +------------+
   20410              :                          | Value      |          | Value      |
   20411              :                          |------------|          |------------|
   20412              : 
   20413              : */
   20414              : 
   20415        12040 : extern "C" void M2Quads_BuildInclBit (void)
   20416              : {
   20417        12040 :   unsigned int tok;
   20418        12040 :   unsigned int el;
   20419        12040 :   unsigned int value;
   20420        12040 :   unsigned int t;
   20421              : 
   20422        12040 :   SafeCheckWithField ();
   20423        12040 :   M2Quads_PopT (&el);
   20424        12040 :   M2Quads_PopT (&value);
   20425        12040 :   tok = M2LexBuf_GetTokenNo ();
   20426        12040 :   if (SymbolTable_IsConst (el))
   20427              :     {
   20428        11907 :       SymbolTable_PushValue (value);  /* onto ALU stack  */
   20429        11907 :       M2ALU_AddBit (tok, el);  /* onto ALU stack  */
   20430        11907 :       SymbolTable_PopValue (value);  /* ALU -> symboltable  */
   20431              :     }
   20432              :   else
   20433              :     {
   20434          133 :       if ((SymbolTable_GetMode (el)) == SymbolTable_LeftValue)
   20435              :         {
   20436            0 :           t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
   20437            0 :           SymbolTable_PutVar (t, SymbolTable_GetSType (el));
   20438            0 :           CheckPointerThroughNil (tok, el);
   20439            0 :           doIndrX (tok, t, el);
   20440            0 :           el = t;
   20441              :         }
   20442          133 :       if (SymbolTable_IsConst (value))
   20443              :         {
   20444              :           /* Move constant or record field into a variable to achieve the include.  */
   20445          133 :           t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
   20446          133 :           SymbolTable_PutVar (t, SymbolTable_GetSType (value));
   20447          133 :           GenQuad (M2Quads_BecomesOp, t, SymbolTable_NulSym, value);
   20448          133 :           value = t;
   20449              :         }
   20450          133 :       GenQuad (M2Quads_InclOp, value, SymbolTable_NulSym, el);
   20451              :     }
   20452        12040 :   M2Quads_PushT (value);
   20453        12040 : }
   20454              : 
   20455              : 
   20456              : /*
   20457              :    SilentBuildConstructor - places NulSym into the constructor fifo queue.
   20458              : */
   20459              : 
   20460            0 : extern "C" void M2Quads_SilentBuildConstructor (void)
   20461              : {
   20462            0 :   FifoQueue_PutConstructorIntoFifoQueue (SymbolTable_NulSym);
   20463            0 : }
   20464              : 
   20465              : 
   20466              : /*
   20467              :    SilentBuildConstructorStart - removes an entry from the constructor fifo queue.
   20468              : */
   20469              : 
   20470        26038 : extern "C" void M2Quads_SilentBuildConstructorStart (void)
   20471              : {
   20472        26038 :   unsigned int constValue;
   20473              : 
   20474        26038 :   FifoQueue_GetConstructorFromFifoQueue (&constValue);
   20475        26038 : }
   20476              : 
   20477              : 
   20478              : /*
   20479              :    BuildConstructor - builds a constructor.
   20480              :                       Stack
   20481              : 
   20482              :                       Entry                 Exit
   20483              : 
   20484              :                Ptr ->
   20485              :                       +------------+
   20486              :                       | Type       |                <- Ptr
   20487              :                       |------------+
   20488              : */
   20489              : 
   20490        37185 : extern "C" void M2Quads_BuildConstructor (unsigned int tokcbrpos)
   20491              : {
   20492        37185 :   unsigned int tok;
   20493        37185 :   NameKey_Name name;
   20494        37185 :   unsigned int errsym;
   20495        37185 :   unsigned int constValue;
   20496        37185 :   unsigned int type;
   20497              : 
   20498        37185 :   PopTntok (&type, &name, &tok);
   20499        37185 :   constValue = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
   20500        37185 :   SymbolTable_PutVar (constValue, type);
   20501        37185 :   SymbolTable_PutConstructor (constValue);
   20502        37185 :   SymbolTable_PushValue (constValue);
   20503        37185 :   if (type == SymbolTable_NulSym)
   20504              :     {
   20505            7 :       if (tok == M2LexBuf_UnknownTokenNo)
   20506              :         {
   20507            0 :           M2MetaError_MetaErrorT0 (tokcbrpos, (const char *) "{%E}constructor requires a type before the opening %{", 53);
   20508              :         }
   20509              :       else
   20510              :         {
   20511              :           /* Spellcheck.  */
   20512            7 :           errsym = SymbolTable_MakeError (tok, name);
   20513            7 :           M2MetaError_MetaErrorT1 (tok, (const char *) "constructor type {%1Ea} is undefined {%1&s}", 43, errsym);
   20514            7 :           SymbolTable_UnknownReported (errsym);
   20515              :         }
   20516              :     }
   20517              :   else
   20518              :     {
   20519        37178 :       M2ALU_ChangeToConstructor (tok, type);
   20520        37178 :       SymbolTable_PutConstructorFrom (constValue, type);
   20521        37178 :       SymbolTable_PopValue (constValue);
   20522        37178 :       FifoQueue_PutConstructorIntoFifoQueue (constValue);
   20523              :     }
   20524        37185 :   PushConstructor (type);
   20525        37185 : }
   20526              : 
   20527              : 
   20528              : /*
   20529              :    BuildConstructorStart - builds a constructor.
   20530              :                            Stack
   20531              : 
   20532              :                            Entry                 Exit
   20533              : 
   20534              :                     Ptr ->                                          <- Ptr
   20535              :                            +------------+        +----------------+
   20536              :                            | Type       |        | ConstructorSym |
   20537              :                            |------------+        |----------------|
   20538              : */
   20539              : 
   20540        11134 : extern "C" void M2Quads_BuildConstructorStart (unsigned int cbratokpos)
   20541              : {
   20542        11134 :   unsigned int typepos;
   20543        11134 :   unsigned int constValue;
   20544        11134 :   unsigned int type;
   20545              : 
   20546        11134 :   M2Quads_PopTtok (&type, &typepos);  /* we ignore the type as we already have the constructor symbol from pass C  */
   20547        11134 :   FifoQueue_GetConstructorFromFifoQueue (&constValue);  /* we ignore the type as we already have the constructor symbol from pass C  */
   20548        11134 :   if (type != (SymbolTable_GetSType (constValue)))
   20549              :     {
   20550            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);
   20551              :     }
   20552        11134 :   M2Quads_PushTtok (constValue, cbratokpos);
   20553        11134 :   PushConstructor (type);
   20554        11134 : }
   20555              : 
   20556              : 
   20557              : /*
   20558              :    BuildConstructorEnd - removes the current constructor frame from the
   20559              :                          constructor stack (it does not effect the quad
   20560              :                          stack)
   20561              : 
   20562              :                          Entry                 Exit
   20563              : 
   20564              :                   Ptr ->                                      <- Ptr
   20565              :                          +------------+        +------------+
   20566              :                          | const      |        | const      |
   20567              :                          |------------|        |------------|
   20568              : 
   20569              :    startpos is the start of the constructor, either the typename or '{'
   20570              :    cbratokpos is the '}'.
   20571              : */
   20572              : 
   20573        11134 : extern "C" void M2Quads_BuildConstructorEnd (unsigned int startpos, unsigned int cbratokpos)
   20574              : {
   20575        11134 :   unsigned int value;
   20576        11134 :   unsigned int valtok;
   20577              : 
   20578        11134 :   if (DebugTokPos)
   20579              :     {
   20580              :       M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "startpos", 8), startpos);
   20581              :       M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "cbratokpos", 10), cbratokpos);
   20582              :     }
   20583        11134 :   M2Quads_PopTtok (&value, &valtok);
   20584        11134 :   if (DebugTokPos)
   20585              :     {
   20586              :       M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "value valtok", 12), valtok);
   20587              :     }
   20588        11134 :   valtok = M2LexBuf_MakeVirtual2Tok (startpos, cbratokpos);
   20589        11134 :   SymbolTable_PutDeclared (valtok, value);
   20590        11134 :   M2Quads_PushTtok (value, valtok);  /* Use valtok as we now know it was a constructor.  */
   20591        11134 :   M2Quads_PopConstructor ();  /* Use valtok as we now know it was a constructor.  */
   20592        11134 :   if (DebugTokPos)
   20593              :     {
   20594              :       M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "aggregate constant", 18), valtok);
   20595              :     }
   20596        11134 : }
   20597              : 
   20598              : 
   20599              : /*
   20600              :    NextConstructorField - increments the top of constructor stacks index by one.
   20601              : */
   20602              : 
   20603        35121 : extern "C" void M2Quads_NextConstructorField (void)
   20604              : {
   20605        35121 :   M2Quads_ConstructorFrame c;
   20606              : 
   20607        35121 :   c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PeepAddress (ConstructorStack, 1));
   20608        35121 :   c->index += 1;
   20609        35121 : }
   20610              : 
   20611              : 
   20612              : /*
   20613              :    BuildTypeForConstructor - pushes the type implied by the current constructor.
   20614              :                              If no constructor is currently being built then
   20615              :                              it Pushes a Bitset type.
   20616              : */
   20617              : 
   20618         1714 : extern "C" void M2Quads_BuildTypeForConstructor (unsigned int tokpos)
   20619              : {
   20620         1714 :   M2Quads_ConstructorFrame c;
   20621              : 
   20622         1714 :   if ((M2StackAddress_NoOfItemsInStackAddress (ConstructorStack)) == 0)
   20623              :     {
   20624          646 :       M2Quads_PushTtok (M2Bitset_Bitset, tokpos);
   20625              :     }
   20626              :   else
   20627              :     {
   20628         1068 :       c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PeepAddress (ConstructorStack, 1));
   20629         1068 :       if ((SymbolTable_IsArray (c->type)) || (SymbolTable_IsSet (c->type)))
   20630              :         {
   20631          972 :           M2Quads_PushTtok (SymbolTable_GetSType (c->type), tokpos);
   20632              :         }
   20633           96 :       else if (SymbolTable_IsRecord (c->type))
   20634              :         {
   20635              :           /* avoid dangling else.  */
   20636           96 :           M2Quads_PushTtok (SymbolTable_GetSType (SymbolTable_GetNth (c->type, c->index)), tokpos);
   20637              :         }
   20638              :       else
   20639              :         {
   20640              :           /* avoid dangling else.  */
   20641            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);
   20642              :         }
   20643              :     }
   20644         1714 : }
   20645              : 
   20646              : 
   20647              : /*
   20648              :    BuildComponentValue -  builds a component value.
   20649              : 
   20650              :                           Entry                 Exit
   20651              : 
   20652              :                    Ptr ->                                      <- Ptr
   20653              : 
   20654              : 
   20655              :                           +------------+        +------------+
   20656              :                           | const      |        | const      |
   20657              :                           |------------|        |------------|
   20658              : */
   20659              : 
   20660        26054 : extern "C" void M2Quads_BuildComponentValue (void)
   20661              : {
   20662        26054 :   unsigned int e1tok;
   20663        26054 :   unsigned int e2tok;
   20664        26054 :   unsigned int consttok;
   20665        26054 :   unsigned int const_;
   20666        26054 :   unsigned int e1;
   20667        26054 :   unsigned int e2;
   20668        26054 :   NameKey_Name nuldotdot;
   20669        26054 :   NameKey_Name nulby;
   20670              : 
   20671        26054 :   M2Quads_PopT (&nulby);
   20672        26054 :   if (nulby == M2Reserved_NulTok)
   20673              :     {
   20674        26024 :       M2Quads_PopT (&nuldotdot);
   20675        26024 :       if (nuldotdot == M2Reserved_NulTok)
   20676              :         {
   20677        25782 :           M2Quads_PopTtok (&e1, &e1tok);
   20678        25782 :           M2Quads_PopTtok (&const_, &consttok);
   20679        25782 :           const_ = AddFieldTo (const_, e1, consttok, e1tok);
   20680        25782 :           PushTFrwtok (const_, SymbolTable_GetSType (const_), static_cast<unsigned int> (SymbolTable_NulSym), M2LexBuf_MakeVirtual2Tok (consttok, e1tok));
   20681              :         }
   20682              :       else
   20683              :         {
   20684          242 :           M2Quads_PopTtok (&e2, &e2tok);
   20685          242 :           M2Quads_PopTtok (&e1, &e1tok);
   20686          242 :           M2Quads_PopTtok (&const_, &consttok);
   20687          242 :           SymbolTable_PushValue (const_);
   20688          242 :           M2ALU_AddBitRange (M2LexBuf_MakeVirtual2Tok (e1tok, e2tok), e1, e2);
   20689          242 :           SymbolTable_PopValue (const_);
   20690          242 :           PushTFrwtok (const_, SymbolTable_GetSType (const_), static_cast<unsigned int> (SymbolTable_NulSym), M2LexBuf_MakeVirtual2Tok (consttok, e2tok));
   20691              :         }
   20692              :     }
   20693              :   else
   20694              :     {
   20695           30 :       M2Quads_PopTtok (&e1, &e1tok);
   20696           30 :       M2Quads_PopT (&nuldotdot);
   20697           30 :       if (nuldotdot == M2Reserved_NulTok)
   20698              :         {
   20699           30 :           M2Quads_PopTtok (&e2, &e2tok);
   20700           30 :           M2Quads_PopTtok (&const_, &consttok);
   20701           30 :           SymbolTable_PushValue (const_);
   20702           30 :           M2ALU_AddElements (M2LexBuf_MakeVirtual2Tok (e1tok, e2tok), e2, e1);
   20703           30 :           SymbolTable_PopValue (const_);
   20704           30 :           PushTFrwtok (const_, SymbolTable_GetSType (const_), static_cast<unsigned int> (SymbolTable_NulSym), M2LexBuf_MakeVirtual2Tok (consttok, e2tok));
   20705              :         }
   20706              :       else
   20707              :         {
   20708            0 :           M2Quads_PopTtok (&e2, &e2tok);
   20709            0 :           M2Quads_PopTtok (&e1, &e1tok);
   20710            0 :           M2Quads_PopTtok (&const_, &consttok);
   20711            0 :           consttok = M2LexBuf_MakeVirtual2Tok (consttok, e2tok);
   20712            0 :           M2MetaError_MetaErrorT1 (consttok, (const char *) "the constant {%E1a} must be either an array constructor or a set constructor", 76, const_);
   20713            0 :           PushTFrwtok (const_, SymbolTable_GetSType (const_), static_cast<unsigned int> (SymbolTable_NulSym), consttok);
   20714              :         }
   20715              :     }
   20716        26054 : }
   20717              : 
   20718              : 
   20719              : /*
   20720              :    PopConstructor - removes the top constructor from the top of stack.
   20721              : */
   20722              : 
   20723        48319 : extern "C" void M2Quads_PopConstructor (void)
   20724              : {
   20725        48319 :   M2Quads_ConstructorFrame c;
   20726              : 
   20727        48319 :   c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PopAddress (ConstructorStack));
   20728        48319 :   Storage_DEALLOCATE ((void **) &c, sizeof (M2Quads__T1));
   20729        48319 : }
   20730              : 
   20731              : 
   20732              : /*
   20733              :    BuildNot   - Builds a NOT operation from the quad stack.
   20734              :                 The Stack is expected to contain:
   20735              : 
   20736              : 
   20737              :                   Entry                   Exit
   20738              :                   =====                   ====
   20739              : 
   20740              :            Ptr ->                                        <- Ptr
   20741              :                   +------------+          +------------+
   20742              :                   | t    | f   |          | f    | t   |
   20743              :                   |------------|          |------------|
   20744              : */
   20745              : 
   20746         4850 : extern "C" void M2Quads_BuildNot (unsigned int notTokPos)
   20747              : {
   20748         4850 :   unsigned int combinedTok;
   20749         4850 :   unsigned int exprTokPos;
   20750         4850 :   unsigned int t;
   20751         4850 :   unsigned int f;
   20752              : 
   20753         4850 :   CheckBooleanId ();
   20754         4850 :   PopBooltok (&t, &f, &exprTokPos);
   20755         4850 :   combinedTok = M2LexBuf_MakeVirtualTok (notTokPos, notTokPos, exprTokPos);
   20756         4850 :   PushBooltok (f, t, combinedTok);
   20757         4850 : }
   20758              : 
   20759              : 
   20760              : /*
   20761              :    RecordOp - Records the operator passed on the stack.
   20762              :               This is called when a boolean operator is found in an
   20763              :               expression.  It is called just after the lhs has been built
   20764              :               and pushed to the quad stack and prior to the rhs build.
   20765              :               It checks to see if AND OR or equality tests are required.
   20766              :               It will short circuit AND and OR expressions.  It also
   20767              :               converts a lhs to a boolean variable if an xor comparison
   20768              :               is about to be performed.
   20769              : 
   20770              :               Checks for AND operator or OR operator
   20771              :               if either of these operators are found then BackPatching
   20772              :               takes place.
   20773              :               The Expected Stack:
   20774              : 
   20775              :               Entry                        Exit
   20776              : 
   20777              :        Ptr ->                                               <- Ptr
   20778              :               +-------------+               +-------------+
   20779              :               | OperatorTok |               | OperatorTok |
   20780              :               |-------------|               |-------------|
   20781              :               | t    | f    |               | t    | f    |
   20782              :               |-------------|               |-------------|
   20783              : 
   20784              : 
   20785              :               If OperatorTok=AndTok
   20786              :               Then
   20787              :                  BackPatch(f, NextQuad)
   20788              :               Elsif OperatorTok=OrTok
   20789              :               Then
   20790              :                  BackPatch(t, NextQuad)
   20791              :               End
   20792              : */
   20793              : 
   20794       105148 : extern "C" void M2Quads_RecordOp (void)
   20795              : {
   20796       105148 :   NameKey_Name Op;
   20797       105148 :   unsigned int tokno;
   20798       105148 :   unsigned int t;
   20799       105148 :   unsigned int f;
   20800              : 
   20801       105148 :   M2Quads_PopTtok (&Op, &tokno);
   20802       105148 :   if ((Op == M2Reserved_AndTok) || (Op == M2Reserved_AmbersandTok))
   20803              :     {
   20804         9636 :       CheckBooleanId ();
   20805         9636 :       PopBool (&t, &f);
   20806         9636 :       BackPatch (t, NextQuad);
   20807         9636 :       PushBool (0, f);
   20808              :     }
   20809        95512 :   else if (Op == M2Reserved_OrTok)
   20810              :     {
   20811              :       /* avoid dangling else.  */
   20812         3536 :       CheckBooleanId ();
   20813         3536 :       PopBool (&t, &f);
   20814         3536 :       BackPatch (f, NextQuad);
   20815         3536 :       PushBool (t, 0);
   20816              :     }
   20817        91976 :   else if ((IsBoolean (1)) && ((((Op == M2Reserved_EqualTok) || (Op == M2Reserved_LessGreaterTok)) || (Op == M2Reserved_HashTok)) || (Op == M2Reserved_InTok)))
   20818              :     {
   20819              :       /* avoid dangling else.  */
   20820           52 :       ConvertBooleanToVariable (tokno, 1);
   20821              :     }
   20822       105148 :   M2Quads_PushTtok (Op, tokno);
   20823       105148 : }
   20824              : 
   20825              : 
   20826              : /*
   20827              :    BuildRelOp   - Builds a relative operation from the quad stack.
   20828              :                   The Stack is expected to contain:
   20829              : 
   20830              : 
   20831              :                   Entry                   Exit
   20832              :                   =====                   ====
   20833              : 
   20834              :            Ptr ->
   20835              :                   +------------+
   20836              :                   | e1         |
   20837              :                   |------------|                          <- Ptr
   20838              :                   | Operator   |
   20839              :                   |------------|          +------------+
   20840              :                   | e2         |          | t    | f   |
   20841              :                   |------------|          |------------|
   20842              : 
   20843              : 
   20844              :                     Quadruples Produced
   20845              : 
   20846              :                     q     IFOperator  e2  e1  TrueExit    ; e2  e1 since
   20847              :                     q+1   GotoOp              FalseExit   ; relation > etc
   20848              :                                                           ; requires order.
   20849              : */
   20850              : 
   20851        90766 : extern "C" void M2Quads_BuildRelOp (unsigned int optokpos)
   20852              : {
   20853        90766 :   unsigned int combinedTok;
   20854        90766 :   unsigned int rightpos;
   20855        90766 :   unsigned int leftpos;
   20856        90766 :   NameKey_Name Op;
   20857        90766 :   unsigned int t;
   20858        90766 :   unsigned int rightType;
   20859        90766 :   unsigned int leftType;
   20860        90766 :   unsigned int right;
   20861        90766 :   unsigned int left;
   20862        90766 :   DynamicStrings_String s;
   20863              : 
   20864        90766 :   if (M2Options_CompilerDebugging)
   20865              :     {
   20866            0 :       M2Quads_DisplayStack ();  /* Debugging info  */
   20867              :     }
   20868        90766 :   if (((M2Quads_IsInConstExpression ()) && (IsBoolean (1))) && (IsBoolean (3)))
   20869              :     {
   20870              :       /* 
   20871              :          we allow # and = to be used with Boolean expressions.
   20872              :          we do not allow >  <  >=  <=  though.  We only examine
   20873              :          this case if we are in a const expression as there will be
   20874              :          no dereferencing of operands.
   20875              :   */
   20876            0 :       BuildRelOpFromBoolean (optokpos);
   20877              :     }
   20878              :   else
   20879              :     {
   20880        90766 :       if (IsBoolean (1))
   20881              :         {
   20882           64 :           ConvertBooleanToVariable (OperandTtok (1), 1);
   20883              :         }
   20884        90766 :       if (IsBoolean (3))
   20885              :         {
   20886            0 :           ConvertBooleanToVariable (OperandTtok (3), 3);
   20887              :         }
   20888        90766 :       M2Quads_PopTFtok (&right, &rightType, &rightpos);
   20889        90766 :       M2Quads_PopT (&Op);
   20890        90766 :       M2Quads_PopTFtok (&left, &leftType, &leftpos);
   20891        90766 :       CheckVariableOrConstantOrProcedure (rightpos, right);
   20892        90766 :       CheckVariableOrConstantOrProcedure (leftpos, left);
   20893        90766 :       combinedTok = M2LexBuf_MakeVirtualTok (optokpos, leftpos, rightpos);
   20894        90766 :       if ((left != SymbolTable_NulSym) && (right != SymbolTable_NulSym))
   20895              :         {
   20896              :           /* BuildRange will check the expression later on once gcc knows about all data types.  */
   20897        90766 :           BuildRange (M2Range_InitTypesExpressionCheck (combinedTok, left, right, true, Op == M2Reserved_InTok));
   20898              :         }
   20899              :       /* Must dereference LeftValue operands.  */
   20900        90766 :       if ((SymbolTable_GetMode (right)) == SymbolTable_LeftValue)
   20901              :         {
   20902         1928 :           t = SymbolTable_MakeTemporary (rightpos, SymbolTable_RightValue);
   20903         1928 :           SymbolTable_PutVar (t, SymbolTable_GetSType (right));
   20904         1928 :           CheckPointerThroughNil (rightpos, right);
   20905         1928 :           doIndrX (rightpos, t, right);
   20906         1928 :           right = t;
   20907              :         }
   20908        90766 :       if ((SymbolTable_GetMode (left)) == SymbolTable_LeftValue)
   20909              :         {
   20910         6233 :           t = SymbolTable_MakeTemporary (leftpos, SymbolTable_RightValue);
   20911         6233 :           SymbolTable_PutVar (t, SymbolTable_GetSType (left));
   20912         6233 :           CheckPointerThroughNil (leftpos, left);
   20913         6233 :           doIndrX (leftpos, t, left);
   20914         6233 :           left = t;
   20915              :         }
   20916        90766 :       if (DebugTokPos)
   20917              :         {
   20918              :           s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (M2LexBuf_GetTokenName (Op)));
   20919              :           M2Error_WarnStringAt (s, optokpos);
   20920              :           s = DynamicStrings_InitString ((const char *) "left", 4);
   20921              :           M2Error_WarnStringAt (s, leftpos);
   20922              :           s = DynamicStrings_InitString ((const char *) "right", 5);
   20923              :           M2Error_WarnStringAt (s, rightpos);
   20924              :           s = DynamicStrings_InitString ((const char *) "caret", 5);
   20925              :           M2Error_WarnStringAt (s, optokpos);
   20926              :           s = DynamicStrings_InitString ((const char *) "combined", 8);
   20927              :           M2Error_WarnStringAt (s, combinedTok);
   20928              :         }
   20929        90766 :       GenQuadOtok (combinedTok, MakeOp (Op), left, right, 0, false, leftpos, rightpos, M2LexBuf_UnknownTokenNo);  /* True  Exit  */
   20930        90766 :       GenQuadO (combinedTok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);  /* False Exit  */
   20931        90766 :       PushBooltok (NextQuad-2, NextQuad-1, combinedTok);  /* False Exit  */
   20932              :     }
   20933        90766 : }
   20934              : 
   20935              : 
   20936              : /*
   20937              :    BuildBinaryOp   - Builds a binary operation from the quad stack.
   20938              :                      Be aware that this procedure will check for
   20939              :                      the overloading of the bitset operators + - \ *.
   20940              :                      So do NOT call this procedure if you are building
   20941              :                      a reference to an array which has a bitset type or
   20942              :                      the address arithmetic will be wrongly coersed into
   20943              :                      logical ORs.
   20944              : 
   20945              :                      The Stack is expected to contain:
   20946              : 
   20947              : 
   20948              :                      Entry                   Exit
   20949              :                      =====                   ====
   20950              : 
   20951              :               Ptr ->
   20952              :                      +------------+
   20953              :                      | Sym1       |
   20954              :                      |------------|
   20955              :                      | Operator   |                          <- Ptr
   20956              :                      |------------|          +------------+
   20957              :                      | Sym2       |          | Temporary  |
   20958              :                      |------------|          |------------|
   20959              : 
   20960              : 
   20961              :                      Quadruples Produced
   20962              : 
   20963              :                      q     Operator  Temporary  Sym1  Sym2
   20964              : 
   20965              : 
   20966              :                 OR
   20967              : 
   20968              : 
   20969              :                      Entry                   Exit
   20970              :                      =====                   ====
   20971              : 
   20972              :               Ptr ->
   20973              :                      +------------+
   20974              :                      | T1   | F1  |
   20975              :                      |------------|
   20976              :                      | OrTok      |                          <- Ptr
   20977              :                      |------------|          +------------+
   20978              :                      | T2   | F2  |          | T1+T2| F1  |
   20979              :                      |------------|          |------------|
   20980              : 
   20981              : 
   20982              :                      Quadruples Produced
   20983              : 
   20984              : */
   20985              : 
   20986        73719 : extern "C" void M2Quads_BuildBinaryOp (void)
   20987              : {
   20988        73719 :   doBuildBinaryOp (true, true);
   20989        73611 : }
   20990              : 
   20991              : 
   20992              : /*
   20993              :    BuildUnaryOp   - Builds a unary operation from the quad stack.
   20994              :                     The Stack is expected to contain:
   20995              : 
   20996              : 
   20997              :                     Entry                   Exit
   20998              :                     =====                   ====
   20999              : 
   21000              :              Ptr ->
   21001              :                     +------------+
   21002              :                     | Sym        |
   21003              :                     |------------|          +------------+
   21004              :                     | Operator   |          | Temporary  | <- Ptr
   21005              :                     |------------|          |------------|
   21006              : 
   21007              : 
   21008              :                     Quadruples Produced
   21009              : 
   21010              :                     q     Operator  Temporary  _ Sym
   21011              : 
   21012              : */
   21013              : 
   21014        21206 : extern "C" void M2Quads_BuildUnaryOp (void)
   21015              : {
   21016        21206 :   unsigned int sympos;
   21017        21206 :   unsigned int tokpos;
   21018        21206 :   NameKey_Name Tok;
   21019        21206 :   unsigned int type;
   21020        21206 :   unsigned int Sym;
   21021        21206 :   unsigned int SymT;
   21022        21206 :   unsigned int r;
   21023        21206 :   unsigned int t;
   21024              : 
   21025        21206 :   PopTrwtok (&Sym, &r, &sympos);
   21026        21206 :   M2Quads_PopTtok (&Tok, &tokpos);
   21027        21206 :   if (Tok == M2Reserved_MinusTok)
   21028              :     {
   21029        21050 :       MarkAsRead (r);
   21030        21050 :       type = M2Base_NegateType (SymbolTable_GetSType (Sym));  /* , sympos  */
   21031        21050 :       tokpos = M2LexBuf_MakeVirtualTok (tokpos, tokpos, sympos);
   21032        22052 :       t = SymbolTable_MakeTemporary (tokpos, AreConstant (SymbolTable_IsConst (Sym)));
   21033        21050 :       SymbolTable_PutVar (t, type);
   21034              :       /* 
   21035              :          variables must have a type and REAL/LONGREAL constants must
   21036              :          be typed
   21037              :   */
   21038        21050 :       if (! (SymbolTable_IsConst (Sym)))
   21039              :         {
   21040              :           /* avoid gcc warning by using compound statement even if not strictly necessary.  */
   21041         1002 :           if ((type != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_SkipType (type))))
   21042              :             {}  /* empty.  */
   21043              :           /* do not dereference set variables  */
   21044          924 :           else if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
   21045              :             {
   21046              :               /* avoid dangling else.  */
   21047              :               /* dereference symbols which are not sets and which are variables  */
   21048            0 :               SymT = SymbolTable_MakeTemporary (sympos, SymbolTable_RightValue);
   21049            0 :               SymbolTable_PutVar (SymT, SymbolTable_GetSType (Sym));
   21050            0 :               CheckPointerThroughNil (sympos, Sym);
   21051            0 :               doIndrX (sympos, SymT, Sym);
   21052            0 :               Sym = SymT;
   21053              :             }
   21054              :         }
   21055        21050 :       GenQuadO (tokpos, M2Quads_NegateOp, t, SymbolTable_NulSym, Sym, true);
   21056        21050 :       M2Quads_PushTtok (t, tokpos);
   21057              :     }
   21058          156 :   else if (Tok == M2Reserved_PlusTok)
   21059              :     {
   21060              :       /* avoid dangling else.  */
   21061          156 :       tokpos = M2LexBuf_MakeVirtualTok (tokpos, tokpos, sympos);
   21062          156 :       PushTrwtok (Sym, r, tokpos);
   21063              :     }
   21064              :   else
   21065              :     {
   21066              :       /* avoid dangling else.  */
   21067            0 :       M2MetaError_MetaErrorNT1 (tokpos, (const char *) "expecting an unary operator, seen {%Ek%a}", 41, Tok);
   21068              :     }
   21069        21206 : }
   21070              : 
   21071              : 
   21072              : /*
   21073              :    OperandT - returns the ident operand stored in the true position on the boolean stack.
   21074              : */
   21075              : 
   21076    214826127 : extern "C" unsigned int M2Quads_OperandT (unsigned int pos)
   21077              : {
   21078    214826127 :   M2Debug_Assert (! (IsBoolean (pos)));
   21079    214826127 :   return OperandTno (pos);
   21080              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   21081              :   __builtin_unreachable ();
   21082              : }
   21083              : 
   21084              : 
   21085              : /*
   21086              :    OperandF - returns the ident operand stored in the false position on the boolean stack.
   21087              : */
   21088              : 
   21089       176325 : extern "C" unsigned int M2Quads_OperandF (unsigned int pos)
   21090              : {
   21091       176325 :   M2Debug_Assert (! (IsBoolean (pos)));
   21092       176325 :   return OperandFno (pos);
   21093              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   21094              :   __builtin_unreachable ();
   21095              : }
   21096              : 
   21097              : 
   21098              : /*
   21099              :    PushTF - Push a True and False numbers onto the True/False stack.
   21100              :             True and False are assumed to contain Symbols or Ident etc.
   21101              : */
   21102              : 
   21103     16053864 : extern "C" void M2Quads_PushTF (unsigned int True, unsigned int False)
   21104              : {
   21105     16053864 :   M2Quads_BoolFrame f;
   21106              : 
   21107     16053864 :   f = newBoolFrame ();
   21108     16053864 :   f->TrueExit = static_cast<unsigned int> (True);
   21109     16053864 :   f->FalseExit = static_cast<unsigned int> (False);
   21110     16053864 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21111     16053864 : }
   21112              : 
   21113              : 
   21114              : /*
   21115              :    PopTF - Pop a True and False number from the True/False stack.
   21116              :            True and False are assumed to contain Symbols or Ident etc.
   21117              : */
   21118              : 
   21119     10794654 : extern "C" void M2Quads_PopTF (unsigned int *True, unsigned int *False)
   21120              : {
   21121     10794654 :   M2Quads_BoolFrame f;
   21122              : 
   21123     10794654 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   21124     10794654 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   21125     10794654 :   (*False) = static_cast<unsigned int> (f->FalseExit);
   21126     10794654 :   M2Debug_Assert (! f->BooleanOp);
   21127     10794654 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   21128     10794654 : }
   21129              : 
   21130              : 
   21131              : /*
   21132              :    PushT - Push an item onto the stack in the T (true) position.
   21133              : */
   21134              : 
   21135     99380482 : extern "C" void M2Quads_PushT (unsigned int True)
   21136              : {
   21137     99380482 :   M2Quads_BoolFrame f;
   21138              : 
   21139     99380482 :   f = newBoolFrame ();
   21140     99380482 :   f->TrueExit = static_cast<unsigned int> (True);
   21141     99380482 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21142     99380482 : }
   21143              : 
   21144              : 
   21145              : /*
   21146              :    PopT - Pops the T value from the stack.
   21147              : */
   21148              : 
   21149    146526691 : extern "C" void M2Quads_PopT (unsigned int *True)
   21150              : {
   21151    146526691 :   M2Quads_BoolFrame f;
   21152              : 
   21153    146526691 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   21154    146526685 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   21155    146526685 :   M2Debug_Assert (! f->BooleanOp);
   21156    146526685 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   21157    146526685 : }
   21158              : 
   21159              : 
   21160              : /*
   21161              :    PushTtok - Push an item onto the stack in the T (true) position,
   21162              :               it is assummed to be a token and its token location is recorded.
   21163              : */
   21164              : 
   21165     78856593 : extern "C" void M2Quads_PushTtok (unsigned int True, unsigned int tokno)
   21166              : {
   21167     78856593 :   M2Quads_BoolFrame f;
   21168              : 
   21169              :   /* PrintTokenNo (tokno) ;  */
   21170     78856593 :   f = newBoolFrame ();
   21171     78856593 :   f->TrueExit = static_cast<unsigned int> (True);
   21172     78856593 :   f->tokenno = tokno;
   21173     78856593 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21174     78856593 : }
   21175              : 
   21176              : 
   21177              : /*
   21178              :    PushTFtok - Push an item onto the stack in the T (true) position,
   21179              :                it is assummed to be a token and its token location is recorded.
   21180              : */
   21181              : 
   21182    157610803 : extern "C" void M2Quads_PushTFtok (unsigned int True, unsigned int False, unsigned int tokno)
   21183              : {
   21184    157610803 :   M2Quads_BoolFrame f;
   21185              : 
   21186    157610803 :   f = newBoolFrame ();
   21187    157610803 :   f->TrueExit = static_cast<unsigned int> (True);
   21188    157610803 :   f->FalseExit = static_cast<unsigned int> (False);
   21189    157610803 :   f->tokenno = tokno;
   21190    157610803 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21191    157610803 : }
   21192              : 
   21193              : 
   21194              : /*
   21195              :    PopTFtok - Pop T/F/tok from the stack.
   21196              : */
   21197              : 
   21198      9540543 : extern "C" void M2Quads_PopTFtok (unsigned int *True, unsigned int *False, unsigned int *tokno)
   21199              : {
   21200      9540543 :   M2Quads_BoolFrame f;
   21201              : 
   21202      9540543 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   21203      9540543 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   21204      9540543 :   (*False) = static_cast<unsigned int> (f->FalseExit);
   21205      9540543 :   (*tokno) = f->tokenno;
   21206      9540543 : }
   21207              : 
   21208              : 
   21209              : /*
   21210              :    PushTFAtok - Push T/F/A/tok to the stack.
   21211              : */
   21212              : 
   21213           54 : extern "C" void M2Quads_PushTFAtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int tokno)
   21214              : {
   21215           54 :   M2Quads_BoolFrame f;
   21216              : 
   21217           54 :   f = newBoolFrame ();
   21218           54 :   f->TrueExit = static_cast<unsigned int> (True);
   21219           54 :   f->FalseExit = static_cast<unsigned int> (False);
   21220           54 :   f->Unbounded = static_cast<unsigned int> (Array);
   21221           54 :   f->tokenno = tokno;
   21222           54 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21223           54 : }
   21224              : 
   21225              : 
   21226              : /*
   21227              :    PopTtok - Pops the T value from the stack and token position.
   21228              : */
   21229              : 
   21230    117980809 : extern "C" void M2Quads_PopTtok (unsigned int *True, unsigned int *tok)
   21231              : {
   21232    117980809 :   M2Quads_BoolFrame f;
   21233              : 
   21234    117980809 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   21235    117980809 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   21236    117980809 :   (*tok) = f->tokenno;
   21237    117980809 :   M2Debug_Assert (! f->BooleanOp);
   21238    117980809 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   21239    117980809 : }
   21240              : 
   21241              : 
   21242              : /*
   21243              :    PushTFn - Push a True and False numbers onto the True/False stack.
   21244              :              True and False are assumed to contain Symbols or Ident etc.
   21245              : */
   21246              : 
   21247            0 : extern "C" void M2Quads_PushTFn (unsigned int True, unsigned int False, unsigned int n)
   21248              : {
   21249            0 :   M2Quads_BoolFrame f;
   21250              : 
   21251            0 :   f = newBoolFrame ();
   21252            0 :   f->TrueExit = static_cast<unsigned int> (True);
   21253            0 :   f->FalseExit = static_cast<unsigned int> (False);
   21254            0 :   f->name = static_cast<unsigned int> (n);
   21255            0 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21256            0 : }
   21257              : 
   21258              : 
   21259              : /*
   21260              :    PushTFntok - Push a True and False numbers onto the True/False stack.
   21261              :                 True and False are assumed to contain Symbols or Ident etc.
   21262              : */
   21263              : 
   21264       666833 : extern "C" void M2Quads_PushTFntok (unsigned int True, unsigned int False, unsigned int n, unsigned int tokno)
   21265              : {
   21266       666833 :   M2Quads_BoolFrame f;
   21267              : 
   21268       666833 :   f = newBoolFrame ();
   21269       666833 :   f->TrueExit = static_cast<unsigned int> (True);
   21270       666833 :   f->FalseExit = static_cast<unsigned int> (False);
   21271       666833 :   f->name = static_cast<unsigned int> (n);
   21272       666833 :   f->tokenno = tokno;
   21273       666833 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21274       666833 : }
   21275              : 
   21276              : 
   21277              : /*
   21278              :    PopTFn - Pop a True and False number from the True/False stack.
   21279              :             True and False are assumed to contain Symbols or Ident etc.
   21280              : */
   21281              : 
   21282            0 : extern "C" void M2Quads_PopTFn (unsigned int *True, unsigned int *False, unsigned int *n)
   21283              : {
   21284            0 :   M2Quads_BoolFrame f;
   21285              : 
   21286            0 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   21287            0 :   (*True) = static_cast<unsigned int> (f->TrueExit);
   21288            0 :   (*False) = static_cast<unsigned int> (f->FalseExit);
   21289            0 :   (*n) = static_cast<unsigned int> (f->name);
   21290            0 :   M2Debug_Assert (! f->BooleanOp);
   21291            0 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   21292            0 : }
   21293              : 
   21294              : 
   21295              : /*
   21296              :    PopNothing - pops the top element on the boolean stack.
   21297              : */
   21298              : 
   21299     66632489 : extern "C" void M2Quads_PopNothing (void)
   21300              : {
   21301     66632489 :   M2Quads_BoolFrame f;
   21302              : 
   21303     66632489 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   21304     66632489 :   Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
   21305     66632489 : }
   21306              : 
   21307              : 
   21308              : /*
   21309              :    PopN - pops multiple elements from the BoolStack.
   21310              : */
   21311              : 
   21312     12798261 : extern "C" void M2Quads_PopN (unsigned int n)
   21313              : {
   21314     48464297 :   while (n > 0)
   21315              :     {
   21316     35666036 :       M2Quads_PopNothing ();
   21317     35666036 :       n -= 1;
   21318              :     }
   21319     12798261 : }
   21320              : 
   21321              : 
   21322              : /*
   21323              :    PushTFA - Push True, False, Array, numbers onto the
   21324              :              True/False stack.  True and False are assumed to
   21325              :              contain Symbols or Ident etc.
   21326              : */
   21327              : 
   21328            0 : extern "C" void M2Quads_PushTFA (unsigned int True, unsigned int False, unsigned int Array)
   21329              : {
   21330            0 :   M2Quads_BoolFrame f;
   21331              : 
   21332            0 :   f = newBoolFrame ();
   21333            0 :   f->TrueExit = static_cast<unsigned int> (True);
   21334            0 :   f->FalseExit = static_cast<unsigned int> (False);
   21335            0 :   f->Unbounded = static_cast<unsigned int> (Array);
   21336            0 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21337            0 : }
   21338              : 
   21339              : 
   21340              : /*
   21341              :    OperandTok - returns the token associated with pos, on the stack.
   21342              : */
   21343              : 
   21344     56991111 : extern "C" unsigned int M2Quads_OperandTok (unsigned int pos)
   21345              : {
   21346     56991111 :   M2Debug_Assert (! (IsBoolean (pos)));
   21347     56991111 :   return static_cast<unsigned int> (OperandTtok (pos));
   21348              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   21349              :   __builtin_unreachable ();
   21350              : }
   21351              : 
   21352              : 
   21353              : /*
   21354              :    OperandA - returns possible array symbol associated with the ident
   21355              :               operand stored on the boolean stack.
   21356              : */
   21357              : 
   21358      2264995 : extern "C" unsigned int M2Quads_OperandA (unsigned int pos)
   21359              : {
   21360      2264995 :   M2Quads_BoolFrame f;
   21361              : 
   21362      2264995 :   M2Debug_Assert (pos > 0);
   21363      2264995 :   M2Debug_Assert (! (IsBoolean (pos)));
   21364      2264995 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
   21365      2264995 :   return static_cast<unsigned int> (f->Unbounded);
   21366              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   21367              :   __builtin_unreachable ();
   21368              : }
   21369              : 
   21370              : 
   21371              : /*
   21372              :    OperandAnno - returns the annotation string associated with the
   21373              :                  position, n, on the stack.
   21374              : */
   21375              : 
   21376            0 : extern "C" DynamicStrings_String M2Quads_OperandAnno (unsigned int n)
   21377              : {
   21378            0 :   M2Quads_BoolFrame f;
   21379              : 
   21380            0 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, n));
   21381            0 :   return f->Annotation;
   21382              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   21383              :   __builtin_unreachable ();
   21384              : }
   21385              : 
   21386              : 
   21387              : /*
   21388              :    Annotate - annotate the top of stack.
   21389              : */
   21390              : 
   21391    126172649 : extern "C" void M2Quads_Annotate (const char *a_, unsigned int _a_high)
   21392              : {
   21393    126172649 :   M2Quads_BoolFrame f;
   21394    126172649 :   char a[_a_high+1];
   21395              : 
   21396              :   /* make a local copy of each unbounded array.  */
   21397    126172649 :   memcpy (a, a_, _a_high+1);
   21398              : 
   21399            0 :   if ((DebugStackOn && M2Options_CompilerDebugging) && ((M2StackAddress_NoOfItemsInStackAddress (BoolStack)) > 0))
   21400              :     {
   21401            0 :       f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, 1));  /* top of stack  */
   21402            0 :       if (f->Annotation != NULL)  /* top of stack  */
   21403              :         {
   21404            0 :           f->Annotation = DynamicStrings_KillString (f->Annotation);
   21405              :         }
   21406            0 :       f->Annotation = DynamicStrings_InitString ((const char *) a, _a_high);
   21407              :     }
   21408    126172649 : }
   21409              : 
   21410              : 
   21411              : /*
   21412              :    DisplayStack - displays the compile time symbol stack.
   21413              : */
   21414              : 
   21415     20456448 : extern "C" void M2Quads_DisplayStack (void)
   21416              : {
   21417     20456448 :   if (DebugStackOn && M2Options_CompilerDebugging)
   21418              :     {
   21419            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});
   21420              :     }
   21421     20456448 : }
   21422              : 
   21423              : 
   21424              : /*
   21425              :    Top - returns the no of items held in the stack.
   21426              : */
   21427              : 
   21428     92077895 : extern "C" unsigned int M2Quads_Top (void)
   21429              : {
   21430     92077895 :   return M2StackAddress_NoOfItemsInStackAddress (BoolStack);
   21431              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   21432              :   __builtin_unreachable ();
   21433              : }
   21434              : 
   21435              : 
   21436              : /*
   21437              :    DupFrame - duplicate the top of stack and push the new frame.
   21438              : */
   21439              : 
   21440            0 : extern "C" void M2Quads_DupFrame (void)
   21441              : {
   21442            0 :   M2Quads_BoolFrame f;
   21443            0 :   M2Quads_BoolFrame newf;
   21444              : 
   21445            0 :   f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
   21446            0 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
   21447            0 :   newf = newBoolFrame ();
   21448            0 :   (*newf) = (*f);
   21449            0 :   M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (newf));
   21450            0 : }
   21451              : 
   21452              : 
   21453              : /*
   21454              :    WriteOperand - displays the operands name, symbol id and mode of addressing.
   21455              : */
   21456              : 
   21457            0 : extern "C" void M2Quads_WriteOperand (unsigned int Sym)
   21458              : {
   21459            0 :   NameKey_Name n;
   21460              : 
   21461            0 :   if (Sym == SymbolTable_NulSym)
   21462              :     {
   21463            0 :       M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "<nulsym>", 8);
   21464              :     }
   21465              :   else
   21466              :     {
   21467            0 :       n = SymbolTable_GetSymName (Sym);
   21468            0 :       M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%a", 2, (const unsigned char *) &n, (sizeof (n)-1));
   21469            0 :       if ((SymbolTable_IsVar (Sym)) || (SymbolTable_IsConst (Sym)))
   21470              :         {
   21471            0 :           M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "[", 1);
   21472            0 :           WriteMode (SymbolTable_GetMode (Sym));
   21473            0 :           M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "]", 1);
   21474              :         }
   21475            0 :       M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "(%d)", 4, (const unsigned char *) &Sym, (sizeof (Sym)-1));
   21476            0 :       if (SymbolConversion_GccKnowsAbout (Sym))
   21477              :         {
   21478            0 :           M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "[gcc]", 5);
   21479              :         }
   21480              :     }
   21481            0 : }
   21482              : 
   21483              : 
   21484              : /*
   21485              :    BeginVarient - begin a varient record.
   21486              : */
   21487              : 
   21488         3054 : extern "C" void M2Quads_BeginVarient (void)
   21489              : {
   21490         3054 :   unsigned int r;
   21491         3054 :   unsigned int v;
   21492              : 
   21493         3054 :   r = GetRecordOrField ();
   21494         6108 :   M2Debug_Assert ((SymbolTable_IsRecord (r)) || (SymbolTable_IsFieldVarient (r)));
   21495         3054 :   v = GetRecordOrField ();
   21496         3054 :   M2Debug_Assert (SymbolTable_IsVarient (v));
   21497         3054 :   BuildRange (M2Range_InitCaseBounds (M2CaseList_PushCase (r, v, SymbolTable_NulSym)));
   21498         3054 : }
   21499              : 
   21500              : 
   21501              : /*
   21502              :    EndVarient - end a varient record.
   21503              : */
   21504              : 
   21505         3054 : extern "C" void M2Quads_EndVarient (void)
   21506              : {
   21507         3054 :   M2CaseList_PopCase ();
   21508         3054 : }
   21509              : 
   21510              : 
   21511              : /*
   21512              :    ElseVarient - associate an ELSE clause with a varient record.
   21513              : */
   21514              : 
   21515          114 : extern "C" void M2Quads_ElseVarient (void)
   21516              : {
   21517          114 :   unsigned int f;
   21518              : 
   21519          114 :   f = GetRecordOrField ();
   21520          114 :   M2Debug_Assert (SymbolTable_IsFieldVarient (f));
   21521          114 :   M2CaseList_ElseCase (f);
   21522          114 : }
   21523              : 
   21524              : 
   21525              : /*
   21526              :    BeginVarientList - begin an ident list containing ranges belonging to a
   21527              :                       varient list.
   21528              : */
   21529              : 
   21530         6108 : extern "C" void M2Quads_BeginVarientList (void)
   21531              : {
   21532         6108 :   unsigned int f;
   21533              : 
   21534         6108 :   f = GetRecordOrField ();
   21535         6108 :   M2Debug_Assert (SymbolTable_IsFieldVarient (f));
   21536         6108 :   M2CaseList_BeginCaseList (f);
   21537         6108 : }
   21538              : 
   21539              : 
   21540              : /*
   21541              :    EndVarientList - end a range list for a varient field.
   21542              : */
   21543              : 
   21544         6108 : extern "C" void M2Quads_EndVarientList (void)
   21545              : {
   21546         6108 :   M2CaseList_EndCaseList ();
   21547         6108 : }
   21548              : 
   21549              : 
   21550              : /*
   21551              :    AddRecordToList - adds the record held on the top of stack to the
   21552              :                      list of records and varient fields.
   21553              : */
   21554              : 
   21555         3054 : extern "C" void M2Quads_AddRecordToList (void)
   21556              : {
   21557         3054 :   unsigned int r;
   21558         3054 :   unsigned int n;
   21559              : 
   21560         3054 :   r = static_cast<unsigned int> (M2Quads_OperandT (1));
   21561         6108 :   M2Debug_Assert ((SymbolTable_IsRecord (r)) || (SymbolTable_IsFieldVarient (r)));
   21562              :   /* 
   21563              :       r might be a field varient if the declaration consists of nested
   21564              :       varients.  However ISO TSIZE can only utilise record types, we store
   21565              :       a varient field anyway as the next pass would not know whether to
   21566              :       ignore a varient field.
   21567              :   */
   21568         3054 :   Lists_PutItemIntoList (VarientFields, r);
   21569         3054 :   if (DebugVarients)
   21570              :     {
   21571              :       n = Lists_NoOfItemsInList (VarientFields);
   21572              :       if (SymbolTable_IsRecord (r))
   21573              :         {
   21574              :           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));
   21575              :         }
   21576              :       else
   21577              :         {
   21578              :           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));
   21579              :         }
   21580              :     }
   21581         3054 : }
   21582              : 
   21583              : 
   21584              : /*
   21585              :    AddVarientToList - adds varient held on the top of stack to the list.
   21586              : */
   21587              : 
   21588         3054 : extern "C" void M2Quads_AddVarientToList (void)
   21589              : {
   21590         3054 :   unsigned int v;
   21591         3054 :   unsigned int n;
   21592              : 
   21593         3054 :   v = static_cast<unsigned int> (M2Quads_OperandT (1));
   21594         3054 :   M2Debug_Assert (SymbolTable_IsVarient (v));
   21595         3054 :   Lists_PutItemIntoList (VarientFields, v);
   21596         3054 :   if (DebugVarients)
   21597              :     {
   21598              :       n = Lists_NoOfItemsInList (VarientFields);
   21599              :       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));
   21600              :     }
   21601         3054 : }
   21602              : 
   21603              : 
   21604              : /*
   21605              :    AddVarientFieldToList - adds varient field, f, to the list of all varient
   21606              :                            fields created.
   21607              : */
   21608              : 
   21609         6222 : extern "C" void M2Quads_AddVarientFieldToList (unsigned int f)
   21610              : {
   21611         6222 :   unsigned int n;
   21612              : 
   21613         6222 :   M2Debug_Assert (SymbolTable_IsFieldVarient (f));
   21614         6222 :   Lists_PutItemIntoList (VarientFields, f);
   21615         6222 :   if (DebugVarients)
   21616              :     {
   21617              :       n = Lists_NoOfItemsInList (VarientFields);
   21618              :       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));
   21619              :     }
   21620         6222 : }
   21621              : 
   21622              : 
   21623              : /*
   21624              :    AddVarientRange - creates a range from the top two contant expressions
   21625              :                      on the stack which are recorded with the current
   21626              :                      varient field.  The stack is unaltered.
   21627              : */
   21628              : 
   21629            0 : extern "C" void M2Quads_AddVarientRange (void)
   21630              : {
   21631            0 :   unsigned int r1;
   21632            0 :   unsigned int r2;
   21633              : 
   21634            0 :   M2Quads_PopT (&r2);
   21635            0 :   M2Quads_PopT (&r1);
   21636            0 :   M2CaseList_AddRange (r1, r2, M2LexBuf_GetTokenNo ());
   21637            0 : }
   21638              : 
   21639              : 
   21640              : /*
   21641              :    AddVarientEquality - adds the contant expression on the top of the stack
   21642              :                         to the current varient field being recorded.
   21643              :                         The stack is unaltered.
   21644              : */
   21645              : 
   21646         6150 : extern "C" void M2Quads_AddVarientEquality (void)
   21647              : {
   21648         6150 :   unsigned int r1;
   21649              : 
   21650         6150 :   M2Quads_PopT (&r1);
   21651         6150 :   M2CaseList_AddRange (r1, SymbolTable_NulSym, M2LexBuf_GetTokenNo ());
   21652         6150 : }
   21653              : 
   21654              : 
   21655              : /*
   21656              :    BuildCodeOn - generates a quadruple declaring that code should be
   21657              :                  emmitted from henceforth.
   21658              : 
   21659              :                  The Stack is unnaffected.
   21660              : */
   21661              : 
   21662            0 : extern "C" void M2Quads_BuildCodeOn (void)
   21663              : {
   21664            0 :   GenQuad (M2Quads_CodeOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
   21665            0 : }
   21666              : 
   21667              : 
   21668              : /*
   21669              :    BuildCodeOff - generates a quadruple declaring that code should not be
   21670              :                   emmitted from henceforth.
   21671              : 
   21672              :                   The Stack is unnaffected.
   21673              : */
   21674              : 
   21675            0 : extern "C" void M2Quads_BuildCodeOff (void)
   21676              : {
   21677            0 :   GenQuad (M2Quads_CodeOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
   21678            0 : }
   21679              : 
   21680              : 
   21681              : /*
   21682              :    BuildProfileOn - generates a quadruple declaring that profile timings
   21683              :                     should be emmitted from henceforth.
   21684              : 
   21685              :                     The Stack is unnaffected.
   21686              : */
   21687              : 
   21688            0 : extern "C" void M2Quads_BuildProfileOn (void)
   21689              : {
   21690            0 :   GenQuad (M2Quads_ProfileOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
   21691            0 : }
   21692              : 
   21693            0 : extern "C" void M2Quads_BuildProfileOff (void)
   21694              : {
   21695              :   /* 
   21696              :    BuildProfileOn - generates a quadruple declaring that profile timings
   21697              :                     should be emmitted from henceforth.
   21698              : 
   21699              :                     The Stack is unnaffected.
   21700              :   */
   21701            0 :   GenQuad (M2Quads_ProfileOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
   21702            0 : }
   21703              : 
   21704              : 
   21705              : /*
   21706              :    BuildOptimizeOn - generates a quadruple declaring that optimization
   21707              :                      should occur from henceforth.
   21708              : 
   21709              :                      The Stack is unnaffected.
   21710              : */
   21711              : 
   21712            0 : extern "C" void M2Quads_BuildOptimizeOn (void)
   21713              : {
   21714            0 :   GenQuad (M2Quads_OptimizeOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
   21715            0 : }
   21716              : 
   21717              : 
   21718              : /*
   21719              :    BuildOptimizeOff - generates a quadruple declaring that optimization
   21720              :                       should not occur from henceforth.
   21721              : 
   21722              :                       The Stack is unnaffected.
   21723              : */
   21724              : 
   21725            0 : extern "C" void M2Quads_BuildOptimizeOff (void)
   21726              : {
   21727            0 :   GenQuad (M2Quads_OptimizeOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
   21728            0 : }
   21729              : 
   21730              : 
   21731              : /*
   21732              :    BuildAsm - builds an Inline pseudo quadruple operator.
   21733              :               The inline interface, Sym, is stored as the operand
   21734              :               to the operator InlineOp.
   21735              : 
   21736              :               The stack is expected to contain:
   21737              : 
   21738              : 
   21739              :                         Entry                   Exit
   21740              :                         =====                   ====
   21741              : 
   21742              :               Ptr ->
   21743              :                      +--------------+
   21744              :                      | Sym          |        Empty
   21745              :                      |--------------|
   21746              : */
   21747              : 
   21748           27 : extern "C" void M2Quads_BuildAsm (unsigned int tok)
   21749              : {
   21750           27 :   unsigned int Sym;
   21751              : 
   21752           27 :   M2Quads_PopT (&Sym);
   21753           27 :   GenQuadO (tok, M2Quads_InlineOp, SymbolTable_NulSym, SymbolTable_NulSym, Sym, false);
   21754           27 : }
   21755              : 
   21756              : 
   21757              : /*
   21758              :    BuildLineNo - builds a LineNumberOp pseudo quadruple operator.
   21759              :                  This quadruple indicates which source line has been
   21760              :                  processed, these quadruples are only generated if we
   21761              :                  are producing runtime debugging information.
   21762              : 
   21763              :                  The stack is not affected, read or altered in any way.
   21764              : 
   21765              : 
   21766              :                         Entry                   Exit
   21767              :                         =====                   ====
   21768              : 
   21769              :                  Ptr ->                              <- Ptr
   21770              : */
   21771              : 
   21772            0 : extern "C" void M2Quads_BuildLineNo (void)
   21773              : {
   21774            0 :   NameKey_Name filename;
   21775            0 :   M2Quads_QuadFrame f;
   21776              : 
   21777            0 :   if (((NextQuad != Head) && (M2Options_GenerateLineDebug || M2Options_GenerateDebugging)) && false)
   21778              :     {
   21779              :       filename = NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()));
   21780              :       f = GetQF (NextQuad-1);
   21781              :       if (! ((f->Operator == M2Quads_LineNumberOp) && (f->Operand1 == ((unsigned int ) (filename)))))
   21782              :         {
   21783              :           GenQuad (M2Quads_LineNumberOp, (unsigned int ) (filename), SymbolTable_NulSym, (unsigned int ) (M2LexBuf_GetLineNo ()));
   21784              :         }
   21785              :     }
   21786            0 : }
   21787              : 
   21788              : 
   21789              : /*
   21790              :    PushLineNo - pushes the current file and line number to the stack.
   21791              : */
   21792              : 
   21793         5152 : extern "C" void M2Quads_PushLineNo (void)
   21794              : {
   21795         5152 :   PushLineNote (InitLineNote (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ())), M2LexBuf_GetLineNo ()));
   21796         5152 : }
   21797              : 
   21798              : 
   21799              : /*
   21800              :    BuildStmtNote - builds a StatementNoteOp pseudo quadruple operator.
   21801              :                    This quadruple indicates which source line has been
   21802              :                    processed and it represents the start of a statement
   21803              :                    sequence.
   21804              :                    It differs from LineNumberOp in that multiple successive
   21805              :                    LineNumberOps will be removed and the final one is attached to
   21806              :                    the next real GCC tree.  Whereas a StatementNoteOp is always left
   21807              :                    alone.  Depending upon the debugging level it will issue a nop
   21808              :                    instruction to ensure that the gdb single step will step into
   21809              :                    this line.  Practically it allows pedalogical debugging to
   21810              :                    occur when there is syntax sugar such as:
   21811              : 
   21812              : 
   21813              :                          END   step 
   21814              :                       END   step 
   21815              :                    END ;  step 
   21816              :                    a := 1 ;  step 
   21817              : 
   21818              :                    REPEAT  step 
   21819              :                       i := 1   step 
   21820              : 
   21821              :                    The stack is not affected, read or altered in any way.
   21822              : 
   21823              : 
   21824              :                         Entry                   Exit
   21825              :                         =====                   ====
   21826              : 
   21827              :                  Ptr ->                              <- Ptr
   21828              : */
   21829              : 
   21830       542276 : extern "C" void M2Quads_BuildStmtNote (int offset)
   21831              : {
   21832       542276 :   int tokenno;
   21833              : 
   21834       542276 :   if (NextQuad != Head)
   21835              :     {
   21836       542276 :       tokenno = offset;
   21837       542276 :       tokenno += M2LexBuf_GetTokenNo ();
   21838       542276 :       BuildStmtNoteTok ((unsigned int ) (tokenno));
   21839              :     }
   21840       542276 : }
   21841              : 
   21842              : 
   21843              : /*
   21844              :    LoopAnalysis - checks whether an infinite loop exists.
   21845              : */
   21846              : 
   21847       410204 : extern "C" void M2Quads_LoopAnalysis (unsigned int Scope, unsigned int Current, unsigned int End)
   21848              : {
   21849       410204 :   M2Quads_QuadOperator op;
   21850       410204 :   unsigned int op1;
   21851       410204 :   unsigned int op2;
   21852       410204 :   unsigned int op3;
   21853              : 
   21854       410204 :   if (M2Options_Pedantic)
   21855              :     {
   21856        11442 :       while ((Current <= End) && (Current != 0))
   21857              :         {
   21858         9990 :           M2Quads_GetQuad (Current, &op, &op1, &op2, &op3);
   21859         9990 :           if ((op == M2Quads_GotoOp) || (M2Quads_IsConditional (Current)))
   21860              :             {
   21861          114 :               if (op3 <= Current)
   21862              :                 {
   21863              :                   /* found a loop - ie a branch which goes back in quadruple numbers  */
   21864           24 :                   if (IsInfiniteLoop (Current))
   21865              :                     {
   21866            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);
   21867            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);
   21868              :                     }
   21869              :                   /* 
   21870              :                   WarnStringAt(InitString('it is very likely (although not absolutely certain) that the top of an infinite loop is here'),
   21871              :                                QuadToTokenNo(op3)) ;
   21872              :                   WarnStringAt(InitString('and the bottom of the infinite loop is ends here or alternatively a component of this loop is never executed'),
   21873              :                                QuadToTokenNo(Current))
   21874              :   */
   21875              :                 }
   21876              :             }
   21877         9990 :           Current = M2Quads_GetNextQuad (Current);
   21878              :         }
   21879              :     }
   21880       410204 : }
   21881              : 
   21882              : 
   21883              : /*
   21884              :    ForLoopAnalysis - checks all the FOR loops for index variable manipulation
   21885              :                      and dangerous usage outside the loop.
   21886              : */
   21887              : 
   21888        14425 : extern "C" void M2Quads_ForLoopAnalysis (void)
   21889              : {
   21890        14425 :   unsigned int i;
   21891        14425 :   unsigned int n;
   21892        14425 :   M2Quads_ForLoopInfo forDesc;
   21893              : 
   21894        14425 :   if (M2Options_Pedantic)
   21895              :     {
   21896          108 :       n = Indexing_HighIndice (ForInfo);
   21897          108 :       i = 1;
   21898          216 :       while (i <= n)
   21899              :         {
   21900            0 :           forDesc = static_cast<M2Quads_ForLoopInfo> (Indexing_GetIndice (ForInfo, i));
   21901            0 :           CheckForIndex (forDesc);
   21902            0 :           i += 1;
   21903              :         }
   21904              :     }
   21905        14425 : }
   21906              : 
   21907              : 
   21908              : /*
   21909              :    BuildSizeCheckStart - switches off all quadruple generation if the function SIZE or HIGH
   21910              :                          is being "called".  This should be done as SIZE only requires the
   21911              :                          actual type of the expression, not its value.  Consider the problem of
   21912              :                          SIZE(UninitializedPointer^) which is quite legal and it must
   21913              :                          also be safe!
   21914              :                          ISO Modula-2 also allows HIGH(a[0]) for a two dimensional array
   21915              :                          and there is no need to compute a[0], we just need to follow the
   21916              :                          type and count dimensions.  However if SIZE(a) or HIGH(a) occurs
   21917              :                          and, a, is an unbounded array then we turn on quadruple generation.
   21918              : 
   21919              :                          The Stack is expected to contain:
   21920              : 
   21921              : 
   21922              :                          Entry                       Exit
   21923              :                          =====                       ====
   21924              : 
   21925              :                  Ptr ->                                                       <- Ptr
   21926              :                         +----------------------+     +----------------------+
   21927              :                         | ProcSym | Type | tok |     | ProcSym | Type | tok |
   21928              :                         |----------------------|     |----------------------|
   21929              : */
   21930              : 
   21931       191968 : extern "C" void M2Quads_BuildSizeCheckStart (void)
   21932              : {
   21933       191968 :   unsigned int ProcSym;
   21934       191968 :   unsigned int Type;
   21935       191968 :   unsigned int tok;
   21936              : 
   21937       191968 :   M2Quads_PopTFtok (&ProcSym, &Type, &tok);
   21938       191968 :   if (((ProcSym == M2Size_Size) || (ProcSym == M2System_TSize)) || (ProcSym == M2System_TBitSize))
   21939              :     {
   21940         9245 :       QuadrupleGeneration = false;
   21941         9245 :       BuildingSize = true;
   21942              :     }
   21943       182723 :   else if (ProcSym == M2Base_High)
   21944              :     {
   21945              :       /* avoid dangling else.  */
   21946         2976 :       QuadrupleGeneration = false;
   21947         2976 :       BuildingHigh = true;
   21948              :     }
   21949       191968 :   M2Quads_PushTFtok (ProcSym, Type, tok);
   21950       191968 : }
   21951              : 
   21952              : 
   21953              : /*
   21954              :    BackPatchSubrangesAndOptParam - runs through all the quadruples and finds SubrangeLow or SubrangeHigh
   21955              :                                    quadruples and replaces it by an assignment to the Low or High component
   21956              :                                    of the subrange type.
   21957              : 
   21958              :                                    Input:
   21959              :                                    SubrangeLow    op1     op3          op3 is a subrange 
   21960              : 
   21961              :                                    Output:
   21962              :                                    Becomes        op1     low
   21963              : 
   21964              :                                    Input:
   21965              :                                    SubrangeHigh   op1     op3          op3 is a subrange 
   21966              : 
   21967              :                                    Output:
   21968              :                                    Becomes        op1     high
   21969              : 
   21970              :                                    Input:
   21971              :                                    OptParam       op1     op2    op3
   21972              : 
   21973              :                                    Output:
   21974              :                                    Param          op1     op2    GetOptArgInit(op3)
   21975              : */
   21976              : 
   21977        14425 : extern "C" void M2Quads_BackPatchSubrangesAndOptParam (void)
   21978              : {
   21979        14425 :   M2Quads_QuadFrame f;
   21980        14425 :   unsigned int q;
   21981              : 
   21982        14425 :   q = M2Quads_GetFirstQuad ();
   21983        14425 :   if (q != 0)
   21984              :     {
   21985      6226458 :       do {
   21986      6226458 :         f = GetQF (q);
   21987      6226458 :         switch (f->Operator)
   21988              :           {
   21989          306 :             case M2Quads_SubrangeLowOp:
   21990          306 :               f->Operand3 = CollectLow (f->Operand3);
   21991          306 :               f->Operator = M2Quads_BecomesOp;
   21992          306 :               f->ConstExpr = false;
   21993          306 :               break;
   21994              : 
   21995          558 :             case M2Quads_SubrangeHighOp:
   21996          558 :               f->Operand3 = CollectHigh (f->Operand3);
   21997          558 :               f->Operator = M2Quads_BecomesOp;
   21998          558 :               f->ConstExpr = false;
   21999          558 :               break;
   22000              : 
   22001         3493 :             case M2Quads_OptParamOp:
   22002         3493 :               f->Operand3 = SymbolTable_GetOptArgInit (f->Operand3);
   22003         3493 :               f->Operator = M2Quads_ParamOp;
   22004         3493 :               break;
   22005              : 
   22006              : 
   22007              :             default:
   22008              :               break;
   22009              :           }
   22010      6226458 :         q = f->Next;
   22011      6226458 :       } while (! (q == 0));
   22012              :     }
   22013        14425 : }
   22014              : 
   22015              : 
   22016              : /*
   22017              :    WriteOperator - writes the name of the quadruple operator.
   22018              : */
   22019              : 
   22020            0 : extern "C" void M2Quads_WriteOperator (M2Quads_QuadOperator Operator)
   22021              : {
   22022            0 :   switch (Operator)
   22023              :     {
   22024            0 :       case M2Quads_ArithAddOp:
   22025            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Arith +           ", 18);
   22026            0 :         break;
   22027              : 
   22028            0 :       case M2Quads_InitAddressOp:
   22029            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitAddress       ", 18);
   22030            0 :         break;
   22031              : 
   22032            0 :       case M2Quads_LastForIteratorOp:
   22033            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "LastForIterator   ", 18);
   22034            0 :         break;
   22035              : 
   22036            0 :       case M2Quads_LogicalOrOp:
   22037            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Or                ", 18);
   22038            0 :         break;
   22039              : 
   22040            0 :       case M2Quads_LogicalAndOp:
   22041            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "And               ", 18);
   22042            0 :         break;
   22043              : 
   22044            0 :       case M2Quads_LogicalXorOp:
   22045            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Xor               ", 18);
   22046            0 :         break;
   22047              : 
   22048            0 :       case M2Quads_LogicalDiffOp:
   22049            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Ldiff             ", 18);
   22050            0 :         break;
   22051              : 
   22052            0 :       case M2Quads_LogicalShiftOp:
   22053            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Shift             ", 18);
   22054            0 :         break;
   22055              : 
   22056            0 :       case M2Quads_LogicalRotateOp:
   22057            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Rotate            ", 18);
   22058            0 :         break;
   22059              : 
   22060            0 :       case M2Quads_BecomesOp:
   22061            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Becomes           ", 18);
   22062            0 :         break;
   22063              : 
   22064            0 :       case M2Quads_IndrXOp:
   22065            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "IndrX             ", 18);
   22066            0 :         break;
   22067              : 
   22068            0 :       case M2Quads_XIndrOp:
   22069            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "XIndr             ", 18);
   22070            0 :         break;
   22071              : 
   22072            0 :       case M2Quads_ArrayOp:
   22073            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Array             ", 18);
   22074            0 :         break;
   22075              : 
   22076            0 :       case M2Quads_ElementSizeOp:
   22077            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ElementSize       ", 18);
   22078            0 :         break;
   22079              : 
   22080            0 :       case M2Quads_RecordFieldOp:
   22081            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RecordField       ", 18);
   22082            0 :         break;
   22083              : 
   22084            0 :       case M2Quads_AddrOp:
   22085            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Addr              ", 18);
   22086            0 :         break;
   22087              : 
   22088            0 :       case M2Quads_SizeOp:
   22089            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Size              ", 18);
   22090            0 :         break;
   22091              : 
   22092            0 :       case M2Quads_IfInOp:
   22093            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If IN             ", 18);
   22094            0 :         break;
   22095              : 
   22096            0 :       case M2Quads_IfNotInOp:
   22097            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If NOT IN         ", 18);
   22098            0 :         break;
   22099              : 
   22100            0 :       case M2Quads_IfNotEquOp:
   22101            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If <>             ", 18);
   22102            0 :         break;
   22103              : 
   22104            0 :       case M2Quads_IfEquOp:
   22105            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If =              ", 18);
   22106            0 :         break;
   22107              : 
   22108            0 :       case M2Quads_IfLessEquOp:
   22109            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If <=             ", 18);
   22110            0 :         break;
   22111              : 
   22112            0 :       case M2Quads_IfGreEquOp:
   22113            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If >=             ", 18);
   22114            0 :         break;
   22115              : 
   22116            0 :       case M2Quads_IfGreOp:
   22117            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If >              ", 18);
   22118            0 :         break;
   22119              : 
   22120            0 :       case M2Quads_IfLessOp:
   22121            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If <              ", 18);
   22122            0 :         break;
   22123              : 
   22124            0 :       case M2Quads_GotoOp:
   22125            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Goto              ", 18);
   22126            0 :         break;
   22127              : 
   22128            0 :       case M2Quads_DummyOp:
   22129            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Dummy             ", 18);
   22130            0 :         break;
   22131              : 
   22132            0 :       case M2Quads_ModuleScopeOp:
   22133            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ModuleScopeOp     ", 18);
   22134            0 :         break;
   22135              : 
   22136            0 :       case M2Quads_StartDefFileOp:
   22137            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StartDefFile      ", 18);
   22138            0 :         break;
   22139              : 
   22140            0 :       case M2Quads_StartModFileOp:
   22141            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StartModFile      ", 18);
   22142            0 :         break;
   22143              : 
   22144            0 :       case M2Quads_EndFileOp:
   22145            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "EndFileOp         ", 18);
   22146            0 :         break;
   22147              : 
   22148            0 :       case M2Quads_InitStartOp:
   22149            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitStart         ", 18);
   22150            0 :         break;
   22151              : 
   22152            0 :       case M2Quads_InitEndOp:
   22153            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitEnd           ", 18);
   22154            0 :         break;
   22155              : 
   22156            0 :       case M2Quads_FinallyStartOp:
   22157            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FinallyStart      ", 18);
   22158            0 :         break;
   22159              : 
   22160            0 :       case M2Quads_FinallyEndOp:
   22161            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FinallyEnd        ", 18);
   22162            0 :         break;
   22163              : 
   22164            0 :       case M2Quads_RetryOp:
   22165            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Retry             ", 18);
   22166            0 :         break;
   22167              : 
   22168            0 :       case M2Quads_TryOp:
   22169            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Try               ", 18);
   22170            0 :         break;
   22171              : 
   22172            0 :       case M2Quads_ThrowOp:
   22173            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Throw             ", 18);
   22174            0 :         break;
   22175              : 
   22176            0 :       case M2Quads_CatchBeginOp:
   22177            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CatchBegin        ", 18);
   22178            0 :         break;
   22179              : 
   22180            0 :       case M2Quads_CatchEndOp:
   22181            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CatchEnd          ", 18);
   22182            0 :         break;
   22183              : 
   22184            0 :       case M2Quads_AddOp:
   22185            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "+                 ", 18);
   22186            0 :         break;
   22187              : 
   22188            0 :       case M2Quads_SubOp:
   22189            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "-                 ", 18);
   22190            0 :         break;
   22191              : 
   22192            0 :       case M2Quads_DivM2Op:
   22193            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV M2            ", 18);
   22194            0 :         break;
   22195              : 
   22196            0 :       case M2Quads_ModM2Op:
   22197            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD M2            ", 18);
   22198            0 :         break;
   22199              : 
   22200            0 :       case M2Quads_DivCeilOp:
   22201            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV ceil          ", 18);
   22202            0 :         break;
   22203              : 
   22204            0 :       case M2Quads_ModCeilOp:
   22205            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD ceil          ", 18);
   22206            0 :         break;
   22207              : 
   22208            0 :       case M2Quads_DivFloorOp:
   22209            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV floor         ", 18);
   22210            0 :         break;
   22211              : 
   22212            0 :       case M2Quads_ModFloorOp:
   22213            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD floor         ", 18);
   22214            0 :         break;
   22215              : 
   22216            0 :       case M2Quads_DivTruncOp:
   22217            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV trunc         ", 18);
   22218            0 :         break;
   22219              : 
   22220            0 :       case M2Quads_ModTruncOp:
   22221            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD trunc         ", 18);
   22222            0 :         break;
   22223              : 
   22224            0 :       case M2Quads_MultOp:
   22225            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "*                 ", 18);
   22226            0 :         break;
   22227              : 
   22228            0 :       case M2Quads_NegateOp:
   22229            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Negate            ", 18);
   22230            0 :         break;
   22231              : 
   22232            0 :       case M2Quads_InclOp:
   22233            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Incl              ", 18);
   22234            0 :         break;
   22235              : 
   22236            0 :       case M2Quads_ExclOp:
   22237            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Excl              ", 18);
   22238            0 :         break;
   22239              : 
   22240            0 :       case M2Quads_ReturnOp:
   22241            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Return            ", 18);
   22242            0 :         break;
   22243              : 
   22244            0 :       case M2Quads_ReturnValueOp:
   22245            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ReturnValue       ", 18);
   22246            0 :         break;
   22247              : 
   22248            0 :       case M2Quads_FunctValueOp:
   22249            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FunctValue        ", 18);
   22250            0 :         break;
   22251              : 
   22252            0 :       case M2Quads_CallOp:
   22253            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Call              ", 18);
   22254            0 :         break;
   22255              : 
   22256            0 :       case M2Quads_ParamOp:
   22257            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Param             ", 18);
   22258            0 :         break;
   22259              : 
   22260            0 :       case M2Quads_OptParamOp:
   22261            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptParam          ", 18);
   22262            0 :         break;
   22263              : 
   22264            0 :       case M2Quads_NewLocalVarOp:
   22265            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "NewLocalVar       ", 18);
   22266            0 :         break;
   22267              : 
   22268            0 :       case M2Quads_KillLocalVarOp:
   22269            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "KillLocalVar      ", 18);
   22270            0 :         break;
   22271              : 
   22272            0 :       case M2Quads_ProcedureScopeOp:
   22273            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProcedureScope    ", 18);
   22274            0 :         break;
   22275              : 
   22276            0 :       case M2Quads_UnboundedOp:
   22277            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Unbounded         ", 18);
   22278            0 :         break;
   22279              : 
   22280            0 :       case M2Quads_CoerceOp:
   22281            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Coerce            ", 18);
   22282            0 :         break;
   22283              : 
   22284            0 :       case M2Quads_ConvertOp:
   22285            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Convert           ", 18);
   22286            0 :         break;
   22287              : 
   22288            0 :       case M2Quads_CastOp:
   22289            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Cast              ", 18);
   22290            0 :         break;
   22291              : 
   22292            0 :       case M2Quads_HighOp:
   22293            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "High              ", 18);
   22294            0 :         break;
   22295              : 
   22296            0 :       case M2Quads_CodeOnOp:
   22297            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CodeOn            ", 18);
   22298            0 :         break;
   22299              : 
   22300            0 :       case M2Quads_CodeOffOp:
   22301            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CodeOff           ", 18);
   22302            0 :         break;
   22303              : 
   22304            0 :       case M2Quads_ProfileOnOp:
   22305            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProfileOn         ", 18);
   22306            0 :         break;
   22307              : 
   22308            0 :       case M2Quads_ProfileOffOp:
   22309            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProfileOff        ", 18);
   22310            0 :         break;
   22311              : 
   22312            0 :       case M2Quads_OptimizeOnOp:
   22313            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptimizeOn        ", 18);
   22314            0 :         break;
   22315              : 
   22316            0 :       case M2Quads_OptimizeOffOp:
   22317            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptimizeOff       ", 18);
   22318            0 :         break;
   22319              : 
   22320            0 :       case M2Quads_InlineOp:
   22321            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Inline            ", 18);
   22322            0 :         break;
   22323              : 
   22324            0 :       case M2Quads_StatementNoteOp:
   22325            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StatementNote     ", 18);
   22326            0 :         break;
   22327              : 
   22328            0 :       case M2Quads_LineNumberOp:
   22329            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "LineNumber        ", 18);
   22330            0 :         break;
   22331              : 
   22332            0 :       case M2Quads_BuiltinConstOp:
   22333            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "BuiltinConst      ", 18);
   22334            0 :         break;
   22335              : 
   22336            0 :       case M2Quads_BuiltinTypeInfoOp:
   22337            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "BuiltinTypeInfo   ", 18);
   22338            0 :         break;
   22339              : 
   22340            0 :       case M2Quads_StandardFunctionOp:
   22341            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StandardFunction  ", 18);
   22342            0 :         break;
   22343              : 
   22344            0 :       case M2Quads_SavePriorityOp:
   22345            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SavePriority      ", 18);
   22346            0 :         break;
   22347              : 
   22348            0 :       case M2Quads_RestorePriorityOp:
   22349            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RestorePriority   ", 18);
   22350            0 :         break;
   22351              : 
   22352            0 :       case M2Quads_RangeCheckOp:
   22353            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RangeCheck        ", 18);
   22354            0 :         break;
   22355              : 
   22356            0 :       case M2Quads_ErrorOp:
   22357            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Error             ", 18);
   22358            0 :         break;
   22359              : 
   22360            0 :       case M2Quads_SaveExceptionOp:
   22361            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SaveException     ", 18);
   22362            0 :         break;
   22363              : 
   22364            0 :       case M2Quads_RestoreExceptionOp:
   22365            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RestoreException  ", 18);
   22366            0 :         break;
   22367              : 
   22368            0 :       case M2Quads_StringConvertCnulOp:
   22369            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringConvertCnul ", 18);
   22370            0 :         break;
   22371              : 
   22372            0 :       case M2Quads_StringConvertM2nulOp:
   22373            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringConvertM2nul", 18);
   22374            0 :         break;
   22375              : 
   22376            0 :       case M2Quads_StringLengthOp:
   22377            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringLength      ", 18);
   22378            0 :         break;
   22379              : 
   22380            0 :       case M2Quads_SubrangeHighOp:
   22381            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SubrangeHigh      ", 18);
   22382            0 :         break;
   22383              : 
   22384            0 :       case M2Quads_SubrangeLowOp:
   22385            0 :         M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SubrangeLow       ", 18);
   22386            0 :         break;
   22387              : 
   22388              : 
   22389            0 :       default:
   22390            0 :         M2Error_InternalError ((const char *) "operator not expected", 21);
   22391            0 :         break;
   22392              :     }
   22393            0 : }
   22394              : 
   22395              : 
   22396              : /*
   22397              :    PushAutoOn - push the auto flag and then set it to TRUE.
   22398              :                 Any call to ident in the parser will result in the token being pushed.
   22399              : */
   22400              : 
   22401     64259014 : extern "C" void M2Quads_PushAutoOn (void)
   22402              : {
   22403     64259014 :   M2StackWord_PushWord (AutoStack, static_cast<unsigned int> (IsAutoOn));
   22404     64259014 :   IsAutoOn = true;
   22405     64259014 : }
   22406              : 
   22407              : 
   22408              : /*
   22409              :    PushAutoOff - push the auto flag and then set it to FALSE.
   22410              : */
   22411              : 
   22412    120356650 : extern "C" void M2Quads_PushAutoOff (void)
   22413              : {
   22414    120356650 :   M2StackWord_PushWord (AutoStack, static_cast<unsigned int> (IsAutoOn));
   22415    120356650 :   IsAutoOn = false;
   22416    120356650 : }
   22417              : 
   22418              : 
   22419              : /*
   22420              :    IsAutoPushOn - returns the value of the current Auto ident push flag.
   22421              : */
   22422              : 
   22423    575375766 : extern "C" bool M2Quads_IsAutoPushOn (void)
   22424              : {
   22425    575375766 :   return IsAutoOn;
   22426              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   22427              :   __builtin_unreachable ();
   22428              : }
   22429              : 
   22430              : 
   22431              : /*
   22432              :    PopAuto - restores the previous value of the Auto flag.
   22433              : */
   22434              : 
   22435    184590820 : extern "C" void M2Quads_PopAuto (void)
   22436              : {
   22437    184590820 :   IsAutoOn = static_cast<bool> (M2StackWord_PopWord (AutoStack));
   22438    184590820 : }
   22439              : 
   22440              : 
   22441              : /*
   22442              :    MustCheckOverflow - returns TRUE if the quadruple should test for overflow.
   22443              : */
   22444              : 
   22445       540923 : extern "C" bool M2Quads_MustCheckOverflow (unsigned int q)
   22446              : {
   22447       540923 :   M2Quads_QuadFrame f;
   22448              : 
   22449       540923 :   f = GetQF (q);
   22450       540923 :   return f->CheckOverflow;
   22451              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   22452              :   __builtin_unreachable ();
   22453              : }
   22454              : 
   22455              : 
   22456              : /*
   22457              :    PushInConstExpression - push the InConstExpression flag and then set it to TRUE.
   22458              : */
   22459              : 
   22460      1251990 : extern "C" void M2Quads_PushInConstExpression (void)
   22461              : {
   22462      1251990 :   M2StackWord_PushWord (ConstExprStack, static_cast<unsigned int> (InConstExpression));
   22463      1251990 :   InConstExpression = true;
   22464      1251990 : }
   22465              : 
   22466              : 
   22467              : /*
   22468              :    PopInConstExpression - restores the previous value of the InConstExpression.
   22469              : */
   22470              : 
   22471      1251966 : extern "C" void M2Quads_PopInConstExpression (void)
   22472              : {
   22473      1251966 :   InConstExpression = static_cast<bool> (M2StackWord_PopWord (ConstExprStack));
   22474      1251966 : }
   22475              : 
   22476              : 
   22477              : /*
   22478              :    IsInConstExpression - returns the value of the InConstExpression.
   22479              : */
   22480              : 
   22481        98110 : extern "C" bool M2Quads_IsInConstExpression (void)
   22482              : {
   22483        98110 :   return InConstExpression;
   22484              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   22485              :   __builtin_unreachable ();
   22486              : }
   22487              : 
   22488              : 
   22489              : /*
   22490              :    PushInConstParameters - push the InConstParameters flag and then set it to TRUE.
   22491              : */
   22492              : 
   22493         1797 : extern "C" void M2Quads_PushInConstParameters (void)
   22494              : {
   22495         1797 :   M2StackWord_PushWord (ConstParamStack, static_cast<unsigned int> (InConstParameters));
   22496         1797 :   InConstParameters = true;
   22497         1797 : }
   22498              : 
   22499              : 
   22500              : /*
   22501              :    PopInConstParameters - restores the previous value of the InConstParameters.
   22502              : */
   22503              : 
   22504         1797 : extern "C" void M2Quads_PopInConstParameters (void)
   22505              : {
   22506         1797 :   InConstParameters = static_cast<bool> (M2StackWord_PopWord (ConstParamStack));
   22507         1797 : }
   22508              : 
   22509              : 
   22510              : /*
   22511              :    IsInConstParameters - returns the value of the InConstParameters.
   22512              : */
   22513              : 
   22514        93325 : extern "C" bool M2Quads_IsInConstParameters (void)
   22515              : {
   22516        93325 :   return InConstParameters;
   22517              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   22518              :   __builtin_unreachable ();
   22519              : }
   22520              : 
   22521              : 
   22522              : /*
   22523              :    BuildAsmElement - the stack is expected to contain:
   22524              : 
   22525              : 
   22526              :                         Entry                      Exit
   22527              :                         =====                      ====
   22528              : 
   22529              :                  Ptr ->
   22530              :                         +------------------+
   22531              :                         | expr | tokpos    |
   22532              :                         |------------------|
   22533              :                         | str              |
   22534              :                         |------------------|
   22535              :                         | name             |
   22536              :                         |------------------|       +------------------+
   22537              :                         | CurrentInterface |       | CurrentInterface |
   22538              :                         |------------------|       |------------------|
   22539              :                         | CurrentAsm       |       | CurrentAsm       |
   22540              :                         |------------------|       |------------------|
   22541              :                         | n                |       | n                |
   22542              :                         |------------------|       |------------------|
   22543              : */
   22544              : 
   22545           33 : extern "C" void M2Quads_BuildAsmElement (bool input, bool output)
   22546              : {
   22547           33 :   DynamicStrings_String s;
   22548           33 :   unsigned int n;
   22549           33 :   unsigned int str;
   22550           33 :   unsigned int expr;
   22551           33 :   unsigned int tokpos;
   22552           33 :   unsigned int CurrentInterface;
   22553           33 :   unsigned int CurrentAsm;
   22554           33 :   unsigned int name;
   22555              : 
   22556           33 :   M2Quads_PopTtok (&expr, &tokpos);
   22557           33 :   M2Quads_PopT (&str);
   22558           33 :   M2Quads_PopT (&name);
   22559           33 :   M2Quads_PopT (&CurrentInterface);
   22560           33 :   M2Quads_PopT (&CurrentAsm);
   22561           66 :   M2Debug_Assert ((SymbolTable_IsGnuAsm (CurrentAsm)) || (SymbolTable_IsGnuAsmVolatile (CurrentAsm)));
   22562           33 :   M2Quads_PopT (&n);
   22563           33 :   n += 1;
   22564           33 :   if (CurrentInterface == SymbolTable_NulSym)
   22565              :     {
   22566           30 :       CurrentInterface = SymbolTable_MakeRegInterface ();
   22567              :     }
   22568           33 :   if (input)
   22569              :     {
   22570           18 :       SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, name, str, expr, NextQuad, 0);
   22571           18 :       if (DebugAsmTokPos)
   22572              :         {
   22573              :           s = DynamicStrings_InitString ((const char *) "input expression", 16);
   22574              :           M2Error_WarnStringAt (s, tokpos);
   22575              :         }
   22576              :     }
   22577           33 :   if (output)
   22578              :     {
   22579           15 :       SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, name, str, expr, 0, NextQuad);
   22580           15 :       if (DebugAsmTokPos)
   22581              :         {
   22582              :           s = DynamicStrings_InitString ((const char *) "output expression", 17);
   22583              :           M2Error_WarnStringAt (s, tokpos);
   22584              :         }
   22585              :     }
   22586           33 :   M2Quads_PushT (n);
   22587           33 :   M2Quads_PushT (CurrentAsm);
   22588           33 :   M2Quads_PushT (CurrentInterface);
   22589           33 : }
   22590              : 
   22591              : 
   22592              : /*
   22593              :    BuildAsmTrash - the stack is expected to contain:
   22594              : 
   22595              : 
   22596              :                         Entry                      Exit
   22597              :                         =====                      ====
   22598              : 
   22599              :                  Ptr ->
   22600              :                         +------------------+
   22601              :                         | expr | tokpos    |
   22602              :                         |------------------|       +------------------+
   22603              :                         | CurrentInterface |       | CurrentInterface |
   22604              :                         |------------------|       |------------------|
   22605              :                         | CurrentAsm       |       | CurrentAsm       |
   22606              :                         |------------------|       |------------------|
   22607              :                         | n                |       | n                |
   22608              :                         |------------------|       |------------------|
   22609              : */
   22610              : 
   22611            3 : extern "C" void M2Quads_BuildAsmTrash (void)
   22612              : {
   22613            3 :   unsigned int n;
   22614            3 :   unsigned int expr;
   22615            3 :   unsigned int tokpos;
   22616            3 :   unsigned int CurrentInterface;
   22617            3 :   unsigned int CurrentAsm;
   22618              : 
   22619            3 :   M2Quads_PopTtok (&expr, &tokpos);
   22620            3 :   M2Quads_PopT (&CurrentInterface);
   22621            3 :   M2Quads_PopT (&CurrentAsm);
   22622            6 :   M2Debug_Assert ((SymbolTable_IsGnuAsm (CurrentAsm)) || (SymbolTable_IsGnuAsmVolatile (CurrentAsm)));
   22623            3 :   M2Quads_PopT (&n);
   22624            3 :   n += 1;
   22625            3 :   if (CurrentInterface == SymbolTable_NulSym)
   22626              :     {
   22627            3 :       CurrentInterface = SymbolTable_MakeRegInterface ();
   22628              :     }
   22629            3 :   SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, NameKey_NulName, SymbolTable_NulSym, expr, 0, NextQuad);
   22630            3 :   M2Quads_PushT (n);
   22631            3 :   M2Quads_PushT (CurrentAsm);
   22632            3 :   M2Quads_PushT (CurrentInterface);
   22633            3 : }
   22634              : 
   22635              : 
   22636              : /*
   22637              :    GetQuadTrash - return the symbol associated with the trashed operand.
   22638              : */
   22639              : 
   22640          268 : extern "C" unsigned int M2Quads_GetQuadTrash (unsigned int quad)
   22641              : {
   22642          268 :   M2Quads_QuadFrame f;
   22643              : 
   22644          268 :   f = GetQF (quad);
   22645          268 :   LastQuadNo = quad;
   22646          268 :   return f->Trash;
   22647              :   /* static analysis guarentees a RETURN statement will be used before here.  */
   22648              :   __builtin_unreachable ();
   22649              : }
   22650              : 
   22651        15451 : extern "C" void _M2_M2Quads_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
   22652              : {
   22653        15451 :   Init ();
   22654        15451 : }
   22655              : 
   22656            0 : extern "C" void _M2_M2Quads_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
   22657              : {
   22658            0 : }
        

Generated by: LCOV version 2.5.0-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.