Branch data Line data Source code
1 : : /* do not edit automatically generated by mc from M2Quads. */
2 : : /* M2Quads.mod generates quadruples.
3 : :
4 : : Copyright (C) 2001-2024 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 <stdbool.h>
26 : : # if !defined (PROC_D)
27 : : # define PROC_D
28 : : typedef void (*PROC_t) (void);
29 : : typedef struct { PROC_t proc; } PROC;
30 : : # endif
31 : :
32 : : # if !defined (TRUE)
33 : : # define TRUE (1==1)
34 : : # endif
35 : :
36 : : # if !defined (FALSE)
37 : : # define FALSE (1==0)
38 : : # endif
39 : :
40 : : # include "GStorage.h"
41 : : # include "Gmcrts.h"
42 : : #if defined(__cplusplus)
43 : : # undef NULL
44 : : # define NULL 0
45 : : #endif
46 : : #define _M2Quads_H
47 : : #define _M2Quads_C
48 : :
49 : : # include "GStorage.h"
50 : : # include "GM2Debug.h"
51 : : # include "GNameKey.h"
52 : : # include "GFormatStrings.h"
53 : : # include "GM2DebugStack.h"
54 : : # include "GStrLib.h"
55 : : # include "GM2Scaffold.h"
56 : : # include "GM2MetaError.h"
57 : : # include "GDynamicStrings.h"
58 : : # include "GSymbolTable.h"
59 : : # include "GM2Batch.h"
60 : : # include "GM2GCCDeclare.h"
61 : : # include "GFifoQueue.h"
62 : : # include "GM2Comp.h"
63 : : # include "GM2LexBuf.h"
64 : : # include "GM2Error.h"
65 : : # include "GM2Printf.h"
66 : : # include "GM2Reserved.h"
67 : : # include "GM2Base.h"
68 : : # include "GM2System.h"
69 : : # include "GM2Size.h"
70 : : # include "GM2Bitset.h"
71 : : # include "GM2ALU.h"
72 : : # include "GLists.h"
73 : : # include "GM2Options.h"
74 : : # include "GM2LangDump.h"
75 : : # include "GM2Pass.h"
76 : : # include "GM2StackAddress.h"
77 : : # include "GM2StackWord.h"
78 : : # include "GIndexing.h"
79 : : # include "GM2Range.h"
80 : : # include "GM2CaseList.h"
81 : : # include "GPCSymBuild.h"
82 : : # include "Gm2builtins.h"
83 : : # include "GFIO.h"
84 : : # include "GSFIO.h"
85 : : # include "GStdIO.h"
86 : :
87 : : # define DebugStackOn true
88 : : # define DebugVarients false
89 : : # define BreakAtQuad 189
90 : : # define DebugTokPos false
91 : : typedef struct M2Quads__T1_r M2Quads__T1;
92 : :
93 : : typedef M2Quads__T1 *M2Quads_ConstructorFrame;
94 : :
95 : : typedef struct M2Quads__T2_r M2Quads__T2;
96 : :
97 : : typedef M2Quads__T2 *M2Quads_BoolFrame;
98 : :
99 : : typedef struct M2Quads__T3_r M2Quads__T3;
100 : :
101 : : typedef M2Quads__T3 *M2Quads_QuadFrame;
102 : :
103 : : typedef struct M2Quads__T4_r M2Quads__T4;
104 : :
105 : : typedef M2Quads__T4 *M2Quads_WithFrame;
106 : :
107 : : typedef struct M2Quads__T5_r M2Quads__T5;
108 : :
109 : : typedef M2Quads__T5 *M2Quads_ForLoopInfo;
110 : :
111 : : typedef struct M2Quads__T6_r M2Quads__T6;
112 : :
113 : : typedef M2Quads__T6 *M2Quads_LineNote;
114 : :
115 : : typedef enum {M2Quads_AddOp, M2Quads_AddrOp, M2Quads_ArithAddOp, M2Quads_ArrayOp, M2Quads_BecomesOp, M2Quads_BuiltinConstOp, M2Quads_BuiltinTypeInfoOp, M2Quads_CallOp, M2Quads_CastOp, M2Quads_CatchBeginOp, M2Quads_CatchEndOp, M2Quads_CodeOffOp, M2Quads_CodeOnOp, M2Quads_CoerceOp, M2Quads_ConvertOp, M2Quads_DivCeilOp, M2Quads_DivFloorOp, M2Quads_DivM2Op, M2Quads_DivTruncOp, M2Quads_DummyOp, M2Quads_ElementSizeOp, M2Quads_EndFileOp, M2Quads_ErrorOp, M2Quads_ExclOp, M2Quads_FinallyEndOp, M2Quads_FinallyStartOp, M2Quads_FunctValueOp, M2Quads_GotoOp, M2Quads_HighOp, M2Quads_IfEquOp, M2Quads_IfGreEquOp, M2Quads_IfGreOp, M2Quads_IfInOp, M2Quads_IfLessEquOp, M2Quads_IfLessOp, M2Quads_IfNotEquOp, M2Quads_IfNotInOp, M2Quads_InclOp, M2Quads_IndrXOp, M2Quads_InitAddressOp, M2Quads_InitEndOp, M2Quads_InitStartOp, M2Quads_InlineOp, M2Quads_KillLocalVarOp, M2Quads_LineNumberOp, M2Quads_LogicalAndOp, M2Quads_LogicalDiffOp, M2Quads_LogicalOrOp, M2Quads_LogicalRotateOp, M2Quads_LogicalShiftOp, M2Quads_LogicalXorOp, M2Quads_ModCeilOp, M2Quads_ModFloorOp, M2Quads_ModM2Op, M2Quads_ModTruncOp, M2Quads_ModuleScopeOp, M2Quads_MultOp, M2Quads_NegateOp, M2Quads_NewLocalVarOp, M2Quads_OptimizeOffOp, M2Quads_OptimizeOnOp, M2Quads_OptParamOp, M2Quads_ParamOp, M2Quads_ProcedureScopeOp, M2Quads_ProfileOffOp, M2Quads_ProfileOnOp, M2Quads_RangeCheckOp, M2Quads_RecordFieldOp, M2Quads_RestoreExceptionOp, M2Quads_RestorePriorityOp, M2Quads_RetryOp, M2Quads_ReturnOp, M2Quads_ReturnValueOp, M2Quads_SaveExceptionOp, M2Quads_SavePriorityOp, M2Quads_SizeOp, M2Quads_StandardFunctionOp, M2Quads_StartDefFileOp, M2Quads_StartModFileOp, M2Quads_StatementNoteOp, M2Quads_SubOp, M2Quads_SubrangeHighOp, M2Quads_SubrangeLowOp, M2Quads_StringConvertCnulOp, M2Quads_StringConvertM2nulOp, M2Quads_StringLengthOp, M2Quads_ThrowOp, M2Quads_TryOp, M2Quads_UnboundedOp, M2Quads_XIndrOp} M2Quads_QuadOperator;
116 : :
117 : : # define DebugAsmTokPos false
118 : : struct M2Quads__T1_r {
119 : : unsigned int type;
120 : : unsigned int index;
121 : : };
122 : :
123 : : struct M2Quads__T2_r {
124 : : unsigned int TrueExit;
125 : : unsigned int FalseExit;
126 : : unsigned int Unbounded;
127 : : bool BooleanOp;
128 : : unsigned int Dimension;
129 : : unsigned int ReadWrite;
130 : : unsigned int name;
131 : : DynamicStrings_String Annotation;
132 : : unsigned int tokenno;
133 : : };
134 : :
135 : : struct M2Quads__T3_r {
136 : : M2Quads_QuadOperator Operator;
137 : : unsigned int Operand1;
138 : : unsigned int Operand2;
139 : : unsigned int Operand3;
140 : : unsigned int Trash;
141 : : unsigned int Next;
142 : : unsigned int LineNo;
143 : : unsigned int TokenNo;
144 : : unsigned int NoOfTimesReferenced;
145 : : bool ConstExpr;
146 : : bool CheckType;
147 : : bool CheckOverflow;
148 : : unsigned int op1pos;
149 : : unsigned int op2pos;
150 : : unsigned int op3pos;
151 : : };
152 : :
153 : : struct M2Quads__T4_r {
154 : : unsigned int RecordSym;
155 : : unsigned int RecordType;
156 : : unsigned int RecordRef;
157 : : unsigned int rw;
158 : : unsigned int RecordTokPos;
159 : : };
160 : :
161 : : struct M2Quads__T5_r {
162 : : unsigned int IncrementQuad;
163 : : unsigned int StartOfForLoop;
164 : : unsigned int EndOfForLoop;
165 : : unsigned int ForLoopIndex;
166 : : unsigned int IndexTok;
167 : : };
168 : :
169 : : struct M2Quads__T6_r {
170 : : unsigned int Line;
171 : : NameKey_Name File;
172 : : M2Quads_LineNote Next;
173 : : };
174 : :
175 : : static M2StackAddress_StackOfAddress ConstructorStack;
176 : : static M2StackAddress_StackOfAddress LineStack;
177 : : static M2StackAddress_StackOfAddress BoolStack;
178 : : static M2StackAddress_StackOfAddress WithStack;
179 : : static M2StackWord_StackOfWord TryStack;
180 : : static M2StackWord_StackOfWord CatchStack;
181 : : static M2StackWord_StackOfWord ExceptStack;
182 : : static M2StackWord_StackOfWord ConstExprStack;
183 : : static M2StackWord_StackOfWord ConstParamStack;
184 : : static M2StackWord_StackOfWord AutoStack;
185 : : static M2StackWord_StackOfWord RepeatStack;
186 : : static M2StackWord_StackOfWord WhileStack;
187 : : static M2StackWord_StackOfWord ForStack;
188 : : static M2StackWord_StackOfWord ExitStack;
189 : : static M2StackWord_StackOfWord ReturnStack;
190 : : static M2StackWord_StackOfWord PriorityStack;
191 : : static bool SuppressWith;
192 : : static Indexing_Index QuadArray;
193 : : static unsigned int NextQuad;
194 : : static unsigned int FreeList;
195 : : static unsigned int CurrentProc;
196 : : static unsigned int InitQuad;
197 : : static unsigned int LastQuadNo;
198 : : static NameKey_Name ArithPlusTok;
199 : : static NameKey_Name LogicalOrTok;
200 : : static NameKey_Name LogicalAndTok;
201 : : static NameKey_Name LogicalXorTok;
202 : : static NameKey_Name LogicalDifferenceTok;
203 : : static bool InConstExpression;
204 : : static bool InConstParameters;
205 : : static bool IsAutoOn;
206 : : static bool MustNotCheckBounds;
207 : : static Indexing_Index ForInfo;
208 : : static unsigned int GrowInitialization;
209 : : static bool BuildingHigh;
210 : : static bool BuildingSize;
211 : : static bool QuadrupleGeneration;
212 : : static M2Quads_LineNote FreeLineList;
213 : : static Lists_List VarientFields;
214 : : static unsigned int VarientFieldNo;
215 : : static unsigned int NoOfQuads;
216 : : static unsigned int Head;
217 : :
218 : : /*
219 : : SetOptionCoding - builds a code quadruple if the profiling
220 : : option was given to the compiler.
221 : : */
222 : :
223 : : extern "C" void M2Quads_SetOptionCoding (bool b);
224 : :
225 : : /*
226 : : SetOptionProfiling - builds a profile quadruple if the profiling
227 : : option was given to the compiler.
228 : : */
229 : :
230 : : extern "C" void M2Quads_SetOptionProfiling (bool b);
231 : :
232 : : /*
233 : : SetOptionOptimizing - builds a quadruple to say that the optimization option
234 : : has been found in a comment.
235 : : */
236 : :
237 : : extern "C" void M2Quads_SetOptionOptimizing (bool b);
238 : :
239 : : /*
240 : : Opposite - returns the opposite comparison operator.
241 : : */
242 : :
243 : : extern "C" M2Quads_QuadOperator M2Quads_Opposite (M2Quads_QuadOperator Operator);
244 : :
245 : : /*
246 : : IsReferenced - returns true if QuadNo is referenced by another quadruple.
247 : : */
248 : :
249 : : extern "C" bool M2Quads_IsReferenced (unsigned int QuadNo);
250 : :
251 : : /*
252 : : IsBackReference - returns TRUE if quadruple, q, is referenced from a quad further on.
253 : : */
254 : :
255 : : extern "C" bool M2Quads_IsBackReference (unsigned int q);
256 : :
257 : : /*
258 : : IsUnConditional - returns true if QuadNo is an unconditional jump.
259 : : */
260 : :
261 : : extern "C" bool M2Quads_IsUnConditional (unsigned int QuadNo);
262 : :
263 : : /*
264 : : IsConditional - returns true if QuadNo is a conditional jump.
265 : : */
266 : :
267 : : extern "C" bool M2Quads_IsConditional (unsigned int QuadNo);
268 : :
269 : : /*
270 : : IsBackReferenceConditional - returns TRUE if quadruple, q, is referenced from
271 : : a conditional quad further on.
272 : : */
273 : :
274 : : extern "C" bool M2Quads_IsBackReferenceConditional (unsigned int q);
275 : :
276 : : /*
277 : : IsGoto - returns true if QuadNo is a goto operation.
278 : : */
279 : :
280 : : extern "C" bool M2Quads_IsGoto (unsigned int QuadNo);
281 : :
282 : : /*
283 : : IsCall - returns true if QuadNo is a call operation.
284 : : */
285 : :
286 : : extern "C" bool M2Quads_IsCall (unsigned int QuadNo);
287 : :
288 : : /*
289 : : IsReturn - returns true if QuadNo is a return operation.
290 : : */
291 : :
292 : : extern "C" bool M2Quads_IsReturn (unsigned int QuadNo);
293 : :
294 : : /*
295 : : IsProcedureScope - returns true if QuadNo is a ProcedureScope operation.
296 : : */
297 : :
298 : : extern "C" bool M2Quads_IsProcedureScope (unsigned int QuadNo);
299 : :
300 : : /*
301 : : IsNewLocalVar - returns true if QuadNo is a NewLocalVar operation.
302 : : */
303 : :
304 : : extern "C" bool M2Quads_IsNewLocalVar (unsigned int QuadNo);
305 : :
306 : : /*
307 : : IsKillLocalVar - returns true if QuadNo is a KillLocalVar operation.
308 : : */
309 : :
310 : : extern "C" bool M2Quads_IsKillLocalVar (unsigned int QuadNo);
311 : :
312 : : /*
313 : : IsCatchBegin - returns true if QuadNo is a catch begin quad.
314 : : */
315 : :
316 : : extern "C" bool M2Quads_IsCatchBegin (unsigned int QuadNo);
317 : :
318 : : /*
319 : : IsCatchEnd - returns true if QuadNo is a catch end quad.
320 : : */
321 : :
322 : : extern "C" bool M2Quads_IsCatchEnd (unsigned int QuadNo);
323 : :
324 : : /*
325 : : IsInitStart - returns true if QuadNo is a init start quad.
326 : : */
327 : :
328 : : extern "C" bool M2Quads_IsInitStart (unsigned int QuadNo);
329 : :
330 : : /*
331 : : IsInitEnd - returns true if QuadNo is a init end quad.
332 : : */
333 : :
334 : : extern "C" bool M2Quads_IsInitEnd (unsigned int QuadNo);
335 : :
336 : : /*
337 : : IsFinallyStart - returns true if QuadNo is a finally start quad.
338 : : */
339 : :
340 : : extern "C" bool M2Quads_IsFinallyStart (unsigned int QuadNo);
341 : :
342 : : /*
343 : : IsFinallyEnd - returns true if QuadNo is a finally end quad.
344 : : */
345 : :
346 : : extern "C" bool M2Quads_IsFinallyEnd (unsigned int QuadNo);
347 : :
348 : : /*
349 : : IsBecomes - return TRUE if QuadNo is a BecomesOp.
350 : : */
351 : :
352 : : extern "C" bool M2Quads_IsBecomes (unsigned int QuadNo);
353 : :
354 : : /*
355 : : IsDummy - return TRUE if QuadNo is a DummyOp.
356 : : */
357 : :
358 : : extern "C" bool M2Quads_IsDummy (unsigned int QuadNo);
359 : :
360 : : /*
361 : : IsQuadConstExpr - returns TRUE if QuadNo is part of a constant expression.
362 : : */
363 : :
364 : : extern "C" bool M2Quads_IsQuadConstExpr (unsigned int QuadNo);
365 : :
366 : : /*
367 : : SetQuadConstExpr - sets the constexpr field to value.
368 : : */
369 : :
370 : : extern "C" void M2Quads_SetQuadConstExpr (unsigned int QuadNo, bool value);
371 : :
372 : : /*
373 : : GetQuadDest - returns the jump destination associated with quad.
374 : : */
375 : :
376 : : extern "C" unsigned int M2Quads_GetQuadDest (unsigned int QuadNo);
377 : :
378 : : /*
379 : : GetQuadOp1 - returns the 1st operand associated with quad.
380 : : */
381 : :
382 : : extern "C" unsigned int M2Quads_GetQuadOp1 (unsigned int QuadNo);
383 : :
384 : : /*
385 : : GetQuadOp2 - returns the 2nd operand associated with quad.
386 : : */
387 : :
388 : : extern "C" unsigned int M2Quads_GetQuadOp2 (unsigned int QuadNo);
389 : :
390 : : /*
391 : : GetQuadOp3 - returns the 3rd operand associated with quad.
392 : : */
393 : :
394 : : extern "C" unsigned int M2Quads_GetQuadOp3 (unsigned int QuadNo);
395 : :
396 : : /*
397 : : IsInitialisingConst - returns TRUE if the quadruple is setting
398 : : a const (op1) with a value.
399 : : */
400 : :
401 : : extern "C" bool M2Quads_IsInitialisingConst (unsigned int QuadNo);
402 : :
403 : : /*
404 : : IsOptimizeOn - returns true if the Optimize flag was true at QuadNo.
405 : : */
406 : :
407 : : extern "C" bool M2Quads_IsOptimizeOn (unsigned int QuadNo);
408 : :
409 : : /*
410 : : IsProfileOn - returns true if the Profile flag was true at QuadNo.
411 : : */
412 : :
413 : : extern "C" bool M2Quads_IsProfileOn (unsigned int QuadNo);
414 : :
415 : : /*
416 : : IsCodeOn - returns true if the Code flag was true at QuadNo.
417 : : */
418 : :
419 : : extern "C" bool M2Quads_IsCodeOn (unsigned int QuadNo);
420 : :
421 : : /*
422 : : IsPseudoQuad - returns true if QuadNo is a compiler directive.
423 : : ie code, profile and optimize.
424 : : StartFile, EndFile,
425 : : */
426 : :
427 : : extern "C" bool M2Quads_IsPseudoQuad (unsigned int QuadNo);
428 : :
429 : : /*
430 : : IsDefOrModFile - returns TRUE if QuadNo is a start of Module or Def file
431 : : directive.
432 : : */
433 : :
434 : : extern "C" bool M2Quads_IsDefOrModFile (unsigned int QuadNo);
435 : :
436 : : /*
437 : : DumpQuadruples - dump all quadruples providing the -fq, -fdump-lang-quad,
438 : : -fdump-lang-quad= or -fdump-lang-all were issued to the
439 : : command line.
440 : : */
441 : :
442 : : extern "C" void M2Quads_DumpQuadruples (const char *title_, unsigned int _title_high);
443 : :
444 : : /*
445 : : DisplayQuadRange - displays all quads in list range, start..end.
446 : : */
447 : :
448 : : extern "C" void M2Quads_DisplayQuadRange (unsigned int scope, unsigned int start, unsigned int end);
449 : :
450 : : /*
451 : : DisplayQuad - displays a quadruple, QuadNo.
452 : : */
453 : :
454 : : extern "C" void M2Quads_DisplayQuad (unsigned int QuadNo);
455 : :
456 : : /*
457 : : GetLastFileQuad - returns the Quadruple number of the last StartDefFile or
458 : : StartModFile quadruple.
459 : : */
460 : :
461 : : extern "C" unsigned int M2Quads_GetLastFileQuad (unsigned int QuadNo);
462 : :
463 : : /*
464 : : GetLastQuadNo - returns the last quadruple number referenced
465 : : by a GetQuad.
466 : : */
467 : :
468 : : extern "C" unsigned int M2Quads_GetLastQuadNo (void);
469 : :
470 : : /*
471 : : QuadToTokenNo - Converts a QuadNo into the approprate token number of the
472 : : source file, the line number is returned.
473 : :
474 : : This may be used to yield an idea where abouts in the
475 : : source file the code generetion is
476 : : processing.
477 : : */
478 : :
479 : : extern "C" unsigned int M2Quads_QuadToTokenNo (unsigned int QuadNo);
480 : :
481 : : /*
482 : : QuadToLineNo - Converts a QuadNo into the approprate line number of the
483 : : source file, the line number is returned.
484 : :
485 : : This may be used to yield an idea where abouts in the
486 : : source file the code generetion is
487 : : processing.
488 : : */
489 : :
490 : : extern "C" unsigned int M2Quads_QuadToLineNo (unsigned int QuadNo);
491 : :
492 : : /*
493 : : GetQuad - returns the Quadruple QuadNo.
494 : : */
495 : :
496 : : extern "C" void M2Quads_GetQuad (unsigned int QuadNo, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3);
497 : :
498 : : /*
499 : : GetQuadOp - returns the operator for quad.
500 : : */
501 : :
502 : : extern "C" M2Quads_QuadOperator M2Quads_GetQuadOp (unsigned int quad);
503 : :
504 : : /*
505 : : GetM2OperatorDesc - returns the Modula-2 string associated with the quad operator
506 : : (if possible). It returns NIL if no there is not an obvious match
507 : : in Modula-2. It is assummed that the string will be used during
508 : : construction of error messages and therefore keywords are
509 : : wrapped with a format specifier.
510 : : */
511 : :
512 : : extern "C" DynamicStrings_String M2Quads_GetM2OperatorDesc (M2Quads_QuadOperator op);
513 : :
514 : : /*
515 : : GetQuadtok - returns the Quadruple QuadNo.
516 : : */
517 : :
518 : : 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);
519 : :
520 : : /*
521 : : GetQuadOtok - returns the Quadruple QuadNo.
522 : : */
523 : :
524 : : 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);
525 : :
526 : : /*
527 : : GetQuadOTypetok - returns the fields associated with quadruple QuadNo.
528 : : */
529 : :
530 : : 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);
531 : :
532 : : /*
533 : : PutQuadOtok - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
534 : : sets a boolean to determinine whether overflow should be checked.
535 : : */
536 : :
537 : : 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);
538 : :
539 : : /*
540 : : PutQuad - overwrites a quadruple QuadNo with Op, Oper1, Oper2, Oper3
541 : : */
542 : :
543 : : extern "C" void M2Quads_PutQuad (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3);
544 : :
545 : : /*
546 : : GetFirstQuad - returns the first quadruple.
547 : : */
548 : :
549 : : extern "C" unsigned int M2Quads_GetFirstQuad (void);
550 : :
551 : : /*
552 : : GetNextQuad - returns the Quadruple number following QuadNo.
553 : : */
554 : :
555 : : extern "C" unsigned int M2Quads_GetNextQuad (unsigned int QuadNo);
556 : :
557 : : /*
558 : : GetRealQuad - returns the Quadruple number of the real quadruple
559 : : at QuadNo or beyond.
560 : : */
561 : :
562 : : extern "C" unsigned int M2Quads_GetRealQuad (unsigned int QuadNo);
563 : :
564 : : /*
565 : : SubQuad - subtracts a quadruple QuadNo from a list Head.
566 : : */
567 : :
568 : : extern "C" void M2Quads_SubQuad (unsigned int QuadNo);
569 : :
570 : : /*
571 : : EraseQuad - erases a quadruple QuadNo, the quadruple is still in the list
572 : : but wiped clean.
573 : : */
574 : :
575 : : extern "C" void M2Quads_EraseQuad (unsigned int QuadNo);
576 : :
577 : : /*
578 : : CountQuads - returns the number of quadruples.
579 : : */
580 : :
581 : : extern "C" unsigned int M2Quads_CountQuads (void);
582 : :
583 : : /*
584 : : BuildScaffold - generate the main, init, finish functions if
585 : : no -c and this is the application module.
586 : : */
587 : :
588 : : extern "C" void M2Quads_BuildScaffold (unsigned int tok, unsigned int moduleSym);
589 : :
590 : : /*
591 : : StartBuildDefFile - generates a StartFileDefOp quadruple indicating the file
592 : : that has produced the subsequent quadruples.
593 : : The code generator uses the StartDefFileOp quadruples
594 : : to relate any error to the appropriate file.
595 : :
596 : :
597 : : Entry Exit
598 : : ===== ====
599 : :
600 : :
601 : : Ptr -> <- Ptr
602 : : +------------+ +------------+
603 : : | ModuleName | | ModuleName |
604 : : |------------| |------------|
605 : :
606 : :
607 : : Quadruples Produced
608 : :
609 : : q StartDefFileOp _ _ ModuleSym
610 : : */
611 : :
612 : : extern "C" void M2Quads_StartBuildDefFile (unsigned int tok);
613 : :
614 : : /*
615 : : StartBuildModFile - generates a StartModFileOp quadruple indicating the file
616 : : that has produced the subsequent quadruples.
617 : : The code generator uses the StartModFileOp quadruples
618 : : to relate any error to the appropriate file.
619 : :
620 : :
621 : : Entry Exit
622 : : ===== ====
623 : :
624 : :
625 : : Ptr -> <- Ptr
626 : : +------------+ +------------+
627 : : | ModuleName | | ModuleName |
628 : : |------------| |------------|
629 : :
630 : :
631 : : Quadruples Produced
632 : :
633 : : q StartModFileOp lineno filename ModuleSym
634 : : */
635 : :
636 : : extern "C" void M2Quads_StartBuildModFile (unsigned int tok);
637 : :
638 : : /*
639 : : EndBuildFile - generates an EndFileOp quadruple indicating the file
640 : : that has produced the previous quadruples has ended.
641 : :
642 : : Entry Exit
643 : : ===== ====
644 : :
645 : :
646 : : Ptr -> <- Ptr
647 : : +------------+ +------------+
648 : : | ModuleName | | ModuleName |
649 : : |------------| |------------|
650 : :
651 : :
652 : : Quadruples Produced
653 : :
654 : : q EndFileOp _ _ ModuleSym
655 : : */
656 : :
657 : : extern "C" void M2Quads_EndBuildFile (unsigned int tok);
658 : :
659 : : /*
660 : : StartBuildInit - Sets the start of initialization code of the
661 : : current module to the next quadruple.
662 : : */
663 : :
664 : : extern "C" void M2Quads_StartBuildInit (unsigned int tok);
665 : :
666 : : /*
667 : : EndBuildInit - Sets the end initialization code of a module.
668 : : */
669 : :
670 : : extern "C" void M2Quads_EndBuildInit (unsigned int tok);
671 : :
672 : : /*
673 : : StartBuildFinally - Sets the start of finalization code of the
674 : : current module to the next quadruple.
675 : : */
676 : :
677 : : extern "C" void M2Quads_StartBuildFinally (unsigned int tok);
678 : :
679 : : /*
680 : : EndBuildFinally - Sets the end finalization code of a module.
681 : : */
682 : :
683 : : extern "C" void M2Quads_EndBuildFinally (unsigned int tok);
684 : :
685 : : /*
686 : : BuildExceptInitial - adds an CatchBeginOp, CatchEndOp quadruple
687 : : in the current block.
688 : : */
689 : :
690 : : extern "C" void M2Quads_BuildExceptInitial (unsigned int tok);
691 : :
692 : : /*
693 : : BuildExceptFinally - adds an ExceptOp quadruple in a modules
694 : : finally block.
695 : : */
696 : :
697 : : extern "C" void M2Quads_BuildExceptFinally (unsigned int tok);
698 : :
699 : : /*
700 : : BuildExceptProcedure - adds an ExceptOp quadruple in a procedure
701 : : block.
702 : : */
703 : :
704 : : extern "C" void M2Quads_BuildExceptProcedure (unsigned int tok);
705 : :
706 : : /*
707 : : BuildRetry - adds an RetryOp quadruple.
708 : : */
709 : :
710 : : extern "C" void M2Quads_BuildRetry (unsigned int tok);
711 : :
712 : : /*
713 : : BuildReThrow - creates a ThrowOp _ _ NulSym, indicating that
714 : : the exception needs to be rethrown. The stack
715 : : is unaltered.
716 : : */
717 : :
718 : : extern "C" void M2Quads_BuildReThrow (unsigned int tokenno);
719 : :
720 : : /*
721 : : StartBuildInnerInit - Sets the start of initialization code of the
722 : : inner module to the next quadruple.
723 : : */
724 : :
725 : : extern "C" void M2Quads_StartBuildInnerInit (unsigned int tok);
726 : :
727 : : /*
728 : : EndBuildInnerInit - Sets the end initialization code of a module.
729 : : */
730 : :
731 : : extern "C" void M2Quads_EndBuildInnerInit (unsigned int tok);
732 : :
733 : : /*
734 : : BuildBuiltinConst - makes reference to a builtin constant within gm2.
735 : :
736 : : Entry Exit
737 : :
738 : : Ptr ->
739 : : +------------+ +------------+
740 : : | Ident | | Sym |
741 : : |------------| |------------|
742 : :
743 : : Quadruple produced:
744 : :
745 : : q Sym BuiltinConstOp Ident
746 : : */
747 : :
748 : : extern "C" void M2Quads_BuildBuiltinConst (void);
749 : :
750 : : /*
751 : : BuildBuiltinTypeInfo - make reference to a builtin typeinfo function
752 : : within gm2.
753 : :
754 : : Entry Exit
755 : :
756 : : Ptr ->
757 : : +-------------+
758 : : | Type |
759 : : |-------------| +------------+
760 : : | Ident | | Sym |
761 : : |-------------| |------------|
762 : :
763 : : Quadruple produced:
764 : :
765 : : q Sym BuiltinTypeInfoOp Type Ident
766 : : */
767 : :
768 : : extern "C" void M2Quads_BuildBuiltinTypeInfo (void);
769 : :
770 : : /*
771 : : BuildAssignment - Builds an assignment from the values given on the
772 : : quad stack. Either an assignment to an
773 : : arithmetic expression or an assignment to a
774 : : boolean expression. This procedure should not
775 : : be called in CONST declarations.
776 : : The Stack is expected to contain:
777 : :
778 : :
779 : : Either
780 : :
781 : : Entry Exit
782 : : ===== ====
783 : :
784 : : Ptr ->
785 : : +------------+
786 : : | Expression |
787 : : |------------|
788 : : | Designator |
789 : : |------------| +------------+
790 : : | | | | <- Ptr
791 : : |------------| |------------|
792 : :
793 : :
794 : : Quadruples Produced
795 : :
796 : : q BecomesOp Designator _ Expression
797 : :
798 : : OR
799 : :
800 : : Entry Exit
801 : : ===== ====
802 : :
803 : : Ptr ->
804 : : +------------+
805 : : | True |False|
806 : : |------------|
807 : : | Designator |
808 : : |------------| +------------+
809 : : | | | | <- Ptr
810 : : |------------| |------------|
811 : :
812 : :
813 : : Quadruples Produced
814 : :
815 : : q BecomesOp Designator _ TRUE
816 : : q+1 GotoOp q+3
817 : : q+2 BecomesOp Designator _ FALSE
818 : :
819 : : */
820 : :
821 : : extern "C" void M2Quads_BuildAssignment (unsigned int becomesTokNo);
822 : :
823 : : /*
824 : : BuildAssignConstant - used to create constant in the CONST declaration.
825 : : The stack is expected to contain:
826 : :
827 : : Either
828 : :
829 : : Entry Exit
830 : : ===== ====
831 : :
832 : : Ptr ->
833 : : +------------+
834 : : | Expression |
835 : : |------------|
836 : : | Designator |
837 : : |------------| +------------+
838 : : | | | | <- Ptr
839 : : |------------| |------------|
840 : :
841 : :
842 : : Quadruples Produced
843 : :
844 : : q BecomesOp Designator _ Expression
845 : :
846 : : OR
847 : :
848 : : Entry Exit
849 : : ===== ====
850 : :
851 : : Ptr ->
852 : : +------------+
853 : : | True |False|
854 : : |------------|
855 : : | Designator |
856 : : |------------| +------------+
857 : : | | | | <- Ptr
858 : : |------------| |------------|
859 : :
860 : :
861 : : Quadruples Produced
862 : :
863 : : q BecomesOp Designator _ TRUE
864 : : q+1 GotoOp q+3
865 : : q+2 BecomesOp Designator _ FALSE
866 : : */
867 : :
868 : : extern "C" void M2Quads_BuildAssignConstant (unsigned int equalsTokNo);
869 : :
870 : : /*
871 : : BuildAlignment - builds an assignment to an alignment constant.
872 : :
873 : : The Stack is expected to contain:
874 : :
875 : :
876 : : Entry Exit
877 : : ===== ====
878 : :
879 : : Ptr ->
880 : : +---------------+
881 : : | Expression |
882 : : |---------------|
883 : : | bytealignment |
884 : : |---------------| empty
885 : : */
886 : :
887 : : extern "C" void M2Quads_BuildAlignment (unsigned int tokno);
888 : :
889 : : /*
890 : : BuildBitLength - builds an assignment to a bit length constant.
891 : :
892 : : The Stack is expected to contain:
893 : :
894 : :
895 : : Entry Exit
896 : : ===== ====
897 : :
898 : : Ptr ->
899 : : +------------+
900 : : | Expression |
901 : : |------------| empty
902 : : */
903 : :
904 : : extern "C" void M2Quads_BuildBitLength (unsigned int tokno);
905 : :
906 : : /*
907 : : BuildPragmaField - builds an assignment to an alignment 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_BuildPragmaField (void);
922 : :
923 : : /*
924 : : BuildDefaultFieldAlignment - 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_BuildDefaultFieldAlignment (void);
939 : :
940 : : /*
941 : : BuildRepeat - Builds the repeat statement from the quad stack.
942 : : The Stack is expected to contain:
943 : :
944 : :
945 : : Entry Exit
946 : : ===== ====
947 : :
948 : :
949 : : Empty
950 : : <- Ptr
951 : : +------------+
952 : : | RepeatQuad |
953 : : |------------|
954 : :
955 : : */
956 : :
957 : : extern "C" void M2Quads_BuildRepeat (void);
958 : :
959 : : /*
960 : : BuildUntil - Builds the until part of the repeat statement
961 : : from the quad stack.
962 : : The Stack is expected to contain:
963 : :
964 : :
965 : : Entry Exit
966 : : ===== ====
967 : :
968 : : Ptr ->
969 : : +------------+
970 : : | t | f |
971 : : |------------|
972 : : | RepeatQuad | Empty
973 : : |------------|
974 : : */
975 : :
976 : : extern "C" void M2Quads_BuildUntil (void);
977 : :
978 : : /*
979 : : BuildWhile - Builds the While part of the While statement
980 : : from the quad stack.
981 : : The Stack is expected to contain:
982 : :
983 : :
984 : : Entry Exit
985 : : ===== ====
986 : :
987 : : <- Ptr
988 : : |------------|
989 : : Empty | WhileQuad |
990 : : |------------|
991 : : */
992 : :
993 : : extern "C" void M2Quads_BuildWhile (void);
994 : :
995 : : /*
996 : : BuildDoWhile - Builds the Do 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 : : | t | f | | 0 | f |
1007 : : |------------| |------------|
1008 : : | WhileQuad | | WhileQuad |
1009 : : |------------| |------------|
1010 : :
1011 : : Quadruples
1012 : :
1013 : : BackPatch t exit to the NextQuad
1014 : : */
1015 : :
1016 : : extern "C" void M2Quads_BuildDoWhile (void);
1017 : :
1018 : : /*
1019 : : BuildEndWhile - Builds the end part of the while statement
1020 : : from the quad stack.
1021 : : The Stack is expected to contain:
1022 : :
1023 : :
1024 : : Entry Exit
1025 : : ===== ====
1026 : :
1027 : : Ptr ->
1028 : : +------------+
1029 : : | t | f |
1030 : : |------------|
1031 : : | WhileQuad | Empty
1032 : : |------------|
1033 : :
1034 : : Quadruples
1035 : :
1036 : : q GotoOp WhileQuad
1037 : : False exit is backpatched with q+1
1038 : : */
1039 : :
1040 : : extern "C" void M2Quads_BuildEndWhile (void);
1041 : :
1042 : : /*
1043 : : BuildLoop - Builds the Loop part of the Loop statement
1044 : : from the quad stack.
1045 : : The Stack is expected to contain:
1046 : :
1047 : :
1048 : : Entry Exit
1049 : : ===== ====
1050 : :
1051 : : <- Ptr
1052 : : Empty +------------+
1053 : : | LoopQuad |
1054 : : |------------|
1055 : : */
1056 : :
1057 : : extern "C" void M2Quads_BuildLoop (void);
1058 : :
1059 : : /*
1060 : : BuildExit - Builds the Exit part of the Loop statement.
1061 : : */
1062 : :
1063 : : extern "C" void M2Quads_BuildExit (void);
1064 : :
1065 : : /*
1066 : : BuildEndLoop - Builds the End part of the Loop statement
1067 : : from the quad stack.
1068 : : The Stack is expected to contain:
1069 : :
1070 : :
1071 : : Entry Exit
1072 : : ===== ====
1073 : :
1074 : : Ptr ->
1075 : : +------------+
1076 : : | LoopQuad | Empty
1077 : : |------------|
1078 : :
1079 : : Quadruples
1080 : :
1081 : : Goto _ _ LoopQuad
1082 : : */
1083 : :
1084 : : extern "C" void M2Quads_BuildEndLoop (void);
1085 : :
1086 : : /*
1087 : : BuildThenIf - Builds the Then part of the If statement
1088 : : from the quad stack.
1089 : : The Stack is expected to contain:
1090 : :
1091 : :
1092 : : Entry Exit
1093 : : ===== ====
1094 : :
1095 : : Ptr -> <- Ptr
1096 : : +------------+ +------------+
1097 : : | t | f | | 0 | f |
1098 : : |------------| |------------|
1099 : :
1100 : : Quadruples
1101 : :
1102 : : The true exit is BackPatched to point to
1103 : : the NextQuad.
1104 : : */
1105 : :
1106 : : extern "C" void M2Quads_BuildThenIf (void);
1107 : :
1108 : : /*
1109 : : BuildElse - Builds the Else part of the If statement
1110 : : from the quad stack.
1111 : : The Stack is expected to contain:
1112 : :
1113 : :
1114 : : Entry Exit
1115 : : ===== ====
1116 : :
1117 : : Ptr ->
1118 : : +------------+ +------------+
1119 : : | t | f | | t+q | 0 |
1120 : : |------------| |------------|
1121 : :
1122 : : Quadruples
1123 : :
1124 : : q GotoOp _ _ 0
1125 : : q+1 <- BackPatched from f
1126 : : */
1127 : :
1128 : : extern "C" void M2Quads_BuildElse (void);
1129 : :
1130 : : /*
1131 : : BuildEndIf - Builds the End part of the If statement
1132 : : from the quad stack.
1133 : : The Stack is expected to contain:
1134 : :
1135 : :
1136 : : Entry Exit
1137 : : ===== ====
1138 : :
1139 : : Ptr ->
1140 : : +------------+
1141 : : | t | f | Empty
1142 : : |------------|
1143 : :
1144 : : Quadruples
1145 : :
1146 : : Both t and f are backpatched to point to the NextQuad
1147 : : */
1148 : :
1149 : : extern "C" void M2Quads_BuildEndIf (void);
1150 : :
1151 : : /*
1152 : : BuildElsif1 - Builds the Elsif part of the If statement
1153 : : from the quad stack.
1154 : : The Stack is expected to contain:
1155 : :
1156 : :
1157 : : Entry Exit
1158 : : ===== ====
1159 : :
1160 : : Ptr ->
1161 : : +------------+ +------------+
1162 : : | t | f | | t+q | 0 |
1163 : : |------------| |------------|
1164 : :
1165 : : Quadruples
1166 : :
1167 : : q GotoOp _ _ 0
1168 : : q+1 <- BackPatched from f
1169 : : */
1170 : :
1171 : : extern "C" void M2Quads_BuildElsif1 (void);
1172 : :
1173 : : /*
1174 : : BuildElsif2 - Builds the Elsif until part of the If statement
1175 : : from the quad stack.
1176 : : The Stack is expected to contain:
1177 : :
1178 : :
1179 : : Entry Exit
1180 : : ===== ====
1181 : :
1182 : : Ptr ->
1183 : : +--------------+
1184 : : | 0 | f1 | <- Ptr
1185 : : |--------------| +---------------+
1186 : : | t2 | f2 | | t2 | f1+f2 |
1187 : : |--------------| |---------------|
1188 : : */
1189 : :
1190 : : extern "C" void M2Quads_BuildElsif2 (void);
1191 : :
1192 : : /*
1193 : : BuildForToByDo - Builds the For To By Do part of the For statement
1194 : : from the quad stack.
1195 : : The Stack is expected to contain:
1196 : :
1197 : :
1198 : : Entry Exit
1199 : : ===== ====
1200 : :
1201 : : <- Ptr
1202 : : +----------------+
1203 : : Ptr -> | RangeId |
1204 : : +----------------+ |----------------|
1205 : : | BySym | ByType | | ForQuad |
1206 : : |----------------| |----------------|
1207 : : | e2 | | LastValue |
1208 : : |----------------| |----------------|
1209 : : | e1 | | BySym | ByType |
1210 : : |----------------| |----------------|
1211 : : | Ident | | IdentSym |
1212 : : |----------------| |----------------|
1213 : :
1214 : :
1215 : : x := e1 ;
1216 : : LASTVALUE := ((e2-e1) DIV BySym) * BySym + e1
1217 : : IF BySym<0
1218 : : THEN
1219 : : IF e1<e2
1220 : : THEN
1221 : : goto exit
1222 : : END
1223 : : ELSE
1224 : : IF e1>e2
1225 : : THEN
1226 : : goto exit
1227 : : END
1228 : : END ;
1229 : : LOOP
1230 : : body
1231 : : IF x=LASTVALUE
1232 : : THEN
1233 : : goto exit
1234 : : END ;
1235 : : INC(x, BySym)
1236 : : END
1237 : :
1238 : : Quadruples:
1239 : :
1240 : : q BecomesOp IdentSym _ e1
1241 : : q+ LastValue := ((e1-e2) DIV by) * by + e1
1242 : : q+1 if >= by 0 q+..2
1243 : : q+2 GotoOp q+3
1244 : : q+3 If >= e1 e2 q+5
1245 : : q+4 GotoOp exit
1246 : : q+5 ..
1247 : : q+..1 Goto q+..5
1248 : : q+..2 If >= e2 e1 q+..4
1249 : : q+..3 GotoOp exit
1250 : : q+..4 ..
1251 : :
1252 : : The For Loop is regarded:
1253 : :
1254 : : For ident := e1 To e2 By by Do
1255 : :
1256 : : End
1257 : : */
1258 : :
1259 : : extern "C" void M2Quads_BuildForToByDo (void);
1260 : :
1261 : : /*
1262 : : BuildPseudoBy - Builds the Non existant part of the By
1263 : : clause of the For statement
1264 : : from the quad stack.
1265 : : The Stack is expected to contain:
1266 : :
1267 : :
1268 : : Entry Exit
1269 : : ===== ====
1270 : :
1271 : : <- Ptr
1272 : : +------------+
1273 : : Ptr -> | BySym | t |
1274 : : +------------+ |------------|
1275 : : | e | t | | e | t |
1276 : : |------------| |------------|
1277 : : */
1278 : :
1279 : : extern "C" void M2Quads_BuildPseudoBy (void);
1280 : :
1281 : : /*
1282 : : BuildEndFor - Builds the End part 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 : : | RangeId |
1293 : : |----------------|
1294 : : | ForQuad |
1295 : : |----------------|
1296 : : | LastValue |
1297 : : |----------------|
1298 : : | BySym | ByType |
1299 : : |----------------|
1300 : : | IdSym | Empty
1301 : : |----------------|
1302 : : */
1303 : :
1304 : : extern "C" void M2Quads_BuildEndFor (unsigned int endpostok);
1305 : :
1306 : : /*
1307 : : BuildCaseStart - starts the case statement.
1308 : : It initializes a backpatch list on the compile
1309 : : time stack, the list is used to contain all
1310 : : case break points. The list is later backpatched
1311 : : and contains all positions of the case statement
1312 : : which jump to the end of the case statement.
1313 : : The stack also contains room for a boolean
1314 : : expression, this is needed to allow , operator
1315 : : in the CaseField alternatives.
1316 : :
1317 : : The Stack is expected to contain:
1318 : :
1319 : :
1320 : : Entry Exit
1321 : : ===== ====
1322 : :
1323 : : <- Ptr
1324 : : +------------+
1325 : : | 0 | 0 |
1326 : : |------------|
1327 : : | 0 | 0 |
1328 : : +-------------+ |------------|
1329 : : | Expr | | | Expr | |
1330 : : |-------------| |------------|
1331 : : */
1332 : :
1333 : : extern "C" void M2Quads_BuildCaseStart (void);
1334 : :
1335 : : /*
1336 : : BuildCaseStartStatementSequence - starts the statement sequence
1337 : : inside a case clause.
1338 : : BackPatches the true exit to the
1339 : : NextQuad.
1340 : : The Stack:
1341 : :
1342 : : Entry Exit
1343 : :
1344 : : Ptr -> <- Ptr
1345 : : +-----------+ +------------+
1346 : : | t | f | | 0 | f |
1347 : : |-----------| |------------|
1348 : : */
1349 : :
1350 : : extern "C" void M2Quads_BuildCaseStartStatementSequence (void);
1351 : :
1352 : : /*
1353 : : BuildCaseEndStatementSequence - ends the statement sequence
1354 : : inside a case clause.
1355 : : BackPatches the false exit f1 to the
1356 : : NextQuad.
1357 : : Asserts that t1 and f2 is 0
1358 : : Pushes t2+q and 0
1359 : :
1360 : : Quadruples:
1361 : :
1362 : : q GotoOp _ _ 0
1363 : :
1364 : : The Stack:
1365 : :
1366 : : Entry Exit
1367 : :
1368 : : Ptr -> <- Ptr
1369 : : +-----------+ +------------+
1370 : : | t1 | f1 | | 0 | 0 |
1371 : : |-----------| |------------|
1372 : : | t2 | f2 | | t2+q | 0 |
1373 : : |-----------| |------------|
1374 : : */
1375 : :
1376 : : extern "C" void M2Quads_BuildCaseEndStatementSequence (void);
1377 : :
1378 : : /*
1379 : : BuildCaseRange - builds the range testing quaruples for
1380 : : a case clause.
1381 : :
1382 : : IF (e1>=ce1) AND (e1<=ce2)
1383 : : THEN
1384 : :
1385 : : ELS..
1386 : :
1387 : : The Stack:
1388 : :
1389 : : Entry Exit
1390 : :
1391 : : Ptr ->
1392 : : +-----------+
1393 : : | ce2 | <- Ptr
1394 : : |-----------| +-----------+
1395 : : | ce1 | | t | f |
1396 : : |-----------| |-----------|
1397 : : | t1 | f1 | | t1 | f1 |
1398 : : |-----------| |-----------|
1399 : : | t2 | f2 | | t2 | f2 |
1400 : : |-----------| |-----------|
1401 : : | e1 | | e1 |
1402 : : |-----------| |-----------|
1403 : : */
1404 : :
1405 : : extern "C" void M2Quads_BuildCaseRange (void);
1406 : :
1407 : : /*
1408 : : BuildCaseEquality - builds the range testing quadruples for
1409 : : a case clause.
1410 : :
1411 : : IF e1=ce1
1412 : : THEN
1413 : :
1414 : : ELS..
1415 : :
1416 : : The Stack:
1417 : :
1418 : : Entry Exit
1419 : :
1420 : : Ptr ->
1421 : : +-----------+ +-----------+
1422 : : | ce1 | | t | f |
1423 : : |-----------| |-----------|
1424 : : | t1 | f1 | | t1 | f1 |
1425 : : |-----------| |-----------|
1426 : : | t2 | f2 | | t2 | f2 |
1427 : : |-----------| |-----------|
1428 : : | e1 | | e1 |
1429 : : |-----------| |-----------|
1430 : : */
1431 : :
1432 : : extern "C" void M2Quads_BuildCaseEquality (void);
1433 : :
1434 : : /*
1435 : : BuildCaseList - merges two case tests into one
1436 : :
1437 : : The Stack:
1438 : :
1439 : : Entry Exit
1440 : :
1441 : : Ptr ->
1442 : : +-----------+
1443 : : | t2 | f2 |
1444 : : |-----------| +-------------+
1445 : : | t1 | f1 | | t1+t2| f1+f2|
1446 : : |-----------| |-------------|
1447 : : */
1448 : :
1449 : : extern "C" void M2Quads_BuildCaseList (void);
1450 : :
1451 : : /*
1452 : : BuildCaseOr - builds the , in the case clause.
1453 : :
1454 : : The Stack:
1455 : :
1456 : : Entry Exit
1457 : :
1458 : : Ptr -> <- Ptr
1459 : : +-----------+ +------------+
1460 : : | t | f | | t | 0 |
1461 : : |-----------| |------------|
1462 : : */
1463 : :
1464 : : extern "C" void M2Quads_BuildCaseOr (void);
1465 : :
1466 : : /*
1467 : : BuildCaseElse - builds the else of case clause.
1468 : :
1469 : : The Stack:
1470 : :
1471 : : Entry Exit
1472 : :
1473 : : Ptr -> <- Ptr
1474 : : +-----------+ +------------+
1475 : : | t | f | | t | 0 |
1476 : : |-----------| |------------|
1477 : : */
1478 : :
1479 : : extern "C" void M2Quads_BuildCaseElse (void);
1480 : :
1481 : : /*
1482 : : BuildCaseEnd - builds the end of case clause.
1483 : :
1484 : : The Stack:
1485 : :
1486 : : Entry Exit
1487 : :
1488 : : Ptr ->
1489 : : +-----------+
1490 : : | t1 | f1 |
1491 : : |-----------|
1492 : : | t2 | f2 |
1493 : : |-----------|
1494 : : | e1 |
1495 : : |-----------| Empty
1496 : : */
1497 : :
1498 : : extern "C" void M2Quads_BuildCaseEnd (void);
1499 : :
1500 : : /*
1501 : : BuildCaseCheck - builds the case checking code to ensure that
1502 : : the program does not need an else clause at runtime.
1503 : : The stack is unaltered.
1504 : : */
1505 : :
1506 : : extern "C" void M2Quads_BuildCaseCheck (void);
1507 : :
1508 : : /*
1509 : : BuildNulParam - Builds a nul parameter on the stack.
1510 : : The Stack:
1511 : :
1512 : : Entry Exit
1513 : :
1514 : : <- Ptr
1515 : : Empty +------------+
1516 : : | 0 |
1517 : : |------------|
1518 : : */
1519 : :
1520 : : extern "C" void M2Quads_BuildNulParam (void);
1521 : :
1522 : : /*
1523 : : BuildProcedureCall - builds a procedure call.
1524 : : Although this procedure does not directly
1525 : : destroy the procedure parameters, it calls
1526 : : routine which will manipulate the stack and
1527 : : so the entry and exit states of the stack are shown.
1528 : :
1529 : : The Stack:
1530 : :
1531 : :
1532 : : Entry Exit
1533 : :
1534 : : Ptr ->
1535 : : +----------------+
1536 : : | NoOfParam |
1537 : : |----------------|
1538 : : | Param 1 |
1539 : : |----------------|
1540 : : | Param 2 |
1541 : : |----------------|
1542 : : . .
1543 : : . .
1544 : : . .
1545 : : |----------------|
1546 : : | Param # |
1547 : : |----------------|
1548 : : | ProcSym | Type | Empty
1549 : : |----------------|
1550 : : */
1551 : :
1552 : : extern "C" void M2Quads_BuildProcedureCall (unsigned int tokno);
1553 : :
1554 : : /*
1555 : : CheckBuildFunction - checks to see whether ProcSym is a function
1556 : : and if so it adds a TempSym value which will
1557 : : hold the return value once the function finishes.
1558 : : This procedure also generates an error message
1559 : : if the user is calling a function and ignoring
1560 : : the return result. The additional TempSym
1561 : : is not created if ProcSym is a procedure
1562 : : and the stack is unaltered.
1563 : :
1564 : : The Stack:
1565 : :
1566 : :
1567 : : Entry Exit
1568 : :
1569 : : Ptr ->
1570 : :
1571 : : +----------------+
1572 : : | ProcSym | Type |
1573 : : +----------------+ |----------------|
1574 : : | ProcSym | Type | | TempSym | Type |
1575 : : |----------------| |----------------|
1576 : : */
1577 : :
1578 : : extern "C" bool M2Quads_CheckBuildFunction (void);
1579 : :
1580 : : /*
1581 : : BuildFunctionCall - builds a function call.
1582 : : The Stack:
1583 : :
1584 : :
1585 : : Entry Exit
1586 : :
1587 : : Ptr ->
1588 : : +----------------+
1589 : : | NoOfParam |
1590 : : |----------------|
1591 : : | Param 1 |
1592 : : |----------------|
1593 : : | Param 2 |
1594 : : |----------------|
1595 : : . .
1596 : : . .
1597 : : . .
1598 : : |----------------|
1599 : : | Param # | <- Ptr
1600 : : |----------------| +------------+
1601 : : | ProcSym | Type | | ReturnVar |
1602 : : |----------------| |------------|
1603 : : */
1604 : :
1605 : : extern "C" void M2Quads_BuildFunctionCall (bool ConstExpr);
1606 : :
1607 : : /*
1608 : : BuildConstFunctionCall - builds a function call and checks that this function can be
1609 : : called inside a ConstExpression.
1610 : :
1611 : : The Stack:
1612 : :
1613 : :
1614 : : Entry Exit
1615 : :
1616 : : Ptr ->
1617 : : +----------------+
1618 : : | NoOfParam |
1619 : : |----------------|
1620 : : | Param 1 |
1621 : : |----------------|
1622 : : | Param 2 |
1623 : : |----------------|
1624 : : . .
1625 : : . .
1626 : : . .
1627 : : |----------------|
1628 : : | Param # | <- Ptr
1629 : : |----------------| +------------+
1630 : : | ProcSym | Type | | ReturnVar |
1631 : : |----------------| |------------|
1632 : :
1633 : : */
1634 : :
1635 : : extern "C" void M2Quads_BuildConstFunctionCall (void);
1636 : :
1637 : : /*
1638 : : BuildBooleanVariable - tests to see whether top of stack is a boolean
1639 : : conditional and if so it converts it into a boolean
1640 : : variable.
1641 : : */
1642 : :
1643 : : extern "C" void M2Quads_BuildBooleanVariable (void);
1644 : :
1645 : : /*
1646 : : BuildModuleStart - starts current module scope.
1647 : : */
1648 : :
1649 : : extern "C" void M2Quads_BuildModuleStart (unsigned int tok);
1650 : :
1651 : : /*
1652 : : BuildProcedureStart - Builds start of the procedure. Generates a
1653 : : quadruple which indicated the start of
1654 : : this procedure declarations scope.
1655 : : The Stack is expected to contain:
1656 : :
1657 : :
1658 : : Entry Exit
1659 : : ===== ====
1660 : :
1661 : : Ptr -> <- Ptr
1662 : : +------------+ +-----------+
1663 : : | ProcSym | | ProcSym |
1664 : : |------------| |-----------|
1665 : : | Name | | Name |
1666 : : |------------| |-----------|
1667 : :
1668 : :
1669 : : Quadruples:
1670 : :
1671 : : q ProcedureScopeOp Line# Scope ProcSym
1672 : : */
1673 : :
1674 : : extern "C" void M2Quads_BuildProcedureStart (void);
1675 : :
1676 : : /*
1677 : : BuildProcedureBegin - determines the start of the BEGIN END block of
1678 : : the procedure.
1679 : : The Stack is expected to contain:
1680 : :
1681 : :
1682 : : Entry Exit
1683 : : ===== ====
1684 : :
1685 : : Ptr -> <- Ptr
1686 : : +------------+ +-----------+
1687 : : | ProcSym | | ProcSym |
1688 : : |------------| |-----------|
1689 : : | Name | | Name |
1690 : : |------------| |-----------|
1691 : :
1692 : :
1693 : : Quadruples:
1694 : :
1695 : : q NewLocalVarOp TokenNo(BEGIN) _ ProcSym
1696 : : */
1697 : :
1698 : : extern "C" void M2Quads_BuildProcedureBegin (void);
1699 : :
1700 : : /*
1701 : : BuildProcedureEnd - Builds end of the procedure. Destroys space for
1702 : : the local variables.
1703 : : The Stack is expected to contain:
1704 : :
1705 : :
1706 : : Entry Exit
1707 : : ===== ====
1708 : :
1709 : : Ptr -> <- Ptr
1710 : : +------------+ +-----------+
1711 : : | ProcSym | | ProcSym |
1712 : : |------------| |-----------|
1713 : : | Name | | Name |
1714 : : |------------| |-----------|
1715 : :
1716 : :
1717 : : Quadruples:
1718 : :
1719 : : q KillLocalVarOp TokenNo(END) _ ProcSym
1720 : : */
1721 : :
1722 : : extern "C" void M2Quads_BuildProcedureEnd (void);
1723 : :
1724 : : /*
1725 : : BuildReturn - Builds the Return part of the procedure.
1726 : : tokreturn is the location of the RETURN keyword.
1727 : : The Stack is expected to contain:
1728 : :
1729 : :
1730 : : Entry Exit
1731 : : ===== ====
1732 : :
1733 : : Ptr ->
1734 : : +------------+
1735 : : | e1 | Empty
1736 : : |------------|
1737 : : */
1738 : :
1739 : : extern "C" void M2Quads_BuildReturn (unsigned int tokreturn);
1740 : :
1741 : : /*
1742 : : BuildModulePriority - assigns the current module with a priority
1743 : : from the top of stack.
1744 : :
1745 : : Entry Exit
1746 : : ===== ====
1747 : :
1748 : :
1749 : : Ptr -> Empty
1750 : : +------------+
1751 : : | Priority |
1752 : : |------------|
1753 : : */
1754 : :
1755 : : extern "C" void M2Quads_BuildModulePriority (void);
1756 : :
1757 : : /*
1758 : : StartBuildWith - performs the with statement.
1759 : : The Stack:
1760 : :
1761 : : Entry Exit
1762 : :
1763 : : +------------+
1764 : : | Sym | Type | Empty
1765 : : |------------|
1766 : : */
1767 : :
1768 : : extern "C" void M2Quads_StartBuildWith (unsigned int withTok);
1769 : :
1770 : : /*
1771 : : EndBuildWith - terminates the innermost with scope.
1772 : : */
1773 : :
1774 : : extern "C" void M2Quads_EndBuildWith (void);
1775 : :
1776 : : /*
1777 : : CheckWithReference - performs the with statement.
1778 : : The Stack:
1779 : :
1780 : : Entry Exit
1781 : :
1782 : : +------------+ +------------+
1783 : : | Sym | Type | | Sym | Type |
1784 : : |------------| |------------|
1785 : : */
1786 : :
1787 : : extern "C" void M2Quads_CheckWithReference (void);
1788 : :
1789 : : /*
1790 : : BuildDesignatorRecord - Builds the record referencing.
1791 : : The Stack is expected to contain:
1792 : :
1793 : :
1794 : : Entry Exit
1795 : : ===== ====
1796 : :
1797 : : Ptr ->
1798 : : +--------------+
1799 : : | n |
1800 : : |--------------|
1801 : : | fld1 | type1 |
1802 : : |--------------|
1803 : : . .
1804 : : . .
1805 : : . .
1806 : : |--------------|
1807 : : | fldn | typen | <- Ptr
1808 : : |--------------| +-------------+
1809 : : | Sym | Type | | S | type1|
1810 : : |--------------| |-------------|
1811 : : */
1812 : :
1813 : : extern "C" void M2Quads_BuildDesignatorRecord (unsigned int dottok);
1814 : :
1815 : : /*
1816 : : BuildDesignatorArray - Builds the array referencing.
1817 : : The purpose of this procedure is to work out
1818 : : whether the DesignatorArray is a static or
1819 : : dynamic array and to call the appropriate
1820 : : BuildRoutine.
1821 : :
1822 : : The Stack is expected to contain:
1823 : :
1824 : :
1825 : : Entry Exit
1826 : : ===== ====
1827 : :
1828 : : Ptr ->
1829 : : +--------------+
1830 : : | e | <- Ptr
1831 : : |--------------| +------------+
1832 : : | Sym | Type | | S | T |
1833 : : |--------------| |------------|
1834 : : */
1835 : :
1836 : : extern "C" void M2Quads_BuildDesignatorArray (void);
1837 : :
1838 : : /*
1839 : : BuildDesignatorPointer - Builds a pointer reference.
1840 : : The Stack is expected to contain:
1841 : :
1842 : :
1843 : : Entry Exit
1844 : : ===== ====
1845 : :
1846 : : Ptr -> <- Ptr
1847 : : +--------------+ +--------------+
1848 : : | Sym1 | Type1| | Sym2 | Type2|
1849 : : |--------------| |--------------|
1850 : : */
1851 : :
1852 : : extern "C" void M2Quads_BuildDesignatorPointer (unsigned int ptrtok);
1853 : :
1854 : : /*
1855 : : BuildNulExpression - Builds a nul expression on the stack.
1856 : : The Stack:
1857 : :
1858 : : Entry Exit
1859 : :
1860 : : <- Ptr
1861 : : Empty +------------+
1862 : : | NulSym |
1863 : : |------------|
1864 : : tokpos is the position of the RETURN token.
1865 : : */
1866 : :
1867 : : extern "C" void M2Quads_BuildNulExpression (unsigned int tokpos);
1868 : :
1869 : : /*
1870 : : BuildSetStart - Pushes a Bitset type on the stack.
1871 : :
1872 : : The Stack:
1873 : :
1874 : : Entry Exit
1875 : :
1876 : : Ptr -> <- Ptr
1877 : :
1878 : : Empty +--------------+
1879 : : | Bitset |
1880 : : |--------------|
1881 : : */
1882 : :
1883 : : extern "C" void M2Quads_BuildSetStart (unsigned int tokpos);
1884 : :
1885 : : /*
1886 : : BuildSetEnd - pops the set value and type from the stack
1887 : : and pushes the value,type pair.
1888 : :
1889 : : Entry Exit
1890 : :
1891 : : Ptr ->
1892 : : +--------------+
1893 : : | Set Value | <- Ptr
1894 : : |--------------| +--------------+
1895 : : | Set Type | | Value | Type |
1896 : : |--------------| |--------------|
1897 : : */
1898 : :
1899 : : extern "C" void M2Quads_BuildSetEnd (void);
1900 : :
1901 : : /*
1902 : : BuildEmptySet - Builds an empty set on the stack.
1903 : : The Stack:
1904 : :
1905 : : Entry Exit
1906 : :
1907 : : <- Ptr
1908 : : +-------------+
1909 : : Ptr -> | Value |
1910 : : +-----------+ |-------------|
1911 : : | SetType | | SetType |
1912 : : |-----------| |-------------|
1913 : :
1914 : : tokpos points to the opening '{'.
1915 : : */
1916 : :
1917 : : extern "C" void M2Quads_BuildEmptySet (unsigned int tokpos);
1918 : :
1919 : : /*
1920 : : BuildInclRange - includes a set range with a set.
1921 : :
1922 : :
1923 : : Entry Exit
1924 : : ===== ====
1925 : :
1926 : :
1927 : : Ptr ->
1928 : : +------------+
1929 : : | El2 |
1930 : : |------------|
1931 : : | El1 | <- Ptr
1932 : : |------------| +-------------------+
1933 : : | Set Value | | Value + {El1..El2}|
1934 : : |------------| |-------------------|
1935 : :
1936 : : No quadruples produced as the range info is contained within
1937 : : the set value.
1938 : : */
1939 : :
1940 : : extern "C" void M2Quads_BuildInclRange (void);
1941 : :
1942 : : /*
1943 : : BuildInclBit - includes a bit into the set.
1944 : :
1945 : : Entry Exit
1946 : : ===== ====
1947 : :
1948 : :
1949 : : Ptr ->
1950 : : +------------+
1951 : : | Element | <- Ptr
1952 : : |------------| +------------+
1953 : : | Value | | Value |
1954 : : |------------| |------------|
1955 : :
1956 : : */
1957 : :
1958 : : extern "C" void M2Quads_BuildInclBit (void);
1959 : :
1960 : : /*
1961 : : SilentBuildConstructor - places NulSym into the constructor fifo queue.
1962 : : */
1963 : :
1964 : : extern "C" void M2Quads_SilentBuildConstructor (void);
1965 : :
1966 : : /*
1967 : : SilentBuildConstructorStart - removes an entry from the constructor fifo queue.
1968 : : */
1969 : :
1970 : : extern "C" void M2Quads_SilentBuildConstructorStart (void);
1971 : :
1972 : : /*
1973 : : BuildConstructor - builds a constructor.
1974 : : Stack
1975 : :
1976 : : Entry Exit
1977 : :
1978 : : Ptr ->
1979 : : +------------+
1980 : : | Type | <- Ptr
1981 : : |------------+
1982 : : */
1983 : :
1984 : : extern "C" void M2Quads_BuildConstructor (unsigned int tokcbrpos);
1985 : :
1986 : : /*
1987 : : BuildConstructorStart - builds a constructor.
1988 : : Stack
1989 : :
1990 : : Entry Exit
1991 : :
1992 : : Ptr -> <- Ptr
1993 : : +------------+ +----------------+
1994 : : | Type | | ConstructorSym |
1995 : : |------------+ |----------------|
1996 : : */
1997 : :
1998 : : extern "C" void M2Quads_BuildConstructorStart (unsigned int cbratokpos);
1999 : :
2000 : : /*
2001 : : BuildConstructorEnd - removes the current constructor frame from the
2002 : : constructor stack (it does not effect the quad
2003 : : stack)
2004 : :
2005 : : Entry Exit
2006 : :
2007 : : Ptr -> <- Ptr
2008 : : +------------+ +------------+
2009 : : | const | | const |
2010 : : |------------| |------------|
2011 : :
2012 : : startpos is the start of the constructor, either the typename or '{'
2013 : : cbratokpos is the '}'.
2014 : : */
2015 : :
2016 : : extern "C" void M2Quads_BuildConstructorEnd (unsigned int startpos, unsigned int cbratokpos);
2017 : :
2018 : : /*
2019 : : NextConstructorField - increments the top of constructor stacks index by one.
2020 : : */
2021 : :
2022 : : extern "C" void M2Quads_NextConstructorField (void);
2023 : :
2024 : : /*
2025 : : BuildTypeForConstructor - pushes the type implied by the current constructor.
2026 : : If no constructor is currently being built then
2027 : : it Pushes a Bitset type.
2028 : : */
2029 : :
2030 : : extern "C" void M2Quads_BuildTypeForConstructor (unsigned int tokpos);
2031 : :
2032 : : /*
2033 : : BuildComponentValue - builds a component value.
2034 : :
2035 : : Entry Exit
2036 : :
2037 : : Ptr -> <- Ptr
2038 : :
2039 : :
2040 : : +------------+ +------------+
2041 : : | const | | const |
2042 : : |------------| |------------|
2043 : : */
2044 : :
2045 : : extern "C" void M2Quads_BuildComponentValue (void);
2046 : :
2047 : : /*
2048 : : PopConstructor - removes the top constructor from the top of stack.
2049 : : */
2050 : :
2051 : : extern "C" void M2Quads_PopConstructor (void);
2052 : :
2053 : : /*
2054 : : BuildNot - Builds a NOT operation from the quad stack.
2055 : : The Stack is expected to contain:
2056 : :
2057 : :
2058 : : Entry Exit
2059 : : ===== ====
2060 : :
2061 : : Ptr -> <- Ptr
2062 : : +------------+ +------------+
2063 : : | t | f | | f | t |
2064 : : |------------| |------------|
2065 : : */
2066 : :
2067 : : extern "C" void M2Quads_BuildNot (unsigned int notTokPos);
2068 : :
2069 : : /*
2070 : : RecordOp - Records the operator passed on the stack.
2071 : : Checks for AND operator or OR operator
2072 : : if either of these operators are found then BackPatching
2073 : : takes place.
2074 : : The Expected Stack:
2075 : :
2076 : : Entry Exit
2077 : :
2078 : : Ptr -> <- Ptr
2079 : : +-------------+ +-------------+
2080 : : | OperatorTok | | OperatorTok |
2081 : : |-------------| |-------------|
2082 : : | t | f | | t | f |
2083 : : |-------------| |-------------|
2084 : :
2085 : :
2086 : : If OperatorTok=AndTok
2087 : : Then
2088 : : BackPatch(f, NextQuad)
2089 : : Elsif OperatorTok=OrTok
2090 : : Then
2091 : : BackPatch(t, NextQuad)
2092 : : End
2093 : : */
2094 : :
2095 : : extern "C" void M2Quads_RecordOp (void);
2096 : :
2097 : : /*
2098 : : BuildRelOp - Builds a relative operation from the quad stack.
2099 : : The Stack is expected to contain:
2100 : :
2101 : :
2102 : : Entry Exit
2103 : : ===== ====
2104 : :
2105 : : Ptr ->
2106 : : +------------+
2107 : : | e1 |
2108 : : |------------| <- Ptr
2109 : : | Operator |
2110 : : |------------| +------------+
2111 : : | e2 | | t | f |
2112 : : |------------| |------------|
2113 : :
2114 : :
2115 : : Quadruples Produced
2116 : :
2117 : : q IFOperator e2 e1 TrueExit ; e2 e1 since
2118 : : q+1 GotoOp FalseExit ; relation > etc
2119 : : ; requires order.
2120 : : */
2121 : :
2122 : : extern "C" void M2Quads_BuildRelOp (unsigned int optokpos);
2123 : :
2124 : : /*
2125 : : BuildBinaryOp - Builds a binary operation from the quad stack.
2126 : : Be aware that this procedure will check for
2127 : : the overloading of the bitset operators + - \ *.
2128 : : So do NOT call this procedure if you are building
2129 : : a reference to an array which has a bitset type or
2130 : : the address arithmetic will be wrongly coersed into
2131 : : logical ORs.
2132 : :
2133 : : The Stack is expected to contain:
2134 : :
2135 : :
2136 : : Entry Exit
2137 : : ===== ====
2138 : :
2139 : : Ptr ->
2140 : : +------------+
2141 : : | Sym1 |
2142 : : |------------|
2143 : : | Operator | <- Ptr
2144 : : |------------| +------------+
2145 : : | Sym2 | | Temporary |
2146 : : |------------| |------------|
2147 : :
2148 : :
2149 : : Quadruples Produced
2150 : :
2151 : : q Operator Temporary Sym1 Sym2
2152 : :
2153 : :
2154 : : OR
2155 : :
2156 : :
2157 : : Entry Exit
2158 : : ===== ====
2159 : :
2160 : : Ptr ->
2161 : : +------------+
2162 : : | T1 | F1 |
2163 : : |------------|
2164 : : | OrTok | <- Ptr
2165 : : |------------| +------------+
2166 : : | T2 | F2 | | T1+T2| F1 |
2167 : : |------------| |------------|
2168 : :
2169 : :
2170 : : Quadruples Produced
2171 : :
2172 : : */
2173 : :
2174 : : extern "C" void M2Quads_BuildBinaryOp (void);
2175 : :
2176 : : /*
2177 : : BuildUnaryOp - Builds a unary operation from the quad stack.
2178 : : The Stack is expected to contain:
2179 : :
2180 : :
2181 : : Entry Exit
2182 : : ===== ====
2183 : :
2184 : : Ptr ->
2185 : : +------------+
2186 : : | Sym |
2187 : : |------------| +------------+
2188 : : | Operator | | Temporary | <- Ptr
2189 : : |------------| |------------|
2190 : :
2191 : :
2192 : : Quadruples Produced
2193 : :
2194 : : q Operator Temporary _ Sym
2195 : :
2196 : : */
2197 : :
2198 : : extern "C" void M2Quads_BuildUnaryOp (void);
2199 : :
2200 : : /*
2201 : : OperandT - returns the ident operand stored in the true position on the boolean stack.
2202 : : */
2203 : :
2204 : : extern "C" unsigned int M2Quads_OperandT (unsigned int pos);
2205 : :
2206 : : /*
2207 : : OperandF - returns the ident operand stored in the false position on the boolean stack.
2208 : : */
2209 : :
2210 : : extern "C" unsigned int M2Quads_OperandF (unsigned int pos);
2211 : :
2212 : : /*
2213 : : PushTF - Push a True and False numbers onto the True/False stack.
2214 : : True and False are assumed to contain Symbols or Ident etc.
2215 : : */
2216 : :
2217 : : extern "C" void M2Quads_PushTF (unsigned int True, unsigned int False);
2218 : :
2219 : : /*
2220 : : PopTF - Pop a True and False number from the True/False stack.
2221 : : True and False are assumed to contain Symbols or Ident etc.
2222 : : */
2223 : :
2224 : : extern "C" void M2Quads_PopTF (unsigned int *True, unsigned int *False);
2225 : :
2226 : : /*
2227 : : PushT - Push an item onto the stack in the T (true) position.
2228 : : */
2229 : :
2230 : : extern "C" void M2Quads_PushT (unsigned int True);
2231 : :
2232 : : /*
2233 : : PopT - Pops the T value from the stack.
2234 : : */
2235 : :
2236 : : extern "C" void M2Quads_PopT (unsigned int *True);
2237 : :
2238 : : /*
2239 : : PushTtok - Push an item onto the stack in the T (true) position,
2240 : : it is assummed to be a token and its token location is recorded.
2241 : : */
2242 : :
2243 : : extern "C" void M2Quads_PushTtok (unsigned int True, unsigned int tokno);
2244 : :
2245 : : /*
2246 : : PushTFtok - Push an item onto the stack in the T (true) position,
2247 : : it is assummed to be a token and its token location is recorded.
2248 : : */
2249 : :
2250 : : extern "C" void M2Quads_PushTFtok (unsigned int True, unsigned int False, unsigned int tokno);
2251 : :
2252 : : /*
2253 : : PopTFtok - Pop T/F/tok from the stack.
2254 : : */
2255 : :
2256 : : extern "C" void M2Quads_PopTFtok (unsigned int *True, unsigned int *False, unsigned int *tokno);
2257 : :
2258 : : /*
2259 : : PushTFAtok - Push T/F/A/tok to the stack.
2260 : : */
2261 : :
2262 : : extern "C" void M2Quads_PushTFAtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int tokno);
2263 : :
2264 : : /*
2265 : : PopTtok - Pops the T value from the stack and token position.
2266 : : */
2267 : :
2268 : : extern "C" void M2Quads_PopTtok (unsigned int *True, unsigned int *tok);
2269 : :
2270 : : /*
2271 : : PushTFn - Push a True and False numbers onto the True/False stack.
2272 : : True and False are assumed to contain Symbols or Ident etc.
2273 : : */
2274 : :
2275 : : extern "C" void M2Quads_PushTFn (unsigned int True, unsigned int False, unsigned int n);
2276 : :
2277 : : /*
2278 : : PushTFntok - Push a True and False numbers onto the True/False stack.
2279 : : True and False are assumed to contain Symbols or Ident etc.
2280 : : */
2281 : :
2282 : : extern "C" void M2Quads_PushTFntok (unsigned int True, unsigned int False, unsigned int n, unsigned int tokno);
2283 : :
2284 : : /*
2285 : : PopTFn - Pop a True and False number from the True/False stack.
2286 : : True and False are assumed to contain Symbols or Ident etc.
2287 : : */
2288 : :
2289 : : extern "C" void M2Quads_PopTFn (unsigned int *True, unsigned int *False, unsigned int *n);
2290 : :
2291 : : /*
2292 : : PopNothing - pops the top element on the boolean stack.
2293 : : */
2294 : :
2295 : : extern "C" void M2Quads_PopNothing (void);
2296 : :
2297 : : /*
2298 : : PopN - pops multiple elements from the BoolStack.
2299 : : */
2300 : :
2301 : : extern "C" void M2Quads_PopN (unsigned int n);
2302 : :
2303 : : /*
2304 : : PushTFA - Push True, False, Array, numbers onto the
2305 : : True/False stack. True and False are assumed to
2306 : : contain Symbols or Ident etc.
2307 : : */
2308 : :
2309 : : extern "C" void M2Quads_PushTFA (unsigned int True, unsigned int False, unsigned int Array);
2310 : :
2311 : : /*
2312 : : OperandTok - returns the token associated with pos, on the stack.
2313 : : */
2314 : :
2315 : : extern "C" unsigned int M2Quads_OperandTok (unsigned int pos);
2316 : :
2317 : : /*
2318 : : OperandA - returns possible array symbol associated with the ident
2319 : : operand stored on the boolean stack.
2320 : : */
2321 : :
2322 : : extern "C" unsigned int M2Quads_OperandA (unsigned int pos);
2323 : :
2324 : : /*
2325 : : OperandAnno - returns the annotation string associated with the
2326 : : position, n, on the stack.
2327 : : */
2328 : :
2329 : : extern "C" DynamicStrings_String M2Quads_OperandAnno (unsigned int n);
2330 : :
2331 : : /*
2332 : : Annotate - annotate the top of stack.
2333 : : */
2334 : :
2335 : : extern "C" void M2Quads_Annotate (const char *a_, unsigned int _a_high);
2336 : :
2337 : : /*
2338 : : DisplayStack - displays the compile time symbol stack.
2339 : : */
2340 : :
2341 : : extern "C" void M2Quads_DisplayStack (void);
2342 : :
2343 : : /*
2344 : : Top - returns the no of items held in the stack.
2345 : : */
2346 : :
2347 : : extern "C" unsigned int M2Quads_Top (void);
2348 : :
2349 : : /*
2350 : : WriteOperand - displays the operands name, symbol id and mode of addressing.
2351 : : */
2352 : :
2353 : : extern "C" void M2Quads_WriteOperand (unsigned int Sym);
2354 : :
2355 : : /*
2356 : : BeginVarient - begin a varient record.
2357 : : */
2358 : :
2359 : : extern "C" void M2Quads_BeginVarient (void);
2360 : :
2361 : : /*
2362 : : EndVarient - end a varient record.
2363 : : */
2364 : :
2365 : : extern "C" void M2Quads_EndVarient (void);
2366 : :
2367 : : /*
2368 : : ElseVarient - associate an ELSE clause with a varient record.
2369 : : */
2370 : :
2371 : : extern "C" void M2Quads_ElseVarient (void);
2372 : :
2373 : : /*
2374 : : BeginVarientList - begin an ident list containing ranges belonging to a
2375 : : varient list.
2376 : : */
2377 : :
2378 : : extern "C" void M2Quads_BeginVarientList (void);
2379 : :
2380 : : /*
2381 : : EndVarientList - end a range list for a varient field.
2382 : : */
2383 : :
2384 : : extern "C" void M2Quads_EndVarientList (void);
2385 : :
2386 : : /*
2387 : : AddRecordToList - adds the record held on the top of stack to the
2388 : : list of records and varient fields.
2389 : : */
2390 : :
2391 : : extern "C" void M2Quads_AddRecordToList (void);
2392 : :
2393 : : /*
2394 : : AddVarientToList - adds varient held on the top of stack to the list.
2395 : : */
2396 : :
2397 : : extern "C" void M2Quads_AddVarientToList (void);
2398 : :
2399 : : /*
2400 : : AddVarientFieldToList - adds varient field, f, to the list of all varient
2401 : : fields created.
2402 : : */
2403 : :
2404 : : extern "C" void M2Quads_AddVarientFieldToList (unsigned int f);
2405 : :
2406 : : /*
2407 : : AddVarientRange - creates a range from the top two contant expressions
2408 : : on the stack which are recorded with the current
2409 : : varient field. The stack is unaltered.
2410 : : */
2411 : :
2412 : : extern "C" void M2Quads_AddVarientRange (void);
2413 : :
2414 : : /*
2415 : : AddVarientEquality - adds the contant expression on the top of the stack
2416 : : to the current varient field being recorded.
2417 : : The stack is unaltered.
2418 : : */
2419 : :
2420 : : extern "C" void M2Quads_AddVarientEquality (void);
2421 : :
2422 : : /*
2423 : : BuildCodeOn - generates a quadruple declaring that code should be
2424 : : emmitted from henceforth.
2425 : :
2426 : : The Stack is unnaffected.
2427 : : */
2428 : :
2429 : : extern "C" void M2Quads_BuildCodeOn (void);
2430 : :
2431 : : /*
2432 : : BuildCodeOff - generates a quadruple declaring that code should not be
2433 : : emmitted from henceforth.
2434 : :
2435 : : The Stack is unnaffected.
2436 : : */
2437 : :
2438 : : extern "C" void M2Quads_BuildCodeOff (void);
2439 : :
2440 : : /*
2441 : : BuildProfileOn - generates a quadruple declaring that profile timings
2442 : : should be emmitted from henceforth.
2443 : :
2444 : : The Stack is unnaffected.
2445 : : */
2446 : :
2447 : : extern "C" void M2Quads_BuildProfileOn (void);
2448 : : extern "C" void M2Quads_BuildProfileOff (void);
2449 : :
2450 : : /*
2451 : : BuildOptimizeOn - generates a quadruple declaring that optimization
2452 : : should occur from henceforth.
2453 : :
2454 : : The Stack is unnaffected.
2455 : : */
2456 : :
2457 : : extern "C" void M2Quads_BuildOptimizeOn (void);
2458 : :
2459 : : /*
2460 : : BuildOptimizeOff - generates a quadruple declaring that optimization
2461 : : should not occur from henceforth.
2462 : :
2463 : : The Stack is unnaffected.
2464 : : */
2465 : :
2466 : : extern "C" void M2Quads_BuildOptimizeOff (void);
2467 : :
2468 : : /*
2469 : : BuildAsm - builds an Inline pseudo quadruple operator.
2470 : : The inline interface, Sym, is stored as the operand
2471 : : to the operator InlineOp.
2472 : :
2473 : : The stack is expected to contain:
2474 : :
2475 : :
2476 : : Entry Exit
2477 : : ===== ====
2478 : :
2479 : : Ptr ->
2480 : : +--------------+
2481 : : | Sym | Empty
2482 : : |--------------|
2483 : : */
2484 : :
2485 : : extern "C" void M2Quads_BuildAsm (unsigned int tok);
2486 : :
2487 : : /*
2488 : : BuildLineNo - builds a LineNumberOp pseudo quadruple operator.
2489 : : This quadruple indicates which source line has been
2490 : : processed, these quadruples are only generated if we
2491 : : are producing runtime debugging information.
2492 : :
2493 : : The stack is not affected, read or altered in any way.
2494 : :
2495 : :
2496 : : Entry Exit
2497 : : ===== ====
2498 : :
2499 : : Ptr -> <- Ptr
2500 : : */
2501 : :
2502 : : extern "C" void M2Quads_BuildLineNo (void);
2503 : :
2504 : : /*
2505 : : PushLineNo - pushes the current file and line number to the stack.
2506 : : */
2507 : :
2508 : : extern "C" void M2Quads_PushLineNo (void);
2509 : :
2510 : : /*
2511 : : BuildStmtNote - builds a StatementNoteOp pseudo quadruple operator.
2512 : : This quadruple indicates which source line has been
2513 : : processed and it represents the start of a statement
2514 : : sequence.
2515 : : It differs from LineNumberOp in that multiple successive
2516 : : LineNumberOps will be removed and the final one is attached to
2517 : : the next real GCC tree. Whereas a StatementNoteOp is always left
2518 : : alone. Depending upon the debugging level it will issue a nop
2519 : : instruction to ensure that the gdb single step will step into
2520 : : this line. Practically it allows pedalogical debugging to
2521 : : occur when there is syntax sugar such as:
2522 : :
2523 : :
2524 : : END step
2525 : : END step
2526 : : END ; step
2527 : : a := 1 ; step
2528 : :
2529 : : REPEAT step
2530 : : i := 1 step
2531 : :
2532 : : The stack is not affected, read or altered in any way.
2533 : :
2534 : :
2535 : : Entry Exit
2536 : : ===== ====
2537 : :
2538 : : Ptr -> <- Ptr
2539 : : */
2540 : :
2541 : : extern "C" void M2Quads_BuildStmtNote (int offset);
2542 : :
2543 : : /*
2544 : : LoopAnalysis - checks whether an infinite loop exists.
2545 : : */
2546 : :
2547 : : extern "C" void M2Quads_LoopAnalysis (unsigned int Scope, unsigned int Current, unsigned int End);
2548 : :
2549 : : /*
2550 : : ForLoopAnalysis - checks all the FOR loops for index variable manipulation
2551 : : and dangerous usage outside the loop.
2552 : : */
2553 : :
2554 : : extern "C" void M2Quads_ForLoopAnalysis (void);
2555 : :
2556 : : /*
2557 : : BuildSizeCheckStart - switches off all quadruple generation if the function SIZE or HIGH
2558 : : is being "called". This should be done as SIZE only requires the
2559 : : actual type of the expression, not its value. Consider the problem of
2560 : : SIZE(UninitializedPointer^) which is quite legal and it must
2561 : : also be safe!
2562 : : ISO Modula-2 also allows HIGH(a[0]) for a two dimensional array
2563 : : and there is no need to compute a[0], we just need to follow the
2564 : : type and count dimensions. However if SIZE(a) or HIGH(a) occurs
2565 : : and, a, is an unbounded array then we turn on quadruple generation.
2566 : :
2567 : : The Stack is expected to contain:
2568 : :
2569 : :
2570 : : Entry Exit
2571 : : ===== ====
2572 : :
2573 : : Ptr -> <- Ptr
2574 : : +----------------------+ +----------------------+
2575 : : | ProcSym | Type | tok | | ProcSym | Type | tok |
2576 : : |----------------------| |----------------------|
2577 : : */
2578 : :
2579 : : extern "C" void M2Quads_BuildSizeCheckStart (void);
2580 : :
2581 : : /*
2582 : : BackPatchSubrangesAndOptParam - runs through all the quadruples and finds SubrangeLow or SubrangeHigh
2583 : : quadruples and replaces it by an assignment to the Low or High component
2584 : : of the subrange type.
2585 : :
2586 : : Input:
2587 : : SubrangeLow op1 op3 op3 is a subrange
2588 : :
2589 : : Output:
2590 : : Becomes op1 low
2591 : :
2592 : : Input:
2593 : : SubrangeHigh op1 op3 op3 is a subrange
2594 : :
2595 : : Output:
2596 : : Becomes op1 high
2597 : :
2598 : : Input:
2599 : : OptParam op1 op2 op3
2600 : :
2601 : : Output:
2602 : : Param op1 op2 GetOptArgInit(op3)
2603 : : */
2604 : :
2605 : : extern "C" void M2Quads_BackPatchSubrangesAndOptParam (void);
2606 : :
2607 : : /*
2608 : : WriteOperator - writes the name of the quadruple operator.
2609 : : */
2610 : :
2611 : : extern "C" void M2Quads_WriteOperator (M2Quads_QuadOperator Operator);
2612 : :
2613 : : /*
2614 : : PushAutoOn - push the auto flag and then set it to TRUE.
2615 : : Any call to ident in the parser will result in the token being pushed.
2616 : : */
2617 : :
2618 : : extern "C" void M2Quads_PushAutoOn (void);
2619 : :
2620 : : /*
2621 : : PushAutoOff - push the auto flag and then set it to FALSE.
2622 : : */
2623 : :
2624 : : extern "C" void M2Quads_PushAutoOff (void);
2625 : :
2626 : : /*
2627 : : IsAutoPushOn - returns the value of the current Auto ident push flag.
2628 : : */
2629 : :
2630 : : extern "C" bool M2Quads_IsAutoPushOn (void);
2631 : :
2632 : : /*
2633 : : PopAuto - restores the previous value of the Auto flag.
2634 : : */
2635 : :
2636 : : extern "C" void M2Quads_PopAuto (void);
2637 : :
2638 : : /*
2639 : : MustCheckOverflow - returns TRUE if the quadruple should test for overflow.
2640 : : */
2641 : :
2642 : : extern "C" bool M2Quads_MustCheckOverflow (unsigned int q);
2643 : :
2644 : : /*
2645 : : PushInConstExpression - push the InConstExpression flag and then set it to TRUE.
2646 : : */
2647 : :
2648 : : extern "C" void M2Quads_PushInConstExpression (void);
2649 : :
2650 : : /*
2651 : : PopInConstExpression - restores the previous value of the InConstExpression.
2652 : : */
2653 : :
2654 : : extern "C" void M2Quads_PopInConstExpression (void);
2655 : :
2656 : : /*
2657 : : IsInConstExpression - returns the value of the InConstExpression.
2658 : : */
2659 : :
2660 : : extern "C" bool M2Quads_IsInConstExpression (void);
2661 : :
2662 : : /*
2663 : : PushInConstParameters - push the InConstParameters flag and then set it to TRUE.
2664 : : */
2665 : :
2666 : : extern "C" void M2Quads_PushInConstParameters (void);
2667 : :
2668 : : /*
2669 : : PopInConstParameters - restores the previous value of the InConstParameters.
2670 : : */
2671 : :
2672 : : extern "C" void M2Quads_PopInConstParameters (void);
2673 : :
2674 : : /*
2675 : : IsInConstParameters - returns the value of the InConstParameters.
2676 : : */
2677 : :
2678 : : extern "C" bool M2Quads_IsInConstParameters (void);
2679 : :
2680 : : /*
2681 : : BuildAsmElement - the stack is expected to contain:
2682 : :
2683 : :
2684 : : Entry Exit
2685 : : ===== ====
2686 : :
2687 : : Ptr ->
2688 : : +------------------+
2689 : : | expr | tokpos |
2690 : : |------------------|
2691 : : | str |
2692 : : |------------------|
2693 : : | name |
2694 : : |------------------| +------------------+
2695 : : | CurrentInterface | | CurrentInterface |
2696 : : |------------------| |------------------|
2697 : : | CurrentAsm | | CurrentAsm |
2698 : : |------------------| |------------------|
2699 : : | n | | n |
2700 : : |------------------| |------------------|
2701 : : */
2702 : :
2703 : : extern "C" void M2Quads_BuildAsmElement (bool input, bool output);
2704 : :
2705 : : /*
2706 : : BuildAsmTrash - the stack is expected to contain:
2707 : :
2708 : :
2709 : : Entry Exit
2710 : : ===== ====
2711 : :
2712 : : Ptr ->
2713 : : +------------------+
2714 : : | expr | tokpos |
2715 : : |------------------| +------------------+
2716 : : | CurrentInterface | | CurrentInterface |
2717 : : |------------------| |------------------|
2718 : : | CurrentAsm | | CurrentAsm |
2719 : : |------------------| |------------------|
2720 : : | n | | n |
2721 : : |------------------| |------------------|
2722 : : */
2723 : :
2724 : : extern "C" void M2Quads_BuildAsmTrash (void);
2725 : :
2726 : : /*
2727 : : GetQuadTrash - return the symbol associated with the trashed operand.
2728 : : */
2729 : :
2730 : : extern "C" unsigned int M2Quads_GetQuadTrash (unsigned int quad);
2731 : :
2732 : : /*
2733 : : DSdbEnter -
2734 : : */
2735 : :
2736 : : static void DSdbEnter (void);
2737 : :
2738 : : /*
2739 : : DSdbExit -
2740 : : */
2741 : :
2742 : : static void DSdbExit (void);
2743 : :
2744 : : /*
2745 : : GetQF - returns the QuadFrame associated with, q.
2746 : : */
2747 : :
2748 : : static M2Quads_QuadFrame GetQF (unsigned int q);
2749 : :
2750 : : /*
2751 : : IsQuadA - returns true if QuadNo is a op.
2752 : : */
2753 : :
2754 : : static bool IsQuadA (unsigned int QuadNo, M2Quads_QuadOperator op);
2755 : :
2756 : : /*
2757 : : AddQuadInformation - adds variable analysis and jump analysis to the new quadruple.
2758 : : */
2759 : :
2760 : : static void AddQuadInformation (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3);
2761 : : static void stop (void);
2762 : :
2763 : : /*
2764 : : PutQuadO - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
2765 : : sets a boolean to determinine whether overflow should be checked.
2766 : : */
2767 : :
2768 : : static void PutQuadO (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow);
2769 : :
2770 : : /*
2771 : : PutQuadOType -
2772 : : */
2773 : :
2774 : : static void PutQuadOType (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow, bool checktype);
2775 : :
2776 : : /*
2777 : : UndoReadWriteInfo -
2778 : : */
2779 : :
2780 : : static void UndoReadWriteInfo (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3);
2781 : :
2782 : : /*
2783 : : CheckAddVariableRead - checks to see whether symbol, Sym, is a variable or
2784 : : a parameter and if so it then adds this quadruple
2785 : : to the variable list.
2786 : : */
2787 : :
2788 : : static void CheckAddVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad);
2789 : :
2790 : : /*
2791 : : CheckRemoveVariableRead - checks to see whether, Sym, is a variable or
2792 : : a parameter and if so then it removes the
2793 : : quadruple from the variable list.
2794 : : */
2795 : :
2796 : : static void CheckRemoveVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad);
2797 : :
2798 : : /*
2799 : : CheckAddVariableWrite - checks to see whether symbol, Sym, is a variable and
2800 : : if so it then adds this quadruple to the variable list.
2801 : : */
2802 : :
2803 : : static void CheckAddVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad);
2804 : :
2805 : : /*
2806 : : CheckRemoveVariableWrite - checks to see whether, Sym, is a variable and
2807 : : if so then it removes the quadruple from the
2808 : : variable list.
2809 : : */
2810 : :
2811 : : static void CheckRemoveVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad);
2812 : :
2813 : : /*
2814 : : CheckConst -
2815 : : */
2816 : :
2817 : : static void CheckConst (unsigned int sym);
2818 : :
2819 : : /*
2820 : : AlterReference - alters all references from OldQuad, to NewQuad in a
2821 : : quadruple list Head.
2822 : : */
2823 : :
2824 : : static void AlterReference (unsigned int Head, unsigned int OldQuad, unsigned int NewQuad);
2825 : :
2826 : : /*
2827 : : GrowQuads - grows the list of quadruples to the quadruple, to.
2828 : : */
2829 : :
2830 : : static void GrowQuads (unsigned int to);
2831 : :
2832 : : /*
2833 : : ManipulateReference - manipulates the quadruple, q, so that it now points to quad, to.
2834 : : */
2835 : :
2836 : : static void ManipulateReference (unsigned int q, unsigned int to);
2837 : :
2838 : : /*
2839 : : RemoveReference - remove the reference by quadruple, q, to wherever
2840 : : it was pointing to.
2841 : : */
2842 : :
2843 : : static void RemoveReference (unsigned int q);
2844 : :
2845 : : /*
2846 : : NewQuad - sets QuadNo to a new quadruple.
2847 : : */
2848 : :
2849 : : static void NewQuad (unsigned int *QuadNo);
2850 : :
2851 : : /*
2852 : : CheckVariableAt - checks to see whether, sym, was declared at a particular address.
2853 : : */
2854 : :
2855 : : static void CheckVariableAt (unsigned int sym);
2856 : :
2857 : : /*
2858 : : CheckVariablesAt - checks to see whether we need to initialize any pointers
2859 : : which point to variable declared at addresses.
2860 : : */
2861 : :
2862 : : static void CheckVariablesAt (unsigned int scope);
2863 : :
2864 : : /*
2865 : : GetTurnInterrupts - returns the TurnInterrupts procedure function.
2866 : : */
2867 : :
2868 : : static unsigned int GetTurnInterrupts (unsigned int tok);
2869 : :
2870 : : /*
2871 : : GetProtection - returns the PROTECTION data type.
2872 : : */
2873 : :
2874 : : static unsigned int GetProtection (unsigned int tok);
2875 : :
2876 : : /*
2877 : : CheckNeedPriorityBegin - checks to see whether we need to save the old
2878 : : module priority and change to another module
2879 : : priority.
2880 : : The current module initialization or procedure
2881 : : being built is defined by, scope. The module whose
2882 : : priority will be used is defined by, module.
2883 : : */
2884 : :
2885 : : static void CheckNeedPriorityBegin (unsigned int tok, unsigned int scope, unsigned int module);
2886 : :
2887 : : /*
2888 : : CheckNeedPriorityEnd - checks to see whether we need to restore the old
2889 : : module priority.
2890 : : The current module initialization or procedure
2891 : : being built is defined by, scope.
2892 : : */
2893 : :
2894 : : static void CheckNeedPriorityEnd (unsigned int tok, unsigned int scope, unsigned int module);
2895 : :
2896 : : /*
2897 : : BuildRTExceptEnter - informs RTExceptions that we are about to enter the except state.
2898 : : */
2899 : :
2900 : : static void BuildRTExceptEnter (unsigned int tok);
2901 : :
2902 : : /*
2903 : : BuildRTExceptLeave - informs RTExceptions that we are about to leave the except state.
2904 : : If, destroy, is TRUE then pop the ExceptStack.
2905 : : */
2906 : :
2907 : : static void BuildRTExceptLeave (unsigned int tok, bool destroy);
2908 : :
2909 : : /*
2910 : : SafeRequestSym - only used during scaffold to get argc, argv, envp.
2911 : : It attempts to get symbol name from the current scope(s) and if
2912 : : it fails then it falls back onto default constants.
2913 : : */
2914 : :
2915 : : static unsigned int SafeRequestSym (unsigned int tok, NameKey_Name name);
2916 : :
2917 : : /*
2918 : : callRequestDependant - create a call:
2919 : : RequestDependant (GetSymName (modulesym), GetLibName (modulesym),
2920 : : GetSymName (depModuleSym), GetLibName (depModuleSym));
2921 : : */
2922 : :
2923 : : static void callRequestDependant (unsigned int tokno, unsigned int moduleSym, unsigned int depModuleSym, unsigned int requestDep);
2924 : :
2925 : : /*
2926 : : ForeachImportInDepDo -
2927 : : */
2928 : :
2929 : : static void ForeachImportInDepDo (Lists_List importStatements, unsigned int moduleSym, unsigned int requestDep);
2930 : :
2931 : : /*
2932 : : ForeachImportedModuleDo -
2933 : : */
2934 : :
2935 : : static void ForeachImportedModuleDo (unsigned int moduleSym, unsigned int requestDep);
2936 : :
2937 : : /*
2938 : : BuildM2DepFunction - creates the dependency graph procedure using IR:
2939 : : static void
2940 : : dependencies (void)
2941 : : {
2942 : : M2RTS_RequestDependant (module_name, libname, "b", "b libname");
2943 : : M2RTS_RequestDependant (module_name, libname, NULL, NULL);
2944 : : }
2945 : : */
2946 : :
2947 : : static void BuildM2DepFunction (unsigned int tokno, unsigned int moduleSym);
2948 : :
2949 : : /*
2950 : : BuildM2LinkFunction - creates the _M2_link procedure which will
2951 : : cause the linker to pull in all the module ctors.
2952 : : */
2953 : :
2954 : : static void BuildM2LinkFunction (unsigned int tokno);
2955 : :
2956 : : /*
2957 : : BuildTry - build the try statement for main.
2958 : : */
2959 : :
2960 : : static void BuildTry (unsigned int tokno);
2961 : :
2962 : : /*
2963 : : BuildExcept - build the except block for main.
2964 : : */
2965 : :
2966 : : static void BuildExcept (unsigned int tokno);
2967 : :
2968 : : /*
2969 : : BuildM2MainFunction - creates the main function with appropriate calls to the scaffold.
2970 : : */
2971 : :
2972 : : static void BuildM2MainFunction (unsigned int tokno);
2973 : :
2974 : : /*
2975 : : DeferMakeConstStringCnul - return a C const string which will be nul terminated.
2976 : : */
2977 : :
2978 : : static unsigned int DeferMakeConstStringCnul (unsigned int tok, unsigned int sym);
2979 : :
2980 : : /*
2981 : : DeferMakeConstStringM2nul - return a const string which will be nul terminated.
2982 : : */
2983 : :
2984 : : static unsigned int DeferMakeConstStringM2nul (unsigned int tok, unsigned int sym);
2985 : :
2986 : : /*
2987 : : BuildStringAdrParam - push the address of a nul terminated string onto the quad stack.
2988 : : */
2989 : :
2990 : : static void BuildStringAdrParam (unsigned int tok, NameKey_Name name);
2991 : :
2992 : : /*
2993 : : BuildM2InitFunction -
2994 : : */
2995 : :
2996 : : static void BuildM2InitFunction (unsigned int tok, unsigned int moduleSym);
2997 : :
2998 : : /*
2999 : : BuildM2FiniFunction -
3000 : : */
3001 : :
3002 : : static void BuildM2FiniFunction (unsigned int tok, unsigned int moduleSym);
3003 : :
3004 : : /*
3005 : : BuildM2CtorFunction - create a constructor function associated with moduleSym.
3006 : :
3007 : : void
3008 : : ctorFunction ()
3009 : : {
3010 : : M2RTS_RegisterModule (GetSymName (moduleSym), GetLibName (moduleSym),
3011 : : init, fini, dependencies);
3012 : : }
3013 : : */
3014 : :
3015 : : static void BuildM2CtorFunction (unsigned int tok, unsigned int moduleSym);
3016 : :
3017 : : /*
3018 : : AddForInfo - adds the description of the FOR loop into the record list.
3019 : : This is used if -pedantic is turned on to check index variable
3020 : : usage.
3021 : : */
3022 : :
3023 : : static void AddForInfo (unsigned int Start, unsigned int End, unsigned int IncQuad, unsigned int Sym, unsigned int idtok);
3024 : :
3025 : : /*
3026 : : CheckForIndex - checks the quadruples: Start..End to see whether a
3027 : : for loop index is manipulated by the programmer.
3028 : : It generates a warning if this is the case.
3029 : : It also checks to see whether the IndexSym is read
3030 : : immediately outside the loop in which case a warning
3031 : : is issued.
3032 : : */
3033 : :
3034 : : static void CheckForIndex (M2Quads_ForLoopInfo forDesc);
3035 : :
3036 : : /*
3037 : : BuildRange - generates a RangeCheckOp quad with, r, as its operand.
3038 : : */
3039 : :
3040 : : static void BuildRange (unsigned int r);
3041 : :
3042 : : /*
3043 : : BuildError - generates a ErrorOp quad, indicating that if this
3044 : : quadruple is reachable, then a runtime error would
3045 : : occur.
3046 : : */
3047 : :
3048 : : static void BuildError (unsigned int r);
3049 : :
3050 : : /*
3051 : : CheckPointerThroughNil - builds a range quadruple, providing, sym, is
3052 : : a candidate for checking against NIL.
3053 : : This range quadruple is only expanded into
3054 : : code during the code generation phase
3055 : : thus allowing limited compile time checking.
3056 : : */
3057 : :
3058 : : static void CheckPointerThroughNil (unsigned int tokpos, unsigned int sym);
3059 : :
3060 : : /*
3061 : : CollectLow - returns the low of the subrange value.
3062 : : */
3063 : :
3064 : : static unsigned int CollectLow (unsigned int sym);
3065 : :
3066 : : /*
3067 : : CollectHigh - returns the high of the subrange value, sym.
3068 : : */
3069 : :
3070 : : static unsigned int CollectHigh (unsigned int sym);
3071 : :
3072 : : /*
3073 : : CheckCompatibleWithBecomes - checks to see that symbol, sym, is
3074 : : compatible with the := operator.
3075 : : */
3076 : :
3077 : : static void CheckCompatibleWithBecomes (unsigned int des, unsigned int expr, unsigned int destok, unsigned int exprtok);
3078 : :
3079 : : /*
3080 : : BuildAssignmentWithoutBounds - calls BuildAssignment but makes sure we do not
3081 : : check bounds.
3082 : : */
3083 : :
3084 : : static void BuildAssignmentWithoutBounds (unsigned int tok, bool checkTypes, bool checkOverflow);
3085 : :
3086 : : /*
3087 : : MarkArrayWritten - marks, Array, as being written.
3088 : : */
3089 : :
3090 : : static void MarkArrayWritten (unsigned int Array);
3091 : :
3092 : : /*
3093 : : MarkAsReadWrite - marks the variable or parameter as being
3094 : : read/write.
3095 : : */
3096 : :
3097 : : static void MarkAsReadWrite (unsigned int sym);
3098 : :
3099 : : /*
3100 : : MarkAsRead - marks the variable or parameter as being read.
3101 : : */
3102 : :
3103 : : static void MarkAsRead (unsigned int sym);
3104 : :
3105 : : /*
3106 : : MarkAsWrite - marks the variable or parameter as being written.
3107 : : */
3108 : :
3109 : : static void MarkAsWrite (unsigned int sym);
3110 : :
3111 : : /*
3112 : : doVal - return an expression which is VAL(type, expr). If
3113 : : expr is a constant then return expr.
3114 : : */
3115 : :
3116 : : static unsigned int doVal (unsigned int type, unsigned int expr);
3117 : :
3118 : : /*
3119 : : MoveWithMode -
3120 : : */
3121 : :
3122 : : static void MoveWithMode (unsigned int tokno, unsigned int Des, unsigned int Exp, unsigned int Array, unsigned int destok, unsigned int exptok, bool checkOverflow);
3123 : :
3124 : : /*
3125 : : CheckBecomesMeta - checks to make sure that we are not
3126 : : assigning a variable to a constant.
3127 : : Also check we are not assigning to an
3128 : : unbounded array.
3129 : : */
3130 : :
3131 : : static void CheckBecomesMeta (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok);
3132 : :
3133 : : /*
3134 : : doBuildAssignment - subsiduary procedure of BuildAssignment.
3135 : : It builds the assignment and optionally
3136 : : checks the types are compatible.
3137 : : */
3138 : :
3139 : : static void doBuildAssignment (unsigned int becomesTokNo, bool checkTypes, bool checkOverflow);
3140 : :
3141 : : /*
3142 : : CheckAssignCompatible - checks to see that an assignment is compatible.
3143 : : It performs limited checking - thorough checking
3144 : : is done in pass 3. But we do what we can here
3145 : : given knowledge so far.
3146 : : */
3147 : :
3148 : : static void CheckAssignCompatible (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok);
3149 : :
3150 : : /*
3151 : : CheckBooleanId - Checks to see if the top operand is a boolean.
3152 : : If the operand is not a boolean then it is tested
3153 : : with true and a boolean is generated.
3154 : : The Stack:
3155 : :
3156 : :
3157 : : Entry Exit
3158 : : Ptr -> <- Ptr
3159 : : +------------+ +------------+
3160 : : | Sym | | t | f |
3161 : : |------------| |------------|
3162 : :
3163 : : Quadruples
3164 : :
3165 : : q If= Sym True _
3166 : : q+1 GotoOp _ _ _
3167 : : */
3168 : :
3169 : : static void CheckBooleanId (void);
3170 : :
3171 : : /*
3172 : : PushOne - pushes the value one to the stack.
3173 : : The Stack is changed:
3174 : :
3175 : :
3176 : : Entry Exit
3177 : : ===== ====
3178 : :
3179 : : <- Ptr
3180 : : +------------+
3181 : : Ptr -> | 1 | type |
3182 : : |------------|
3183 : : */
3184 : :
3185 : : static void PushOne (unsigned int tok, unsigned int type, const char *message_, unsigned int _message_high);
3186 : :
3187 : : /*
3188 : : PushZero - pushes the value zero to the stack.
3189 : : The Stack is changed:
3190 : :
3191 : :
3192 : : Entry Exit
3193 : : ===== ====
3194 : :
3195 : : <- Ptr
3196 : : +------------+
3197 : : Ptr -> | 0 | type |
3198 : : |------------|
3199 : : */
3200 : :
3201 : : static void PushZero (unsigned int tok, unsigned int type);
3202 : :
3203 : : /*
3204 : : BuildForLoopToRangeCheck - builds the range check to ensure that the id
3205 : : does not exceed the limits of its type.
3206 : : */
3207 : :
3208 : : static void BuildForLoopToRangeCheck (void);
3209 : :
3210 : : /*
3211 : : BuildSizeCheckEnd - checks to see whether the function "called" was in fact SIZE.
3212 : : If so then we restore quadruple generation.
3213 : : */
3214 : :
3215 : : static void BuildSizeCheckEnd (unsigned int ProcSym);
3216 : :
3217 : : /*
3218 : : BuildRealProcedureCall - builds a real procedure call.
3219 : : The Stack:
3220 : :
3221 : :
3222 : : Entry Exit
3223 : :
3224 : : Ptr ->
3225 : : +----------------+
3226 : : | NoOfParam |
3227 : : |----------------|
3228 : : | Param 1 |
3229 : : |----------------|
3230 : : | Param 2 |
3231 : : |----------------|
3232 : : . .
3233 : : . .
3234 : : . .
3235 : : |----------------|
3236 : : | Param # |
3237 : : |----------------|
3238 : : | ProcSym | Type | Empty
3239 : : |----------------|
3240 : : */
3241 : :
3242 : : static void BuildRealProcedureCall (unsigned int tokno);
3243 : :
3244 : : /*
3245 : : BuildRealFuncProcCall - builds a real procedure or function call.
3246 : : The Stack:
3247 : :
3248 : :
3249 : : Entry Exit
3250 : :
3251 : : Ptr ->
3252 : : +----------------+
3253 : : | NoOfParam |
3254 : : |----------------|
3255 : : | Param 1 |
3256 : : |----------------|
3257 : : | Param 2 |
3258 : : |----------------|
3259 : : . .
3260 : : . .
3261 : : . .
3262 : : |----------------|
3263 : : | Param # |
3264 : : |----------------|
3265 : : | ProcSym | Type | Empty
3266 : : |----------------|
3267 : : */
3268 : :
3269 : : static void BuildRealFuncProcCall (unsigned int tokno, bool IsFunc, bool IsForC, bool ConstExpr);
3270 : :
3271 : : /*
3272 : : CheckProcedureParameters - Checks the parameters which are being passed to
3273 : : procedure ProcSym.
3274 : :
3275 : : The Stack:
3276 : :
3277 : :
3278 : : Entry Exit
3279 : :
3280 : : Ptr -> <- Ptr
3281 : : +----------------+ +----------------+
3282 : : | NoOfParam | | NoOfParam |
3283 : : |----------------| |----------------|
3284 : : | Param 1 | | Param 1 |
3285 : : |----------------| |----------------|
3286 : : | Param 2 | | Param 2 |
3287 : : |----------------| |----------------|
3288 : : . . . .
3289 : : . . . .
3290 : : . . . .
3291 : : |----------------| |----------------|
3292 : : | Param # | | Param # |
3293 : : |----------------| |----------------|
3294 : : | ProcSym | Type | | ProcSym | Type |
3295 : : |----------------| |----------------|
3296 : :
3297 : : */
3298 : :
3299 : : static void CheckProcedureParameters (bool IsForC);
3300 : :
3301 : : /*
3302 : : CheckProcTypeAndProcedure - checks the ProcType with the call.
3303 : : */
3304 : :
3305 : : static void CheckProcTypeAndProcedure (unsigned int tokno, unsigned int ProcType, unsigned int call);
3306 : :
3307 : : /*
3308 : : IsReallyPointer - returns TRUE is sym is a pointer, address or a type declared
3309 : : as a pointer or address.
3310 : : */
3311 : :
3312 : : static bool IsReallyPointer (unsigned int Sym);
3313 : :
3314 : : /*
3315 : : LegalUnboundedParam - returns TRUE if the parameter, Actual, can legitimately be
3316 : : passed to ProcSym, i, the, Formal, parameter.
3317 : : */
3318 : :
3319 : : static bool LegalUnboundedParam (unsigned int tokpos, unsigned int ProcSym, unsigned int i, unsigned int ActualType, unsigned int Actual, unsigned int Dimension, unsigned int Formal);
3320 : :
3321 : : /*
3322 : : CheckParameter - checks that types ActualType and FormalType are compatible for parameter
3323 : : passing. ProcSym is the procedure and i is the parameter number.
3324 : :
3325 : : We obey the following rules:
3326 : :
3327 : : (1) we allow WORD, BYTE, LOC to be compitable with any like sized
3328 : : type.
3329 : : (2) we allow ADDRESS to be compatible with any pointer type.
3330 : : (3) we relax INTEGER and CARDINAL checking for Temporary variables.
3331 : :
3332 : : Note that type sizes are checked during the code generation pass.
3333 : : */
3334 : :
3335 : : static void CheckParameter (unsigned int tokpos, unsigned int Actual, unsigned int Dimension, unsigned int Formal, unsigned int ProcSym, unsigned int i, Lists_List TypeList);
3336 : :
3337 : : /*
3338 : : DescribeType - returns a String describing a symbol, Sym, name and its type.
3339 : : */
3340 : :
3341 : : static DynamicStrings_String DescribeType (unsigned int Sym);
3342 : :
3343 : : /*
3344 : : FailParameter - generates an error message indicating that a parameter
3345 : : declaration has failed.
3346 : :
3347 : : The parameters are:
3348 : :
3349 : : CurrentState - string describing the current failing state.
3350 : : Given - the token that the source code provided.
3351 : : Expecting - token or identifier that was expected.
3352 : : ParameterNo - parameter number that has failed.
3353 : : ProcedureSym - procedure symbol where parameter has failed.
3354 : :
3355 : : If any parameter is Nul then it is ignored.
3356 : : */
3357 : :
3358 : : static void FailParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Given, unsigned int Expecting, unsigned int ProcedureSym, unsigned int ParameterNo);
3359 : :
3360 : : /*
3361 : : WarnParameter - generates a warning message indicating that a parameter
3362 : : use might cause problems on another target.
3363 : :
3364 : : The parameters are:
3365 : :
3366 : : CurrentState - string describing the current failing state.
3367 : : Given - the token that the source code provided.
3368 : : Expecting - token or identifier that was expected.
3369 : : ParameterNo - parameter number that has failed.
3370 : : ProcedureSym - procedure symbol where parameter has failed.
3371 : :
3372 : : If any parameter is Nul then it is ignored.
3373 : : */
3374 : :
3375 : : static void WarnParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Given, unsigned int Expecting, unsigned int ProcedureSym, unsigned int ParameterNo);
3376 : :
3377 : : /*
3378 : : doIndrX - perform des = *exp with a conversion if necessary.
3379 : : */
3380 : :
3381 : : static void doIndrX (unsigned int tok, unsigned int des, unsigned int exp);
3382 : :
3383 : : /*
3384 : : MakeRightValue - returns a temporary which will have the RightValue of symbol, Sym.
3385 : : If Sym is a right value and has type, type, then no quadruples are
3386 : : generated and Sym is returned. Otherwise a new temporary is created
3387 : : and an IndrX quadruple is generated.
3388 : : */
3389 : :
3390 : : static unsigned int MakeRightValue (unsigned int tok, unsigned int Sym, unsigned int type);
3391 : :
3392 : : /*
3393 : : MakeLeftValue - returns a temporary coresponding to the LeftValue of
3394 : : symbol, Sym. No quadruple is generated if Sym is already
3395 : : a LeftValue and has the same type.
3396 : : */
3397 : :
3398 : : static unsigned int MakeLeftValue (unsigned int tok, unsigned int Sym, SymbolTable_ModeOfAddr with, unsigned int type);
3399 : :
3400 : : /*
3401 : : ManipulatePseudoCallParameters - manipulates the parameters to a pseudo function or
3402 : : procedure. It dereferences all LeftValue parameters
3403 : : and Boolean parameters.
3404 : : The Stack:
3405 : :
3406 : :
3407 : : Entry Exit
3408 : :
3409 : : Ptr -> exactly the same
3410 : : +----------------+
3411 : : | NoOfParameters |
3412 : : |----------------|
3413 : : | Param 1 |
3414 : : |----------------|
3415 : : | Param 2 |
3416 : : |----------------|
3417 : : . .
3418 : : . .
3419 : : . .
3420 : : |----------------|
3421 : : | Param # |
3422 : : |----------------|
3423 : : | ProcSym | Type |
3424 : : |----------------|
3425 : :
3426 : : */
3427 : :
3428 : : static void ManipulatePseudoCallParameters (void);
3429 : :
3430 : : /*
3431 : : ManipulateParameters - manipulates the procedure parameters in
3432 : : preparation for a procedure call.
3433 : : Prepares Boolean, Unbounded and VAR parameters.
3434 : : The Stack:
3435 : :
3436 : :
3437 : : Entry Exit
3438 : :
3439 : : Ptr -> exactly the same
3440 : : +----------------+
3441 : : | NoOfParameters |
3442 : : |----------------|
3443 : : | Param 1 |
3444 : : |----------------|
3445 : : | Param 2 |
3446 : : |----------------|
3447 : : . .
3448 : : . .
3449 : : . .
3450 : : |----------------|
3451 : : | Param # |
3452 : : |----------------|
3453 : : | ProcSym | Type |
3454 : : |----------------|
3455 : : */
3456 : :
3457 : : static void ManipulateParameters (bool IsForC);
3458 : :
3459 : : /*
3460 : : CheckParameterOrdinals - check that ordinal values are within type range.
3461 : : */
3462 : :
3463 : : static void CheckParameterOrdinals (void);
3464 : :
3465 : : /*
3466 : : IsSameUnbounded - returns TRUE if unbounded types, t1, and, t2,
3467 : : are compatible.
3468 : : */
3469 : :
3470 : : static bool IsSameUnbounded (unsigned int t1, unsigned int t2);
3471 : :
3472 : : /*
3473 : : AssignUnboundedVar - assigns an Unbounded symbol fields,
3474 : : ArrayAddress and ArrayHigh, from an array symbol.
3475 : : UnboundedSym is not a VAR parameter and therefore
3476 : : this procedure can complete both of the fields.
3477 : : Sym can be a Variable with type Unbounded.
3478 : : Sym can be a Variable with type Array.
3479 : : Sym can be a String Constant.
3480 : :
3481 : : ParamType is the TYPE of the parameter
3482 : : */
3483 : :
3484 : : static void AssignUnboundedVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3485 : :
3486 : : /*
3487 : : AssignUnboundedNonVar - assigns an Unbounded symbol fields,
3488 : : The difference between this procedure and
3489 : : AssignUnboundedVar is that this procedure cannot
3490 : : set the Unbounded.Address since the data from
3491 : : Sym will be copied because parameter is NOT a VAR
3492 : : parameter.
3493 : : UnboundedSym is not a VAR parameter and therefore
3494 : : this procedure can only complete the HIGH field
3495 : : and not the ADDRESS field.
3496 : : Sym can be a Variable with type Unbounded.
3497 : : Sym can be a Variable with type Array.
3498 : : Sym can be a String Constant.
3499 : :
3500 : : ParamType is the TYPE of the paramater
3501 : : */
3502 : :
3503 : : static void AssignUnboundedNonVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3504 : :
3505 : : /*
3506 : : GenHigh - generates a HighOp but it checks if op3 is a
3507 : : L value and if so it dereferences it. This
3508 : : is inefficient, however it is clean and we let the gcc
3509 : : backend detect these as common subexpressions.
3510 : : It will also detect that a R value -> L value -> R value
3511 : : via indirection and eleminate these.
3512 : : */
3513 : :
3514 : : static void GenHigh (unsigned int tok, unsigned int op1, unsigned int op2, unsigned int op3);
3515 : :
3516 : : /*
3517 : : AssignHighField -
3518 : : */
3519 : :
3520 : : static void AssignHighField (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int actuali, unsigned int formali);
3521 : :
3522 : : /*
3523 : : AssignHighFields -
3524 : : */
3525 : :
3526 : : static void AssignHighFields (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3527 : :
3528 : : /*
3529 : : UnboundedNonVarLinkToArray - links an array, ArraySym, to an unbounded
3530 : : array, UnboundedSym. The parameter is a
3531 : : NON VAR variety.
3532 : : */
3533 : :
3534 : : static void UnboundedNonVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3535 : :
3536 : : /*
3537 : : UnboundedVarLinkToArray - links an array, ArraySym, to an unbounded array,
3538 : : UnboundedSym. The parameter is a VAR variety.
3539 : : */
3540 : :
3541 : : static void UnboundedVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3542 : :
3543 : : /*
3544 : : BuildPseudoProcedureCall - builds a pseudo procedure call.
3545 : : This procedure does not directly alter the
3546 : : stack, but by calling routines the stack
3547 : : will change in the following way when this
3548 : : procedure returns.
3549 : :
3550 : : The Stack:
3551 : :
3552 : :
3553 : : Entry Exit
3554 : :
3555 : : Ptr ->
3556 : : +----------------+
3557 : : | NoOfParam |
3558 : : |----------------|
3559 : : | Param 1 |
3560 : : |----------------|
3561 : : | Param 2 |
3562 : : |----------------|
3563 : : . .
3564 : : . .
3565 : : . .
3566 : : |----------------|
3567 : : | Param # |
3568 : : |----------------|
3569 : : | ProcSym | Type | Empty
3570 : : |----------------|
3571 : : */
3572 : :
3573 : : static void BuildPseudoProcedureCall (unsigned int tokno);
3574 : :
3575 : : /*
3576 : : GetItemPointedTo - returns the symbol type that is being pointed to
3577 : : by Sym.
3578 : : */
3579 : :
3580 : : static unsigned int GetItemPointedTo (unsigned int Sym);
3581 : :
3582 : : /*
3583 : : BuildThrowProcedure - builds the pseudo procedure call M2RTS.Throw.
3584 : : The Stack:
3585 : :
3586 : :
3587 : : Entry Exit
3588 : :
3589 : : Ptr ->
3590 : : +----------------+
3591 : : | NoOfParam |
3592 : : |----------------|
3593 : : | Param 1 |
3594 : : |----------------|
3595 : : | Param 2 |
3596 : : |----------------|
3597 : : . .
3598 : : . .
3599 : : . .
3600 : : |----------------|
3601 : : | Param # |
3602 : : |----------------|
3603 : : | ProcSym | Type | Empty
3604 : : |----------------|
3605 : : */
3606 : :
3607 : : static void BuildThrowProcedure (void);
3608 : :
3609 : : /*
3610 : : BuildNewProcedure - builds the pseudo procedure call NEW.
3611 : : This procedure is traditionally a "macro" for
3612 : : NEW(x, ...) --> ALLOCATE(x, TSIZE(x^, ...))
3613 : : One method of implementation is to emulate a "macro"
3614 : : processor by pushing the relevant input tokens
3615 : : back onto the input stack.
3616 : : However this causes two problems:
3617 : :
3618 : : (i) Unnecessary code is produced for x^
3619 : : (ii) SIZE must be imported from SYSTEM
3620 : : Therefore we chose an alternative method of
3621 : : implementation;
3622 : : generate quadruples for ALLOCATE(x, TSIZE(x^, ...))
3623 : : this, although slightly more efficient,
3624 : : is more complex and circumvents problems (i) and (ii).
3625 : :
3626 : : The Stack:
3627 : :
3628 : :
3629 : : Entry Exit
3630 : :
3631 : : Ptr ->
3632 : : +----------------+
3633 : : | NoOfParam |
3634 : : |----------------|
3635 : : | Param 1 |
3636 : : |----------------|
3637 : : | Param 2 |
3638 : : |----------------|
3639 : : . .
3640 : : . .
3641 : : . .
3642 : : |----------------|
3643 : : | Param # |
3644 : : |----------------|
3645 : : | ProcSym | Type | Empty
3646 : : |----------------|
3647 : : */
3648 : :
3649 : : static void BuildNewProcedure (unsigned int functok);
3650 : :
3651 : : /*
3652 : : BuildDisposeProcedure - builds the pseudo procedure call DISPOSE.
3653 : : This procedure is traditionally a "macro" for
3654 : : DISPOSE(x) --> DEALLOCATE(x, TSIZE(x^))
3655 : : One method of implementation is to emulate a "macro"
3656 : : processor by pushing the relevant input tokens
3657 : : back onto the input stack.
3658 : : However this causes two problems:
3659 : :
3660 : : (i) Unnecessary code is produced for x^
3661 : : (ii) TSIZE must be imported from SYSTEM
3662 : : Therefore we chose an alternative method of
3663 : : implementation;
3664 : : generate quadruples for DEALLOCATE(x, TSIZE(x^))
3665 : : this, although slightly more efficient,
3666 : : is more complex and circumvents problems (i)
3667 : : and (ii).
3668 : :
3669 : : The Stack:
3670 : :
3671 : :
3672 : : Entry Exit
3673 : :
3674 : : Ptr ->
3675 : : +----------------+
3676 : : | NoOfParam |
3677 : : |----------------|
3678 : : | Param 1 |
3679 : : |----------------|
3680 : : | Param 2 |
3681 : : |----------------|
3682 : : . .
3683 : : . .
3684 : : . .
3685 : : |----------------|
3686 : : | Param # |
3687 : : |----------------|
3688 : : | ProcSym | Type | Empty
3689 : : |----------------|
3690 : : */
3691 : :
3692 : : static void BuildDisposeProcedure (unsigned int functok);
3693 : :
3694 : : /*
3695 : : CheckRangeIncDec - performs des := des <tok> expr
3696 : : with range checking (if enabled).
3697 : :
3698 : : Stack
3699 : : Entry Exit
3700 : :
3701 : : +------------+
3702 : : empty | des + expr |
3703 : : |------------|
3704 : : */
3705 : :
3706 : : static void CheckRangeIncDec (unsigned int tokenpos, unsigned int des, unsigned int expr, NameKey_Name tok);
3707 : :
3708 : : /*
3709 : : BuildIncProcedure - builds the pseudo procedure call INC.
3710 : : INC is a procedure which increments a variable.
3711 : : It takes one or two parameters:
3712 : : INC(a, b) or INC(a)
3713 : : a := a+b or a := a+1
3714 : :
3715 : : The Stack:
3716 : :
3717 : :
3718 : : Entry Exit
3719 : :
3720 : : Ptr ->
3721 : : +----------------+
3722 : : | NoOfParam |
3723 : : |----------------|
3724 : : | Param 1 |
3725 : : |----------------|
3726 : : | Param 2 |
3727 : : |----------------|
3728 : : . .
3729 : : . .
3730 : : . .
3731 : : |----------------|
3732 : : | Param # |
3733 : : |----------------|
3734 : : | ProcSym | Type | Empty
3735 : : |----------------|
3736 : : */
3737 : :
3738 : : static void BuildIncProcedure (void);
3739 : :
3740 : : /*
3741 : : BuildDecProcedure - builds the pseudo procedure call DEC.
3742 : : DEC is a procedure which decrements a variable.
3743 : : It takes one or two parameters:
3744 : : DEC(a, b) or DEC(a)
3745 : : a := a-b or a := a-1
3746 : :
3747 : : The Stack:
3748 : :
3749 : :
3750 : : Entry Exit
3751 : :
3752 : : Ptr ->
3753 : : +----------------+
3754 : : | NoOfParam |
3755 : : |----------------|
3756 : : | Param 1 |
3757 : : |----------------|
3758 : : | Param 2 |
3759 : : |----------------|
3760 : : . .
3761 : : . .
3762 : : . .
3763 : : |----------------|
3764 : : | Param # |
3765 : : |----------------|
3766 : : | ProcSym | Type | Empty
3767 : : |----------------|
3768 : : */
3769 : :
3770 : : static void BuildDecProcedure (void);
3771 : :
3772 : : /*
3773 : : DereferenceLValue - checks to see whether, operand, is declare as an LValue
3774 : : and if so it dereferences it.
3775 : : */
3776 : :
3777 : : static unsigned int DereferenceLValue (unsigned int tok, unsigned int operand);
3778 : :
3779 : : /*
3780 : : BuildInclProcedure - builds the pseudo procedure call INCL.
3781 : : INCL is a procedure which adds bit b into a BITSET a.
3782 : : It takes two parameters:
3783 : : INCL(a, b)
3784 : :
3785 : : a := a + {b}
3786 : :
3787 : : The Stack:
3788 : :
3789 : :
3790 : : Entry Exit
3791 : :
3792 : : Ptr ->
3793 : : +----------------+
3794 : : | NoOfParam |
3795 : : |----------------|
3796 : : | Param 1 |
3797 : : |----------------|
3798 : : | Param 2 |
3799 : : |----------------|
3800 : : | ProcSym | Type | Empty
3801 : : |----------------|
3802 : : */
3803 : :
3804 : : static void BuildInclProcedure (void);
3805 : :
3806 : : /*
3807 : : BuildExclProcedure - builds the pseudo procedure call EXCL.
3808 : : INCL is a procedure which removes bit b from SET a.
3809 : : It takes two parameters:
3810 : : EXCL(a, b)
3811 : :
3812 : : a := a - {b}
3813 : :
3814 : : The Stack:
3815 : :
3816 : :
3817 : : Entry Exit
3818 : :
3819 : : Ptr ->
3820 : : +----------------+
3821 : : | NoOfParam |
3822 : : |----------------|
3823 : : | Param 1 |
3824 : : |----------------|
3825 : : | Param 2 |
3826 : : |----------------|
3827 : : | ProcSym | Type | Empty
3828 : : |----------------|
3829 : : */
3830 : :
3831 : : static void BuildExclProcedure (void);
3832 : :
3833 : : /*
3834 : : BuildTypeCoercion - builds the type coersion.
3835 : : Modula-2 allows types to be coersed with no runtime
3836 : : penility.
3837 : : It insists that the TSIZE(t1)=TSIZE(t2) where
3838 : : t2 variable := t2(variable of type t1).
3839 : : The ReturnVar on the stack is of type t2.
3840 : :
3841 : : The Stack:
3842 : :
3843 : :
3844 : : Entry Exit
3845 : :
3846 : : Ptr ->
3847 : : +----------------+
3848 : : | NoOfParam |
3849 : : |----------------|
3850 : : | Param 1 |
3851 : : |----------------|
3852 : : | Param 2 |
3853 : : |----------------|
3854 : : . .
3855 : : . .
3856 : : . .
3857 : : |----------------|
3858 : : | Param # | <- Ptr
3859 : : |----------------| +------------+
3860 : : | ProcSym | Type | | ReturnVar |
3861 : : |----------------| |------------|
3862 : :
3863 : : Quadruples:
3864 : :
3865 : : CoerceOp ReturnVar Type Param1
3866 : :
3867 : : A type coercion will only be legal if the different
3868 : : types have exactly the same size.
3869 : : Since we can only decide this after M2Eval has processed
3870 : : the symbol table then we create a quadruple explaining
3871 : : the coercion taking place, the code generator can test
3872 : : this assertion and report an error if the type sizes
3873 : : differ.
3874 : : */
3875 : :
3876 : : static void BuildTypeCoercion (void);
3877 : :
3878 : : /*
3879 : : BuildRealFunctionCall - builds a function call.
3880 : : The Stack:
3881 : :
3882 : :
3883 : : Entry Exit
3884 : :
3885 : : Ptr ->
3886 : : +----------------+
3887 : : | NoOfParam |
3888 : : |----------------|
3889 : : | Param 1 |
3890 : : |----------------|
3891 : : | Param 2 |
3892 : : |----------------|
3893 : : . .
3894 : : . .
3895 : : . .
3896 : : |----------------|
3897 : : | Param # | <- Ptr
3898 : : |----------------| +------------+
3899 : : | ProcSym | Type | | ReturnVar |
3900 : : |----------------| |------------|
3901 : : */
3902 : :
3903 : : static void BuildRealFunctionCall (unsigned int tokno, bool ConstExpr);
3904 : :
3905 : : /*
3906 : : BuildPseudoFunctionCall - builds the pseudo function
3907 : : The Stack:
3908 : :
3909 : :
3910 : : Entry Exit
3911 : :
3912 : : Ptr ->
3913 : : +----------------+
3914 : : | NoOfParam |
3915 : : |----------------|
3916 : : | Param 1 |
3917 : : |----------------|
3918 : : | Param 2 |
3919 : : |----------------|
3920 : : . .
3921 : : . .
3922 : : . .
3923 : : |----------------|
3924 : : | Param # | <- Ptr
3925 : : |----------------| +------------+
3926 : : | ProcSym | Type | | ReturnVar |
3927 : : |----------------| |------------|
3928 : :
3929 : : */
3930 : :
3931 : : static void BuildPseudoFunctionCall (bool ConstExpr);
3932 : :
3933 : : /*
3934 : : BuildAddAdrFunction - builds the pseudo procedure call ADDADR.
3935 : :
3936 : : PROCEDURE ADDADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
3937 : :
3938 : : Which returns address given by (addr + offset),
3939 : : [ the standard says that it _may_
3940 : : "raise an exception if this address is not valid."
3941 : : currently we do not generate any exception code ]
3942 : :
3943 : : The Stack:
3944 : :
3945 : : Entry Exit
3946 : :
3947 : : Ptr ->
3948 : : +----------------+
3949 : : | NoOfParam |
3950 : : |----------------|
3951 : : | Param 1 |
3952 : : |----------------|
3953 : : | Param 2 | <- Ptr
3954 : : |----------------| +------------+
3955 : : | ProcSym | Type | | ReturnVar |
3956 : : |----------------| |------------|
3957 : : */
3958 : :
3959 : : static void BuildAddAdrFunction (unsigned int ProcSym, bool ConstExpr);
3960 : :
3961 : : /*
3962 : : BuildSubAdrFunction - builds the pseudo procedure call ADDADR.
3963 : :
3964 : : PROCEDURE SUBADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
3965 : :
3966 : : Which returns address given by (addr - offset),
3967 : : [ the standard says that it _may_
3968 : : "raise an exception if this address is not valid."
3969 : : currently we do not generate any exception code ]
3970 : :
3971 : : The Stack:
3972 : :
3973 : : Entry Exit
3974 : :
3975 : : Ptr ->
3976 : : +----------------+
3977 : : | NoOfParam |
3978 : : |----------------|
3979 : : | Param 1 |
3980 : : |----------------|
3981 : : | Param 2 | <- Ptr
3982 : : |----------------| +------------+
3983 : : | ProcSym | Type | | ReturnVar |
3984 : : |----------------| |------------|
3985 : : */
3986 : :
3987 : : static void BuildSubAdrFunction (unsigned int ProcSym, bool ConstExpr);
3988 : :
3989 : : /*
3990 : : BuildDifAdrFunction - builds the pseudo procedure call DIFADR.
3991 : :
3992 : : PROCEDURE DIFADR (addr1, addr2: ADDRESS): INTEGER ;
3993 : :
3994 : : Which returns address given by (addr1 - addr2),
3995 : : [ the standard says that it _may_
3996 : : "raise an exception if this address is invalid or
3997 : : address space is non-contiguous."
3998 : : currently we do not generate any exception code ]
3999 : :
4000 : : The Stack:
4001 : :
4002 : : Entry Exit
4003 : :
4004 : : Ptr ->
4005 : : +----------------+
4006 : : | NoOfParam |
4007 : : |----------------|
4008 : : | Param 1 |
4009 : : |----------------|
4010 : : | Param 2 | <- Ptr
4011 : : |----------------| +------------+
4012 : : | ProcSym | Type | | ReturnVar |
4013 : : |----------------| |------------|
4014 : : */
4015 : :
4016 : : static void BuildDifAdrFunction (unsigned int ProcSym, bool ConstExpr);
4017 : :
4018 : : /*
4019 : : BuildHighFunction - checks the stack in preparation for generating
4020 : : quadruples which perform HIGH.
4021 : : This procedure does not alter the stack but
4022 : : determines whether, a, in HIGH(a) is an ArraySym
4023 : : or UnboundedSym.
4024 : : Both cases are different and appropriate quadruple
4025 : : generating routines are called.
4026 : :
4027 : : The Stack:
4028 : :
4029 : :
4030 : : Entry Exit
4031 : :
4032 : : Ptr ->
4033 : : +----------------+
4034 : : | NoOfParam |
4035 : : |----------------|
4036 : : | Param 1 |
4037 : : |----------------|
4038 : : | Param 2 |
4039 : : |----------------|
4040 : : . .
4041 : : . .
4042 : : . .
4043 : : |----------------|
4044 : : | Param # | <- Ptr
4045 : : |----------------| +------------+
4046 : : | ProcSym | Type | | ReturnVar |
4047 : : |----------------| |------------|
4048 : :
4049 : : */
4050 : :
4051 : : static void BuildHighFunction (void);
4052 : :
4053 : : /*
4054 : : BuildConstHighFromSym - builds the pseudo function HIGH from an Sym.
4055 : : Sym is a constant or an array which has constant bounds
4056 : : and therefore it can be calculated at compile time.
4057 : :
4058 : : The Stack:
4059 : :
4060 : :
4061 : : Entry Exit
4062 : :
4063 : : Ptr ->
4064 : : +----------------+
4065 : : | NoOfParam |
4066 : : |----------------|
4067 : : | Param 1 |
4068 : : |----------------|
4069 : : | Param 2 |
4070 : : |----------------|
4071 : : . .
4072 : : . .
4073 : : . .
4074 : : |----------------|
4075 : : | Param # | <- Ptr
4076 : : |----------------| +------------+
4077 : : | ProcSym | Type | | ReturnVar |
4078 : : |----------------| |------------|
4079 : : */
4080 : :
4081 : : static void BuildConstHighFromSym (unsigned int tok);
4082 : :
4083 : : /*
4084 : : BuildHighFromUnbounded - builds the pseudo function HIGH from an
4085 : : UnboundedSym.
4086 : :
4087 : : The Stack:
4088 : :
4089 : :
4090 : : Entry Exit
4091 : :
4092 : : Ptr ->
4093 : : +----------------+
4094 : : | NoOfParam |
4095 : : |----------------|
4096 : : | Param # | <- Ptr
4097 : : |----------------| +------------+
4098 : : | ProcSym | Type | | ReturnVar |
4099 : : |----------------| |------------|
4100 : :
4101 : : */
4102 : :
4103 : : static void BuildHighFromUnbounded (unsigned int tok);
4104 : :
4105 : : /*
4106 : : GetQualidentImport - returns the symbol as if it were qualified from, module.n.
4107 : : This is used to reference runtime support procedures and an
4108 : : error is generated if the symbol cannot be obtained.
4109 : : */
4110 : :
4111 : : static unsigned int GetQualidentImport (unsigned int tokno, NameKey_Name n, NameKey_Name module);
4112 : :
4113 : : /*
4114 : : ConstExprError - return TRUE if a constant expression is being built and Var is a variable.
4115 : : */
4116 : :
4117 : : static bool ConstExprError (unsigned int Func, unsigned int Var, unsigned int optok, bool ConstExpr);
4118 : :
4119 : : /*
4120 : : DeferMakeLengthConst - creates a constant which contains the length of string, sym.
4121 : : */
4122 : :
4123 : : static unsigned int DeferMakeLengthConst (unsigned int tok, unsigned int sym);
4124 : :
4125 : : /*
4126 : : BuildLengthFunction - builds the inline standard function LENGTH.
4127 : :
4128 : : The Stack:
4129 : :
4130 : :
4131 : : Entry Exit
4132 : :
4133 : : Ptr ->
4134 : : +----------------+
4135 : : | NoOfParam |
4136 : : |----------------|
4137 : : | Param 1 | <- Ptr
4138 : : |----------------| +------------+
4139 : : | ProcSym | Type | | ReturnVar |
4140 : : |----------------| |------------|
4141 : :
4142 : : */
4143 : :
4144 : : static void BuildLengthFunction (unsigned int Function, bool ConstExpr);
4145 : :
4146 : : /*
4147 : : BuildOddFunction - builds the pseudo procedure call ODD.
4148 : : This procedure is actually a "macro" for
4149 : : ORD(x) --> VAL(BOOLEAN, x MOD 2)
4150 : : However we cannot push tokens back onto the input stack
4151 : : because the compiler is currently building a function
4152 : : call and expecting a ReturnVar on the stack.
4153 : : Hence we manipulate the stack and call
4154 : : BuildConvertFunction.
4155 : :
4156 : : The Stack:
4157 : :
4158 : :
4159 : : Entry Exit
4160 : :
4161 : : Ptr ->
4162 : : +----------------+
4163 : : | NoOfParam |
4164 : : |----------------|
4165 : : | Param 1 |
4166 : : |----------------|
4167 : : | Param 2 |
4168 : : |----------------|
4169 : : . .
4170 : : . .
4171 : : . .
4172 : : |----------------|
4173 : : | Param # |
4174 : : |----------------|
4175 : : | ProcSym | Type | Empty
4176 : : |----------------|
4177 : : */
4178 : :
4179 : : static void BuildOddFunction (unsigned int ProcSym, bool ConstExpr);
4180 : :
4181 : : /*
4182 : : BuildAbsFunction - builds a call to the standard function ABS.
4183 : :
4184 : : We cannot implement it as a macro or inline an
4185 : : IF THEN statement as the IF THEN ELSE requires
4186 : : we write the value to the same variable (or constant)
4187 : : twice. The macro implementation will fail as
4188 : : the compiler maybe building a function
4189 : : call and expecting a ReturnVar on the stack.
4190 : : The only method to implement this is to pass it to the
4191 : : gcc backend.
4192 : :
4193 : : The Stack:
4194 : :
4195 : :
4196 : : Entry Exit
4197 : :
4198 : : Ptr ->
4199 : : +----------------+
4200 : : | NoOfParam |
4201 : : |----------------|
4202 : : | Param 1 |
4203 : : |----------------|
4204 : : | Param 2 |
4205 : : |----------------|
4206 : : . .
4207 : : . .
4208 : : . .
4209 : : |----------------|
4210 : : | Param # |
4211 : : |----------------|
4212 : : | ProcSym | Type | Empty
4213 : : |----------------|
4214 : : */
4215 : :
4216 : : static void BuildAbsFunction (unsigned int ProcSym, bool ConstExpr);
4217 : :
4218 : : /*
4219 : : BuildCapFunction - builds the pseudo procedure call CAP.
4220 : : We generate a the following quad:
4221 : :
4222 : :
4223 : : StandardFunctionOp ReturnVal Cap Param1
4224 : :
4225 : : The Stack:
4226 : :
4227 : :
4228 : : Entry Exit
4229 : :
4230 : : Ptr ->
4231 : : +----------------+
4232 : : | NoOfParam = 1 |
4233 : : |----------------|
4234 : : | Param 1 |
4235 : : |----------------| +-------------+
4236 : : | ProcSym | Type | | ReturnVal |
4237 : : |----------------| |-------------|
4238 : : */
4239 : :
4240 : : static void BuildCapFunction (unsigned int ProcSym, bool ConstExpr);
4241 : :
4242 : : /*
4243 : : BuildChrFunction - builds the pseudo procedure call CHR.
4244 : : This procedure is actually a "macro" for
4245 : : CHR(x) --> CONVERT(CHAR, x)
4246 : : However we cannot push tokens back onto the input stack
4247 : : because the compiler is currently building a function
4248 : : call and expecting a ReturnVar on the stack.
4249 : : Hence we manipulate the stack and call
4250 : : BuildConvertFunction.
4251 : :
4252 : : The Stack:
4253 : :
4254 : :
4255 : : Entry Exit
4256 : :
4257 : : Ptr ->
4258 : : +----------------+
4259 : : | NoOfParam |
4260 : : |----------------|
4261 : : | Param 1 |
4262 : : |----------------|
4263 : : | Param 2 |
4264 : : |----------------|
4265 : : . .
4266 : : . .
4267 : : . .
4268 : : |----------------|
4269 : : | Param # |
4270 : : |----------------|
4271 : : | ProcSym | Type | Empty
4272 : : |----------------|
4273 : : */
4274 : :
4275 : : static void BuildChrFunction (unsigned int ProcSym, bool ConstExpr);
4276 : :
4277 : : /*
4278 : : BuildOrdFunction - builds the pseudo procedure call ORD.
4279 : : This procedure is actually a "macro" for
4280 : : ORD(x) --> CONVERT(GetSType(sym), x)
4281 : : However we cannot push tokens back onto the input stack
4282 : : because the compiler is currently building a function
4283 : : call and expecting a ReturnVar on the stack.
4284 : : Hence we manipulate the stack and call
4285 : : BuildConvertFunction.
4286 : :
4287 : : The Stack:
4288 : :
4289 : :
4290 : : Entry Exit
4291 : :
4292 : : Ptr ->
4293 : : +----------------+
4294 : : | NoOfParam |
4295 : : |----------------|
4296 : : | Param 1 |
4297 : : |----------------|
4298 : : | Param 2 |
4299 : : |----------------|
4300 : : . .
4301 : : . .
4302 : : . .
4303 : : |----------------|
4304 : : | Param # |
4305 : : |----------------|
4306 : : | ProcSym | Type | Empty
4307 : : |----------------|
4308 : : */
4309 : :
4310 : : static void BuildOrdFunction (unsigned int Sym, bool ConstExpr);
4311 : :
4312 : : /*
4313 : : BuildIntFunction - builds the pseudo procedure call INT.
4314 : : This procedure is actually a "macro" for
4315 : : INT(x) --> CONVERT(INTEGER, x)
4316 : : However we cannot push tokens back onto the input stack
4317 : : because the compiler is currently building a function
4318 : : call and expecting a ReturnVar on the stack.
4319 : : Hence we manipulate the stack and call
4320 : : BuildConvertFunction.
4321 : :
4322 : : The Stack:
4323 : :
4324 : :
4325 : : Entry Exit
4326 : :
4327 : : Ptr ->
4328 : : +----------------+
4329 : : | NoOfParam |
4330 : : |----------------|
4331 : : | Param 1 |
4332 : : |----------------|
4333 : : | Param 2 |
4334 : : |----------------|
4335 : : . .
4336 : : . .
4337 : : . .
4338 : : |----------------|
4339 : : | Param # |
4340 : : |----------------|
4341 : : | ProcSym | Type | Empty
4342 : : |----------------|
4343 : : */
4344 : :
4345 : : static void BuildIntFunction (unsigned int Sym, bool ConstExpr);
4346 : :
4347 : : /*
4348 : : BuildMakeAdrFunction - builds the pseudo procedure call MAKEADR.
4349 : :
4350 : : The Stack:
4351 : :
4352 : :
4353 : : Entry Exit
4354 : :
4355 : : Ptr ->
4356 : : +----------------+
4357 : : | NoOfParam |
4358 : : |----------------|
4359 : : | Param 1 |
4360 : : |----------------|
4361 : : | Param 2 |
4362 : : |----------------|
4363 : : . .
4364 : : . .
4365 : : . .
4366 : : |----------------|
4367 : : | Param # |
4368 : : |----------------|
4369 : : | ProcSym | Type | Empty
4370 : : |----------------|
4371 : : */
4372 : :
4373 : : static void BuildMakeAdrFunction (void);
4374 : :
4375 : : /*
4376 : : BuildShiftFunction - builds the pseudo procedure call SHIFT.
4377 : :
4378 : : PROCEDURE SHIFT (val: <any type>;
4379 : : num: INTEGER): <any type> ;
4380 : :
4381 : : "Returns a bit sequence obtained from val by
4382 : : shifting up or down (left or right) by the
4383 : : absolute value of num, introducing
4384 : : zeros as necessary. The direction is down if
4385 : : the sign of num is negative, otherwise the
4386 : : direction is up."
4387 : :
4388 : : The Stack:
4389 : :
4390 : : Entry Exit
4391 : :
4392 : : Ptr ->
4393 : : +----------------+
4394 : : | NoOfParam |
4395 : : |----------------|
4396 : : | Param 1 |
4397 : : |----------------|
4398 : : | Param 2 | <- Ptr
4399 : : |----------------| +------------+
4400 : : | ProcSym | Type | | ReturnVar |
4401 : : |----------------| |------------|
4402 : : */
4403 : :
4404 : : static void BuildShiftFunction (void);
4405 : :
4406 : : /*
4407 : : BuildRotateFunction - builds the pseudo procedure call ROTATE.
4408 : :
4409 : : PROCEDURE ROTATE (val: <any type>;
4410 : : num: INTEGER): <any type> ;
4411 : :
4412 : : "Returns a bit sequence obtained from val
4413 : : by rotating up or down (left or right) by
4414 : : the absolute value of num. The direction is
4415 : : down if the sign of num is negative, otherwise
4416 : : the direction is up."
4417 : :
4418 : : The Stack:
4419 : :
4420 : : Entry Exit
4421 : :
4422 : : Ptr ->
4423 : : +----------------+
4424 : : | NoOfParam |
4425 : : |----------------|
4426 : : | Param 1 |
4427 : : |----------------|
4428 : : | Param 2 | <- Ptr
4429 : : |----------------| +------------+
4430 : : | ProcSym | Type | | ReturnVar |
4431 : : |----------------| |------------|
4432 : : */
4433 : :
4434 : : static void BuildRotateFunction (void);
4435 : :
4436 : : /*
4437 : : BuildValFunction - builds the pseudo procedure call VAL.
4438 : : This procedure is actually a "macro" for
4439 : : VAL(Type, x) --> CONVERT(Type, x)
4440 : : However we cannot push tokens back onto the input stack
4441 : : because the compiler is currently building a function
4442 : : call and expecting a ReturnVar on the stack.
4443 : : Hence we manipulate the stack and call
4444 : : BuildConvertFunction.
4445 : :
4446 : : The Stack:
4447 : :
4448 : :
4449 : : Entry Exit
4450 : :
4451 : : Ptr ->
4452 : : +----------------+
4453 : : | NoOfParam |
4454 : : |----------------|
4455 : : | Param 1 |
4456 : : |----------------|
4457 : : | Param 2 |
4458 : : |----------------|
4459 : : . .
4460 : : . .
4461 : : . .
4462 : : |----------------|
4463 : : | Param # |
4464 : : |----------------|
4465 : : | ProcSym | Type | Empty
4466 : : |----------------|
4467 : : */
4468 : :
4469 : : static void BuildValFunction (unsigned int ProcSym, bool ConstExpr);
4470 : :
4471 : : /*
4472 : : BuildCastFunction - builds the pseudo procedure call CAST.
4473 : : This procedure is actually a "macro" for
4474 : : CAST(Type, x) --> Type(x)
4475 : : However we cannot push tokens back onto the input stack
4476 : : because the compiler is currently building a function
4477 : : call and expecting a ReturnVar on the stack.
4478 : : Hence we manipulate the stack and call
4479 : : BuildConvertFunction.
4480 : :
4481 : : The Stack:
4482 : :
4483 : :
4484 : : Entry Exit
4485 : :
4486 : : Ptr ->
4487 : : +----------------+
4488 : : | NoOfParam |
4489 : : |----------------|
4490 : : | Param 1 |
4491 : : |----------------|
4492 : : | Param 2 |
4493 : : |----------------|
4494 : : . .
4495 : : . .
4496 : : . .
4497 : : |----------------|
4498 : : | Param # |
4499 : : |----------------|
4500 : : | ProcSym | Type | Empty
4501 : : |----------------|
4502 : : */
4503 : :
4504 : : static void BuildCastFunction (unsigned int ProcSym, bool ConstExpr);
4505 : :
4506 : : /*
4507 : : BuildConvertFunction - builds the pseudo function CONVERT.
4508 : : CONVERT( Type, Variable ) ;
4509 : :
4510 : : The Stack:
4511 : :
4512 : :
4513 : : Entry Exit
4514 : :
4515 : : Ptr ->
4516 : : +----------------+
4517 : : | NoOfParam |
4518 : : |----------------|
4519 : : | Param 1 |
4520 : : |----------------|
4521 : : | Param 2 |
4522 : : |----------------|
4523 : : . .
4524 : : . .
4525 : : . .
4526 : : |----------------|
4527 : : | Param # | <- Ptr
4528 : : |----------------| +---------------------+
4529 : : | ProcSym | Type | | ReturnVar | Param1 |
4530 : : |----------------| |---------------------|
4531 : :
4532 : : Quadruples:
4533 : :
4534 : : ConvertOp ReturnVar Param1 Param2
4535 : :
4536 : : Converts variable Param2 into a variable Param1
4537 : : with a type Param1.
4538 : : */
4539 : :
4540 : : static void BuildConvertFunction (unsigned int ProcSym, bool ConstExpr);
4541 : :
4542 : : /*
4543 : : CheckBaseTypeValue - checks to see whether the value, min, really exists.
4544 : : */
4545 : :
4546 : : static unsigned int CheckBaseTypeValue (unsigned int tok, unsigned int type, unsigned int min, unsigned int func);
4547 : :
4548 : : /*
4549 : : GetTypeMin - returns the minimium value of type.
4550 : : */
4551 : :
4552 : : static unsigned int GetTypeMin (unsigned int tok, unsigned int func, unsigned int type);
4553 : :
4554 : : /*
4555 : : GetTypeMax - returns the maximum value of type.
4556 : : */
4557 : :
4558 : : static unsigned int GetTypeMax (unsigned int tok, unsigned int func, unsigned int type);
4559 : :
4560 : : /*
4561 : : BuildMinFunction - builds the pseudo function call Min.
4562 : :
4563 : : The Stack:
4564 : :
4565 : : Entry Exit
4566 : :
4567 : : Ptr ->
4568 : : +----------------+
4569 : : | NoOfParam=1 |
4570 : : |----------------|
4571 : : | Param 1 |
4572 : : |----------------|
4573 : : | ProcSym | Type | Empty
4574 : : |----------------|
4575 : : */
4576 : :
4577 : : static void BuildMinFunction (void);
4578 : :
4579 : : /*
4580 : : BuildMaxFunction - builds the pseudo function call Max.
4581 : :
4582 : : The Stack:
4583 : :
4584 : : Entry Exit
4585 : :
4586 : : Ptr ->
4587 : : +----------------+
4588 : : | NoOfParam=1 |
4589 : : |----------------|
4590 : : | Param 1 |
4591 : : |----------------|
4592 : : | ProcSym | Type | Empty
4593 : : |----------------|
4594 : : */
4595 : :
4596 : : static void BuildMaxFunction (void);
4597 : :
4598 : : /*
4599 : : BuildTruncFunction - builds the pseudo procedure call TRUNC.
4600 : : This procedure is actually a "macro" for
4601 : : TRUNC(x) --> CONVERT(INTEGER, x)
4602 : : However we cannot push tokens back onto the input stack
4603 : : because the compiler is currently building a function
4604 : : call and expecting a ReturnVar on the stack.
4605 : : Hence we manipulate the stack and call
4606 : : BuildConvertFunction.
4607 : :
4608 : : The Stack:
4609 : :
4610 : :
4611 : : Entry Exit
4612 : :
4613 : : Ptr ->
4614 : : +----------------+
4615 : : | NoOfParam |
4616 : : |----------------|
4617 : : | Param 1 |
4618 : : |----------------|
4619 : : | Param 2 |
4620 : : |----------------|
4621 : : . .
4622 : : . .
4623 : : . .
4624 : : |----------------|
4625 : : | Param # |
4626 : : |----------------|
4627 : : | ProcSym | Type | Empty
4628 : : |----------------|
4629 : : */
4630 : :
4631 : : static void BuildTruncFunction (unsigned int Sym, bool ConstExpr);
4632 : :
4633 : : /*
4634 : : BuildFloatFunction - builds the pseudo procedure call FLOAT.
4635 : : This procedure is actually a "macro" for
4636 : : FLOAT(x) --> CONVERT(REAL, x)
4637 : : However we cannot push tokens back onto the input stack
4638 : : because the compiler is currently building a function
4639 : : call and expecting a ReturnVar on the stack.
4640 : : Hence we manipulate the stack and call
4641 : : BuildConvertFunction.
4642 : :
4643 : : The Stack:
4644 : :
4645 : :
4646 : : Entry Exit
4647 : :
4648 : : Ptr ->
4649 : : +----------------+
4650 : : | NoOfParam |
4651 : : |----------------|
4652 : : | Param 1 |
4653 : : |----------------|
4654 : : | Param 2 |
4655 : : |----------------|
4656 : : . .
4657 : : . .
4658 : : . .
4659 : : |----------------|
4660 : : | Param # |
4661 : : |----------------|
4662 : : | ProcSym | Type | Empty
4663 : : |----------------|
4664 : : */
4665 : :
4666 : : static void BuildFloatFunction (unsigned int Sym, bool ConstExpr);
4667 : :
4668 : : /*
4669 : : BuildReFunction - builds the pseudo procedure call RE.
4670 : :
4671 : : The Stack:
4672 : :
4673 : :
4674 : : Entry Exit
4675 : :
4676 : : Ptr ->
4677 : : +----------------+
4678 : : | NoOfParam |
4679 : : |----------------|
4680 : : | Param 1 |
4681 : : |----------------|
4682 : : | Param 2 |
4683 : : |----------------|
4684 : : . .
4685 : : . .
4686 : : . .
4687 : : |----------------|
4688 : : | Param # |
4689 : : |----------------|
4690 : : | ProcSym | Type | Empty
4691 : : |----------------|
4692 : : */
4693 : :
4694 : : static void BuildReFunction (unsigned int Sym, bool ConstExpr);
4695 : :
4696 : : /*
4697 : : BuildImFunction - builds the pseudo procedure call IM.
4698 : :
4699 : : The Stack:
4700 : :
4701 : :
4702 : : Entry Exit
4703 : :
4704 : : Ptr ->
4705 : : +----------------+
4706 : : | NoOfParam |
4707 : : |----------------|
4708 : : | Param 1 |
4709 : : |----------------|
4710 : : | Param 2 |
4711 : : |----------------|
4712 : : . .
4713 : : . .
4714 : : . .
4715 : : |----------------|
4716 : : | Param # |
4717 : : |----------------|
4718 : : | ProcSym | Type | Empty
4719 : : |----------------|
4720 : : */
4721 : :
4722 : : static void BuildImFunction (unsigned int Sym, bool ConstExpr);
4723 : :
4724 : : /*
4725 : : BuildCmplxFunction - builds the pseudo procedure call CMPLX.
4726 : :
4727 : : The Stack:
4728 : :
4729 : :
4730 : : Entry Exit
4731 : :
4732 : : Ptr ->
4733 : : +----------------+
4734 : : | NoOfParam |
4735 : : |----------------|
4736 : : | Param 1 |
4737 : : |----------------|
4738 : : | Param 2 |
4739 : : |----------------|
4740 : : . .
4741 : : . .
4742 : : . .
4743 : : |----------------|
4744 : : | Param # |
4745 : : |----------------|
4746 : : | ProcSym | Type | Empty
4747 : : |----------------|
4748 : : */
4749 : :
4750 : : static void BuildCmplxFunction (unsigned int func, bool ConstExpr);
4751 : :
4752 : : /*
4753 : : BuildAdrFunction - builds the pseudo function ADR
4754 : : The Stack:
4755 : :
4756 : :
4757 : : Entry Exit
4758 : :
4759 : : Ptr ->
4760 : : +----------------+
4761 : : | NoOfParam |
4762 : : |----------------|
4763 : : | Param 1 |
4764 : : |----------------|
4765 : : | Param 2 |
4766 : : |----------------|
4767 : : . .
4768 : : . .
4769 : : . .
4770 : : |----------------|
4771 : : | Param # | <- Ptr
4772 : : |----------------| +------------+
4773 : : | ProcSym | Type | | ReturnVar |
4774 : : |----------------| |------------|
4775 : :
4776 : : */
4777 : :
4778 : : static void BuildAdrFunction (void);
4779 : :
4780 : : /*
4781 : : BuildSizeFunction - builds the pseudo function SIZE
4782 : : The Stack:
4783 : :
4784 : :
4785 : : Entry Exit
4786 : :
4787 : : Ptr ->
4788 : : +----------------+
4789 : : | NoOfParam |
4790 : : |----------------|
4791 : : | Param 1 |
4792 : : |----------------|
4793 : : | Param 2 |
4794 : : |----------------|
4795 : : . .
4796 : : . .
4797 : : . .
4798 : : |----------------|
4799 : : | Param # | <- Ptr
4800 : : |----------------| +------------+
4801 : : | ProcSym | Type | | ReturnVar |
4802 : : |----------------| |------------|
4803 : : */
4804 : :
4805 : : static void BuildSizeFunction (void);
4806 : :
4807 : : /*
4808 : : BuildTSizeFunction - builds the pseudo function TSIZE
4809 : : The Stack:
4810 : :
4811 : :
4812 : : Entry Exit
4813 : :
4814 : : Ptr ->
4815 : : +----------------+
4816 : : | NoOfParam |
4817 : : |----------------|
4818 : : | Param 1 |
4819 : : |----------------|
4820 : : | Param 2 |
4821 : : |----------------|
4822 : : . .
4823 : : . .
4824 : : . .
4825 : : |----------------|
4826 : : | Param # | <- Ptr
4827 : : |----------------| +------------+
4828 : : | ProcSym | Type | | ReturnVar |
4829 : : |----------------| |------------|
4830 : :
4831 : : */
4832 : :
4833 : : static void BuildTSizeFunction (void);
4834 : :
4835 : : /*
4836 : : BuildTBitSizeFunction - builds the pseudo function TBITSIZE
4837 : : The Stack:
4838 : :
4839 : :
4840 : : Entry Exit
4841 : :
4842 : : Ptr ->
4843 : : +----------------+
4844 : : | NoOfParam |
4845 : : |----------------|
4846 : : | Param 1 |
4847 : : |----------------|
4848 : : | Param 2 |
4849 : : |----------------|
4850 : : . .
4851 : : . .
4852 : : . .
4853 : : |----------------|
4854 : : | Param # | <- Ptr
4855 : : |----------------| +------------+
4856 : : | ProcSym | Type | | ReturnVar |
4857 : : |----------------| |------------|
4858 : :
4859 : : */
4860 : :
4861 : : static void BuildTBitSizeFunction (void);
4862 : :
4863 : : /*
4864 : : ExpectingParameterType -
4865 : : */
4866 : :
4867 : : static void ExpectingParameterType (unsigned int BlockSym, unsigned int Type);
4868 : :
4869 : : /*
4870 : : ExpectingVariableType -
4871 : : */
4872 : :
4873 : : static void ExpectingVariableType (unsigned int BlockSym, unsigned int Type);
4874 : :
4875 : : /*
4876 : : CheckVariablesAndParameterTypesInBlock - checks to make sure that block, BlockSym, has
4877 : : parameters types and variable types which are legal.
4878 : : */
4879 : :
4880 : : static void CheckVariablesAndParameterTypesInBlock (unsigned int BlockSym);
4881 : :
4882 : : /*
4883 : : IsNeverAltered - returns TRUE if variable, sym, is never altered
4884 : : between quadruples: Start..End
4885 : : */
4886 : :
4887 : : static bool IsNeverAltered (unsigned int sym, unsigned int Start, unsigned int End);
4888 : :
4889 : : /*
4890 : : IsConditionVariable - returns TRUE if the condition at quadruple, q, is variable.
4891 : : */
4892 : :
4893 : : static bool IsConditionVariable (unsigned int q, unsigned int Start, unsigned int End);
4894 : :
4895 : : /*
4896 : : IsInfiniteLoop - returns TRUE if an infinite loop is found.
4897 : : Given a backwards jump at, End, it returns a BOOLEAN which depends on
4898 : : whether a jump is found to jump beyond, End. If a conditonal jump is found
4899 : : to pass over, End, the condition is tested for global variables, procedure variables and
4900 : : constants.
4901 : :
4902 : : constant - ignored
4903 : : variables - tested to see whether they are altered inside the loop
4904 : : global variable - the procedure tests to see whether it is altered as above
4905 : : but will also test to see whether this loop calls a procedure
4906 : : in which case it believes the loop NOT to be infinite
4907 : : (as this procedure call might alter the global variable)
4908 : :
4909 : : Note that this procedure can easily be fooled by the user altering variables
4910 : : with pointers.
4911 : : */
4912 : :
4913 : : static bool IsInfiniteLoop (unsigned int End);
4914 : :
4915 : : /*
4916 : : CheckVariablesInBlock - given a block, BlockSym, check whether all variables are used.
4917 : : */
4918 : :
4919 : : static void CheckVariablesInBlock (unsigned int BlockSym);
4920 : :
4921 : : /*
4922 : : CheckFunctionReturn - checks to see that a RETURN statement was present in a function.
4923 : : */
4924 : :
4925 : : static void CheckFunctionReturn (unsigned int ProcSym);
4926 : :
4927 : : /*
4928 : : CheckReturnType - checks to see that the return type from currentProc is
4929 : : assignment compatible with actualType.
4930 : : */
4931 : :
4932 : : static void CheckReturnType (unsigned int tokno, unsigned int currentProc, unsigned int actualVal, unsigned int actualType);
4933 : :
4934 : : /*
4935 : : IsReadOnly - a helper procedure function to detect constants.
4936 : : */
4937 : :
4938 : : static bool IsReadOnly (unsigned int sym);
4939 : :
4940 : : /*
4941 : : BuildDesignatorError - removes the designator from the stack and replaces
4942 : : it with an error symbol.
4943 : : */
4944 : :
4945 : : static void BuildDesignatorError (const char *message_, unsigned int _message_high);
4946 : :
4947 : : /*
4948 : : BuildStaticArray - Builds the array referencing for static arrays.
4949 : : The Stack is expected to contain:
4950 : :
4951 : :
4952 : : Entry Exit
4953 : : ===== ====
4954 : :
4955 : : Ptr ->
4956 : : +--------------+
4957 : : | e | <- Ptr
4958 : : |--------------| +------------+
4959 : : | Sym | Type | | S | T |
4960 : : |--------------| |------------|
4961 : : */
4962 : :
4963 : : static void BuildStaticArray (void);
4964 : :
4965 : : /*
4966 : : calculateMultipicand - generates quadruples which calculate the
4967 : : multiplicand for the array at dimension, dim.
4968 : : */
4969 : :
4970 : : static unsigned int calculateMultipicand (unsigned int tok, unsigned int arraySym, unsigned int arrayType, unsigned int dim);
4971 : :
4972 : : /*
4973 : : ConvertToAddress - convert sym to an address.
4974 : : */
4975 : :
4976 : : static unsigned int ConvertToAddress (unsigned int tokpos, unsigned int sym);
4977 : :
4978 : : /*
4979 : : BuildDynamicArray - Builds the array referencing for dynamic arrays.
4980 : : The Stack is expected to contain:
4981 : :
4982 : :
4983 : : Entry Exit
4984 : : ===== ====
4985 : :
4986 : : Ptr ->
4987 : : +-----------------------+
4988 : : | Index | <- Ptr
4989 : : |-----------------------| +---------------------------+
4990 : : | ArraySym | Type | Dim | | S | T | ArraySym | Dim+1 |
4991 : : |-----------------------| |---------------------------|
4992 : :
4993 : :
4994 : : if Dim=1
4995 : : then
4996 : : S := base of ArraySym + TSIZE(Type)*Index
4997 : : else
4998 : : S := S + TSIZE(Type)*Index
4999 : : fi
5000 : : */
5001 : :
5002 : : static void BuildDynamicArray (void);
5003 : :
5004 : : /*
5005 : : DebugLocation -
5006 : : */
5007 : :
5008 : : static void DebugLocation (unsigned int tok, const char *message_, unsigned int _message_high);
5009 : :
5010 : : /*
5011 : : PushWith - pushes sym and type onto the with stack. It checks for
5012 : : previous declaration of this record type.
5013 : : */
5014 : :
5015 : : static void PushWith (unsigned int Sym, unsigned int Type, unsigned int Ref, unsigned int Tok);
5016 : : static void PopWith (void);
5017 : :
5018 : : /*
5019 : : BuildAccessWithField - similar to BuildDesignatorRecord except it
5020 : : does not perform the address operation.
5021 : : The address will have been computed at the
5022 : : beginning of the WITH statement.
5023 : : It also stops the GenQuad procedure from examining the
5024 : : with stack.
5025 : :
5026 : : The Stack
5027 : :
5028 : : Entry
5029 : :
5030 : : Ptr ->
5031 : : +--------------+
5032 : : | Field | Type1| <- Ptr
5033 : : |-------|------| +-------------+
5034 : : | Adr | Type2| | Sym | Type1|
5035 : : |--------------| |-------------|
5036 : : */
5037 : :
5038 : : static void BuildAccessWithField (void);
5039 : :
5040 : : /*
5041 : : PushConstructor -
5042 : : */
5043 : :
5044 : : static void PushConstructor (unsigned int sym);
5045 : :
5046 : : /*
5047 : : AddFieldTo - adds field, e, to, value.
5048 : : */
5049 : :
5050 : : static unsigned int AddFieldTo (unsigned int value, unsigned int e);
5051 : :
5052 : : /*
5053 : : CheckLogicalOperator - returns a logical operator if the operands imply
5054 : : a logical operation should be performed.
5055 : : */
5056 : :
5057 : : static NameKey_Name CheckLogicalOperator (NameKey_Name Tok, unsigned int left, unsigned int lefttype);
5058 : :
5059 : : /*
5060 : : CheckDivModRem - initiates calls to check the divisor for DIV, MOD, REM
5061 : : expressions.
5062 : : */
5063 : :
5064 : : static void CheckDivModRem (unsigned int TokPos, NameKey_Name tok, unsigned int d, unsigned int e);
5065 : :
5066 : : /*
5067 : : doConvert - convert, sym, to a new symbol with, type.
5068 : : Return the new symbol.
5069 : : */
5070 : :
5071 : : static unsigned int doConvert (unsigned int type, unsigned int sym);
5072 : :
5073 : : /*
5074 : : doBuildBinaryOp - build the binary op, with or without type
5075 : : checking.
5076 : : */
5077 : :
5078 : : static void doBuildBinaryOp (bool checkTypes, bool checkOverflow);
5079 : :
5080 : : /*
5081 : : AreConstant - returns immediate addressing mode if b is true else
5082 : : offset mode is returned. b determines whether the
5083 : : operands are all constant - in which case we can use
5084 : : a constant temporary variable.
5085 : : */
5086 : :
5087 : : static SymbolTable_ModeOfAddr AreConstant (bool b);
5088 : :
5089 : : /*
5090 : : ConvertBooleanToVariable - converts a BoolStack(i) from a Boolean True|False
5091 : : exit pair into a variable containing the value TRUE or
5092 : : FALSE. The parameter, i, is relative to the top
5093 : : of the stack.
5094 : : */
5095 : :
5096 : : static void ConvertBooleanToVariable (unsigned int tok, unsigned int i);
5097 : :
5098 : : /*
5099 : : BuildRelOpFromBoolean - builds a relational operator sequence of quadruples
5100 : : instead of using a temporary boolean variable.
5101 : : This function can only be used when we perform
5102 : : the following translation:
5103 : :
5104 : : (a=b) # (c=d) alternatively (a=b) = (c=d)
5105 : : ^ ^
5106 : :
5107 : : it only allows # = to be used as >= <= > < all
5108 : : assume a particular value for TRUE and FALSE.
5109 : : (In which case the user should specify ORD)
5110 : :
5111 : :
5112 : : before
5113 : :
5114 : : q if r1 op1 op2 t2
5115 : : q+1 Goto f2
5116 : : q+2 if r2 op3 op4 t1
5117 : : q+3 Goto f1
5118 : :
5119 : : after (in case of =)
5120 : :
5121 : : q if r1 op1 op2 q+2
5122 : : q+1 Goto q+4
5123 : : q+2 if r2 op3 op4 t
5124 : : q+3 Goto f
5125 : : q+4 if r2 op3 op4 f
5126 : : q+5 Goto t
5127 : :
5128 : : after (in case of #)
5129 : :
5130 : : q if r1 op1 op2 q+2
5131 : : q+1 Goto q+4
5132 : : q+2 if r2 op3 op4 f
5133 : : q+3 Goto t
5134 : : q+4 if r2 op3 op4 t
5135 : : q+5 Goto f
5136 : :
5137 : : The Stack is expected to contain:
5138 : :
5139 : :
5140 : : Entry Exit
5141 : : ===== ====
5142 : :
5143 : : Ptr ->
5144 : : +------------+
5145 : : | t1 | f1 |
5146 : : |------------|
5147 : : | Operator | <- Ptr
5148 : : |------------| +------------+
5149 : : | t2 | f2 | | t | f |
5150 : : |------------| |------------|
5151 : :
5152 : :
5153 : : */
5154 : :
5155 : : static void BuildRelOpFromBoolean (unsigned int tokpos);
5156 : :
5157 : : /*
5158 : : CheckVariableOrConstantOrProcedure - checks to make sure sym is a variable, constant or procedure.
5159 : : */
5160 : :
5161 : : static void CheckVariableOrConstantOrProcedure (unsigned int tokpos, unsigned int sym);
5162 : :
5163 : : /*
5164 : : MakeOp - returns the equalent quadruple operator to a token, t.
5165 : : */
5166 : :
5167 : : static M2Quads_QuadOperator MakeOp (NameKey_Name t);
5168 : :
5169 : : /*
5170 : : GenQuadO - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
5171 : : */
5172 : :
5173 : : static void GenQuadO (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow);
5174 : :
5175 : : /*
5176 : : GenQuadOTrash - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
5177 : : */
5178 : :
5179 : : static void GenQuadOTrash (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow, unsigned int trash);
5180 : :
5181 : : /*
5182 : : GenQuad - Generate a quadruple with Operation, Op1, Op2, Op3.
5183 : : */
5184 : :
5185 : : static void GenQuad (M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3);
5186 : :
5187 : : /*
5188 : : GenQuadOtok - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
5189 : : */
5190 : :
5191 : : 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);
5192 : :
5193 : : /*
5194 : : GenQuadOTypetok - assigns the fields of the quadruple with
5195 : : the parameters.
5196 : : */
5197 : :
5198 : : 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);
5199 : :
5200 : : /*
5201 : : DumpUntil - dump all quadruples until we seen the ending quadruple
5202 : : with procsym in the third operand.
5203 : : Return the quad number containing the match.
5204 : : */
5205 : :
5206 : : static unsigned int DumpUntil (M2Quads_QuadOperator ending, unsigned int procsym, unsigned int quad);
5207 : :
5208 : : /*
5209 : : GetCtorInit - return the init procedure for the module.
5210 : : */
5211 : :
5212 : : static unsigned int GetCtorInit (unsigned int sym);
5213 : :
5214 : : /*
5215 : : GetCtorFini - return the fini procedure for the module.
5216 : : */
5217 : :
5218 : : static unsigned int GetCtorFini (unsigned int sym);
5219 : :
5220 : : /*
5221 : : DumpQuadrupleFilter -
5222 : : */
5223 : :
5224 : : static void DumpQuadrupleFilter (void);
5225 : :
5226 : : /*
5227 : : DumpQuadrupleAll - dump all quadruples.
5228 : : */
5229 : :
5230 : : static void DumpQuadrupleAll (void);
5231 : :
5232 : : /*
5233 : : BackPatch - Makes each of the quadruples on the list pointed to by
5234 : : StartQuad, take quadruple Value as a target.
5235 : : */
5236 : :
5237 : : static void BackPatch (unsigned int QuadNo, unsigned int Value);
5238 : :
5239 : : /*
5240 : : Merge - joins two quad lists, QuadList2 to the end of QuadList1.
5241 : : A QuadList of value zero is a nul list.
5242 : : */
5243 : :
5244 : : static unsigned int Merge (unsigned int QuadList1, unsigned int QuadList2);
5245 : :
5246 : : /*
5247 : : DisplayProcedureAttributes -
5248 : : */
5249 : :
5250 : : static void DisplayProcedureAttributes (unsigned int proc);
5251 : :
5252 : : /*
5253 : : WriteQuad - Writes out the Quad BufferQuad.
5254 : : */
5255 : :
5256 : : static void WriteQuad (unsigned int BufferQuad);
5257 : :
5258 : : /*
5259 : : WriteOperand - displays the operands name, symbol id and mode of addressing.
5260 : : */
5261 : :
5262 : : static void WriteMode (SymbolTable_ModeOfAddr Mode);
5263 : :
5264 : : /*
5265 : : PushExit - pushes the exit value onto the EXIT stack.
5266 : : */
5267 : :
5268 : : static void PushExit (unsigned int Exit);
5269 : :
5270 : : /*
5271 : : PopExit - pops the exit value from the EXIT stack.
5272 : : */
5273 : :
5274 : : static unsigned int PopExit (void);
5275 : :
5276 : : /*
5277 : : PushFor - pushes the exit value onto the FOR stack.
5278 : : */
5279 : :
5280 : : static void PushFor (unsigned int Exit);
5281 : :
5282 : : /*
5283 : : PopFor - pops the exit value from the FOR stack.
5284 : : */
5285 : :
5286 : : static unsigned int PopFor (void);
5287 : :
5288 : : /*
5289 : : OperandTno - returns the ident operand stored in the true position
5290 : : on the boolean stack. This is exactly the same as
5291 : : OperandT but it has no IsBoolean checking.
5292 : : */
5293 : :
5294 : : static unsigned int OperandTno (unsigned int pos);
5295 : :
5296 : : /*
5297 : : OperandFno - returns the ident operand stored in the false position
5298 : : on the boolean stack. This is exactly the same as
5299 : : OperandF but it has no IsBoolean checking.
5300 : : */
5301 : :
5302 : : static unsigned int OperandFno (unsigned int pos);
5303 : :
5304 : : /*
5305 : : OperandTtok - returns the token associated with the position, pos
5306 : : on the boolean stack.
5307 : : */
5308 : :
5309 : : static unsigned int OperandTtok (unsigned int pos);
5310 : :
5311 : : /*
5312 : : PopBooltok - Pops a True and a False exit quad number from the True/False
5313 : : stack.
5314 : : */
5315 : :
5316 : : static void PopBooltok (unsigned int *True, unsigned int *False, unsigned int *tokno);
5317 : :
5318 : : /*
5319 : : PushBooltok - Push a True and a False exit quad numbers onto the
5320 : : True/False stack.
5321 : : */
5322 : :
5323 : : static void PushBooltok (unsigned int True, unsigned int False, unsigned int tokno);
5324 : :
5325 : : /*
5326 : : PopBool - Pops a True and a False exit quad number from the True/False
5327 : : stack.
5328 : : */
5329 : :
5330 : : static void PopBool (unsigned int *True, unsigned int *False);
5331 : :
5332 : : /*
5333 : : PushBool - Push a True and a False exit quad numbers onto the
5334 : : True/False stack.
5335 : : */
5336 : :
5337 : : static void PushBool (unsigned int True, unsigned int False);
5338 : :
5339 : : /*
5340 : : IsBoolean - returns true is the Stack position pos contains a Boolean
5341 : : Exit. False is returned if an Ident is stored.
5342 : : */
5343 : :
5344 : : static bool IsBoolean (unsigned int pos);
5345 : :
5346 : : /*
5347 : : OperandD - returns possible array dimension associated with the ident
5348 : : operand stored on the boolean stack.
5349 : : */
5350 : :
5351 : : static unsigned int OperandD (unsigned int pos);
5352 : :
5353 : : /*
5354 : : OperandRW - returns the rw operand stored on the boolean stack.
5355 : : */
5356 : :
5357 : : static unsigned int OperandRW (unsigned int pos);
5358 : :
5359 : : /*
5360 : : OperandMergeRW - returns the rw operand if not NulSym else it
5361 : : returns True.
5362 : : */
5363 : :
5364 : : static unsigned int OperandMergeRW (unsigned int pos);
5365 : :
5366 : : /*
5367 : : UseLineNote - uses the line note and returns it to the free list.
5368 : : */
5369 : :
5370 : : static void UseLineNote (M2Quads_LineNote l);
5371 : :
5372 : : /*
5373 : : PopLineNo - pops a line note from the line stack.
5374 : : */
5375 : :
5376 : : static M2Quads_LineNote PopLineNo (void);
5377 : :
5378 : : /*
5379 : : InitLineNote - creates a line note and initializes it to
5380 : : contain, file, line.
5381 : : */
5382 : :
5383 : : static M2Quads_LineNote InitLineNote (NameKey_Name file, unsigned int line);
5384 : :
5385 : : /*
5386 : : PushLineNote -
5387 : : */
5388 : :
5389 : : static void PushLineNote (M2Quads_LineNote l);
5390 : :
5391 : : /*
5392 : : BuildStmtNoteTok - adds a nop (with an assigned tokenno location) to the code.
5393 : : */
5394 : :
5395 : : static void BuildStmtNoteTok (unsigned int tokenno);
5396 : :
5397 : : /*
5398 : : GetRecordOrField -
5399 : : */
5400 : :
5401 : : static unsigned int GetRecordOrField (void);
5402 : :
5403 : : /*
5404 : : PushTFAD - Push True, False, Array, Dim, numbers onto the
5405 : : True/False stack. True and False are assumed to
5406 : : contain Symbols or Ident etc.
5407 : : */
5408 : :
5409 : : static void PushTFAD (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim);
5410 : :
5411 : : /*
5412 : : PushTFADtok - Push True, False, Array, Dim, numbers onto the
5413 : : True/False stack. True and False are assumed to
5414 : : contain Symbols or Ident etc.
5415 : : */
5416 : :
5417 : : static void PushTFADtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int tokno);
5418 : :
5419 : : /*
5420 : : PushTFADrwtok - Push True, False, Array, Dim, rw, numbers onto the
5421 : : True/False stack. True and False are assumed to
5422 : : contain Symbols or Ident etc.
5423 : : */
5424 : :
5425 : : static void PushTFADrwtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int rw, unsigned int Tok);
5426 : :
5427 : : /*
5428 : : PopTFrwtok - Pop a True and False number from the True/False stack.
5429 : : True and False are assumed to contain Symbols or Ident etc.
5430 : : */
5431 : :
5432 : : static void PopTFrwtok (unsigned int *True, unsigned int *False, unsigned int *rw, unsigned int *tokno);
5433 : :
5434 : : /*
5435 : : PushTFrwtok - Push an item onto the stack in the T (true) position,
5436 : : it is assummed to be a token and its token location is recorded.
5437 : : */
5438 : :
5439 : : static void PushTFrwtok (unsigned int True, unsigned int False, unsigned int rw, unsigned int tokno);
5440 : :
5441 : : /*
5442 : : PushTFDtok - Push True, False, Dim, numbers onto the
5443 : : True/False stack. True and False are assumed to
5444 : : contain Symbols or Ident etc.
5445 : : */
5446 : :
5447 : : static void PushTFDtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int Tok);
5448 : :
5449 : : /*
5450 : : PopTFDtok - Pop a True, False, Dim number from the True/False stack.
5451 : : True and False are assumed to contain Symbols or Ident etc.
5452 : : */
5453 : :
5454 : : static void PopTFDtok (unsigned int *True, unsigned int *False, unsigned int *Dim, unsigned int *Tok);
5455 : :
5456 : : /*
5457 : : PushTFDrwtok - Push True, False, Dim, numbers onto the
5458 : : True/False stack. True and False are assumed to
5459 : : contain Symbols or Ident etc.
5460 : : */
5461 : :
5462 : : static void PushTFDrwtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int rw, unsigned int Tok);
5463 : :
5464 : : /*
5465 : : PushTFrw - Push a True and False numbers onto the True/False stack.
5466 : : True and False are assumed to contain Symbols or Ident etc.
5467 : : It also pushes the higher level symbol which is associated
5468 : : with the True symbol. Eg record variable or array variable.
5469 : : */
5470 : :
5471 : : static void PushTFrw (unsigned int True, unsigned int False, unsigned int rw);
5472 : :
5473 : : /*
5474 : : PopTFrw - Pop a True and False number from the True/False stack.
5475 : : True and False are assumed to contain Symbols or Ident etc.
5476 : : */
5477 : :
5478 : : static void PopTFrw (unsigned int *True, unsigned int *False, unsigned int *rw);
5479 : :
5480 : : /*
5481 : : newBoolFrame - creates a new BoolFrame with all fields initialised to their defaults.
5482 : : */
5483 : :
5484 : : static M2Quads_BoolFrame newBoolFrame (void);
5485 : :
5486 : : /*
5487 : : PushTrwtok - Push an item onto the True/False stack. The False value will be zero.
5488 : : */
5489 : :
5490 : : static void PushTrwtok (unsigned int True, unsigned int rw, unsigned int tok);
5491 : :
5492 : : /*
5493 : : PopTrw - Pop a True field and rw symbol from the stack.
5494 : : */
5495 : :
5496 : : static void PopTrw (unsigned int *True, unsigned int *rw);
5497 : :
5498 : : /*
5499 : : PopTrwtok - Pop a True field and rw symbol from the stack.
5500 : : */
5501 : :
5502 : : static void PopTrwtok (unsigned int *True, unsigned int *rw, unsigned int *tok);
5503 : :
5504 : : /*
5505 : : Init - initialize the M2Quads module, all the stacks, all the lists
5506 : : and the quads list.
5507 : : */
5508 : :
5509 : : static void Init (void);
5510 : :
5511 : :
5512 : : /*
5513 : : DSdbEnter -
5514 : : */
5515 : :
5516 : 0 : static void DSdbEnter (void)
5517 : : {
5518 : 0 : }
5519 : :
5520 : :
5521 : : /*
5522 : : DSdbExit -
5523 : : */
5524 : :
5525 : 0 : static void DSdbExit (void)
5526 : : {
5527 : 0 : }
5528 : :
5529 : :
5530 : : /*
5531 : : GetQF - returns the QuadFrame associated with, q.
5532 : : */
5533 : :
5534 : 1943593333 : static M2Quads_QuadFrame GetQF (unsigned int q)
5535 : : {
5536 : 0 : return (M2Quads_QuadFrame) (Indexing_GetIndice (QuadArray, q));
5537 : : /* static analysis guarentees a RETURN statement will be used before here. */
5538 : : __builtin_unreachable ();
5539 : : }
5540 : :
5541 : :
5542 : : /*
5543 : : IsQuadA - returns true if QuadNo is a op.
5544 : : */
5545 : :
5546 : 59463217 : static bool IsQuadA (unsigned int QuadNo, M2Quads_QuadOperator op)
5547 : : {
5548 : 59463217 : M2Quads_QuadFrame f;
5549 : :
5550 : 0 : f = GetQF (QuadNo);
5551 : 59463217 : return f->Operator == op;
5552 : : /* static analysis guarentees a RETURN statement will be used before here. */
5553 : : __builtin_unreachable ();
5554 : : }
5555 : :
5556 : :
5557 : : /*
5558 : : AddQuadInformation - adds variable analysis and jump analysis to the new quadruple.
5559 : : */
5560 : :
5561 : 4451839 : static void AddQuadInformation (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
5562 : : {
5563 : 4451839 : switch (Op)
5564 : : {
5565 : 130806 : case M2Quads_IfInOp:
5566 : 130806 : case M2Quads_IfNotInOp:
5567 : 130806 : case M2Quads_IfEquOp:
5568 : 130806 : case M2Quads_IfNotEquOp:
5569 : 130806 : case M2Quads_IfLessOp:
5570 : 130806 : case M2Quads_IfLessEquOp:
5571 : 130806 : case M2Quads_IfGreOp:
5572 : 130806 : case M2Quads_IfGreEquOp:
5573 : 130806 : ManipulateReference (QuadNo, Oper3);
5574 : 130806 : CheckAddVariableRead (Oper1, false, QuadNo);
5575 : 130806 : CheckAddVariableRead (Oper2, false, QuadNo);
5576 : 130806 : break;
5577 : :
5578 : 135034 : case M2Quads_TryOp:
5579 : 135034 : case M2Quads_RetryOp:
5580 : 135034 : case M2Quads_GotoOp:
5581 : 135034 : ManipulateReference (QuadNo, Oper3);
5582 : 135034 : break;
5583 : :
5584 : 1205 : case M2Quads_InclOp:
5585 : 1205 : case M2Quads_ExclOp:
5586 : : /* variable references */
5587 : 1205 : CheckConst (Oper1);
5588 : 1205 : CheckAddVariableRead (Oper3, false, QuadNo);
5589 : 1205 : CheckAddVariableWrite (Oper1, true, QuadNo);
5590 : 1205 : break;
5591 : :
5592 : 512872 : case M2Quads_UnboundedOp:
5593 : 512872 : case M2Quads_FunctValueOp:
5594 : 512872 : case M2Quads_NegateOp:
5595 : 512872 : case M2Quads_BecomesOp:
5596 : 512872 : case M2Quads_HighOp:
5597 : 512872 : case M2Quads_SizeOp:
5598 : 512872 : CheckConst (Oper1);
5599 : 512872 : CheckAddVariableWrite (Oper1, false, QuadNo);
5600 : 512872 : CheckAddVariableRead (Oper3, false, QuadNo);
5601 : 512872 : break;
5602 : :
5603 : 165142 : case M2Quads_AddrOp:
5604 : 165142 : CheckConst (Oper1);
5605 : 165142 : CheckAddVariableWrite (Oper1, false, QuadNo);
5606 : : /* the next line is a kludge and assumes we _will_
5607 : : write to the variable as we have taken its address */
5608 : 165142 : CheckRemoveVariableWrite (Oper1, true, QuadNo);
5609 : 165142 : break;
5610 : :
5611 : 17903 : case M2Quads_ReturnValueOp:
5612 : 17903 : CheckAddVariableRead (Oper1, false, QuadNo);
5613 : 17903 : break;
5614 : :
5615 : : case M2Quads_ReturnOp:
5616 : : case M2Quads_NewLocalVarOp:
5617 : : case M2Quads_KillLocalVarOp:
5618 : : break;
5619 : :
5620 : 168660 : case M2Quads_CallOp:
5621 : 168660 : CheckAddVariableRead (Oper3, true, QuadNo);
5622 : 168660 : break;
5623 : :
5624 : 481619 : case M2Quads_ParamOp:
5625 : 481619 : CheckAddVariableRead (Oper2, false, QuadNo);
5626 : 481619 : CheckAddVariableRead (Oper3, false, QuadNo);
5627 : 481619 : if (((Oper1 > 0) && (Oper1 <= (SymbolTable_NoOfParam (Oper2)))) && (SymbolTable_IsVarParam (Oper2, Oper1)))
5628 : : {
5629 : : /* _may_ also write to a var parameter, although we dont know */
5630 : 16802 : CheckAddVariableWrite (Oper3, true, QuadNo);
5631 : : }
5632 : : break;
5633 : :
5634 : 275300 : case M2Quads_RecordFieldOp:
5635 : 275300 : case M2Quads_ArrayOp:
5636 : 275300 : case M2Quads_LogicalShiftOp:
5637 : 275300 : case M2Quads_LogicalRotateOp:
5638 : 275300 : case M2Quads_LogicalOrOp:
5639 : 275300 : case M2Quads_LogicalAndOp:
5640 : 275300 : case M2Quads_LogicalXorOp:
5641 : 275300 : case M2Quads_CoerceOp:
5642 : 275300 : case M2Quads_ConvertOp:
5643 : 275300 : case M2Quads_CastOp:
5644 : 275300 : case M2Quads_AddOp:
5645 : 275300 : case M2Quads_SubOp:
5646 : 275300 : case M2Quads_MultOp:
5647 : 275300 : case M2Quads_DivM2Op:
5648 : 275300 : case M2Quads_ModM2Op:
5649 : 275300 : case M2Quads_ModFloorOp:
5650 : 275300 : case M2Quads_DivCeilOp:
5651 : 275300 : case M2Quads_ModCeilOp:
5652 : 275300 : case M2Quads_DivFloorOp:
5653 : 275300 : case M2Quads_ModTruncOp:
5654 : 275300 : case M2Quads_DivTruncOp:
5655 : 275300 : CheckConst (Oper1);
5656 : 275300 : CheckAddVariableWrite (Oper1, false, QuadNo);
5657 : 275300 : CheckAddVariableRead (Oper2, false, QuadNo);
5658 : 275300 : CheckAddVariableRead (Oper3, false, QuadNo);
5659 : 275300 : break;
5660 : :
5661 : 33484 : case M2Quads_XIndrOp:
5662 : 33484 : CheckConst (Oper1);
5663 : 33484 : CheckAddVariableWrite (Oper1, true, QuadNo);
5664 : 33484 : CheckAddVariableRead (Oper3, false, QuadNo);
5665 : 33484 : break;
5666 : :
5667 : 13752 : case M2Quads_IndrXOp:
5668 : 13752 : CheckConst (Oper1);
5669 : 13752 : CheckAddVariableWrite (Oper1, false, QuadNo);
5670 : 13752 : CheckAddVariableRead (Oper3, true, QuadNo);
5671 : 13752 : break;
5672 : :
5673 : 2558 : case M2Quads_SaveExceptionOp:
5674 : : /* RangeCheckOp : CheckRangeAddVariableRead(Oper3, QuadNo) | */
5675 : 2558 : CheckConst (Oper1);
5676 : 2558 : CheckAddVariableWrite (Oper1, false, QuadNo);
5677 : 2558 : break;
5678 : :
5679 : 2672 : case M2Quads_RestoreExceptionOp:
5680 : 2672 : CheckAddVariableRead (Oper1, false, QuadNo);
5681 : 2672 : break;
5682 : :
5683 : :
5684 : : default:
5685 : : break;
5686 : : }
5687 : 4451839 : }
5688 : :
5689 : 0 : static void stop (void)
5690 : : {
5691 : 0 : }
5692 : :
5693 : :
5694 : : /*
5695 : : PutQuadO - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
5696 : : sets a boolean to determinine whether overflow should be checked.
5697 : : */
5698 : :
5699 : 3715594 : static void PutQuadO (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow)
5700 : : {
5701 : 0 : PutQuadOType (QuadNo, Op, Oper1, Oper2, Oper3, overflow, true);
5702 : 0 : }
5703 : :
5704 : :
5705 : : /*
5706 : : PutQuadOType -
5707 : : */
5708 : :
5709 : 4391766 : static void PutQuadOType (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow, bool checktype)
5710 : : {
5711 : 4391766 : M2Quads_QuadFrame f;
5712 : :
5713 : 4391766 : if (QuadNo == BreakAtQuad)
5714 : : {
5715 : 4391766 : stop ();
5716 : : }
5717 : 4391766 : if (QuadrupleGeneration)
5718 : : {
5719 : 4391766 : M2Quads_EraseQuad (QuadNo);
5720 : 4391766 : AddQuadInformation (QuadNo, Op, Oper1, Oper2, Oper3);
5721 : 4391766 : f = GetQF (QuadNo);
5722 : 4391766 : f->Operator = Op;
5723 : 4391766 : f->Operand1 = Oper1;
5724 : 4391766 : f->Operand2 = Oper2;
5725 : 4391766 : f->Operand3 = Oper3;
5726 : 4391766 : f->CheckOverflow = overflow;
5727 : 4391766 : f->CheckType = checktype;
5728 : 4391766 : f->ConstExpr = M2Quads_IsInConstExpression ();
5729 : : }
5730 : 4391766 : }
5731 : :
5732 : :
5733 : : /*
5734 : : UndoReadWriteInfo -
5735 : : */
5736 : :
5737 : 5648580 : static void UndoReadWriteInfo (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
5738 : : {
5739 : 5648580 : switch (Op)
5740 : : {
5741 : 70665 : case M2Quads_IfInOp:
5742 : 70665 : case M2Quads_IfNotInOp:
5743 : 70665 : case M2Quads_IfEquOp:
5744 : 70665 : case M2Quads_IfNotEquOp:
5745 : 70665 : case M2Quads_IfLessOp:
5746 : 70665 : case M2Quads_IfLessEquOp:
5747 : 70665 : case M2Quads_IfGreOp:
5748 : 70665 : case M2Quads_IfGreEquOp:
5749 : : /* jumps, calls and branches */
5750 : 70665 : RemoveReference (QuadNo);
5751 : 70665 : CheckRemoveVariableRead (Oper1, false, QuadNo);
5752 : 70665 : CheckRemoveVariableRead (Oper2, false, QuadNo);
5753 : 70665 : break;
5754 : :
5755 : 97620 : case M2Quads_TryOp:
5756 : 97620 : case M2Quads_RetryOp:
5757 : 97620 : case M2Quads_GotoOp:
5758 : 97620 : RemoveReference (QuadNo);
5759 : 97620 : break;
5760 : :
5761 : 0 : case M2Quads_InclOp:
5762 : 0 : case M2Quads_ExclOp:
5763 : : /* variable references */
5764 : 0 : CheckRemoveVariableRead (Oper1, false, QuadNo);
5765 : 0 : CheckRemoveVariableWrite (Oper1, true, QuadNo);
5766 : 0 : break;
5767 : :
5768 : 253006 : case M2Quads_UnboundedOp:
5769 : 253006 : case M2Quads_FunctValueOp:
5770 : 253006 : case M2Quads_NegateOp:
5771 : 253006 : case M2Quads_BecomesOp:
5772 : 253006 : case M2Quads_HighOp:
5773 : 253006 : case M2Quads_SizeOp:
5774 : 253006 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
5775 : 253006 : CheckRemoveVariableRead (Oper3, false, QuadNo);
5776 : 253006 : break;
5777 : :
5778 : 820 : case M2Quads_AddrOp:
5779 : 820 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
5780 : : /* the next line is a kludge and assumes we _will_
5781 : : write to the variable as we have taken its address */
5782 : 820 : CheckRemoveVariableWrite (Oper1, true, QuadNo);
5783 : 820 : break;
5784 : :
5785 : 72 : case M2Quads_ReturnValueOp:
5786 : 72 : CheckRemoveVariableRead (Oper1, false, QuadNo);
5787 : 72 : break;
5788 : :
5789 : : case M2Quads_ReturnOp:
5790 : : case M2Quads_CallOp:
5791 : : case M2Quads_NewLocalVarOp:
5792 : : case M2Quads_KillLocalVarOp:
5793 : : break;
5794 : :
5795 : 4808 : case M2Quads_ParamOp:
5796 : 4808 : CheckRemoveVariableRead (Oper2, false, QuadNo);
5797 : 4808 : CheckRemoveVariableRead (Oper3, false, QuadNo);
5798 : 4808 : if (((Oper1 > 0) && (Oper1 <= (SymbolTable_NoOfParam (Oper2)))) && (SymbolTable_IsVarParam (Oper2, Oper1)))
5799 : : {
5800 : : /* _may_ also write to a var parameter, although we dont know */
5801 : 88 : CheckRemoveVariableWrite (Oper3, true, QuadNo);
5802 : : }
5803 : : break;
5804 : :
5805 : 30181 : case M2Quads_RecordFieldOp:
5806 : 30181 : case M2Quads_ArrayOp:
5807 : 30181 : case M2Quads_LogicalShiftOp:
5808 : 30181 : case M2Quads_LogicalRotateOp:
5809 : 30181 : case M2Quads_LogicalOrOp:
5810 : 30181 : case M2Quads_LogicalAndOp:
5811 : 30181 : case M2Quads_LogicalXorOp:
5812 : 30181 : case M2Quads_CoerceOp:
5813 : 30181 : case M2Quads_ConvertOp:
5814 : 30181 : case M2Quads_CastOp:
5815 : 30181 : case M2Quads_AddOp:
5816 : 30181 : case M2Quads_SubOp:
5817 : 30181 : case M2Quads_MultOp:
5818 : 30181 : case M2Quads_DivM2Op:
5819 : 30181 : case M2Quads_ModM2Op:
5820 : 30181 : case M2Quads_ModFloorOp:
5821 : 30181 : case M2Quads_DivCeilOp:
5822 : 30181 : case M2Quads_ModCeilOp:
5823 : 30181 : case M2Quads_DivFloorOp:
5824 : 30181 : case M2Quads_ModTruncOp:
5825 : 30181 : case M2Quads_DivTruncOp:
5826 : 30181 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
5827 : 30181 : CheckRemoveVariableRead (Oper2, false, QuadNo);
5828 : 30181 : CheckRemoveVariableRead (Oper3, false, QuadNo);
5829 : 30181 : break;
5830 : :
5831 : 4 : case M2Quads_XIndrOp:
5832 : 4 : CheckRemoveVariableWrite (Oper1, true, QuadNo);
5833 : 4 : CheckRemoveVariableRead (Oper3, false, QuadNo);
5834 : 4 : break;
5835 : :
5836 : 360 : case M2Quads_IndrXOp:
5837 : 360 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
5838 : 360 : CheckRemoveVariableRead (Oper3, true, QuadNo);
5839 : 360 : break;
5840 : :
5841 : 0 : case M2Quads_SaveExceptionOp:
5842 : : /* RangeCheckOp : CheckRangeRemoveVariableRead(Oper3, QuadNo) | */
5843 : 0 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
5844 : 0 : break;
5845 : :
5846 : 174 : case M2Quads_RestoreExceptionOp:
5847 : 174 : CheckRemoveVariableRead (Oper1, false, QuadNo);
5848 : 174 : break;
5849 : :
5850 : :
5851 : : default:
5852 : : break;
5853 : : }
5854 : 5648580 : }
5855 : :
5856 : :
5857 : : /*
5858 : : CheckAddVariableRead - checks to see whether symbol, Sym, is a variable or
5859 : : a parameter and if so it then adds this quadruple
5860 : : to the variable list.
5861 : : */
5862 : :
5863 : 2525998 : static void CheckAddVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad)
5864 : : {
5865 : 2525998 : if (SymbolTable_IsVar (Sym))
5866 : : {
5867 : 912659 : SymbolTable_PutReadQuad (Sym, SymbolTable_GetMode (Sym), Quad);
5868 : 912659 : if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
5869 : : {
5870 : 13820 : SymbolTable_PutReadQuad (Sym, SymbolTable_RightValue, Quad);
5871 : : }
5872 : : }
5873 : 2525998 : }
5874 : :
5875 : :
5876 : : /*
5877 : : CheckRemoveVariableRead - checks to see whether, Sym, is a variable or
5878 : : a parameter and if so then it removes the
5879 : : quadruple from the variable list.
5880 : : */
5881 : :
5882 : 464924 : static void CheckRemoveVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad)
5883 : : {
5884 : 464924 : if (SymbolTable_IsVar (Sym))
5885 : : {
5886 : 84395 : SymbolTable_RemoveReadQuad (Sym, SymbolTable_GetMode (Sym), Quad);
5887 : 84395 : if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
5888 : : {
5889 : 360 : SymbolTable_RemoveReadQuad (Sym, SymbolTable_RightValue, Quad);
5890 : : }
5891 : : }
5892 : 464924 : }
5893 : :
5894 : :
5895 : : /*
5896 : : CheckAddVariableWrite - checks to see whether symbol, Sym, is a variable and
5897 : : if so it then adds this quadruple to the variable list.
5898 : : */
5899 : :
5900 : 1021115 : static void CheckAddVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad)
5901 : : {
5902 : 1021115 : if (SymbolTable_IsVar (Sym))
5903 : : {
5904 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
5905 : 744033 : if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
5906 : : {
5907 : 46626 : SymbolTable_PutReadQuad (Sym, SymbolTable_LeftValue, Quad);
5908 : 46626 : SymbolTable_PutWriteQuad (Sym, SymbolTable_RightValue, Quad);
5909 : : }
5910 : : else
5911 : : {
5912 : 697407 : SymbolTable_PutWriteQuad (Sym, SymbolTable_GetMode (Sym), Quad);
5913 : : }
5914 : : }
5915 : 1021115 : }
5916 : :
5917 : :
5918 : : /*
5919 : : CheckRemoveVariableWrite - checks to see whether, Sym, is a variable and
5920 : : if so then it removes the quadruple from the
5921 : : variable list.
5922 : : */
5923 : :
5924 : 450421 : static void CheckRemoveVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad)
5925 : : {
5926 : 450421 : if (SymbolTable_IsVar (Sym))
5927 : : {
5928 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
5929 : 172215 : if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
5930 : : {
5931 : 8333 : SymbolTable_RemoveReadQuad (Sym, SymbolTable_LeftValue, Quad);
5932 : 8333 : SymbolTable_RemoveWriteQuad (Sym, SymbolTable_RightValue, Quad);
5933 : : }
5934 : : else
5935 : : {
5936 : 163882 : SymbolTable_RemoveWriteQuad (Sym, SymbolTable_GetMode (Sym), Quad);
5937 : : }
5938 : : }
5939 : 450421 : }
5940 : :
5941 : :
5942 : : /*
5943 : : CheckConst -
5944 : : */
5945 : :
5946 : 1004313 : static void CheckConst (unsigned int sym)
5947 : : {
5948 : 1004313 : if (SymbolTable_IsConst (sym))
5949 : : {
5950 : 277058 : M2GCCDeclare_PutToBeSolvedByQuads (sym);
5951 : : }
5952 : 1004313 : }
5953 : :
5954 : :
5955 : : /*
5956 : : AlterReference - alters all references from OldQuad, to NewQuad in a
5957 : : quadruple list Head.
5958 : : */
5959 : :
5960 : 1196741 : static void AlterReference (unsigned int Head, unsigned int OldQuad, unsigned int NewQuad)
5961 : : {
5962 : 1196741 : M2Quads_QuadFrame f;
5963 : 1196741 : M2Quads_QuadFrame g;
5964 : 1196741 : unsigned int i;
5965 : :
5966 : 1196741 : f = GetQF (OldQuad);
5967 : 8793418 : while ((f->NoOfTimesReferenced > 0) && (Head != 0))
5968 : : {
5969 : 6399936 : g = GetQF (Head);
5970 : 6399936 : switch (g->Operator)
5971 : : {
5972 : 308806 : case M2Quads_IfInOp:
5973 : 308806 : case M2Quads_IfNotInOp:
5974 : 308806 : case M2Quads_IfEquOp:
5975 : 308806 : case M2Quads_IfNotEquOp:
5976 : 308806 : case M2Quads_IfLessOp:
5977 : 308806 : case M2Quads_IfLessEquOp:
5978 : 308806 : case M2Quads_IfGreOp:
5979 : 308806 : case M2Quads_IfGreEquOp:
5980 : 308806 : case M2Quads_TryOp:
5981 : 308806 : case M2Quads_RetryOp:
5982 : 308806 : case M2Quads_GotoOp:
5983 : 308806 : if (g->Operand3 == OldQuad)
5984 : : {
5985 : 8387 : ManipulateReference (Head, NewQuad);
5986 : : }
5987 : : break;
5988 : :
5989 : :
5990 : : default:
5991 : : break;
5992 : : }
5993 : 6399936 : i = g->Next;
5994 : 6399936 : Head = i;
5995 : : }
5996 : 1196741 : }
5997 : :
5998 : :
5999 : : /*
6000 : : GrowQuads - grows the list of quadruples to the quadruple, to.
6001 : : */
6002 : :
6003 : 471423 : static void GrowQuads (unsigned int to)
6004 : : {
6005 : 471423 : unsigned int i;
6006 : 471423 : M2Quads_QuadFrame f;
6007 : :
6008 : 471423 : if ((to != 0) && (to > GrowInitialization))
6009 : : {
6010 : 8177 : i = GrowInitialization+1;
6011 : 16354 : while (i <= to)
6012 : : {
6013 : 8177 : if (Indexing_InBounds (QuadArray, i))
6014 : : {
6015 : 0 : M2Debug_Assert ((Indexing_GetIndice (QuadArray, i)) != NULL);
6016 : : }
6017 : : else
6018 : : {
6019 : 8177 : Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T3));
6020 : 8177 : if (f == NULL)
6021 : : {
6022 : 0 : M2Error_InternalError ((const char *) "out of memory error when trying to allocate a quadruple", 55);
6023 : : }
6024 : 8177 : Indexing_PutIndice (QuadArray, i, reinterpret_cast<void *> (f));
6025 : 8177 : f->NoOfTimesReferenced = 0;
6026 : : }
6027 : 8177 : i += 1;
6028 : : }
6029 : 8177 : GrowInitialization = to;
6030 : : }
6031 : 471423 : }
6032 : :
6033 : :
6034 : : /*
6035 : : ManipulateReference - manipulates the quadruple, q, so that it now points to quad, to.
6036 : : */
6037 : :
6038 : 471423 : static void ManipulateReference (unsigned int q, unsigned int to)
6039 : : {
6040 : 471423 : M2Quads_QuadFrame f;
6041 : :
6042 : 942846 : M2Debug_Assert ((GrowInitialization >= q) || (to == 0));
6043 : 471423 : GrowQuads (to);
6044 : 471423 : RemoveReference (q);
6045 : 471423 : f = GetQF (q);
6046 : 471423 : f->Operand3 = to;
6047 : 471423 : if (to != 0)
6048 : : {
6049 : 300858 : f = GetQF (to);
6050 : 300858 : f->NoOfTimesReferenced += 1;
6051 : : }
6052 : 471423 : }
6053 : :
6054 : :
6055 : : /*
6056 : : RemoveReference - remove the reference by quadruple, q, to wherever
6057 : : it was pointing to.
6058 : : */
6059 : :
6060 : 639708 : static void RemoveReference (unsigned int q)
6061 : : {
6062 : 639708 : M2Quads_QuadFrame f;
6063 : 639708 : M2Quads_QuadFrame g;
6064 : :
6065 : 639708 : f = GetQF (q);
6066 : 639708 : if ((f->Operand3 != 0) && (f->Operand3 < NextQuad))
6067 : : {
6068 : 203303 : g = GetQF (f->Operand3);
6069 : 203303 : M2Debug_Assert (g->NoOfTimesReferenced != 0);
6070 : 203303 : g->NoOfTimesReferenced -= 1;
6071 : : }
6072 : 639708 : }
6073 : :
6074 : :
6075 : : /*
6076 : : NewQuad - sets QuadNo to a new quadruple.
6077 : : */
6078 : :
6079 : 4394254 : static void NewQuad (unsigned int *QuadNo)
6080 : : {
6081 : 4394254 : M2Quads_QuadFrame f;
6082 : :
6083 : 4394254 : (*QuadNo) = FreeList;
6084 : 4394254 : if ((Indexing_InBounds (QuadArray, (*QuadNo))) && ((Indexing_GetIndice (QuadArray, (*QuadNo))) != NULL))
6085 : : {
6086 : 8177 : f = static_cast<M2Quads_QuadFrame> (Indexing_GetIndice (QuadArray, (*QuadNo)));
6087 : : }
6088 : : else
6089 : : {
6090 : 4386077 : Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T3));
6091 : 4386077 : if (f == NULL)
6092 : : {
6093 : 0 : M2Error_InternalError ((const char *) "out of memory error trying to allocate a quadruple", 50);
6094 : : }
6095 : : else
6096 : : {
6097 : 4386077 : NoOfQuads += 1;
6098 : 4386077 : Indexing_PutIndice (QuadArray, (*QuadNo), reinterpret_cast<void *> (f));
6099 : 4386077 : f->NoOfTimesReferenced = 0;
6100 : : }
6101 : : }
6102 : 4394254 : f->Operator = M2Quads_DummyOp;
6103 : 4394254 : f->Operand3 = 0;
6104 : 4394254 : f->Next = 0;
6105 : 4394254 : FreeList += 1;
6106 : 4394254 : if (GrowInitialization < FreeList)
6107 : : {
6108 : 4386077 : GrowInitialization = FreeList;
6109 : : }
6110 : 4394254 : }
6111 : :
6112 : :
6113 : : /*
6114 : : CheckVariableAt - checks to see whether, sym, was declared at a particular address.
6115 : : */
6116 : :
6117 : 2418231 : static void CheckVariableAt (unsigned int sym)
6118 : : {
6119 : 2418231 : if ((SymbolTable_IsVar (sym)) && (SymbolTable_IsVariableAtAddress (sym)))
6120 : : {
6121 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
6122 : 54 : if ((SymbolTable_GetMode (sym)) == SymbolTable_LeftValue)
6123 : : {
6124 : 54 : GenQuad (M2Quads_InitAddressOp, sym, SymbolTable_NulSym, SymbolTable_GetVariableAtAddress (sym));
6125 : : }
6126 : : else
6127 : : {
6128 : 0 : M2Error_InternalError ((const char *) "expecting lvalue for this variable which is declared at an explicit address", 75);
6129 : : }
6130 : : }
6131 : 2418231 : }
6132 : :
6133 : :
6134 : : /*
6135 : : CheckVariablesAt - checks to see whether we need to initialize any pointers
6136 : : which point to variable declared at addresses.
6137 : : */
6138 : :
6139 : 123121 : static void CheckVariablesAt (unsigned int scope)
6140 : : {
6141 : 0 : SymbolTable_ForeachLocalSymDo (scope, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) CheckVariableAt});
6142 : 0 : }
6143 : :
6144 : :
6145 : : /*
6146 : : GetTurnInterrupts - returns the TurnInterrupts procedure function.
6147 : : */
6148 : :
6149 : 840 : static unsigned int GetTurnInterrupts (unsigned int tok)
6150 : : {
6151 : 840 : if (M2Options_Iso)
6152 : : {
6153 : 0 : return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "TurnInterrupts", 14), NameKey_MakeKey ((const char *) "COROUTINES", 10));
6154 : : }
6155 : : else
6156 : : {
6157 : 840 : return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "TurnInterrupts", 14), NameKey_MakeKey ((const char *) "SYSTEM", 6));
6158 : : }
6159 : : /* static analysis guarentees a RETURN statement will be used before here. */
6160 : : __builtin_unreachable ();
6161 : : }
6162 : :
6163 : :
6164 : : /*
6165 : : GetProtection - returns the PROTECTION data type.
6166 : : */
6167 : :
6168 : 420 : static unsigned int GetProtection (unsigned int tok)
6169 : : {
6170 : 420 : if (M2Options_Iso)
6171 : : {
6172 : 0 : return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "PROTECTION", 10), NameKey_MakeKey ((const char *) "COROUTINES", 10));
6173 : : }
6174 : : else
6175 : : {
6176 : 420 : return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "PROTECTION", 10), NameKey_MakeKey ((const char *) "SYSTEM", 6));
6177 : : }
6178 : : /* static analysis guarentees a RETURN statement will be used before here. */
6179 : : __builtin_unreachable ();
6180 : : }
6181 : :
6182 : :
6183 : : /*
6184 : : CheckNeedPriorityBegin - checks to see whether we need to save the old
6185 : : module priority and change to another module
6186 : : priority.
6187 : : The current module initialization or procedure
6188 : : being built is defined by, scope. The module whose
6189 : : priority will be used is defined by, module.
6190 : : */
6191 : :
6192 : 136619 : static void CheckNeedPriorityBegin (unsigned int tok, unsigned int scope, unsigned int module)
6193 : : {
6194 : 136619 : unsigned int ProcSym;
6195 : 136619 : unsigned int old;
6196 : :
6197 : 136619 : if ((SymbolTable_GetPriority (module)) != SymbolTable_NulSym)
6198 : : {
6199 : : /* module has been given a priority */
6200 : 420 : ProcSym = GetTurnInterrupts (tok);
6201 : 420 : if (ProcSym != SymbolTable_NulSym)
6202 : : {
6203 : 420 : old = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
6204 : 420 : SymbolTable_PutVar (old, GetProtection (tok));
6205 : 840 : GenQuadO (tok, M2Quads_SavePriorityOp, old, scope, ProcSym, false);
6206 : 420 : M2StackWord_PushWord (PriorityStack, old);
6207 : : }
6208 : : }
6209 : 136619 : }
6210 : :
6211 : :
6212 : : /*
6213 : : CheckNeedPriorityEnd - checks to see whether we need to restore the old
6214 : : module priority.
6215 : : The current module initialization or procedure
6216 : : being built is defined by, scope.
6217 : : */
6218 : :
6219 : 136541 : static void CheckNeedPriorityEnd (unsigned int tok, unsigned int scope, unsigned int module)
6220 : : {
6221 : 136541 : unsigned int ProcSym;
6222 : 136541 : unsigned int old;
6223 : :
6224 : 136541 : if ((SymbolTable_GetPriority (module)) != SymbolTable_NulSym)
6225 : : {
6226 : : /* module has been given a priority */
6227 : 420 : ProcSym = GetTurnInterrupts (tok);
6228 : 420 : if (ProcSym != SymbolTable_NulSym)
6229 : : {
6230 : 420 : old = static_cast<unsigned int> (M2StackWord_PopWord (PriorityStack));
6231 : 420 : GenQuad (M2Quads_RestorePriorityOp, old, scope, ProcSym);
6232 : : }
6233 : : }
6234 : 136541 : }
6235 : :
6236 : :
6237 : : /*
6238 : : BuildRTExceptEnter - informs RTExceptions that we are about to enter the except state.
6239 : : */
6240 : :
6241 : 2558 : static void BuildRTExceptEnter (unsigned int tok)
6242 : : {
6243 : 2558 : unsigned int old;
6244 : 2558 : unsigned int ProcSym;
6245 : :
6246 : 2558 : if (M2Options_Exceptions)
6247 : : {
6248 : : /* now inform the Modula-2 runtime we are in the exception state */
6249 : 2558 : ProcSym = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "SetExceptionState", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
6250 : 2558 : if (ProcSym == SymbolTable_NulSym)
6251 : : {
6252 : 0 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%W}no procedure SetExceptionState found in RTExceptions which is needed to implement exception handling", 104);
6253 : : }
6254 : : else
6255 : : {
6256 : 2558 : old = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
6257 : 2558 : SymbolTable_PutVar (old, M2Base_Boolean);
6258 : 5116 : GenQuadO (tok, M2Quads_SaveExceptionOp, old, SymbolTable_NulSym, ProcSym, false);
6259 : 2558 : M2StackWord_PushWord (ExceptStack, old);
6260 : : }
6261 : : }
6262 : : else
6263 : : {
6264 : 0 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}cannot use {%kEXCEPT} blocks with the -fno-exceptions flag", 62);
6265 : : }
6266 : 2558 : }
6267 : :
6268 : :
6269 : : /*
6270 : : BuildRTExceptLeave - informs RTExceptions that we are about to leave the except state.
6271 : : If, destroy, is TRUE then pop the ExceptStack.
6272 : : */
6273 : :
6274 : 2672 : static void BuildRTExceptLeave (unsigned int tok, bool destroy)
6275 : : {
6276 : 2672 : unsigned int old;
6277 : 2672 : unsigned int ProcSym;
6278 : :
6279 : 2672 : if (M2Options_Exceptions)
6280 : : {
6281 : : /* avoid dangling else. */
6282 : : /* now inform the Modula-2 runtime we are in the exception state */
6283 : 2672 : ProcSym = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "SetExceptionState", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
6284 : 2672 : if (ProcSym != SymbolTable_NulSym)
6285 : : {
6286 : 2672 : if (destroy)
6287 : : {
6288 : 2558 : old = static_cast<unsigned int> (M2StackWord_PopWord (ExceptStack));
6289 : : }
6290 : : else
6291 : : {
6292 : 114 : old = static_cast<unsigned int> (M2StackWord_PeepWord (ExceptStack, 1));
6293 : : }
6294 : 2672 : GenQuadO (tok, M2Quads_RestoreExceptionOp, old, SymbolTable_NulSym, ProcSym, false);
6295 : : }
6296 : : }
6297 : : /* no need for an error message here as it will be generated in the Enter procedure above */
6298 : 2672 : }
6299 : :
6300 : :
6301 : : /*
6302 : : SafeRequestSym - only used during scaffold to get argc, argv, envp.
6303 : : It attempts to get symbol name from the current scope(s) and if
6304 : : it fails then it falls back onto default constants.
6305 : : */
6306 : :
6307 : 14268 : static unsigned int SafeRequestSym (unsigned int tok, NameKey_Name name)
6308 : : {
6309 : 14268 : unsigned int sym;
6310 : :
6311 : 14268 : sym = SymbolTable_GetSym (name);
6312 : 14268 : if (sym == SymbolTable_NulSym)
6313 : : {
6314 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
6315 : 0 : if (name == (NameKey_MakeKey ((const char *) "argc", 4)))
6316 : : {
6317 : 0 : return SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType);
6318 : : }
6319 : 0 : else if ((name == (NameKey_MakeKey ((const char *) "argv", 4))) || (name == (NameKey_MakeKey ((const char *) "envp", 4))))
6320 : : {
6321 : : /* avoid dangling else. */
6322 : 0 : return M2Base_Nil;
6323 : : }
6324 : : else
6325 : : {
6326 : : /* avoid dangling else. */
6327 : 0 : M2Error_InternalError ((const char *) "not expecting this parameter name", 33);
6328 : : return M2Base_Nil;
6329 : : }
6330 : : }
6331 : : return sym;
6332 : : /* static analysis guarentees a RETURN statement will be used before here. */
6333 : : __builtin_unreachable ();
6334 : : }
6335 : :
6336 : :
6337 : : /*
6338 : : callRequestDependant - create a call:
6339 : : RequestDependant (GetSymName (modulesym), GetLibName (modulesym),
6340 : : GetSymName (depModuleSym), GetLibName (depModuleSym));
6341 : : */
6342 : :
6343 : 32772 : static void callRequestDependant (unsigned int tokno, unsigned int moduleSym, unsigned int depModuleSym, unsigned int requestDep)
6344 : : {
6345 : 32772 : M2Debug_Assert (requestDep != SymbolTable_NulSym);
6346 : 32772 : M2Quads_PushTtok (requestDep, tokno);
6347 : 32772 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
6348 : 32772 : M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetSymName (moduleSym)), tokno);
6349 : 32772 : M2Quads_PushT (static_cast<unsigned int> (1));
6350 : 32772 : BuildAdrFunction ();
6351 : 32772 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
6352 : 32772 : M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetLibName (moduleSym)), tokno);
6353 : 32772 : M2Quads_PushT (static_cast<unsigned int> (1));
6354 : 32772 : BuildAdrFunction ();
6355 : 32772 : if (depModuleSym == SymbolTable_NulSym)
6356 : : {
6357 : 13138 : M2Quads_PushTF (M2Base_Nil, M2System_Address);
6358 : 13138 : M2Quads_PushTF (M2Base_Nil, M2System_Address);
6359 : : }
6360 : : else
6361 : : {
6362 : 19634 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
6363 : 19634 : M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetSymName (depModuleSym)), tokno);
6364 : 19634 : M2Quads_PushT (static_cast<unsigned int> (1));
6365 : 19634 : BuildAdrFunction ();
6366 : 19634 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
6367 : 19634 : M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetLibName (depModuleSym)), tokno);
6368 : 19634 : M2Quads_PushT (static_cast<unsigned int> (1));
6369 : 19634 : BuildAdrFunction ();
6370 : : }
6371 : 32772 : M2Quads_PushT (static_cast<unsigned int> (4));
6372 : 32772 : M2Quads_BuildProcedureCall (tokno);
6373 : 32772 : }
6374 : :
6375 : :
6376 : : /*
6377 : : ForeachImportInDepDo -
6378 : : */
6379 : :
6380 : 26276 : static void ForeachImportInDepDo (Lists_List importStatements, unsigned int moduleSym, unsigned int requestDep)
6381 : : {
6382 : 26276 : unsigned int i;
6383 : 26276 : unsigned int j;
6384 : 26276 : unsigned int m;
6385 : 26276 : unsigned int n;
6386 : 26276 : unsigned int imported;
6387 : 26276 : unsigned int stmt;
6388 : 26276 : Lists_List l;
6389 : :
6390 : 26276 : if (importStatements != NULL)
6391 : : {
6392 : 15994 : i = 1;
6393 : 15994 : n = Lists_NoOfItemsInList (importStatements);
6394 : 51168 : while (i <= n)
6395 : : {
6396 : 19180 : stmt = static_cast<unsigned int> (Lists_GetItemFromList (importStatements, i));
6397 : 19180 : M2Debug_Assert (SymbolTable_IsImportStatement (stmt));
6398 : 19180 : l = SymbolTable_GetImportStatementList (stmt);
6399 : 19180 : j = 1;
6400 : 19180 : m = Lists_NoOfItemsInList (l);
6401 : 57994 : while (j <= m)
6402 : : {
6403 : 19634 : imported = static_cast<unsigned int> (Lists_GetItemFromList (l, j));
6404 : 19634 : M2Debug_Assert (SymbolTable_IsImport (imported));
6405 : 19634 : callRequestDependant (SymbolTable_GetImportDeclared (imported), moduleSym, SymbolTable_GetImportModule (imported), requestDep);
6406 : 19634 : j += 1;
6407 : : }
6408 : 19180 : i += 1;
6409 : : }
6410 : : }
6411 : 26276 : }
6412 : :
6413 : :
6414 : : /*
6415 : : ForeachImportedModuleDo -
6416 : : */
6417 : :
6418 : 13138 : static void ForeachImportedModuleDo (unsigned int moduleSym, unsigned int requestDep)
6419 : : {
6420 : 13138 : Lists_List importStatements;
6421 : :
6422 : 13138 : importStatements = SymbolTable_GetModuleModImportStatementList (moduleSym);
6423 : 13138 : ForeachImportInDepDo (importStatements, moduleSym, requestDep);
6424 : 13138 : importStatements = SymbolTable_GetModuleDefImportStatementList (moduleSym);
6425 : 13138 : ForeachImportInDepDo (importStatements, moduleSym, requestDep);
6426 : 13138 : }
6427 : :
6428 : :
6429 : : /*
6430 : : BuildM2DepFunction - creates the dependency graph procedure using IR:
6431 : : static void
6432 : : dependencies (void)
6433 : : {
6434 : : M2RTS_RequestDependant (module_name, libname, "b", "b libname");
6435 : : M2RTS_RequestDependant (module_name, libname, NULL, NULL);
6436 : : }
6437 : : */
6438 : :
6439 : 13180 : static void BuildM2DepFunction (unsigned int tokno, unsigned int moduleSym)
6440 : : {
6441 : 13180 : unsigned int requestDep;
6442 : 13180 : unsigned int ctor;
6443 : 13180 : unsigned int init;
6444 : 13180 : unsigned int fini;
6445 : 13180 : unsigned int dep;
6446 : :
6447 : 13180 : if (M2Options_ScaffoldDynamic)
6448 : : {
6449 : : /* Scaffold required and dynamic dependency graph should be produced. */
6450 : 13138 : SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
6451 : 13138 : M2Quads_PushT (dep);
6452 : 13138 : M2Quads_BuildProcedureStart ();
6453 : 13138 : M2Quads_BuildProcedureBegin ();
6454 : 13138 : SymbolTable_StartScope (dep);
6455 : 13138 : requestDep = GetQualidentImport (tokno, NameKey_MakeKey ((const char *) "RequestDependant", 16), NameKey_MakeKey ((const char *) "M2RTS", 5));
6456 : 13138 : if (requestDep != SymbolTable_NulSym)
6457 : : {
6458 : 13138 : ForeachImportedModuleDo (moduleSym, requestDep);
6459 : 13138 : callRequestDependant (tokno, moduleSym, SymbolTable_NulSym, requestDep);
6460 : : }
6461 : 13138 : SymbolTable_EndScope ();
6462 : 13138 : M2Quads_BuildProcedureEnd ();
6463 : 13138 : M2Quads_PopN (1);
6464 : : }
6465 : 13180 : }
6466 : :
6467 : :
6468 : : /*
6469 : : BuildM2LinkFunction - creates the _M2_link procedure which will
6470 : : cause the linker to pull in all the module ctors.
6471 : : */
6472 : :
6473 : 2412 : static void BuildM2LinkFunction (unsigned int tokno)
6474 : : {
6475 : 2412 : if (M2Options_ScaffoldDynamic)
6476 : : {
6477 : 2378 : if (M2Scaffold_linkFunction != SymbolTable_NulSym)
6478 : : {
6479 : : /* void
6480 : : _M2_link (void)
6481 : : {
6482 : : for each module in uselist do
6483 : : PROC foo_%d = _M2_module_ctor
6484 : : done
6485 : : }. */
6486 : 2378 : M2Quads_PushT (M2Scaffold_linkFunction);
6487 : 2378 : M2Quads_BuildProcedureStart ();
6488 : 2378 : M2Quads_BuildProcedureBegin ();
6489 : 2378 : SymbolTable_StartScope (M2Scaffold_linkFunction);
6490 : 2378 : M2Scaffold_PopulateCtorArray (tokno);
6491 : 2378 : SymbolTable_EndScope ();
6492 : 2378 : M2Quads_BuildProcedureEnd ();
6493 : 2378 : M2Quads_PopN (1);
6494 : : }
6495 : : }
6496 : 2412 : }
6497 : :
6498 : :
6499 : : /*
6500 : : BuildTry - build the try statement for main.
6501 : : */
6502 : :
6503 : 2378 : static void BuildTry (unsigned int tokno)
6504 : : {
6505 : 2378 : if (M2Options_Exceptions)
6506 : : {
6507 : 2378 : M2StackWord_PushWord (TryStack, NextQuad);
6508 : 2378 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
6509 : 2378 : GenQuadO (tokno, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
6510 : : }
6511 : 2378 : }
6512 : :
6513 : :
6514 : : /*
6515 : : BuildExcept - build the except block for main.
6516 : : */
6517 : :
6518 : 2378 : static void BuildExcept (unsigned int tokno)
6519 : : {
6520 : 2378 : unsigned int catchProcedure;
6521 : :
6522 : 2378 : if (M2Options_Exceptions)
6523 : : {
6524 : 2378 : M2Quads_BuildExceptInitial (tokno);
6525 : 2378 : catchProcedure = GetQualidentImport (tokno, NameKey_MakeKey ((const char *) "DefaultErrorCatch", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
6526 : 2378 : if (catchProcedure != SymbolTable_NulSym)
6527 : : {
6528 : 2378 : M2Quads_PushTtok (catchProcedure, tokno);
6529 : 2378 : M2Quads_PushT (static_cast<unsigned int> (0));
6530 : 2378 : M2Quads_BuildProcedureCall (tokno);
6531 : : }
6532 : 2378 : BuildRTExceptLeave (tokno, true);
6533 : 2378 : GenQuadO (tokno, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
6534 : : }
6535 : 2378 : }
6536 : :
6537 : :
6538 : : /*
6539 : : BuildM2MainFunction - creates the main function with appropriate calls to the scaffold.
6540 : : */
6541 : :
6542 : 2412 : static void BuildM2MainFunction (unsigned int tokno)
6543 : : {
6544 : 2412 : if ((M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic) && ! M2Options_SharedFlag)
6545 : : {
6546 : : /*
6547 : : int
6548 : : main (int argc, char *argv[], char *envp[])
6549 : : {
6550 : : try {
6551 : : _M2_init (argc, argv, envp);
6552 : : _M2_fini (argc, argv, envp);
6553 : : return 0;
6554 : : }
6555 : : catch (...) {
6556 : : RTExceptions_DefaultErrorCatch ();
6557 : : return 0;
6558 : : }
6559 : : }
6560 : : */
6561 : 2378 : M2Quads_PushT (M2Scaffold_mainFunction);
6562 : 2378 : M2Quads_BuildProcedureStart ();
6563 : 2378 : M2Quads_BuildProcedureBegin ();
6564 : 2378 : SymbolTable_StartScope (M2Scaffold_mainFunction);
6565 : 2378 : BuildTry (tokno);
6566 : : /* _M2_init (argc, argv, envp); */
6567 : 2378 : M2Quads_PushTtok (M2Scaffold_initFunction, tokno);
6568 : 2378 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argc", 4)), tokno);
6569 : 2378 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argv", 4)), tokno);
6570 : 2378 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "envp", 4)), tokno);
6571 : 2378 : M2Quads_PushT (static_cast<unsigned int> (3));
6572 : 2378 : M2Quads_BuildProcedureCall (tokno);
6573 : : /* _M2_fini (argc, argv, envp); */
6574 : 2378 : M2Quads_PushTtok (M2Scaffold_finiFunction, tokno);
6575 : 2378 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argc", 4)), tokno);
6576 : 2378 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argv", 4)), tokno);
6577 : 2378 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "envp", 4)), tokno);
6578 : 2378 : M2Quads_PushT (static_cast<unsigned int> (3));
6579 : 2378 : M2Quads_BuildProcedureCall (tokno);
6580 : 2378 : PushZero (tokno, M2Base_Integer);
6581 : 2378 : M2Quads_BuildReturn (tokno);
6582 : 2378 : BuildExcept (tokno);
6583 : 2378 : PushZero (tokno, M2Base_Integer);
6584 : 2378 : M2Quads_BuildReturn (tokno);
6585 : 2378 : SymbolTable_EndScope ();
6586 : 2378 : M2Quads_BuildProcedureEnd ();
6587 : 2378 : M2Quads_PopN (1);
6588 : : }
6589 : 2412 : }
6590 : :
6591 : :
6592 : : /*
6593 : : DeferMakeConstStringCnul - return a C const string which will be nul terminated.
6594 : : */
6595 : :
6596 : 6967 : static unsigned int DeferMakeConstStringCnul (unsigned int tok, unsigned int sym)
6597 : : {
6598 : 6967 : unsigned int const_;
6599 : :
6600 : 6967 : const_ = SymbolTable_MakeConstStringCnul (tok, NameKey_NulName, false);
6601 : 13934 : GenQuadO (tok, M2Quads_StringConvertCnulOp, const_, 0, sym, false);
6602 : 6967 : return const_;
6603 : : /* static analysis guarentees a RETURN statement will be used before here. */
6604 : : __builtin_unreachable ();
6605 : : }
6606 : :
6607 : :
6608 : : /*
6609 : : DeferMakeConstStringM2nul - return a const string which will be nul terminated.
6610 : : */
6611 : :
6612 : 29066 : static unsigned int DeferMakeConstStringM2nul (unsigned int tok, unsigned int sym)
6613 : : {
6614 : 29066 : unsigned int const_;
6615 : :
6616 : 29066 : const_ = SymbolTable_MakeConstStringM2nul (tok, NameKey_NulName, false);
6617 : 58132 : GenQuadO (tok, M2Quads_StringConvertM2nulOp, const_, 0, sym, false);
6618 : 29066 : return const_;
6619 : : /* static analysis guarentees a RETURN statement will be used before here. */
6620 : : __builtin_unreachable ();
6621 : : }
6622 : :
6623 : :
6624 : : /*
6625 : : BuildStringAdrParam - push the address of a nul terminated string onto the quad stack.
6626 : : */
6627 : :
6628 : 7134 : static void BuildStringAdrParam (unsigned int tok, NameKey_Name name)
6629 : : {
6630 : 7134 : unsigned int str;
6631 : 7134 : unsigned int m2strnul;
6632 : :
6633 : 7134 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6634 : 7134 : str = SymbolTable_MakeConstString (tok, name);
6635 : 7134 : SymbolTable_PutConstStringKnown (tok, str, name, false, true);
6636 : 7134 : m2strnul = DeferMakeConstStringM2nul (tok, str);
6637 : 7134 : M2Quads_PushTtok (m2strnul, tok);
6638 : 7134 : M2Quads_PushT (static_cast<unsigned int> (1));
6639 : 7134 : BuildAdrFunction ();
6640 : 7134 : }
6641 : :
6642 : :
6643 : : /*
6644 : : BuildM2InitFunction -
6645 : : */
6646 : :
6647 : 2412 : static void BuildM2InitFunction (unsigned int tok, unsigned int moduleSym)
6648 : : {
6649 : 2412 : unsigned int constructModules;
6650 : :
6651 : 2412 : if (M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic)
6652 : : {
6653 : : /* int
6654 : : _M2_init (int argc, char *argv[], char *envp[])
6655 : : {
6656 : : M2RTS_ConstructModules (module_name, libname,
6657 : : overrideliborder, argc, argv, envp);
6658 : : } */
6659 : 2378 : M2Quads_PushT (M2Scaffold_initFunction);
6660 : 2378 : M2Quads_BuildProcedureStart ();
6661 : 2378 : M2Quads_BuildProcedureBegin ();
6662 : 2378 : SymbolTable_StartScope (M2Scaffold_initFunction);
6663 : 2378 : if (M2Options_ScaffoldDynamic)
6664 : : {
6665 : : /* avoid dangling else. */
6666 : 2378 : if (M2Scaffold_linkFunction != SymbolTable_NulSym)
6667 : : {
6668 : : /* _M2_link (); */
6669 : 2378 : M2Quads_PushTtok (M2Scaffold_linkFunction, tok);
6670 : 2378 : M2Quads_PushT (static_cast<unsigned int> (0));
6671 : 2378 : M2Quads_BuildProcedureCall (tok);
6672 : : }
6673 : : /* Lookup ConstructModules and call it. */
6674 : 2378 : constructModules = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "ConstructModules", 16), NameKey_MakeKey ((const char *) "M2RTS", 5));
6675 : 2378 : if (constructModules != SymbolTable_NulSym)
6676 : : {
6677 : : /* ConstructModules (module_name, argc, argv, envp); */
6678 : 2378 : M2Quads_PushTtok (constructModules, tok);
6679 : 2378 : BuildStringAdrParam (tok, SymbolTable_GetSymName (moduleSym));
6680 : 2378 : BuildStringAdrParam (tok, SymbolTable_GetLibName (moduleSym));
6681 : 2378 : BuildStringAdrParam (tok, NameKey_makekey (M2Options_GetRuntimeModuleOverride ()));
6682 : 2378 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argc", 4)), tok);
6683 : 2378 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argv", 4)), tok);
6684 : 2378 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "envp", 4)), tok);
6685 : 2378 : M2Quads_PushT (static_cast<unsigned int> (6));
6686 : 2378 : M2Quads_BuildProcedureCall (tok);
6687 : : }
6688 : : }
6689 : 0 : else if (M2Options_ScaffoldStatic)
6690 : : {
6691 : : /* avoid dangling else. */
6692 : 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)));
6693 : : }
6694 : 2378 : SymbolTable_EndScope ();
6695 : 2378 : M2Quads_BuildProcedureEnd ();
6696 : 2378 : M2Quads_PopN (1);
6697 : : }
6698 : 2412 : }
6699 : :
6700 : :
6701 : : /*
6702 : : BuildM2FiniFunction -
6703 : : */
6704 : :
6705 : 2412 : static void BuildM2FiniFunction (unsigned int tok, unsigned int moduleSym)
6706 : : {
6707 : 2412 : unsigned int deconstructModules;
6708 : :
6709 : 2412 : if (M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic)
6710 : : {
6711 : : /* Scaffold required and main should be produced. */
6712 : 2378 : M2Quads_PushT (M2Scaffold_finiFunction);
6713 : 2378 : M2Quads_BuildProcedureStart ();
6714 : 2378 : M2Quads_BuildProcedureBegin ();
6715 : 2378 : SymbolTable_StartScope (M2Scaffold_finiFunction);
6716 : 2378 : if (M2Options_ScaffoldDynamic)
6717 : : {
6718 : : /* avoid dangling else. */
6719 : : /* static void
6720 : : _M2_finish (int argc, char *argv[], char *envp[])
6721 : : {
6722 : : M2RTS_DeconstructModules (module_name, argc, argv, envp);
6723 : : } */
6724 : 2378 : deconstructModules = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "DeconstructModules", 18), NameKey_MakeKey ((const char *) "M2RTS", 5));
6725 : 2378 : if (deconstructModules != SymbolTable_NulSym)
6726 : : {
6727 : : /* DeconstructModules (module_name, argc, argv, envp); */
6728 : 2378 : M2Quads_PushTtok (deconstructModules, tok);
6729 : 2378 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6730 : 2378 : M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetSymName (moduleSym)), tok);
6731 : 2378 : M2Quads_PushT (static_cast<unsigned int> (1));
6732 : 2378 : BuildAdrFunction ();
6733 : 2378 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6734 : 2378 : M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetLibName (moduleSym)), tok);
6735 : 2378 : M2Quads_PushT (static_cast<unsigned int> (1));
6736 : 2378 : BuildAdrFunction ();
6737 : 2378 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argc", 4)), tok);
6738 : 2378 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argv", 4)), tok);
6739 : 2378 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "envp", 4)), tok);
6740 : 2378 : M2Quads_PushT (static_cast<unsigned int> (5));
6741 : 2378 : M2Quads_BuildProcedureCall (tok);
6742 : : }
6743 : : }
6744 : 0 : else if (M2Options_ScaffoldStatic)
6745 : : {
6746 : : /* avoid dangling else. */
6747 : 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)));
6748 : : }
6749 : 2378 : SymbolTable_EndScope ();
6750 : 2378 : M2Quads_BuildProcedureEnd ();
6751 : 2378 : M2Quads_PopN (1);
6752 : : }
6753 : 2412 : }
6754 : :
6755 : :
6756 : : /*
6757 : : BuildM2CtorFunction - create a constructor function associated with moduleSym.
6758 : :
6759 : : void
6760 : : ctorFunction ()
6761 : : {
6762 : : M2RTS_RegisterModule (GetSymName (moduleSym), GetLibName (moduleSym),
6763 : : init, fini, dependencies);
6764 : : }
6765 : : */
6766 : :
6767 : 13180 : static void BuildM2CtorFunction (unsigned int tok, unsigned int moduleSym)
6768 : : {
6769 : 13180 : unsigned int RegisterModule;
6770 : 13180 : unsigned int ctor;
6771 : 13180 : unsigned int init;
6772 : 13180 : unsigned int fini;
6773 : 13180 : unsigned int dep;
6774 : :
6775 : 13180 : if (M2Options_ScaffoldDynamic)
6776 : : {
6777 : 13138 : SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
6778 : 13138 : if (ctor != SymbolTable_NulSym)
6779 : : {
6780 : 13138 : M2Debug_Assert (SymbolTable_IsProcedure (ctor));
6781 : 13138 : M2Quads_PushT (ctor);
6782 : 13138 : M2Quads_BuildProcedureStart ();
6783 : 13138 : M2Quads_BuildProcedureBegin ();
6784 : 13138 : SymbolTable_StartScope (ctor);
6785 : 13138 : RegisterModule = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "RegisterModule", 14), NameKey_MakeKey ((const char *) "M2RTS", 5));
6786 : 13138 : if (RegisterModule != SymbolTable_NulSym)
6787 : : {
6788 : : /* RegisterModule (module_name, init, fini, dependencies); */
6789 : 13138 : M2Quads_PushTtok (RegisterModule, tok);
6790 : 13138 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6791 : 13138 : M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetSymName (moduleSym)), tok);
6792 : 13138 : M2Quads_PushT (static_cast<unsigned int> (1));
6793 : 13138 : BuildAdrFunction ();
6794 : 13138 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6795 : 13138 : M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetLibName (moduleSym)), tok);
6796 : 13138 : M2Quads_PushT (static_cast<unsigned int> (1));
6797 : 13138 : BuildAdrFunction ();
6798 : 13138 : M2Quads_PushTtok (init, tok);
6799 : 13138 : M2Quads_PushTtok (fini, tok);
6800 : 13138 : M2Quads_PushTtok (dep, tok);
6801 : 13138 : M2Quads_PushT (static_cast<unsigned int> (5));
6802 : 13138 : M2Quads_BuildProcedureCall (tok);
6803 : : }
6804 : 13138 : SymbolTable_EndScope ();
6805 : 13138 : M2Quads_BuildProcedureEnd ();
6806 : 13138 : M2Quads_PopN (1);
6807 : : }
6808 : : }
6809 : 13180 : }
6810 : :
6811 : :
6812 : : /*
6813 : : AddForInfo - adds the description of the FOR loop into the record list.
6814 : : This is used if -pedantic is turned on to check index variable
6815 : : usage.
6816 : : */
6817 : :
6818 : 1852 : static void AddForInfo (unsigned int Start, unsigned int End, unsigned int IncQuad, unsigned int Sym, unsigned int idtok)
6819 : : {
6820 : 1852 : M2Quads_ForLoopInfo forDesc;
6821 : :
6822 : 1852 : if (M2Options_Pedantic)
6823 : : {
6824 : 0 : Storage_ALLOCATE ((void **) &forDesc, sizeof (M2Quads__T5));
6825 : 0 : forDesc->IncrementQuad = IncQuad;
6826 : 0 : forDesc->StartOfForLoop = Start;
6827 : 0 : forDesc->EndOfForLoop = End;
6828 : 0 : forDesc->ForLoopIndex = Sym;
6829 : 0 : forDesc->IndexTok = idtok;
6830 : 0 : Indexing_IncludeIndiceIntoIndex (ForInfo, reinterpret_cast<void *> (forDesc));
6831 : : }
6832 : 1852 : }
6833 : :
6834 : :
6835 : : /*
6836 : : CheckForIndex - checks the quadruples: Start..End to see whether a
6837 : : for loop index is manipulated by the programmer.
6838 : : It generates a warning if this is the case.
6839 : : It also checks to see whether the IndexSym is read
6840 : : immediately outside the loop in which case a warning
6841 : : is issued.
6842 : : */
6843 : :
6844 : 0 : static void CheckForIndex (M2Quads_ForLoopInfo forDesc)
6845 : : {
6846 : 0 : unsigned int ReadStart;
6847 : 0 : unsigned int ReadEnd;
6848 : 0 : unsigned int WriteStart;
6849 : 0 : unsigned int WriteEnd;
6850 : :
6851 : 0 : SymbolTable_GetWriteLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->StartOfForLoop, forDesc->EndOfForLoop, &WriteStart, &WriteEnd);
6852 : 0 : if ((WriteStart < forDesc->IncrementQuad) && (WriteStart > forDesc->StartOfForLoop))
6853 : : {
6854 : 0 : M2MetaError_MetaErrorT1 (forDesc->IndexTok, (const char *) "{%kFOR} loop index variable {%1Wad} is being manipulated inside the loop", 72, forDesc->ForLoopIndex);
6855 : 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);
6856 : : }
6857 : 0 : SymbolTable_GetWriteLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->EndOfForLoop, 0, &WriteStart, &WriteEnd);
6858 : 0 : SymbolTable_GetReadLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->EndOfForLoop, 0, &ReadStart, &ReadEnd);
6859 : 0 : if ((ReadStart != 0) && ((ReadStart < WriteStart) || (WriteStart == 0)))
6860 : : {
6861 : 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);
6862 : 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);
6863 : : }
6864 : 0 : }
6865 : :
6866 : :
6867 : : /*
6868 : : BuildRange - generates a RangeCheckOp quad with, r, as its operand.
6869 : : */
6870 : :
6871 : 1219091 : static void BuildRange (unsigned int r)
6872 : : {
6873 : 1219091 : GenQuad (M2Quads_RangeCheckOp, (unsigned int ) (M2LexBuf_GetLineNo ()), SymbolTable_NulSym, r);
6874 : 1219091 : }
6875 : :
6876 : :
6877 : : /*
6878 : : BuildError - generates a ErrorOp quad, indicating that if this
6879 : : quadruple is reachable, then a runtime error would
6880 : : occur.
6881 : : */
6882 : :
6883 : 11861 : static void BuildError (unsigned int r)
6884 : : {
6885 : 11861 : GenQuad (M2Quads_ErrorOp, (unsigned int ) (M2LexBuf_GetLineNo ()), SymbolTable_NulSym, r);
6886 : 11861 : }
6887 : :
6888 : :
6889 : : /*
6890 : : CheckPointerThroughNil - builds a range quadruple, providing, sym, is
6891 : : a candidate for checking against NIL.
6892 : : This range quadruple is only expanded into
6893 : : code during the code generation phase
6894 : : thus allowing limited compile time checking.
6895 : : */
6896 : :
6897 : 59950 : static void CheckPointerThroughNil (unsigned int tokpos, unsigned int sym)
6898 : : {
6899 : 59950 : if ((SymbolTable_IsVar (sym)) && (SymbolTable_GetVarPointerCheck (sym)))
6900 : : {
6901 : : /* PutVarPointerCheck(sym, FALSE) ; so we do not detect this again */
6902 : 15922 : BuildRange (M2Range_InitPointerRangeCheck (tokpos, sym, (SymbolTable_GetMode (sym)) == SymbolTable_LeftValue));
6903 : : }
6904 : 59950 : }
6905 : :
6906 : :
6907 : : /*
6908 : : CollectLow - returns the low of the subrange value.
6909 : : */
6910 : :
6911 : 234 : static unsigned int CollectLow (unsigned int sym)
6912 : : {
6913 : 234 : unsigned int low;
6914 : 234 : unsigned int high;
6915 : :
6916 : 234 : if (SymbolTable_IsSubrange (sym))
6917 : : {
6918 : 234 : SymbolTable_GetSubrange (sym, &high, &low);
6919 : 234 : return low;
6920 : : }
6921 : : else
6922 : : {
6923 : 0 : M2Error_InternalError ((const char *) "expecting Subrange symbol", 25);
6924 : : }
6925 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
6926 : : __builtin_unreachable ();
6927 : : }
6928 : :
6929 : :
6930 : : /*
6931 : : CollectHigh - returns the high of the subrange value, sym.
6932 : : */
6933 : :
6934 : 2882 : static unsigned int CollectHigh (unsigned int sym)
6935 : : {
6936 : 2882 : unsigned int low;
6937 : 2882 : unsigned int high;
6938 : :
6939 : 2882 : if (SymbolTable_IsSubrange (sym))
6940 : : {
6941 : 2882 : SymbolTable_GetSubrange (sym, &high, &low);
6942 : 2882 : return high;
6943 : : }
6944 : : else
6945 : : {
6946 : 0 : M2Error_InternalError ((const char *) "expecting Subrange symbol", 25);
6947 : : }
6948 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
6949 : : __builtin_unreachable ();
6950 : : }
6951 : :
6952 : :
6953 : : /*
6954 : : CheckCompatibleWithBecomes - checks to see that symbol, sym, is
6955 : : compatible with the := operator.
6956 : : */
6957 : :
6958 : 383175 : static void CheckCompatibleWithBecomes (unsigned int des, unsigned int expr, unsigned int destok, unsigned int exprtok)
6959 : : {
6960 : 383175 : if (SymbolTable_IsType (des))
6961 : : {
6962 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to a type {%1a}", 51, des);
6963 : : }
6964 : 383175 : else if (SymbolTable_IsProcedure (des))
6965 : : {
6966 : : /* avoid dangling else. */
6967 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to a procedure {%1a}", 56, des);
6968 : : }
6969 : 383175 : else if (SymbolTable_IsFieldEnumeration (des))
6970 : : {
6971 : : /* avoid dangling else. */
6972 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to an enumeration field {%1a}", 65, des);
6973 : : }
6974 : 383175 : if ((M2Base_IsPseudoBaseProcedure (expr)) || (M2Base_IsPseudoBaseFunction (expr)))
6975 : : {
6976 : 6 : M2MetaError_MetaErrorT1 (exprtok, (const char *) "an assignment cannot assign a {%1d} {%1a}", 41, expr);
6977 : : }
6978 : 383175 : }
6979 : :
6980 : :
6981 : : /*
6982 : : BuildAssignmentWithoutBounds - calls BuildAssignment but makes sure we do not
6983 : : check bounds.
6984 : : */
6985 : :
6986 : 70171 : static void BuildAssignmentWithoutBounds (unsigned int tok, bool checkTypes, bool checkOverflow)
6987 : : {
6988 : 70171 : bool old;
6989 : :
6990 : 70171 : old = MustNotCheckBounds;
6991 : 70171 : MustNotCheckBounds = true;
6992 : 0 : doBuildAssignment (tok, checkTypes, checkOverflow);
6993 : 70171 : MustNotCheckBounds = old;
6994 : 15585 : }
6995 : :
6996 : :
6997 : : /*
6998 : : MarkArrayWritten - marks, Array, as being written.
6999 : : */
7000 : :
7001 : 82942 : static void MarkArrayWritten (unsigned int Array)
7002 : : {
7003 : 82942 : if ((Array != SymbolTable_NulSym) && (SymbolTable_IsVarAParam (Array)))
7004 : : {
7005 : 11811 : SymbolTable_PutVarWritten (Array, true);
7006 : : }
7007 : 82942 : }
7008 : :
7009 : :
7010 : : /*
7011 : : MarkAsReadWrite - marks the variable or parameter as being
7012 : : read/write.
7013 : : */
7014 : :
7015 : 24659 : static void MarkAsReadWrite (unsigned int sym)
7016 : : {
7017 : 24659 : if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
7018 : : {
7019 : 17692 : SymbolTable_PutReadQuad (sym, SymbolTable_RightValue, NextQuad);
7020 : 17692 : SymbolTable_PutWriteQuad (sym, SymbolTable_RightValue, NextQuad);
7021 : : }
7022 : 24659 : }
7023 : :
7024 : :
7025 : : /*
7026 : : MarkAsRead - marks the variable or parameter as being read.
7027 : : */
7028 : :
7029 : 985719 : static void MarkAsRead (unsigned int sym)
7030 : : {
7031 : 985719 : if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
7032 : : {
7033 : 283026 : SymbolTable_PutReadQuad (sym, SymbolTable_RightValue, NextQuad);
7034 : : }
7035 : 985719 : }
7036 : :
7037 : :
7038 : : /*
7039 : : MarkAsWrite - marks the variable or parameter as being written.
7040 : : */
7041 : :
7042 : 383175 : static void MarkAsWrite (unsigned int sym)
7043 : : {
7044 : 383175 : if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
7045 : : {
7046 : 68123 : SymbolTable_PutWriteQuad (sym, SymbolTable_RightValue, NextQuad);
7047 : : }
7048 : 383175 : }
7049 : :
7050 : :
7051 : : /*
7052 : : doVal - return an expression which is VAL(type, expr). If
7053 : : expr is a constant then return expr.
7054 : : */
7055 : :
7056 : 33564 : static unsigned int doVal (unsigned int type, unsigned int expr)
7057 : : {
7058 : 33564 : if ((! (SymbolTable_IsConst (expr))) && ((SymbolTable_SkipType (type)) != (SymbolTable_GetDType (expr))))
7059 : : {
7060 : 24067 : M2Quads_PushTF (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym));
7061 : 24067 : M2Quads_PushT (SymbolTable_SkipType (type));
7062 : 24067 : M2Quads_PushT (expr);
7063 : 24067 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
7064 : 24067 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
7065 : 24067 : M2Quads_PopT (&expr);
7066 : : }
7067 : 33564 : return expr;
7068 : : /* static analysis guarentees a RETURN statement will be used before here. */
7069 : : __builtin_unreachable ();
7070 : : }
7071 : :
7072 : :
7073 : : /*
7074 : : MoveWithMode -
7075 : : */
7076 : :
7077 : 383175 : static void MoveWithMode (unsigned int tokno, unsigned int Des, unsigned int Exp, unsigned int Array, unsigned int destok, unsigned int exptok, bool checkOverflow)
7078 : : {
7079 : 383175 : unsigned int t;
7080 : :
7081 : 383175 : if ((SymbolTable_IsConstString (Exp)) && (SymbolTable_IsConst (Des)))
7082 : : {
7083 : 1644 : GenQuadOtok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, destok, M2LexBuf_UnknownTokenNo, exptok);
7084 : 822 : SymbolTable_CopyConstString (tokno, Des, Exp);
7085 : : }
7086 : : else
7087 : : {
7088 : 382353 : if ((SymbolTable_GetMode (Des)) == SymbolTable_RightValue)
7089 : : {
7090 : 124274 : if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
7091 : : {
7092 : 1960 : CheckPointerThroughNil (tokno, Exp); /* Des = *Exp */
7093 : 1960 : doIndrX (tokno, Des, Exp); /* Des = *Exp */
7094 : : }
7095 : : else
7096 : : {
7097 : 122314 : GenQuadOtok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, destok, M2LexBuf_UnknownTokenNo, exptok);
7098 : : }
7099 : : }
7100 : 258079 : else if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
7101 : : {
7102 : : /* avoid dangling else. */
7103 : 33422 : MarkArrayWritten (Array);
7104 : 33422 : if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
7105 : : {
7106 : 913 : t = SymbolTable_MakeTemporary (tokno, SymbolTable_RightValue);
7107 : 913 : SymbolTable_PutVar (t, SymbolTable_GetSType (Exp));
7108 : 913 : CheckPointerThroughNil (tokno, Exp);
7109 : 913 : doIndrX (tokno, t, Exp);
7110 : 913 : CheckPointerThroughNil (tokno, Des); /* *Des = Exp */
7111 : 913 : GenQuadO (tokno, M2Quads_XIndrOp, Des, SymbolTable_GetSType (Des), doVal (SymbolTable_GetSType (Des), t), checkOverflow); /* *Des = Exp */
7112 : : }
7113 : : else
7114 : : {
7115 : 32509 : CheckPointerThroughNil (tokno, Des); /* *Des = Exp */
7116 : 32509 : GenQuadO (tokno, M2Quads_XIndrOp, Des, SymbolTable_GetSType (Des), doVal (SymbolTable_GetSType (Des), Exp), checkOverflow); /* *Des = Exp */
7117 : : }
7118 : : }
7119 : : else
7120 : : {
7121 : : /* avoid dangling else. */
7122 : 224657 : GenQuadOtok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, destok, M2LexBuf_UnknownTokenNo, exptok);
7123 : : }
7124 : : }
7125 : 383163 : }
7126 : :
7127 : :
7128 : : /*
7129 : : CheckBecomesMeta - checks to make sure that we are not
7130 : : assigning a variable to a constant.
7131 : : Also check we are not assigning to an
7132 : : unbounded array.
7133 : : */
7134 : :
7135 : 322528 : static void CheckBecomesMeta (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok)
7136 : : {
7137 : 322528 : if ((SymbolTable_IsConst (Des)) && (SymbolTable_IsVar (Exp)))
7138 : : {
7139 : 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);
7140 : : }
7141 : 322528 : if ((((SymbolTable_GetDType (Des)) != SymbolTable_NulSym) && (SymbolTable_IsVar (Des))) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (Des))))
7142 : : {
7143 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "in assignment, cannot assign to an unbounded array {%1ad}", 57, Des);
7144 : : }
7145 : 322528 : if ((((SymbolTable_GetDType (Exp)) != SymbolTable_NulSym) && (SymbolTable_IsVar (Exp))) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (Exp))))
7146 : : {
7147 : 0 : M2MetaError_MetaErrorT1 (exprtok, (const char *) "in assignment, cannot assign from an unbounded array {%1ad}", 59, Exp);
7148 : : }
7149 : 322528 : }
7150 : :
7151 : :
7152 : : /*
7153 : : doBuildAssignment - subsiduary procedure of BuildAssignment.
7154 : : It builds the assignment and optionally
7155 : : checks the types are compatible.
7156 : : */
7157 : :
7158 : 391352 : static void doBuildAssignment (unsigned int becomesTokNo, bool checkTypes, bool checkOverflow)
7159 : : {
7160 : 391352 : unsigned int r;
7161 : 391352 : unsigned int w;
7162 : 391352 : unsigned int t;
7163 : 391352 : unsigned int f;
7164 : 391352 : unsigned int Array;
7165 : 391352 : unsigned int Des;
7166 : 391352 : unsigned int Exp;
7167 : 391352 : unsigned int combinedtok;
7168 : 391352 : unsigned int destok;
7169 : 391352 : unsigned int exptok;
7170 : :
7171 : 391352 : M2Quads_DisplayStack ();
7172 : 391352 : if (IsBoolean (1))
7173 : : {
7174 : 16354 : PopBool (&t, &f);
7175 : 8177 : M2Quads_PopTtok (&Des, &destok);
7176 : : /* Conditional Boolean Assignment. */
7177 : 8177 : BackPatch (t, NextQuad);
7178 : 8177 : if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
7179 : : {
7180 : 31 : CheckPointerThroughNil (destok, Des);
7181 : 31 : GenQuadO (destok, M2Quads_XIndrOp, Des, M2Base_Boolean, M2Base_True, checkOverflow);
7182 : : }
7183 : : else
7184 : : {
7185 : 8146 : GenQuadO (becomesTokNo, M2Quads_BecomesOp, Des, SymbolTable_NulSym, M2Base_True, checkOverflow);
7186 : : }
7187 : 16354 : GenQuadO (destok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, NextQuad+2, checkOverflow);
7188 : 8177 : BackPatch (f, NextQuad);
7189 : 8177 : if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
7190 : : {
7191 : 31 : CheckPointerThroughNil (destok, Des);
7192 : 31 : GenQuadO (destok, M2Quads_XIndrOp, Des, M2Base_Boolean, M2Base_False, checkOverflow);
7193 : : }
7194 : : else
7195 : : {
7196 : 8146 : GenQuadO (becomesTokNo, M2Quads_BecomesOp, Des, SymbolTable_NulSym, M2Base_False, checkOverflow);
7197 : : }
7198 : : }
7199 : : else
7200 : : {
7201 : 383175 : PopTrwtok (&Exp, &r, &exptok);
7202 : 383175 : MarkAsRead (r);
7203 : 383175 : if (Exp == SymbolTable_NulSym)
7204 : : {
7205 : 0 : M2MetaError_MetaError0 ((const char *) "{%E}unknown expression found during assignment", 46);
7206 : 0 : M2Error_FlushErrors ();
7207 : : }
7208 : 383175 : Array = static_cast<unsigned int> (M2Quads_OperandA (1));
7209 : 383175 : PopTrwtok (&Des, &w, &destok);
7210 : 383175 : MarkAsWrite (w);
7211 : 383175 : CheckCompatibleWithBecomes (Des, Exp, destok, exptok);
7212 : 383175 : if (DebugTokPos)
7213 : : {
7214 : : M2MetaError_MetaErrorT1 (becomesTokNo, (const char *) "becomestok {%1Oad}", 18, Des);
7215 : : M2MetaError_MetaErrorT1 (destok, (const char *) "destok {%1Oad}", 14, Des);
7216 : : M2MetaError_MetaErrorT1 (exptok, (const char *) "exptok {%1Oad}", 14, Exp);
7217 : : }
7218 : 383175 : combinedtok = M2LexBuf_MakeVirtualTok (becomesTokNo, destok, exptok);
7219 : 383175 : if (DebugTokPos)
7220 : : {
7221 : : M2MetaError_MetaErrorT1 (combinedtok, (const char *) "combined {%1Oad}", 16, Des);
7222 : : }
7223 : 383175 : if (((SymbolTable_GetSType (Des)) != SymbolTable_NulSym) && (! (SymbolTable_IsSet (SymbolTable_GetDType (Des)))))
7224 : : {
7225 : : /* Tell code generator to test runtime values of assignment so ensure we
7226 : : catch overflow and underflow. */
7227 : 375727 : BuildRange (M2Range_InitAssignmentRangeCheck (combinedtok, Des, Exp, destok, exptok));
7228 : : }
7229 : 383175 : if (checkTypes)
7230 : : {
7231 : 322528 : CheckBecomesMeta (Des, Exp, combinedtok, destok, exptok);
7232 : : }
7233 : : /* Simple assignment. */
7234 : 383175 : MoveWithMode (combinedtok, Des, Exp, Array, destok, exptok, checkOverflow);
7235 : 383163 : if (checkTypes)
7236 : : {
7237 : : /* BuildRange (InitTypesAssignmentCheck (combinedtok, Des, Exp)) ; */
7238 : 322516 : CheckAssignCompatible (Des, Exp, combinedtok, destok, exptok);
7239 : : }
7240 : : }
7241 : 391340 : M2Quads_DisplayStack ();
7242 : 391340 : }
7243 : :
7244 : :
7245 : : /*
7246 : : CheckAssignCompatible - checks to see that an assignment is compatible.
7247 : : It performs limited checking - thorough checking
7248 : : is done in pass 3. But we do what we can here
7249 : : given knowledge so far.
7250 : : */
7251 : :
7252 : 322516 : static void CheckAssignCompatible (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok)
7253 : : {
7254 : 322516 : unsigned int DesT;
7255 : 322516 : unsigned int ExpT;
7256 : 322516 : unsigned int DesL;
7257 : :
7258 : 322516 : DesT = SymbolTable_GetSType (Des);
7259 : 322516 : ExpT = SymbolTable_GetSType (Exp);
7260 : 322516 : DesL = SymbolTable_GetLType (Des);
7261 : 322516 : if (((SymbolTable_IsProcedure (Exp)) && ((DesT != SymbolTable_NulSym) && (! (SymbolTable_IsProcType (DesT))))) && ((DesL != SymbolTable_NulSym) && (! (SymbolTable_IsProcType (DesL)))))
7262 : : {
7263 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "incorrectly assigning a procedure to a designator {%1Ead} (designator is not a procedure type, {%1ast})", 103, Des);
7264 : : }
7265 : : /* We ignore checking of these types in pass 3 - but we do check them thoroughly post pass 3 */
7266 : 322516 : else if ((SymbolTable_IsProcedure (Exp)) && (SymbolTable_IsProcedureNested (Exp)))
7267 : : {
7268 : : /* avoid dangling else. */
7269 : 0 : M2MetaError_MetaErrorT1 (exprtok, (const char *) "cannot call nested procedure {%1Ead} indirectly as the outer scope will not be known", 84, Exp);
7270 : : }
7271 : 322516 : else if (SymbolTable_IsConstString (Exp))
7272 : : {
7273 : : /* avoid dangling else. */
7274 : : }
7275 : 320157 : else if ((DesT != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (DesT)))
7276 : : {
7277 : : /* avoid dangling else. */
7278 : : }
7279 : 320157 : else if ((ExpT != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (ExpT)))
7280 : : {
7281 : : /* avoid dangling else. */
7282 : : }
7283 : 320157 : else if ((DesL != SymbolTable_NulSym) && (SymbolTable_IsArray (DesL)))
7284 : : {
7285 : : /* avoid dangling else. */
7286 : : }
7287 : 319381 : else if (SymbolTable_IsConstructor (Exp))
7288 : : {
7289 : : /* avoid dangling else. */
7290 : 5495 : if (ExpT == SymbolTable_NulSym)
7291 : : {} /* empty. */
7292 : 5455 : else if (((DesT == SymbolTable_NulSym) && (SymbolTable_IsConst (Des))) && ((SymbolTable_IsConstructor (Des)) || (SymbolTable_IsConstSet (Des))))
7293 : : {
7294 : : /* avoid dangling else. */
7295 : 0 : SymbolTable_PutConst (Des, ExpT);
7296 : : }
7297 : 5455 : else if (! (M2Base_IsAssignmentCompatible (DesT, ExpT)))
7298 : : {
7299 : : /* avoid dangling else. */
7300 : 0 : M2MetaError_MetaErrorT1 (combinedtok, (const char *) "constructor expression is not compatible during assignment to {%1Ead}", 69, Des);
7301 : : }
7302 : : }
7303 : 313886 : else if (((DesT != SymbolTable_NulSym) && (SymbolTable_IsSet (DesT))) && (SymbolTable_IsConst (Exp)))
7304 : : {
7305 : : /* avoid dangling else. */
7306 : : }
7307 : 313874 : else if ((((((SymbolTable_IsConst (Exp)) && (ExpT != M2System_Address)) && (! (SymbolTable_IsConst (Des)))) && (DesL != SymbolTable_NulSym)) && ((DesL == M2Base_Cardinal) || (! (SymbolTable_IsSubrange (DesL))))) && (! (SymbolTable_IsEnumeration (DesL))))
7308 : : {
7309 : : /* avoid dangling else. */
7310 : 20296 : if ((M2Base_IsBaseType (DesL)) || (M2System_IsSystemType (DesL)))
7311 : : {
7312 : 20296 : M2Base_CheckAssignmentCompatible (combinedtok, ExpT, DesT);
7313 : : }
7314 : : else
7315 : : {
7316 : 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);
7317 : : }
7318 : : }
7319 : : else
7320 : : {
7321 : : /* avoid dangling else. */
7322 : 293578 : if (((DesT != SymbolTable_NulSym) && (SymbolTable_IsProcType (DesT))) && (SymbolTable_IsProcedure (Exp)))
7323 : : {
7324 : 24342 : DesT = SymbolTable_GetSType (DesT); /* we can at least check RETURN values of procedure variables */
7325 : : /* remember that thorough assignment checking is done post pass 3 */
7326 : 24342 : M2Base_CheckAssignmentCompatible (combinedtok, ExpT, DesT);
7327 : : }
7328 : : }
7329 : 322516 : }
7330 : :
7331 : :
7332 : : /*
7333 : : CheckBooleanId - Checks to see if the top operand is a boolean.
7334 : : If the operand is not a boolean then it is tested
7335 : : with true and a boolean is generated.
7336 : : The Stack:
7337 : :
7338 : :
7339 : : Entry Exit
7340 : : Ptr -> <- Ptr
7341 : : +------------+ +------------+
7342 : : | Sym | | t | f |
7343 : : |------------| |------------|
7344 : :
7345 : : Quadruples
7346 : :
7347 : : q If= Sym True _
7348 : : q+1 GotoOp _ _ _
7349 : : */
7350 : :
7351 : 63586 : static void CheckBooleanId (void)
7352 : : {
7353 : 63586 : unsigned int tok;
7354 : :
7355 : 63586 : if (! (IsBoolean (1)))
7356 : : {
7357 : 12307 : tok = static_cast<unsigned int> (M2Quads_OperandTok (1));
7358 : 12307 : if (SymbolTable_IsVar (M2Quads_OperandT (1)))
7359 : : {
7360 : 11018 : if ((SymbolTable_GetSType (M2Quads_OperandT (1))) != M2Base_Boolean)
7361 : : {
7362 : 0 : M2MetaError_MetaError1 ((const char *) "{%1Ua:is not a boolean expression}''{!%1Ua:boolean expression expected}", 71, M2Quads_OperandT (1));
7363 : : }
7364 : : }
7365 : 12307 : M2Quads_PushT (M2Reserved_EqualTok);
7366 : 12307 : M2Quads_PushT (M2Base_True);
7367 : 12307 : M2Quads_BuildRelOp (tok);
7368 : : }
7369 : 63586 : }
7370 : :
7371 : :
7372 : : /*
7373 : : PushOne - pushes the value one to the stack.
7374 : : The Stack is changed:
7375 : :
7376 : :
7377 : : Entry Exit
7378 : : ===== ====
7379 : :
7380 : : <- Ptr
7381 : : +------------+
7382 : : Ptr -> | 1 | type |
7383 : : |------------|
7384 : : */
7385 : :
7386 : 12465 : static void PushOne (unsigned int tok, unsigned int type, const char *message_, unsigned int _message_high)
7387 : : {
7388 : 12465 : unsigned int const_;
7389 : 12465 : char message[_message_high+1];
7390 : :
7391 : : /* make a local copy of each unbounded array. */
7392 : 12465 : memcpy (message, message_, _message_high+1);
7393 : :
7394 : 12465 : if (type == SymbolTable_NulSym)
7395 : : {
7396 : 76 : const_ = SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), SymbolTable_NulSym);
7397 : 76 : SymbolTable_PutConstLitInternal (const_, true);
7398 : 76 : M2Quads_PushTFtok (const_, static_cast<unsigned int> (SymbolTable_NulSym), tok);
7399 : : }
7400 : 12389 : else if (SymbolTable_IsEnumeration (type))
7401 : : {
7402 : : /* avoid dangling else. */
7403 : 238 : if ((SymbolTable_NoOfElements (type)) == 0)
7404 : : {
7405 : 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);
7406 : 0 : PushZero (tok, type);
7407 : : }
7408 : : else
7409 : : {
7410 : 238 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
7411 : 238 : M2Quads_PushT (type);
7412 : 238 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_ZType), M2Base_ZType, tok);
7413 : 238 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
7414 : 238 : BuildConvertFunction (M2Base_Convert, true); /* Two parameters */
7415 : : }
7416 : : }
7417 : : else
7418 : : {
7419 : : /* avoid dangling else. */
7420 : 12151 : const_ = SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), type);
7421 : 12151 : SymbolTable_PutConstLitInternal (const_, true);
7422 : 12151 : M2Quads_PushTFtok (const_, type, tok);
7423 : : }
7424 : 12465 : }
7425 : :
7426 : :
7427 : : /*
7428 : : PushZero - pushes the value zero to the stack.
7429 : : The Stack is changed:
7430 : :
7431 : :
7432 : : Entry Exit
7433 : : ===== ====
7434 : :
7435 : : <- Ptr
7436 : : +------------+
7437 : : Ptr -> | 0 | type |
7438 : : |------------|
7439 : : */
7440 : :
7441 : 6608 : static void PushZero (unsigned int tok, unsigned int type)
7442 : : {
7443 : 6608 : if (type == SymbolTable_NulSym)
7444 : : {
7445 : 232 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym), static_cast<unsigned int> (SymbolTable_NulSym), tok);
7446 : : }
7447 : 6376 : else if (SymbolTable_IsEnumeration (type))
7448 : : {
7449 : : /* avoid dangling else. */
7450 : 184 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
7451 : 184 : M2Quads_PushTtok (type, tok);
7452 : 184 : M2Quads_PushTtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType), tok);
7453 : 184 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
7454 : 184 : BuildConvertFunction (M2Base_Convert, true); /* Two parameters */
7455 : : }
7456 : : else
7457 : : {
7458 : : /* avoid dangling else. */
7459 : 6192 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), type), type, tok);
7460 : : }
7461 : 6608 : }
7462 : :
7463 : :
7464 : : /*
7465 : : BuildForLoopToRangeCheck - builds the range check to ensure that the id
7466 : : does not exceed the limits of its type.
7467 : : */
7468 : :
7469 : 1852 : static void BuildForLoopToRangeCheck (void)
7470 : : {
7471 : 1852 : unsigned int d;
7472 : 1852 : unsigned int dt;
7473 : 1852 : unsigned int e;
7474 : 1852 : unsigned int et;
7475 : :
7476 : 1852 : M2Quads_PopTF (&e, &et);
7477 : 1852 : M2Quads_PopTF (&d, &dt);
7478 : 1852 : BuildRange (M2Range_InitForLoopToRangeCheck (d, e));
7479 : 1852 : M2Quads_PushTF (d, dt);
7480 : 1852 : M2Quads_PushTF (e, et);
7481 : 1852 : }
7482 : :
7483 : :
7484 : : /*
7485 : : BuildSizeCheckEnd - checks to see whether the function "called" was in fact SIZE.
7486 : : If so then we restore quadruple generation.
7487 : : */
7488 : :
7489 : 7820 : static void BuildSizeCheckEnd (unsigned int ProcSym)
7490 : : {
7491 : 7820 : if (((ProcSym == M2Size_Size) || (ProcSym == M2System_TSize)) || (ProcSym == M2System_TBitSize))
7492 : : {
7493 : 5534 : QuadrupleGeneration = true;
7494 : 5534 : BuildingSize = false;
7495 : : }
7496 : 2286 : else if (ProcSym == M2Base_High)
7497 : : {
7498 : : /* avoid dangling else. */
7499 : 2286 : QuadrupleGeneration = true;
7500 : 2286 : BuildingHigh = false;
7501 : : }
7502 : 7820 : }
7503 : :
7504 : :
7505 : : /*
7506 : : BuildRealProcedureCall - builds a real procedure call.
7507 : : The Stack:
7508 : :
7509 : :
7510 : : Entry Exit
7511 : :
7512 : : Ptr ->
7513 : : +----------------+
7514 : : | NoOfParam |
7515 : : |----------------|
7516 : : | Param 1 |
7517 : : |----------------|
7518 : : | Param 2 |
7519 : : |----------------|
7520 : : . .
7521 : : . .
7522 : : . .
7523 : : |----------------|
7524 : : | Param # |
7525 : : |----------------|
7526 : : | ProcSym | Type | Empty
7527 : : |----------------|
7528 : : */
7529 : :
7530 : 130392 : static void BuildRealProcedureCall (unsigned int tokno)
7531 : : {
7532 : 130392 : unsigned int NoOfParam;
7533 : 130392 : unsigned int ProcSym;
7534 : :
7535 : 130392 : M2Quads_PopT (&NoOfParam);
7536 : 130392 : M2Quads_PushT (NoOfParam);
7537 : 130392 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+2));
7538 : 130392 : ProcSym = PCSymBuild_SkipConst (ProcSym);
7539 : : /* --checkme-- */
7540 : 130392 : if (SymbolTable_IsVar (ProcSym))
7541 : : {
7542 : : /* Procedure Variable ? */
7543 : 596 : ProcSym = SymbolTable_SkipType (M2Quads_OperandF (NoOfParam+2));
7544 : : }
7545 : 130392 : if ((SymbolTable_IsDefImp (SymbolTable_GetScope (ProcSym))) && (SymbolTable_IsDefinitionForC (SymbolTable_GetScope (ProcSym))))
7546 : : {
7547 : 11433 : BuildRealFuncProcCall (tokno, false, true, false);
7548 : : }
7549 : : else
7550 : : {
7551 : 118959 : BuildRealFuncProcCall (tokno, false, false, false);
7552 : : }
7553 : 130392 : }
7554 : :
7555 : :
7556 : : /*
7557 : : BuildRealFuncProcCall - builds a real procedure or function call.
7558 : : The Stack:
7559 : :
7560 : :
7561 : : Entry Exit
7562 : :
7563 : : Ptr ->
7564 : : +----------------+
7565 : : | NoOfParam |
7566 : : |----------------|
7567 : : | Param 1 |
7568 : : |----------------|
7569 : : | Param 2 |
7570 : : |----------------|
7571 : : . .
7572 : : . .
7573 : : . .
7574 : : |----------------|
7575 : : | Param # |
7576 : : |----------------|
7577 : : | ProcSym | Type | Empty
7578 : : |----------------|
7579 : : */
7580 : :
7581 : 168660 : static void BuildRealFuncProcCall (unsigned int tokno, bool IsFunc, bool IsForC, bool ConstExpr)
7582 : : {
7583 : 168660 : bool AllocateProc;
7584 : 168660 : bool DeallocateProc;
7585 : 168660 : bool ForcedFunc;
7586 : 168660 : bool ParamConstant;
7587 : 168660 : unsigned int trash;
7588 : 168660 : unsigned int resulttok;
7589 : 168660 : unsigned int paramtok;
7590 : 168660 : unsigned int proctok;
7591 : 168660 : unsigned int NoOfParameters;
7592 : 168660 : unsigned int i;
7593 : 168660 : unsigned int pi;
7594 : 168660 : unsigned int ParamType;
7595 : 168660 : unsigned int Param1;
7596 : 168660 : unsigned int ReturnVar;
7597 : 168660 : unsigned int ProcSym;
7598 : 168660 : unsigned int Proc;
7599 : :
7600 : 168660 : Param1 = SymbolTable_NulSym; /* Used to remember first param for allocate/deallocate. */
7601 : 168660 : ParamType = SymbolTable_NulSym;
7602 : 168660 : CheckProcedureParameters (IsForC);
7603 : 168660 : M2Quads_PopT (&NoOfParameters);
7604 : 168660 : M2Quads_PushT (NoOfParameters); /* Restore stack to original state. */
7605 : 168660 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+2)); /* Restore stack to original state. */
7606 : 168660 : proctok = tokno; /* OperandTtok (NoOfParameters+2) ; */
7607 : 168660 : if (proctok == M2LexBuf_UnknownTokenNo) /* OperandTtok (NoOfParameters+2) ; */
7608 : : {
7609 : 0 : proctok = M2LexBuf_GetTokenNo ();
7610 : : }
7611 : 168660 : paramtok = proctok;
7612 : 168660 : ProcSym = PCSymBuild_SkipConst (ProcSym);
7613 : 168660 : ForcedFunc = false;
7614 : 168660 : AllocateProc = false;
7615 : 168660 : DeallocateProc = false;
7616 : 168660 : if (SymbolTable_IsVar (ProcSym))
7617 : : {
7618 : : /* Procedure Variable ? */
7619 : 672 : Proc = SymbolTable_SkipType (M2Quads_OperandF (NoOfParameters+2));
7620 : 672 : ParamConstant = false;
7621 : : }
7622 : : else
7623 : : {
7624 : 167988 : Proc = ProcSym;
7625 : 167988 : ParamConstant = true;
7626 : 167988 : AllocateProc = (SymbolTable_GetSymName (Proc)) == (NameKey_MakeKey ((const char *) "ALLOCATE", 8));
7627 : 167988 : DeallocateProc = (SymbolTable_GetSymName (Proc)) == (NameKey_MakeKey ((const char *) "DEALLOCATE", 10));
7628 : : }
7629 : 168660 : if (IsFunc)
7630 : : {
7631 : : /* avoid dangling else. */
7632 : 38268 : if ((SymbolTable_GetSType (Proc)) == SymbolTable_NulSym)
7633 : : {
7634 : 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);
7635 : : }
7636 : : }
7637 : : else
7638 : : {
7639 : : /* is being called as a procedure */
7640 : 130392 : if ((SymbolTable_GetSType (Proc)) != SymbolTable_NulSym)
7641 : : {
7642 : : /* however it was declared as a procedure function */
7643 : 6037 : if (! (SymbolTable_IsReturnOptional (Proc)))
7644 : : {
7645 : 0 : 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);
7646 : : }
7647 : : IsFunc = true;
7648 : : ForcedFunc = true;
7649 : : }
7650 : : }
7651 : 168660 : if (AllocateProc || DeallocateProc)
7652 : : {
7653 : 1350 : Param1 = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+1)); /* Remember this before manipulating. */
7654 : : }
7655 : 168660 : ManipulateParameters (IsForC);
7656 : 168660 : CheckParameterOrdinals ();
7657 : 168660 : M2Quads_PopT (&NoOfParameters);
7658 : 168660 : if (IsFunc)
7659 : : {
7660 : 44305 : GenQuad (M2Quads_ParamOp, 0, Proc, ProcSym); /* Space for return value */
7661 : : }
7662 : 168660 : if (((NoOfParameters+1) == (SymbolTable_NoOfParam (Proc))) && (SymbolTable_UsesOptArg (Proc)))
7663 : : {
7664 : 2396 : GenQuad (M2Quads_OptParamOp, SymbolTable_NoOfParam (Proc), Proc, Proc);
7665 : : }
7666 : 168660 : i = NoOfParameters;
7667 : 168660 : pi = 1; /* stack index referencing stacked parameter, i */
7668 : 605950 : while (i > 0) /* stack index referencing stacked parameter, i */
7669 : : {
7670 : 437290 : paramtok = OperandTtok (pi);
7671 : 437290 : if (((AllocateProc || DeallocateProc) && (i == 1)) && (Param1 != SymbolTable_NulSym))
7672 : : {
7673 : 1350 : ParamType = GetItemPointedTo (Param1);
7674 : 1350 : if (ParamType == SymbolTable_NulSym)
7675 : : {
7676 : 0 : GenQuadO (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true);
7677 : : }
7678 : : else
7679 : : {
7680 : 1350 : if (AllocateProc)
7681 : : {
7682 : 900 : trash = SymbolTable_MakeTemporary (paramtok, SymbolTable_RightValue);
7683 : 900 : SymbolTable_PutVar (trash, ParamType);
7684 : 900 : SymbolTable_PutVarHeap (trash, true);
7685 : : }
7686 : : else
7687 : : {
7688 : 450 : M2Debug_Assert (DeallocateProc);
7689 : 450 : trash = M2Base_Nil;
7690 : : }
7691 : 1350 : GenQuadOTrash (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true, trash);
7692 : : }
7693 : : }
7694 : : else
7695 : : {
7696 : 435940 : GenQuadO (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true);
7697 : : }
7698 : 437290 : if (! (SymbolTable_IsConst (M2Quads_OperandT (pi))))
7699 : : {
7700 : 366872 : ParamConstant = false;
7701 : : }
7702 : 437290 : i -= 1;
7703 : 437290 : pi += 1;
7704 : : }
7705 : 337320 : GenQuadO (proctok, M2Quads_CallOp, SymbolTable_NulSym, SymbolTable_NulSym, ProcSym, true);
7706 : 168660 : M2Quads_PopN (NoOfParameters+1); /* Destroy arguments and procedure call */
7707 : 168660 : if (IsFunc)
7708 : : {
7709 : : /* ReturnVar has the type of the procedure. */
7710 : 44305 : resulttok = M2LexBuf_MakeVirtualTok (proctok, proctok, paramtok);
7711 : 44305 : if (ConstExpr && (! (SymbolTable_IsProcedureBuiltinAvailable (Proc))))
7712 : : {
7713 : 0 : M2MetaError_MetaError1 ((const char *) "{%1d} {%1ad} cannot be used in a constant expression", 52, Proc);
7714 : 0 : ParamConstant = false;
7715 : : }
7716 : 44305 : ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (ParamConstant && ConstExpr));
7717 : 44305 : SymbolTable_PutVar (ReturnVar, SymbolTable_GetSType (Proc));
7718 : 88610 : GenQuadO (resulttok, M2Quads_FunctValueOp, ReturnVar, SymbolTable_NulSym, Proc, true);
7719 : 44305 : if (! ForcedFunc)
7720 : : {
7721 : 38268 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (Proc), resulttok);
7722 : : }
7723 : : }
7724 : 168660 : }
7725 : :
7726 : :
7727 : : /*
7728 : : CheckProcedureParameters - Checks the parameters which are being passed to
7729 : : procedure ProcSym.
7730 : :
7731 : : The Stack:
7732 : :
7733 : :
7734 : : Entry Exit
7735 : :
7736 : : Ptr -> <- Ptr
7737 : : +----------------+ +----------------+
7738 : : | NoOfParam | | NoOfParam |
7739 : : |----------------| |----------------|
7740 : : | Param 1 | | Param 1 |
7741 : : |----------------| |----------------|
7742 : : | Param 2 | | Param 2 |
7743 : : |----------------| |----------------|
7744 : : . . . .
7745 : : . . . .
7746 : : . . . .
7747 : : |----------------| |----------------|
7748 : : | Param # | | Param # |
7749 : : |----------------| |----------------|
7750 : : | ProcSym | Type | | ProcSym | Type |
7751 : : |----------------| |----------------|
7752 : :
7753 : : */
7754 : :
7755 : 168660 : static void CheckProcedureParameters (bool IsForC)
7756 : : {
7757 : 168660 : unsigned int proctok;
7758 : 168660 : unsigned int paramtok;
7759 : 168660 : NameKey_Name n1;
7760 : 168660 : NameKey_Name n2;
7761 : 168660 : unsigned int Dim;
7762 : 168660 : unsigned int Actual;
7763 : 168660 : unsigned int FormalI;
7764 : 168660 : unsigned int ParamTotal;
7765 : 168660 : unsigned int pi;
7766 : 168660 : unsigned int Proc;
7767 : 168660 : unsigned int ProcSym;
7768 : 168660 : unsigned int i;
7769 : 168660 : DynamicStrings_String s;
7770 : :
7771 : 168660 : M2Quads_PopT (&ParamTotal);
7772 : 168660 : M2Quads_PushT (ParamTotal); /* Restore stack to origional state */
7773 : 168660 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((ParamTotal+1)+1)); /* Restore stack to origional state */
7774 : 168660 : proctok = OperandTtok ((ParamTotal+1)+1);
7775 : 168660 : if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (SymbolTable_GetDType (ProcSym))))
7776 : : {
7777 : : /* Procedure Variable ? */
7778 : 672 : Proc = SymbolTable_SkipType (M2Quads_OperandF ((ParamTotal+1)+1));
7779 : : }
7780 : : else
7781 : : {
7782 : 167988 : Proc = PCSymBuild_SkipConst (ProcSym);
7783 : : }
7784 : 168660 : if (! ((SymbolTable_IsProcedure (Proc)) || (SymbolTable_IsProcType (Proc))))
7785 : : {
7786 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
7787 : 0 : if (SymbolTable_IsUnknown (Proc))
7788 : : {
7789 : 0 : M2MetaError_MetaError1 ((const char *) "{%1Ua} is not recognised as a procedure, check declaration or import", 68, Proc);
7790 : : }
7791 : : else
7792 : : {
7793 : 0 : M2MetaError_MetaErrors1 ((const char *) "{%1a} is not recognised as a procedure, check declaration or import", 67, (const char *) "{%1Ua} is not recognised as a procedure, check declaration or import", 68, Proc);
7794 : : }
7795 : : }
7796 : 168660 : if (M2Options_CompilerDebugging)
7797 : : {
7798 : 0 : n1 = SymbolTable_GetSymName (Proc);
7799 : 0 : M2Printf_printf1 ((const char *) " %a ( ", 7, (const unsigned char *) &n1, (sizeof (n1)-1));
7800 : : }
7801 : 168660 : if (DebugTokPos)
7802 : : {
7803 : : s = DynamicStrings_InitString ((const char *) "procedure", 9);
7804 : : M2Error_WarnStringAt (s, proctok);
7805 : : }
7806 : 168660 : i = 1;
7807 : 168660 : pi = ParamTotal+1; /* stack index referencing stacked parameter, i */
7808 : 603356 : while (i <= ParamTotal) /* stack index referencing stacked parameter, i */
7809 : : {
7810 : 434696 : if (i <= (SymbolTable_NoOfParam (Proc)))
7811 : : {
7812 : 430505 : FormalI = SymbolTable_GetParam (Proc, i);
7813 : 430505 : if (M2Options_CompilerDebugging)
7814 : : {
7815 : 0 : n1 = SymbolTable_GetSymName (FormalI);
7816 : 0 : n2 = SymbolTable_GetSymName (SymbolTable_GetSType (FormalI));
7817 : 0 : M2Printf_printf2 ((const char *) "%a: %a", 6, (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
7818 : : }
7819 : 430505 : Actual = static_cast<unsigned int> (M2Quads_OperandT (pi));
7820 : 430505 : Dim = static_cast<unsigned int> (OperandD (pi));
7821 : 430505 : paramtok = OperandTtok (pi);
7822 : 430505 : if (DebugTokPos)
7823 : : {
7824 : : s = DynamicStrings_InitString ((const char *) "actual", 6);
7825 : : M2Error_WarnStringAt (s, paramtok);
7826 : : }
7827 : 430505 : BuildRange (M2Range_InitTypesParameterCheck (paramtok, Proc, i, FormalI, Actual));
7828 : 430505 : if (SymbolTable_IsConst (Actual))
7829 : : {
7830 : : /* avoid dangling else. */
7831 : 98719 : if (SymbolTable_IsVarParam (Proc, i))
7832 : : {
7833 : 0 : FailParameter (paramtok, (const char *) "trying to pass a constant to a VAR parameter", 44, Actual, FormalI, Proc, i);
7834 : : }
7835 : 98719 : else if (SymbolTable_IsConstString (Actual))
7836 : : {
7837 : : /* avoid dangling else. */
7838 : 30402 : if (! (SymbolTable_IsConstStringKnown (Actual)))
7839 : : {} /* empty. */
7840 : 30270 : else if ((SymbolTable_IsArray (SymbolTable_GetDType (FormalI))) && ((SymbolTable_GetSType (SymbolTable_GetDType (FormalI))) == M2Base_Char))
7841 : : {
7842 : : /* avoid dangling else. */
7843 : : }
7844 : 30246 : else if ((SymbolTable_GetStringLength (paramtok, Actual)) == 1)
7845 : : {
7846 : : /* avoid dangling else. */
7847 : 3232 : CheckParameter (paramtok, Actual, Dim, FormalI, Proc, i, static_cast<Lists_List> (NULL));
7848 : : }
7849 : 27014 : else if (! (SymbolTable_IsUnboundedParam (Proc, i)))
7850 : : {
7851 : : /* avoid dangling else. */
7852 : 6 : if (IsForC && ((SymbolTable_GetSType (FormalI)) == M2System_Address))
7853 : : {
7854 : 0 : FailParameter (paramtok, (const char *) "a string constant can either be passed to an ADDRESS parameter or an ARRAY OF CHAR", 82, Actual, FormalI, Proc, i);
7855 : : }
7856 : : else
7857 : : {
7858 : 6 : FailParameter (paramtok, (const char *) "cannot pass a string constant to a non unbounded array parameter", 64, Actual, FormalI, Proc, i);
7859 : : }
7860 : : }
7861 : : }
7862 : : }
7863 : : else
7864 : : {
7865 : 331786 : CheckParameter (paramtok, Actual, Dim, FormalI, Proc, i, static_cast<Lists_List> (NULL));
7866 : : }
7867 : : }
7868 : : else
7869 : : {
7870 : 4191 : if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
7871 : : {
7872 : : /* these are varargs, therefore we don't check them */
7873 : 4191 : i = ParamTotal;
7874 : : }
7875 : : else
7876 : : {
7877 : 0 : M2MetaError_MetaErrorT2 (proctok, (const char *) "too many parameters, {%2n} passed to {%1a} ", 43, Proc, i);
7878 : : }
7879 : : }
7880 : 434696 : i += 1;
7881 : 434696 : pi -= 1;
7882 : 434696 : if (M2Options_CompilerDebugging)
7883 : : {
7884 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
7885 : 0 : if (i <= ParamTotal)
7886 : : {
7887 : 0 : M2Printf_printf0 ((const char *) "; ", 2);
7888 : : }
7889 : : else
7890 : : {
7891 : 0 : M2Printf_printf0 ((const char *) " ) ; \\n", 7);
7892 : : }
7893 : : }
7894 : : }
7895 : 168660 : }
7896 : :
7897 : :
7898 : : /*
7899 : : CheckProcTypeAndProcedure - checks the ProcType with the call.
7900 : : */
7901 : :
7902 : 41227 : static void CheckProcTypeAndProcedure (unsigned int tokno, unsigned int ProcType, unsigned int call)
7903 : : {
7904 : 41227 : NameKey_Name n1;
7905 : 41227 : NameKey_Name n2;
7906 : 41227 : unsigned int i;
7907 : 41227 : unsigned int n;
7908 : 41227 : unsigned int t;
7909 : 41227 : unsigned int CheckedProcedure;
7910 : 41227 : M2Error_Error e;
7911 : :
7912 : 41227 : n = SymbolTable_NoOfParam (ProcType);
7913 : 41227 : if (((SymbolTable_IsVar (call)) || (SymbolTable_IsTemporary (call))) || (SymbolTable_IsParameter (call)))
7914 : : {
7915 : 580 : CheckedProcedure = SymbolTable_GetDType (call);
7916 : : }
7917 : : else
7918 : : {
7919 : : CheckedProcedure = call;
7920 : : }
7921 : 41227 : if (n != (SymbolTable_NoOfParam (CheckedProcedure)))
7922 : : {
7923 : 0 : e = M2Error_NewError (SymbolTable_GetDeclaredMod (ProcType));
7924 : 0 : n1 = SymbolTable_GetSymName (call);
7925 : 0 : n2 = SymbolTable_GetSymName (ProcType);
7926 : 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));
7927 : 0 : e = M2Error_ChainError (SymbolTable_GetDeclaredMod (call), e);
7928 : 0 : t = SymbolTable_NoOfParam (CheckedProcedure);
7929 : 0 : if (n < 2)
7930 : : {
7931 : 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));
7932 : : }
7933 : : else
7934 : : {
7935 : 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));
7936 : : }
7937 : : }
7938 : : else
7939 : : {
7940 : : i = 1;
7941 : 122435 : while (i <= n)
7942 : : {
7943 : 81208 : if ((SymbolTable_IsVarParam (ProcType, i)) != (SymbolTable_IsVarParam (CheckedProcedure, i)))
7944 : : {
7945 : 0 : M2MetaError_MetaError3 ((const char *) "parameter {%3n} in {%1dD} causes a mismatch it was declared as a {%2d}", 70, ProcType, SymbolTable_GetNth (ProcType, i), i);
7946 : 0 : M2MetaError_MetaError3 ((const char *) "parameter {%3n} in {%1dD} causes a mismatch it was declared as a {%2d}", 70, call, SymbolTable_GetNth (call, i), i);
7947 : : }
7948 : 81208 : BuildRange (M2Range_InitTypesParameterCheck (tokno, CheckedProcedure, i, SymbolTable_GetParam (CheckedProcedure, i), SymbolTable_GetParam (ProcType, i)));
7949 : : /* CheckParameter(tokpos, GetParam(CheckedProcedure, i), 0, GetParam(ProcType, i), call, i, TypeList) ; */
7950 : 81208 : i += 1;
7951 : : }
7952 : : }
7953 : 41227 : }
7954 : :
7955 : :
7956 : : /*
7957 : : IsReallyPointer - returns TRUE is sym is a pointer, address or a type declared
7958 : : as a pointer or address.
7959 : : */
7960 : :
7961 : 916 : static bool IsReallyPointer (unsigned int Sym)
7962 : : {
7963 : 916 : if (SymbolTable_IsVar (Sym))
7964 : : {
7965 : 916 : Sym = SymbolTable_GetSType (Sym);
7966 : : }
7967 : 916 : Sym = SymbolTable_SkipType (Sym);
7968 : 916 : return (SymbolTable_IsPointer (Sym)) || (Sym == M2System_Address);
7969 : : /* static analysis guarentees a RETURN statement will be used before here. */
7970 : : __builtin_unreachable ();
7971 : : }
7972 : :
7973 : :
7974 : : /*
7975 : : LegalUnboundedParam - returns TRUE if the parameter, Actual, can legitimately be
7976 : : passed to ProcSym, i, the, Formal, parameter.
7977 : : */
7978 : :
7979 : 8483 : static bool LegalUnboundedParam (unsigned int tokpos, unsigned int ProcSym, unsigned int i, unsigned int ActualType, unsigned int Actual, unsigned int Dimension, unsigned int Formal)
7980 : : {
7981 : 8483 : unsigned int FormalType;
7982 : 8483 : unsigned int n;
7983 : 8483 : unsigned int m;
7984 : :
7985 : 8483 : ActualType = SymbolTable_SkipType (ActualType);
7986 : 8483 : FormalType = SymbolTable_GetDType (Formal);
7987 : 8483 : FormalType = SymbolTable_GetSType (FormalType); /* type of the unbounded ARRAY */
7988 : 8483 : if (SymbolTable_IsArray (ActualType)) /* type of the unbounded ARRAY */
7989 : : {
7990 : 6093 : m = SymbolTable_GetDimension (Formal);
7991 : 6093 : n = 0;
7992 : 12378 : while (SymbolTable_IsArray (ActualType))
7993 : : {
7994 : 6249 : n += 1;
7995 : 6249 : ActualType = SymbolTable_GetDType (ActualType);
7996 : 6249 : if ((m == n) && (ActualType == FormalType))
7997 : : {
7998 : : return true;
7999 : : }
8000 : : }
8001 : 36 : if (n == m)
8002 : : {} /* empty. */
8003 : : else
8004 : : {
8005 : : /* now we fall though and test ActualType against FormalType */
8006 : 12 : if (M2System_IsGenericSystemType (FormalType))
8007 : : {
8008 : : return true;
8009 : : }
8010 : : else
8011 : : {
8012 : 0 : FailParameter (tokpos, (const char *) "attempting to pass an array with the incorrect number dimenisons to an unbounded formal parameter of different dimensions", 121, Actual, Formal, ProcSym, i);
8013 : 0 : return false;
8014 : : }
8015 : : }
8016 : : }
8017 : 2390 : else if (SymbolTable_IsUnbounded (ActualType))
8018 : : {
8019 : : /* avoid dangling else. */
8020 : 36 : if ((Dimension == 0) && ((SymbolTable_GetDimension (Formal)) == (SymbolTable_GetDimension (Actual))))
8021 : : {
8022 : : /* now we fall though and test ActualType against FormalType */
8023 : 0 : ActualType = SymbolTable_GetSType (ActualType);
8024 : : }
8025 : : else
8026 : : {
8027 : 36 : if (M2System_IsGenericSystemType (FormalType))
8028 : : {
8029 : : return true;
8030 : : }
8031 : : else
8032 : : {
8033 : 12 : if (((SymbolTable_GetDimension (Actual))-Dimension) == (SymbolTable_GetDimension (Formal)))
8034 : : {
8035 : 12 : ActualType = SymbolTable_GetSType (ActualType);
8036 : : }
8037 : : else
8038 : : {
8039 : 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, Formal, ProcSym, i);
8040 : 0 : return false;
8041 : : }
8042 : : }
8043 : : }
8044 : : }
8045 : 2390 : if (((M2System_IsGenericSystemType (FormalType)) || (M2System_IsGenericSystemType (ActualType))) || (M2Base_IsAssignmentCompatible (FormalType, ActualType)))
8046 : : {
8047 : : /* we think it is legal, but we ask post pass 3 to check as
8048 : : not all types are known at this point */
8049 : 2390 : return true;
8050 : : }
8051 : : else
8052 : : {
8053 : 0 : FailParameter (tokpos, (const char *) "identifier with an incompatible type is being passed to this procedure", 70, Actual, Formal, ProcSym, i);
8054 : 0 : return false;
8055 : : }
8056 : : /* static analysis guarentees a RETURN statement will be used before here. */
8057 : : __builtin_unreachable ();
8058 : : }
8059 : :
8060 : :
8061 : : /*
8062 : : CheckParameter - checks that types ActualType and FormalType are compatible for parameter
8063 : : passing. ProcSym is the procedure and i is the parameter number.
8064 : :
8065 : : We obey the following rules:
8066 : :
8067 : : (1) we allow WORD, BYTE, LOC to be compitable with any like sized
8068 : : type.
8069 : : (2) we allow ADDRESS to be compatible with any pointer type.
8070 : : (3) we relax INTEGER and CARDINAL checking for Temporary variables.
8071 : :
8072 : : Note that type sizes are checked during the code generation pass.
8073 : : */
8074 : :
8075 : 335018 : static void CheckParameter (unsigned int tokpos, unsigned int Actual, unsigned int Dimension, unsigned int Formal, unsigned int ProcSym, unsigned int i, Lists_List TypeList)
8076 : : {
8077 : 335018 : bool NewList;
8078 : 335018 : unsigned int ActualType;
8079 : 335018 : unsigned int FormalType;
8080 : :
8081 : 335018 : if ((SymbolTable_IsConstString (Actual)) && (! (SymbolTable_IsConstStringKnown (Actual))))
8082 : : {
8083 : : /* Cannot check if the string content is not yet known. */
8084 : : return ;
8085 : : }
8086 : 335018 : FormalType = SymbolTable_GetDType (Formal);
8087 : 335018 : if ((SymbolTable_IsConstString (Actual)) && ((SymbolTable_GetStringLength (tokpos, Actual)) == 1)) /* if = 1 then it maybe treated as a char */
8088 : : {
8089 : 3232 : ActualType = M2Base_Char;
8090 : : }
8091 : 331786 : else if (Actual == M2Base_Boolean)
8092 : : {
8093 : : /* avoid dangling else. */
8094 : : ActualType = Actual;
8095 : : }
8096 : : else
8097 : : {
8098 : : /* avoid dangling else. */
8099 : 331786 : ActualType = SymbolTable_GetDType (Actual);
8100 : : }
8101 : 335018 : if (TypeList == NULL)
8102 : : {
8103 : 335018 : NewList = true;
8104 : 335018 : Lists_InitList (&TypeList);
8105 : : }
8106 : : else
8107 : : {
8108 : : NewList = false;
8109 : : }
8110 : 335018 : if (Lists_IsItemInList (TypeList, ActualType))
8111 : : {
8112 : : /* no need to check */
8113 : : return ;
8114 : : }
8115 : 335018 : Lists_IncludeItemIntoList (TypeList, ActualType);
8116 : 335018 : if (SymbolTable_IsProcType (FormalType))
8117 : : {
8118 : 41227 : if ((! (SymbolTable_IsProcedure (Actual))) && ((ActualType == SymbolTable_NulSym) || (! (SymbolTable_IsProcType (SymbolTable_SkipType (ActualType))))))
8119 : : {
8120 : 0 : FailParameter (tokpos, (const char *) "expecting a procedure or procedure variable as a parameter", 58, Actual, Formal, ProcSym, i);
8121 : 0 : return ;
8122 : : }
8123 : 41227 : if ((SymbolTable_IsProcedure (Actual)) && (SymbolTable_IsProcedureNested (Actual)))
8124 : : {
8125 : 0 : 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);
8126 : : }
8127 : : /* we can check the return type of both proc types */
8128 : 41227 : if ((ActualType != SymbolTable_NulSym) && (SymbolTable_IsProcType (ActualType)))
8129 : : {
8130 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
8131 : 580 : if (((SymbolTable_GetSType (ActualType)) != SymbolTable_NulSym) && ((SymbolTable_GetSType (FormalType)) == SymbolTable_NulSym))
8132 : : {
8133 : 0 : FailParameter (tokpos, (const char *) "the item being passed is a function whereas the formal procedure parameter is a procedure", 89, Actual, Formal, ProcSym, i);
8134 : 0 : return ;
8135 : : }
8136 : 580 : else if (((SymbolTable_GetSType (ActualType)) == SymbolTable_NulSym) && ((SymbolTable_GetSType (FormalType)) != SymbolTable_NulSym))
8137 : : {
8138 : : /* avoid dangling else. */
8139 : 0 : FailParameter (tokpos, (const char *) "the item being passed is a procedure whereas the formal procedure parameter is a function", 89, Actual, Formal, ProcSym, i);
8140 : 0 : return ;
8141 : : }
8142 : 580 : else if (M2Base_AssignmentRequiresWarning (SymbolTable_GetSType (ActualType), SymbolTable_GetSType (FormalType)))
8143 : : {
8144 : : /* avoid dangling else. */
8145 : 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, Formal, ProcSym, i);
8146 : 0 : return ;
8147 : : }
8148 : 580 : else if (((M2System_IsGenericSystemType (SymbolTable_GetSType (FormalType))) || (M2System_IsGenericSystemType (SymbolTable_GetSType (ActualType)))) || (M2Base_IsAssignmentCompatible (SymbolTable_GetSType (ActualType), SymbolTable_GetSType (FormalType))))
8149 : : {
8150 : : /* avoid dangling else. */
8151 : : }
8152 : : else
8153 : : {
8154 : : /* avoid dangling else. */
8155 : : /* pass */
8156 : 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, Formal, ProcSym, i);
8157 : 0 : return ;
8158 : : }
8159 : : }
8160 : : /* now to check each parameter of the proc type */
8161 : 41227 : CheckProcTypeAndProcedure (tokpos, FormalType, Actual);
8162 : : }
8163 : 293791 : else if ((ActualType != FormalType) && (ActualType != SymbolTable_NulSym))
8164 : : {
8165 : : /* avoid dangling else. */
8166 : 14416 : if (SymbolTable_IsUnknown (FormalType))
8167 : : {
8168 : 0 : FailParameter (tokpos, (const char *) "procedure parameter type is undeclared", 38, Actual, Formal, ProcSym, i);
8169 : 0 : return ;
8170 : : }
8171 : 14416 : if ((SymbolTable_IsUnbounded (ActualType)) && (! (SymbolTable_IsUnboundedParam (ProcSym, i))))
8172 : : {
8173 : 0 : FailParameter (tokpos, (const char *) "attempting to pass an unbounded array to a NON unbounded parameter", 66, Actual, Formal, ProcSym, i);
8174 : 0 : return ;
8175 : : }
8176 : 14416 : else if (SymbolTable_IsUnboundedParam (ProcSym, i))
8177 : : {
8178 : : /* avoid dangling else. */
8179 : 8483 : if (! (LegalUnboundedParam (tokpos, ProcSym, i, ActualType, Actual, Dimension, Formal)))
8180 : : {
8181 : : return ;
8182 : : }
8183 : : }
8184 : 5933 : else if (ActualType != FormalType)
8185 : : {
8186 : : /* avoid dangling else. */
8187 : 5933 : if (M2Base_AssignmentRequiresWarning (FormalType, ActualType))
8188 : : {
8189 : 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, Formal, ProcSym, i);
8190 : : }
8191 : 5933 : else if (((M2System_IsGenericSystemType (FormalType)) || (M2System_IsGenericSystemType (ActualType))) || (M2Base_IsAssignmentCompatible (ActualType, FormalType)))
8192 : : {
8193 : : /* avoid dangling else. */
8194 : : }
8195 : : else
8196 : : {
8197 : : /* avoid dangling else. */
8198 : : /* so far we know it is legal, but not all types have been resolved
8199 : : and so this is checked later on in another pass. */
8200 : 12 : FailParameter (tokpos, (const char *) "identifier with an incompatible type is being passed to this procedure", 70, Actual, Formal, ProcSym, i);
8201 : : }
8202 : : }
8203 : : }
8204 : 335018 : if (NewList)
8205 : : {
8206 : 335018 : Lists_KillList (&TypeList);
8207 : : }
8208 : : }
8209 : :
8210 : :
8211 : : /*
8212 : : DescribeType - returns a String describing a symbol, Sym, name and its type.
8213 : : */
8214 : :
8215 : 0 : static DynamicStrings_String DescribeType (unsigned int Sym)
8216 : : {
8217 : 0 : DynamicStrings_String s;
8218 : 0 : DynamicStrings_String s1;
8219 : 0 : DynamicStrings_String s2;
8220 : 0 : unsigned int Low;
8221 : 0 : unsigned int High;
8222 : 0 : unsigned int Subrange;
8223 : 0 : unsigned int Subscript;
8224 : 0 : unsigned int Type;
8225 : :
8226 : 0 : s = static_cast<DynamicStrings_String> (NULL);
8227 : 0 : if (SymbolTable_IsConstString (Sym))
8228 : : {
8229 : : /* If = 1 then it maybe treated as a char. */
8230 : 0 : if ((SymbolTable_IsConstStringKnown (Sym)) && ((SymbolTable_GetStringLength (SymbolTable_GetDeclaredMod (Sym), Sym)) == 1))
8231 : : {
8232 : 0 : s = DynamicStrings_InitString ((const char *) "(constant string) or {%kCHAR}", 29);
8233 : : }
8234 : : else
8235 : : {
8236 : 0 : s = DynamicStrings_InitString ((const char *) "(constant string)", 17);
8237 : : }
8238 : : }
8239 : 0 : else if (SymbolTable_IsConst (Sym))
8240 : : {
8241 : : /* avoid dangling else. */
8242 : 0 : s = DynamicStrings_InitString ((const char *) "(constant)", 10);
8243 : : }
8244 : 0 : else if (SymbolTable_IsUnknown (Sym))
8245 : : {
8246 : : /* avoid dangling else. */
8247 : 0 : s = DynamicStrings_InitString ((const char *) "(unknown)", 9);
8248 : : }
8249 : : else
8250 : : {
8251 : : /* avoid dangling else. */
8252 : 0 : Type = SymbolTable_GetSType (Sym);
8253 : 0 : if (Type == SymbolTable_NulSym)
8254 : : {
8255 : 0 : s = DynamicStrings_InitString ((const char *) "(unknown)", 9);
8256 : : }
8257 : 0 : else if (SymbolTable_IsUnbounded (Type))
8258 : : {
8259 : : /* avoid dangling else. */
8260 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (SymbolTable_GetSType (Type)))));
8261 : 0 : s = FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "{%%kARRAY} {%%kOF} %s", 21)), (const unsigned char *) &s1, (sizeof (s1)-1));
8262 : : }
8263 : 0 : else if (SymbolTable_IsArray (Type))
8264 : : {
8265 : : /* avoid dangling else. */
8266 : 0 : s = DynamicStrings_InitString ((const char *) "{%kARRAY} [", 11);
8267 : 0 : Subscript = SymbolTable_GetArraySubscript (Type);
8268 : 0 : if (Subscript != SymbolTable_NulSym)
8269 : : {
8270 : 0 : M2Debug_Assert (SymbolTable_IsSubscript (Subscript));
8271 : 0 : Subrange = SymbolTable_GetSType (Subscript);
8272 : 0 : if (! (SymbolTable_IsSubrange (Subrange)))
8273 : : {
8274 : 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);
8275 : : }
8276 : 0 : M2Debug_Assert (SymbolTable_IsSubrange (Subrange));
8277 : 0 : SymbolTable_GetSubrange (Subrange, &High, &Low);
8278 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Low))));
8279 : 0 : s2 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (High))));
8280 : 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))));
8281 : : }
8282 : 0 : s1 = DynamicStrings_Mark (DescribeType (Type));
8283 : 0 : s = DynamicStrings_ConCat (DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "] OF ", 5))), s1);
8284 : : }
8285 : : else
8286 : : {
8287 : : /* avoid dangling else. */
8288 : 0 : if (SymbolTable_IsUnknown (Type))
8289 : : {
8290 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Type))));
8291 : 0 : s = FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "%s (currently unknown, check declaration or import)", 51)), (const unsigned char *) &s1, (sizeof (s1)-1));
8292 : : }
8293 : : else
8294 : : {
8295 : 0 : s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Type)));
8296 : : }
8297 : : }
8298 : : }
8299 : 0 : return s;
8300 : : /* static analysis guarentees a RETURN statement will be used before here. */
8301 : : __builtin_unreachable ();
8302 : : }
8303 : :
8304 : :
8305 : : /*
8306 : : FailParameter - generates an error message indicating that a parameter
8307 : : declaration has failed.
8308 : :
8309 : : The parameters are:
8310 : :
8311 : : CurrentState - string describing the current failing state.
8312 : : Given - the token that the source code provided.
8313 : : Expecting - token or identifier that was expected.
8314 : : ParameterNo - parameter number that has failed.
8315 : : ProcedureSym - procedure symbol where parameter has failed.
8316 : :
8317 : : If any parameter is Nul then it is ignored.
8318 : : */
8319 : :
8320 : 18 : static void FailParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Given, unsigned int Expecting, unsigned int ProcedureSym, unsigned int ParameterNo)
8321 : : {
8322 : 18 : unsigned int First;
8323 : 18 : unsigned int ExpectType;
8324 : 18 : DynamicStrings_String s;
8325 : 18 : DynamicStrings_String s1;
8326 : 18 : DynamicStrings_String s2;
8327 : 18 : char CurrentState[_CurrentState_high+1];
8328 : :
8329 : : /* make a local copy of each unbounded array. */
8330 : 18 : memcpy (CurrentState, CurrentState_, _CurrentState_high+1);
8331 : :
8332 : 18 : M2MetaError_MetaErrorT2 (tokpos, (const char *) "parameter mismatch between the {%2N} parameter of procedure {%1Ead}", 67, ProcedureSym, ParameterNo);
8333 : 18 : s = DynamicStrings_InitString ((const char *) "{%kPROCEDURE} {%1Eau} (", 23);
8334 : 18 : if ((SymbolTable_NoOfParam (ProcedureSym)) >= ParameterNo)
8335 : : {
8336 : : /* avoid dangling else. */
8337 : 18 : if (ParameterNo > 1)
8338 : : {
8339 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ".., ", 4)));
8340 : : }
8341 : 18 : if (SymbolTable_IsVarParam (ProcedureSym, ParameterNo))
8342 : : {
8343 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "{%kVAR} ", 8)));
8344 : : }
8345 : 18 : First = SymbolTable_GetDeclaredMod (SymbolTable_GetNthParam (ProcedureSym, ParameterNo));
8346 : 18 : ExpectType = SymbolTable_GetSType (Expecting);
8347 : 18 : if (SymbolTable_IsUnboundedParam (ProcedureSym, ParameterNo))
8348 : : {
8349 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Expecting))));
8350 : 0 : s2 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (SymbolTable_GetSType (ExpectType)))));
8351 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (FormatStrings_Sprintf2 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "%s: {%%kARRAY} {%%kOF} %s", 25)), (const unsigned char *) &s1, (sizeof (s1)-1), (const unsigned char *) &s2, (sizeof (s2)-1))));
8352 : : }
8353 : : else
8354 : : {
8355 : 18 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Expecting))));
8356 : 18 : s2 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (ExpectType))));
8357 : 18 : 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))));
8358 : : }
8359 : 18 : if (ParameterNo < (SymbolTable_NoOfParam (ProcedureSym)))
8360 : : {
8361 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "; ... ", 6)));
8362 : : }
8363 : : }
8364 : : else
8365 : : {
8366 : 0 : First = SymbolTable_GetDeclaredMod (ProcedureSym);
8367 : 0 : if ((SymbolTable_NoOfParam (ProcedureSym)) > 0)
8368 : : {
8369 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "..", 2)));
8370 : : }
8371 : : }
8372 : 18 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "){%1Tau:% : {%1Tau}} ;", 22)));
8373 : 18 : M2MetaError_MetaErrorStringT1 (First, DynamicStrings_Dup (s), ProcedureSym);
8374 : 18 : M2MetaError_MetaErrorStringT1 (tokpos, s, ProcedureSym);
8375 : 18 : if ((SymbolTable_GetLType (Given)) == SymbolTable_NulSym)
8376 : : {
8377 : 6 : M2MetaError_MetaError1 ((const char *) "item being passed is {%1EDda} {%1Dad}", 37, Given);
8378 : : }
8379 : : else
8380 : : {
8381 : 12 : M2MetaError_MetaError1 ((const char *) "item being passed is {%1EDda} {%1Dad} of type {%1Dts}", 53, Given);
8382 : : }
8383 : 18 : }
8384 : :
8385 : :
8386 : : /*
8387 : : WarnParameter - generates a warning message indicating that a parameter
8388 : : use might cause problems on another target.
8389 : :
8390 : : The parameters are:
8391 : :
8392 : : CurrentState - string describing the current failing state.
8393 : : Given - the token that the source code provided.
8394 : : Expecting - token or identifier that was expected.
8395 : : ParameterNo - parameter number that has failed.
8396 : : ProcedureSym - procedure symbol where parameter has failed.
8397 : :
8398 : : If any parameter is Nul then it is ignored.
8399 : : */
8400 : :
8401 : 0 : static void WarnParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Given, unsigned int Expecting, unsigned int ProcedureSym, unsigned int ParameterNo)
8402 : : {
8403 : 0 : unsigned int First;
8404 : 0 : unsigned int ExpectType;
8405 : 0 : unsigned int ReturnType;
8406 : 0 : DynamicStrings_String s;
8407 : 0 : DynamicStrings_String s1;
8408 : 0 : DynamicStrings_String s2;
8409 : 0 : char CurrentState[_CurrentState_high+1];
8410 : :
8411 : : /* make a local copy of each unbounded array. */
8412 : 0 : memcpy (CurrentState, CurrentState_, _CurrentState_high+1);
8413 : :
8414 : 0 : s = DynamicStrings_InitString ((const char *) "{%W}", 4);
8415 : 0 : if (M2Comp_CompilingImplementationModule ())
8416 : : {
8417 : 0 : s = DynamicStrings_ConCat (s, FormatStrings_Sprintf0 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "warning issued while compiling the implementation module\\n", 58))));
8418 : : }
8419 : 0 : else if (M2Comp_CompilingProgramModule ())
8420 : : {
8421 : : /* avoid dangling else. */
8422 : 0 : s = DynamicStrings_ConCat (s, FormatStrings_Sprintf0 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "warning issued while compiling the program module\\n", 51))));
8423 : : }
8424 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (ProcedureSym))));
8425 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (FormatStrings_Sprintf2 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "problem in parameter %d, PROCEDURE %s (", 39)), (const unsigned char *) &ParameterNo, (sizeof (ParameterNo)-1), (const unsigned char *) &s1, (sizeof (s1)-1))));
8426 : 0 : if ((SymbolTable_NoOfParam (ProcedureSym)) >= ParameterNo)
8427 : : {
8428 : : /* avoid dangling else. */
8429 : 0 : if (ParameterNo > 1)
8430 : : {
8431 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ".., ", 4)));
8432 : : }
8433 : 0 : if (SymbolTable_IsVarParam (ProcedureSym, ParameterNo))
8434 : : {
8435 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "{%kVAR} ", 8)));
8436 : : }
8437 : 0 : First = SymbolTable_GetDeclaredMod (SymbolTable_GetNthParam (ProcedureSym, ParameterNo));
8438 : 0 : ExpectType = SymbolTable_GetSType (Expecting);
8439 : 0 : if (SymbolTable_IsUnboundedParam (ProcedureSym, ParameterNo))
8440 : : {
8441 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Expecting))));
8442 : 0 : s2 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (SymbolTable_GetSType (ExpectType)))));
8443 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (FormatStrings_Sprintf2 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "%s: {%%kARRAY} {%%kOF} %s", 25)), (const unsigned char *) &s1, (sizeof (s1)-1), (const unsigned char *) &s2, (sizeof (s2)-1))));
8444 : : }
8445 : : else
8446 : : {
8447 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Expecting))));
8448 : 0 : s2 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (ExpectType))));
8449 : 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))));
8450 : : }
8451 : 0 : if (ParameterNo < (SymbolTable_NoOfParam (ProcedureSym)))
8452 : : {
8453 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "; ... ", 6)));
8454 : : }
8455 : : }
8456 : : else
8457 : : {
8458 : 0 : First = SymbolTable_GetDeclaredMod (ProcedureSym);
8459 : 0 : if ((SymbolTable_NoOfParam (ProcedureSym)) > 0)
8460 : : {
8461 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "..", 2)));
8462 : : }
8463 : : }
8464 : 0 : ReturnType = SymbolTable_GetSType (ProcedureSym);
8465 : 0 : if (ReturnType == SymbolTable_NulSym)
8466 : : {
8467 : 0 : s = DynamicStrings_ConCat (s, FormatStrings_Sprintf0 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ") ;\\n", 5))));
8468 : : }
8469 : : else
8470 : : {
8471 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (ReturnType))));
8472 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ") : %s ;\\n", 10)), (const unsigned char *) &s1, (sizeof (s1)-1))));
8473 : : }
8474 : 0 : if (SymbolTable_IsConstString (Given))
8475 : : {
8476 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Given))));
8477 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "item being passed is '%s'", 25)), (const unsigned char *) &s1, (sizeof (s1)-1))));
8478 : : }
8479 : 0 : else if (SymbolTable_IsTemporary (Given))
8480 : : {
8481 : : /* avoid dangling else. */
8482 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "item being passed has type", 26)));
8483 : : }
8484 : : else
8485 : : {
8486 : : /* avoid dangling else. */
8487 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Given))));
8488 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "item being passed is '%s'", 25)), (const unsigned char *) &s1, (sizeof (s1)-1))));
8489 : : }
8490 : 0 : s1 = DescribeType (Given);
8491 : 0 : s2 = DynamicStrings_Mark (DynamicStrings_InitString ((const char *) CurrentState, _CurrentState_high));
8492 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (FormatStrings_Sprintf2 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ": %s\\nparameter mismatch: %s", 28)), (const unsigned char *) &s1, (sizeof (s1)-1), (const unsigned char *) &s2, (sizeof (s2)-1))));
8493 : 0 : M2MetaError_MetaErrorStringT0 (tokpos, DynamicStrings_Dup (s));
8494 : 0 : M2MetaError_MetaErrorStringT0 (First, DynamicStrings_Dup (s));
8495 : 0 : }
8496 : :
8497 : :
8498 : : /*
8499 : : doIndrX - perform des = *exp with a conversion if necessary.
8500 : : */
8501 : :
8502 : 13314 : static void doIndrX (unsigned int tok, unsigned int des, unsigned int exp)
8503 : : {
8504 : 13314 : unsigned int t;
8505 : :
8506 : 13314 : if ((SymbolTable_GetDType (des)) == (SymbolTable_GetDType (exp)))
8507 : : {
8508 : 13172 : GenQuadOtok (tok, M2Quads_IndrXOp, des, SymbolTable_GetSType (des), exp, true, tok, tok, tok);
8509 : : }
8510 : : else
8511 : : {
8512 : 142 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
8513 : 142 : SymbolTable_PutVar (t, SymbolTable_GetSType (exp));
8514 : 142 : GenQuadOtok (tok, M2Quads_IndrXOp, t, SymbolTable_GetSType (exp), exp, true, tok, tok, tok);
8515 : 142 : GenQuadOtok (tok, M2Quads_BecomesOp, des, SymbolTable_NulSym, doVal (SymbolTable_GetSType (des), t), true, tok, M2LexBuf_UnknownTokenNo, tok);
8516 : : }
8517 : 13314 : }
8518 : :
8519 : :
8520 : : /*
8521 : : MakeRightValue - returns a temporary which will have the RightValue of symbol, Sym.
8522 : : If Sym is a right value and has type, type, then no quadruples are
8523 : : generated and Sym is returned. Otherwise a new temporary is created
8524 : : and an IndrX quadruple is generated.
8525 : : */
8526 : :
8527 : 1045 : static unsigned int MakeRightValue (unsigned int tok, unsigned int Sym, unsigned int type)
8528 : : {
8529 : 1045 : unsigned int t;
8530 : :
8531 : 1045 : if ((SymbolTable_GetMode (Sym)) == SymbolTable_RightValue)
8532 : : {
8533 : 0 : if ((SymbolTable_GetSType (Sym)) == type)
8534 : : {
8535 : : return Sym;
8536 : : }
8537 : : else
8538 : : {
8539 : : /*
8540 : : type change or mode change, type changes are a pain, but I've
8541 : : left them here as it is perhaps easier to remove them later.
8542 : : */
8543 : 0 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
8544 : 0 : SymbolTable_PutVar (t, type);
8545 : 0 : GenQuadOtok (tok, M2Quads_BecomesOp, t, SymbolTable_NulSym, doVal (type, Sym), true, tok, tok, tok);
8546 : 0 : return t;
8547 : : }
8548 : : }
8549 : : else
8550 : : {
8551 : 1045 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
8552 : 1045 : SymbolTable_PutVar (t, type);
8553 : 1045 : CheckPointerThroughNil (tok, Sym);
8554 : 1045 : doIndrX (tok, t, Sym);
8555 : 1045 : return t;
8556 : : }
8557 : : /* static analysis guarentees a RETURN statement will be used before here. */
8558 : : __builtin_unreachable ();
8559 : : }
8560 : :
8561 : :
8562 : : /*
8563 : : MakeLeftValue - returns a temporary coresponding to the LeftValue of
8564 : : symbol, Sym. No quadruple is generated if Sym is already
8565 : : a LeftValue and has the same type.
8566 : : */
8567 : :
8568 : 165300 : static unsigned int MakeLeftValue (unsigned int tok, unsigned int Sym, SymbolTable_ModeOfAddr with, unsigned int type)
8569 : : {
8570 : 165300 : unsigned int t;
8571 : :
8572 : 165300 : if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
8573 : : {
8574 : 4879 : if ((SymbolTable_GetSType (Sym)) == type)
8575 : : {
8576 : : return Sym;
8577 : : }
8578 : : else
8579 : : {
8580 : : /*
8581 : : type change or mode change, type changes are a pain, but I've
8582 : : left them here as it is perhaps easier to remove them later
8583 : : */
8584 : 80 : t = SymbolTable_MakeTemporary (tok, with);
8585 : 80 : SymbolTable_PutVar (t, type);
8586 : 80 : GenQuadOtok (tok, M2Quads_BecomesOp, t, SymbolTable_NulSym, Sym, true, tok, M2LexBuf_UnknownTokenNo, tok);
8587 : 80 : return t;
8588 : : }
8589 : : }
8590 : : else
8591 : : {
8592 : 160421 : t = SymbolTable_MakeTemporary (tok, with);
8593 : 160421 : SymbolTable_PutVar (t, type);
8594 : 160421 : GenQuadOtok (tok, M2Quads_AddrOp, t, SymbolTable_NulSym, Sym, true, tok, M2LexBuf_UnknownTokenNo, tok);
8595 : 160421 : return t;
8596 : : }
8597 : : /* static analysis guarentees a RETURN statement will be used before here. */
8598 : : __builtin_unreachable ();
8599 : : }
8600 : :
8601 : :
8602 : : /*
8603 : : ManipulatePseudoCallParameters - manipulates the parameters to a pseudo function or
8604 : : procedure. It dereferences all LeftValue parameters
8605 : : and Boolean parameters.
8606 : : The Stack:
8607 : :
8608 : :
8609 : : Entry Exit
8610 : :
8611 : : Ptr -> exactly the same
8612 : : +----------------+
8613 : : | NoOfParameters |
8614 : : |----------------|
8615 : : | Param 1 |
8616 : : |----------------|
8617 : : | Param 2 |
8618 : : |----------------|
8619 : : . .
8620 : : . .
8621 : : . .
8622 : : |----------------|
8623 : : | Param # |
8624 : : |----------------|
8625 : : | ProcSym | Type |
8626 : : |----------------|
8627 : :
8628 : : */
8629 : :
8630 : 49180 : static void ManipulatePseudoCallParameters (void)
8631 : : {
8632 : 49180 : unsigned int NoOfParameters;
8633 : 49180 : unsigned int ProcSym;
8634 : 49180 : unsigned int Proc;
8635 : 49180 : unsigned int i;
8636 : 49180 : unsigned int pi;
8637 : 49180 : M2Quads_BoolFrame f;
8638 : :
8639 : 49180 : M2Quads_PopT (&NoOfParameters);
8640 : 49180 : M2Quads_PushT (NoOfParameters); /* restored to original state */
8641 : : /* Ptr points to the ProcSym */
8642 : 49180 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((NoOfParameters+1)+1));
8643 : 49180 : if (SymbolTable_IsVar (ProcSym))
8644 : : {
8645 : 0 : M2Error_InternalError ((const char *) "expecting a pseudo procedure or a type", 38);
8646 : : }
8647 : : else
8648 : : {
8649 : 49180 : Proc = ProcSym;
8650 : : }
8651 : 49180 : i = 1;
8652 : 49180 : pi = NoOfParameters+1;
8653 : 107897 : while (i <= NoOfParameters)
8654 : : {
8655 : 58717 : 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)))
8656 : : {
8657 : : /* must dereference LeftValue */
8658 : 884 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pi));
8659 : 884 : f->TrueExit = MakeRightValue (M2LexBuf_GetTokenNo (), M2Quads_OperandT (pi), SymbolTable_GetSType (M2Quads_OperandT (pi)));
8660 : : }
8661 : 58717 : i += 1;
8662 : 58717 : pi -= 1;
8663 : : }
8664 : 49180 : }
8665 : :
8666 : :
8667 : : /*
8668 : : ManipulateParameters - manipulates the procedure parameters in
8669 : : preparation for a procedure call.
8670 : : Prepares Boolean, Unbounded and VAR parameters.
8671 : : The Stack:
8672 : :
8673 : :
8674 : : Entry Exit
8675 : :
8676 : : Ptr -> exactly the same
8677 : : +----------------+
8678 : : | NoOfParameters |
8679 : : |----------------|
8680 : : | Param 1 |
8681 : : |----------------|
8682 : : | Param 2 |
8683 : : |----------------|
8684 : : . .
8685 : : . .
8686 : : . .
8687 : : |----------------|
8688 : : | Param # |
8689 : : |----------------|
8690 : : | ProcSym | Type |
8691 : : |----------------|
8692 : : */
8693 : :
8694 : 168660 : static void ManipulateParameters (bool IsForC)
8695 : : {
8696 : 168660 : unsigned int tokpos;
8697 : 168660 : unsigned int np;
8698 : 168660 : DynamicStrings_String s;
8699 : 168660 : unsigned int ArraySym;
8700 : 168660 : unsigned int UnboundedType;
8701 : 168660 : unsigned int ParamType;
8702 : 168660 : unsigned int NoOfParameters;
8703 : 168660 : unsigned int i;
8704 : 168660 : unsigned int pi;
8705 : 168660 : unsigned int ProcSym;
8706 : 168660 : unsigned int rw;
8707 : 168660 : unsigned int Proc;
8708 : 168660 : unsigned int t;
8709 : 168660 : M2Quads_BoolFrame f;
8710 : :
8711 : 168660 : M2Quads_PopT (&NoOfParameters);
8712 : 168660 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+1));
8713 : 168660 : tokpos = OperandTtok (NoOfParameters+1);
8714 : 168660 : if (SymbolTable_IsVar (ProcSym))
8715 : : {
8716 : : /* Procedure Variable ? */
8717 : 672 : Proc = SymbolTable_SkipType (M2Quads_OperandF (NoOfParameters+1));
8718 : : }
8719 : : else
8720 : : {
8721 : 167988 : Proc = PCSymBuild_SkipConst (ProcSym);
8722 : : }
8723 : 168660 : if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
8724 : : {
8725 : : /* avoid dangling else. */
8726 : 7170 : if (NoOfParameters < (SymbolTable_NoOfParam (Proc)))
8727 : : {
8728 : 0 : s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
8729 : 0 : np = SymbolTable_NoOfParam (Proc);
8730 : 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));
8731 : : }
8732 : : }
8733 : 161490 : else if (SymbolTable_UsesOptArg (Proc))
8734 : : {
8735 : : /* avoid dangling else. */
8736 : 2576 : if (! ((NoOfParameters == (SymbolTable_NoOfParam (Proc))) || ((NoOfParameters+1) == (SymbolTable_NoOfParam (Proc)))))
8737 : : {
8738 : 0 : s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
8739 : 0 : np = SymbolTable_NoOfParam (Proc);
8740 : 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));
8741 : : }
8742 : : }
8743 : 158914 : else if (NoOfParameters != (SymbolTable_NoOfParam (Proc)))
8744 : : {
8745 : : /* avoid dangling else. */
8746 : 0 : s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
8747 : 0 : np = SymbolTable_NoOfParam (Proc);
8748 : 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));
8749 : : }
8750 : 168660 : i = 1;
8751 : 168660 : pi = NoOfParameters;
8752 : 605950 : while (i <= NoOfParameters)
8753 : : {
8754 : 437290 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pi));
8755 : 437290 : rw = static_cast<unsigned int> (OperandMergeRW (pi));
8756 : 437290 : M2Debug_Assert (SymbolTable_IsLegal (rw));
8757 : 437290 : if (i > (SymbolTable_NoOfParam (Proc)))
8758 : : {
8759 : 6785 : if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
8760 : : {
8761 : : /* avoid dangling else. */
8762 : 6785 : if (((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym) && (SymbolTable_IsArray (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
8763 : : {
8764 : 156 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_RightValue, M2System_Address);
8765 : 156 : MarkAsReadWrite (rw);
8766 : : }
8767 : 6629 : else if (SymbolTable_IsConstString (M2Quads_OperandT (pi)))
8768 : : {
8769 : : /* avoid dangling else. */
8770 : 233 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), DeferMakeConstStringCnul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi)), SymbolTable_RightValue, M2System_Address);
8771 : 233 : MarkAsReadWrite (rw);
8772 : : }
8773 : 6396 : else if (((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (M2Quads_OperandT (pi)))))
8774 : : {
8775 : : /* avoid dangling else. */
8776 : 152 : MarkAsReadWrite (rw);
8777 : : /* pass the address field of an unbounded variable */
8778 : 152 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, M2Quads_OperandTok (pi));
8779 : 152 : PushTFAD (f->TrueExit, f->FalseExit, f->Unbounded, f->Dimension);
8780 : 152 : M2Quads_PushT (static_cast<unsigned int> (1));
8781 : 152 : BuildAdrFunction ();
8782 : 152 : M2Quads_PopT (&f->TrueExit);
8783 : : }
8784 : 6244 : else if ((SymbolTable_GetMode (M2Quads_OperandT (pi))) == SymbolTable_LeftValue)
8785 : : {
8786 : : /* avoid dangling else. */
8787 : 374 : MarkAsReadWrite (rw);
8788 : : /* must dereference LeftValue (even if we are passing variable as a vararg) */
8789 : 374 : t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
8790 : 374 : SymbolTable_PutVar (t, SymbolTable_GetSType (M2Quads_OperandT (pi)));
8791 : 374 : CheckPointerThroughNil (tokpos, M2Quads_OperandT (pi));
8792 : 374 : doIndrX (M2Quads_OperandTok (pi), t, M2Quads_OperandT (pi));
8793 : 374 : f->TrueExit = t;
8794 : : }
8795 : : }
8796 : : else
8797 : : {
8798 : 0 : M2MetaError_MetaErrorT2 (tokpos, (const char *) "attempting to pass too many parameters to procedure {%1a}, the {%2N} parameter does not exist", 93, Proc, i);
8799 : : }
8800 : : }
8801 : 430505 : else if (((IsForC && (SymbolTable_IsUnboundedParam (Proc, i))) && ((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym)) && (SymbolTable_IsArray (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
8802 : : {
8803 : : /* avoid dangling else. */
8804 : 24 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_RightValue, M2System_Address);
8805 : 24 : MarkAsReadWrite (rw);
8806 : : }
8807 : 430481 : else if (((IsForC && (SymbolTable_IsUnboundedParam (Proc, i))) && ((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym)) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
8808 : : {
8809 : : /* avoid dangling else. */
8810 : 184 : MarkAsReadWrite (rw);
8811 : : /* pass the address field of an unbounded variable */
8812 : 184 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, M2Quads_OperandTok (pi));
8813 : 184 : PushTFAD (f->TrueExit, f->FalseExit, f->Unbounded, f->Dimension);
8814 : 184 : M2Quads_PushT (static_cast<unsigned int> (1));
8815 : 184 : BuildAdrFunction ();
8816 : 184 : M2Quads_PopT (&f->TrueExit);
8817 : : }
8818 : 430297 : else if ((IsForC && (SymbolTable_IsConstString (M2Quads_OperandT (pi)))) && ((SymbolTable_IsUnboundedParam (Proc, i)) || ((SymbolTable_GetDType (SymbolTable_GetParam (Proc, i))) == M2System_Address)))
8819 : : {
8820 : : /* avoid dangling else. */
8821 : 6734 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), DeferMakeConstStringCnul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi)), SymbolTable_RightValue, M2System_Address);
8822 : 6734 : MarkAsReadWrite (rw);
8823 : : }
8824 : 423563 : else if (SymbolTable_IsUnboundedParam (Proc, i))
8825 : : {
8826 : : /* avoid dangling else. */
8827 : : /* always pass constant strings with a nul terminator, but leave the HIGH as before. */
8828 : 33436 : if (SymbolTable_IsConstString (M2Quads_OperandT (pi)))
8829 : : {
8830 : : /* this is a Modula-2 string which must be nul terminated. */
8831 : 21932 : f->TrueExit = DeferMakeConstStringM2nul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi));
8832 : : }
8833 : 33436 : t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
8834 : 33436 : UnboundedType = SymbolTable_GetSType (SymbolTable_GetParam (Proc, i));
8835 : 33436 : SymbolTable_PutVar (t, UnboundedType);
8836 : 33436 : ParamType = SymbolTable_GetSType (UnboundedType);
8837 : 33436 : if ((OperandD (pi)) == 0)
8838 : : {
8839 : 33388 : ArraySym = static_cast<unsigned int> (M2Quads_OperandT (pi));
8840 : : }
8841 : : else
8842 : : {
8843 : 48 : ArraySym = static_cast<unsigned int> (M2Quads_OperandA (pi));
8844 : : }
8845 : 33436 : if (SymbolTable_IsVarParam (Proc, i))
8846 : : {
8847 : 3923 : MarkArrayWritten (M2Quads_OperandT (pi));
8848 : 3923 : MarkArrayWritten (M2Quads_OperandA (pi));
8849 : 3923 : MarkAsReadWrite (rw);
8850 : 3923 : AssignUnboundedVar (OperandTtok (pi), M2Quads_OperandT (pi), ArraySym, t, ParamType, OperandD (pi));
8851 : : }
8852 : : else
8853 : : {
8854 : 29513 : MarkAsRead (rw);
8855 : 29513 : AssignUnboundedNonVar (OperandTtok (pi), M2Quads_OperandT (pi), ArraySym, t, ParamType, OperandD (pi));
8856 : : }
8857 : 33436 : f->TrueExit = t;
8858 : : }
8859 : 390127 : else if (SymbolTable_IsVarParam (Proc, i))
8860 : : {
8861 : : /* avoid dangling else. */
8862 : : /* must reference by address, but we contain the type of the referenced entity */
8863 : 12879 : MarkArrayWritten (M2Quads_OperandT (pi));
8864 : 12879 : MarkArrayWritten (M2Quads_OperandA (pi));
8865 : 12879 : MarkAsReadWrite (rw);
8866 : 12879 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_LeftValue, SymbolTable_GetSType (SymbolTable_GetParam (Proc, i)));
8867 : : }
8868 : 377248 : else if ((! (SymbolTable_IsVarParam (Proc, i))) && ((SymbolTable_GetMode (M2Quads_OperandT (pi))) == SymbolTable_LeftValue))
8869 : : {
8870 : : /* avoid dangling else. */
8871 : : /* must dereference LeftValue */
8872 : 1246 : t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
8873 : 1246 : SymbolTable_PutVar (t, SymbolTable_GetSType (M2Quads_OperandT (pi)));
8874 : 1246 : CheckPointerThroughNil (tokpos, M2Quads_OperandT (pi));
8875 : 1246 : doIndrX (M2Quads_OperandTok (pi), t, M2Quads_OperandT (pi));
8876 : 1246 : f->TrueExit = t;
8877 : 1246 : MarkAsRead (rw);
8878 : : }
8879 : : else
8880 : : {
8881 : : /* avoid dangling else. */
8882 : 376002 : MarkAsRead (rw);
8883 : : }
8884 : 437290 : i += 1;
8885 : 437290 : pi -= 1;
8886 : : }
8887 : 168660 : M2Quads_PushT (NoOfParameters);
8888 : 168660 : }
8889 : :
8890 : :
8891 : : /*
8892 : : CheckParameterOrdinals - check that ordinal values are within type range.
8893 : : */
8894 : :
8895 : 168660 : static void CheckParameterOrdinals (void)
8896 : : {
8897 : 168660 : unsigned int tokno;
8898 : 168660 : unsigned int Proc;
8899 : 168660 : unsigned int ProcSym;
8900 : 168660 : unsigned int Actual;
8901 : 168660 : unsigned int FormalI;
8902 : 168660 : unsigned int ParamTotal;
8903 : 168660 : unsigned int pi;
8904 : 168660 : unsigned int i;
8905 : :
8906 : 168660 : M2Quads_PopT (&ParamTotal);
8907 : 168660 : M2Quads_PushT (ParamTotal); /* Restore stack to origional state */
8908 : 168660 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((ParamTotal+1)+1)); /* Restore stack to origional state */
8909 : 168660 : if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (SymbolTable_GetDType (ProcSym))))
8910 : : {
8911 : : /* Indirect procedure call. */
8912 : 672 : Proc = SymbolTable_SkipType (M2Quads_OperandF ((ParamTotal+1)+1));
8913 : : }
8914 : : else
8915 : : {
8916 : 167988 : Proc = PCSymBuild_SkipConst (ProcSym);
8917 : : }
8918 : 168660 : i = 1;
8919 : 168660 : pi = ParamTotal+1; /* stack index referencing stacked parameter, i */
8920 : 605950 : while (i <= ParamTotal) /* stack index referencing stacked parameter, i */
8921 : : {
8922 : 437290 : if (i <= (SymbolTable_NoOfParam (Proc)))
8923 : : {
8924 : 430505 : FormalI = SymbolTable_GetParam (Proc, i);
8925 : 430505 : Actual = static_cast<unsigned int> (M2Quads_OperandT (pi));
8926 : 430505 : tokno = static_cast<unsigned int> (M2Quads_OperandTok (pi));
8927 : 430505 : if (M2Base_IsOrdinalType (SymbolTable_GetLType (FormalI)))
8928 : : {
8929 : 111300 : if (! (SymbolTable_IsSet (SymbolTable_GetDType (FormalI))))
8930 : : {
8931 : : /* tell code generator to test runtime values of assignment so ensure we
8932 : : catch overflow and underflow */
8933 : 111300 : BuildRange (M2Range_InitParameterRangeCheck (tokno, Proc, i, FormalI, Actual));
8934 : : }
8935 : : }
8936 : : }
8937 : 437290 : i += 1;
8938 : 437290 : pi -= 1;
8939 : : }
8940 : 168660 : }
8941 : :
8942 : :
8943 : : /*
8944 : : IsSameUnbounded - returns TRUE if unbounded types, t1, and, t2,
8945 : : are compatible.
8946 : : */
8947 : :
8948 : 36 : static bool IsSameUnbounded (unsigned int t1, unsigned int t2)
8949 : : {
8950 : 36 : M2Debug_Assert (SymbolTable_IsUnbounded (t1));
8951 : 36 : M2Debug_Assert (SymbolTable_IsUnbounded (t2));
8952 : 36 : return (SymbolTable_GetDType (t1)) == (SymbolTable_GetDType (t2));
8953 : : /* static analysis guarentees a RETURN statement will be used before here. */
8954 : : __builtin_unreachable ();
8955 : : }
8956 : :
8957 : :
8958 : : /*
8959 : : AssignUnboundedVar - assigns an Unbounded symbol fields,
8960 : : ArrayAddress and ArrayHigh, from an array symbol.
8961 : : UnboundedSym is not a VAR parameter and therefore
8962 : : this procedure can complete both of the fields.
8963 : : Sym can be a Variable with type Unbounded.
8964 : : Sym can be a Variable with type Array.
8965 : : Sym can be a String Constant.
8966 : :
8967 : : ParamType is the TYPE of the parameter
8968 : : */
8969 : :
8970 : 3923 : static void AssignUnboundedVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
8971 : : {
8972 : 3923 : unsigned int Type;
8973 : :
8974 : 3923 : if (SymbolTable_IsConst (Sym))
8975 : : {
8976 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
8977 : : }
8978 : 3923 : else if (SymbolTable_IsVar (Sym))
8979 : : {
8980 : : /* avoid dangling else. */
8981 : 3923 : Type = SymbolTable_GetDType (Sym);
8982 : 3923 : if (Type == SymbolTable_NulSym)
8983 : : {
8984 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} has no type and cannot be passed to a VAR formal parameter", 65, Sym);
8985 : : }
8986 : 3923 : else if (SymbolTable_IsUnbounded (Type))
8987 : : {
8988 : : /* avoid dangling else. */
8989 : 1274 : if (Type == (SymbolTable_GetSType (UnboundedSym)))
8990 : : {
8991 : : /* Copy Unbounded Symbol ie. UnboundedSym := Sym */
8992 : 1238 : M2Quads_PushT (UnboundedSym);
8993 : 1238 : M2Quads_PushT (Sym);
8994 : 1238 : BuildAssignmentWithoutBounds (tok, false, true);
8995 : : }
8996 : 36 : else if ((IsSameUnbounded (Type, SymbolTable_GetSType (UnboundedSym))) || (M2System_IsGenericSystemType (ParamType)))
8997 : : {
8998 : : /* avoid dangling else. */
8999 : 36 : UnboundedVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9000 : : }
9001 : : else
9002 : : {
9003 : : /* avoid dangling else. */
9004 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
9005 : : }
9006 : : }
9007 : 2649 : else if ((SymbolTable_IsArray (Type)) || (M2System_IsGenericSystemType (ParamType)))
9008 : : {
9009 : : /* avoid dangling else. */
9010 : 2649 : UnboundedVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9011 : : }
9012 : : else
9013 : : {
9014 : : /* avoid dangling else. */
9015 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
9016 : : }
9017 : : }
9018 : : else
9019 : : {
9020 : : /* avoid dangling else. */
9021 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
9022 : : }
9023 : 3923 : }
9024 : :
9025 : :
9026 : : /*
9027 : : AssignUnboundedNonVar - assigns an Unbounded symbol fields,
9028 : : The difference between this procedure and
9029 : : AssignUnboundedVar is that this procedure cannot
9030 : : set the Unbounded.Address since the data from
9031 : : Sym will be copied because parameter is NOT a VAR
9032 : : parameter.
9033 : : UnboundedSym is not a VAR parameter and therefore
9034 : : this procedure can only complete the HIGH field
9035 : : and not the ADDRESS field.
9036 : : Sym can be a Variable with type Unbounded.
9037 : : Sym can be a Variable with type Array.
9038 : : Sym can be a String Constant.
9039 : :
9040 : : ParamType is the TYPE of the paramater
9041 : : */
9042 : :
9043 : 29513 : static void AssignUnboundedNonVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9044 : : {
9045 : 29513 : unsigned int Type;
9046 : :
9047 : 29513 : if (SymbolTable_IsConst (Sym)) /* was IsConstString(Sym) */
9048 : : {
9049 : 21968 : UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9050 : : }
9051 : 7545 : else if (SymbolTable_IsVar (Sym))
9052 : : {
9053 : : /* avoid dangling else. */
9054 : 7545 : Type = SymbolTable_GetDType (Sym);
9055 : 7545 : if (Type == SymbolTable_NulSym)
9056 : : {
9057 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} has no type and cannot be passed to a non VAR formal parameter", 69, Sym);
9058 : : }
9059 : 7545 : else if (SymbolTable_IsUnbounded (Type))
9060 : : {
9061 : : /* avoid dangling else. */
9062 : 3303 : UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9063 : : }
9064 : 4242 : else if ((SymbolTable_IsArray (Type)) || (M2System_IsGenericSystemType (ParamType)))
9065 : : {
9066 : : /* avoid dangling else. */
9067 : 4242 : UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9068 : : }
9069 : : else
9070 : : {
9071 : : /* avoid dangling else. */
9072 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "illegal type parameter {%1Ead} expecting array or dynamic array", 63, Sym);
9073 : : }
9074 : : }
9075 : : else
9076 : : {
9077 : : /* avoid dangling else. */
9078 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "illegal parameter {%1Ead} which cannot be passed as {%kVAR} {%kARRAY} {%kOF} {%1tsad}", 85, Sym);
9079 : : }
9080 : 29513 : }
9081 : :
9082 : :
9083 : : /*
9084 : : GenHigh - generates a HighOp but it checks if op3 is a
9085 : : L value and if so it dereferences it. This
9086 : : is inefficient, however it is clean and we let the gcc
9087 : : backend detect these as common subexpressions.
9088 : : It will also detect that a R value -> L value -> R value
9089 : : via indirection and eleminate these.
9090 : : */
9091 : :
9092 : 34454 : static void GenHigh (unsigned int tok, unsigned int op1, unsigned int op2, unsigned int op3)
9093 : : {
9094 : 34454 : unsigned int sym;
9095 : :
9096 : 34454 : if (((SymbolTable_GetMode (op3)) == SymbolTable_LeftValue) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (op3))))
9097 : : {
9098 : 48 : sym = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
9099 : 48 : SymbolTable_PutVar (sym, SymbolTable_GetSType (op3));
9100 : 48 : doIndrX (tok, sym, op3);
9101 : 48 : GenQuadO (tok, M2Quads_HighOp, op1, op2, sym, true);
9102 : : }
9103 : : else
9104 : : {
9105 : 34406 : GenQuadO (tok, M2Quads_HighOp, op1, op2, op3, true);
9106 : : }
9107 : 34454 : }
9108 : :
9109 : :
9110 : : /*
9111 : : AssignHighField -
9112 : : */
9113 : :
9114 : 32342 : static void AssignHighField (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int actuali, unsigned int formali)
9115 : : {
9116 : 32342 : unsigned int ReturnVar;
9117 : 32342 : unsigned int ArrayType;
9118 : 32342 : unsigned int Field;
9119 : :
9120 : : /* Unbounded.ArrayHigh := HIGH(ArraySym) */
9121 : 32342 : M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
9122 : 32342 : Field = SymbolTable_GetUnboundedHighOffset (SymbolTable_GetSType (UnboundedSym), formali);
9123 : 32342 : M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
9124 : 32342 : M2Quads_PushT (static_cast<unsigned int> (1));
9125 : 32342 : M2Quads_BuildDesignatorRecord (tok);
9126 : 32342 : if (M2System_IsGenericSystemType (ParamType))
9127 : : {
9128 : 1146 : if (SymbolTable_IsConstString (Sym))
9129 : : {
9130 : 18 : M2Quads_PushTtok (DeferMakeLengthConst (tok, Sym), tok);
9131 : : }
9132 : : else
9133 : : {
9134 : 1128 : ArrayType = SymbolTable_GetSType (Sym);
9135 : 1128 : if (SymbolTable_IsUnbounded (ArrayType))
9136 : : {
9137 : : /*
9138 : : * SIZE(parameter) DIV TSIZE(ParamType)
9139 : : * however in this case parameter
9140 : : * is an unbounded symbol and therefore we must use
9141 : : * (HIGH(parameter)+1)*SIZE(unbounded type) DIV TSIZE(ParamType)
9142 : : *
9143 : : * we call upon the function SIZE(ArraySym)
9144 : : * remember SIZE doubles as
9145 : : * (HIGH(a)+1) * SIZE(ArrayType) for unbounded symbols
9146 : : */
9147 : 294 : M2Quads_PushTFtok (calculateMultipicand (tok, ArraySym, ArrayType, actuali-1), M2Base_Cardinal, tok);
9148 : 294 : M2Quads_PushT (M2Reserved_DivideTok); /* Divide by */
9149 : 294 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok); /* TSIZE(ParamType) */
9150 : 294 : M2Quads_PushTtok (ParamType, tok); /* TSIZE(ParamType) */
9151 : 294 : M2Quads_PushT (static_cast<unsigned int> (1)); /* 1 parameter for TSIZE() */
9152 : 294 : M2Quads_BuildFunctionCall (false); /* 1 parameter for TSIZE() */
9153 : 294 : M2Quads_BuildBinaryOp ();
9154 : : }
9155 : : else
9156 : : {
9157 : : /* SIZE(parameter) DIV TSIZE(ParamType) */
9158 : 834 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok); /* TSIZE(ArrayType) */
9159 : 834 : M2Quads_PushTtok (ArrayType, tok); /* TSIZE(ArrayType) */
9160 : 834 : M2Quads_PushT (static_cast<unsigned int> (1)); /* 1 parameter for TSIZE() */
9161 : 834 : M2Quads_BuildFunctionCall (true); /* 1 parameter for TSIZE() */
9162 : 834 : M2Quads_PushT (M2Reserved_DivideTok); /* Divide by */
9163 : 834 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok); /* TSIZE(ParamType) */
9164 : 834 : M2Quads_PushTtok (ParamType, tok); /* TSIZE(ParamType) */
9165 : 834 : M2Quads_PushT (static_cast<unsigned int> (1)); /* 1 parameter for TSIZE() */
9166 : 834 : M2Quads_BuildFunctionCall (true); /* 1 parameter for TSIZE() */
9167 : 834 : M2Quads_BuildBinaryOp ();
9168 : : }
9169 : : /* now convert from no of elements into HIGH by subtracting 1 */
9170 : 1128 : M2Quads_PushT (M2Reserved_MinusTok); /* -1 */
9171 : 1128 : M2Quads_PushTtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal), tok); /* -1 */
9172 : 1128 : M2Quads_BuildBinaryOp ();
9173 : : }
9174 : : }
9175 : : else
9176 : : {
9177 : 31196 : ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
9178 : 31196 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
9179 : 31196 : if (((actuali != formali) && (ArraySym != SymbolTable_NulSym)) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (ArraySym))))
9180 : : {
9181 : 12 : GenHigh (tok, ReturnVar, actuali, ArraySym);
9182 : : }
9183 : : else
9184 : : {
9185 : 31184 : GenHigh (tok, ReturnVar, formali, Sym);
9186 : : }
9187 : 31196 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), tok);
9188 : : }
9189 : 32342 : BuildAssignmentWithoutBounds (tok, false, true);
9190 : 32342 : }
9191 : :
9192 : :
9193 : : /*
9194 : : AssignHighFields -
9195 : : */
9196 : :
9197 : 32198 : static void AssignHighFields (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9198 : : {
9199 : 32198 : unsigned int type;
9200 : 32198 : unsigned int actuali;
9201 : 32198 : unsigned int formali;
9202 : 32198 : unsigned int actualn;
9203 : 32198 : unsigned int formaln;
9204 : :
9205 : 32198 : type = SymbolTable_GetDType (Sym);
9206 : 32198 : actualn = 1;
9207 : 32198 : if ((type != SymbolTable_NulSym) && ((SymbolTable_IsUnbounded (type)) || (SymbolTable_IsArray (type))))
9208 : : {
9209 : 9420 : actualn = SymbolTable_GetDimension (type);
9210 : : }
9211 : 32198 : actuali = dim+1;
9212 : 32198 : formali = 1;
9213 : 32198 : formaln = SymbolTable_GetDimension (SymbolTable_GetDType (UnboundedSym));
9214 : 64540 : while ((actuali < actualn) && (formali < formaln))
9215 : : {
9216 : 144 : AssignHighField (tok, Sym, ArraySym, UnboundedSym, SymbolTable_NulSym, actuali, formali);
9217 : 144 : actuali += 1;
9218 : 144 : formali += 1;
9219 : : }
9220 : 32198 : AssignHighField (tok, Sym, ArraySym, UnboundedSym, ParamType, actuali, formali);
9221 : 32198 : }
9222 : :
9223 : :
9224 : : /*
9225 : : UnboundedNonVarLinkToArray - links an array, ArraySym, to an unbounded
9226 : : array, UnboundedSym. The parameter is a
9227 : : NON VAR variety.
9228 : : */
9229 : :
9230 : 29513 : static void UnboundedNonVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9231 : : {
9232 : 29513 : unsigned int Field;
9233 : 29513 : unsigned int AddressField;
9234 : :
9235 : : /* Unbounded.ArrayAddress := to be assigned at runtime. */
9236 : 29513 : M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
9237 : 29513 : Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
9238 : 29513 : M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
9239 : 29513 : M2Quads_PushT (static_cast<unsigned int> (1));
9240 : 29513 : M2Quads_BuildDesignatorRecord (tok);
9241 : 29513 : M2Quads_PopT (&AddressField);
9242 : : /* caller saves non var unbounded array contents. */
9243 : 59026 : GenQuadO (tok, M2Quads_UnboundedOp, AddressField, SymbolTable_NulSym, Sym, false);
9244 : 29513 : AssignHighFields (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9245 : 29513 : }
9246 : :
9247 : :
9248 : : /*
9249 : : UnboundedVarLinkToArray - links an array, ArraySym, to an unbounded array,
9250 : : UnboundedSym. The parameter is a VAR variety.
9251 : : */
9252 : :
9253 : 2685 : static void UnboundedVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9254 : : {
9255 : 2685 : unsigned int SymType;
9256 : 2685 : unsigned int Field;
9257 : :
9258 : 2685 : SymType = SymbolTable_GetSType (Sym);
9259 : : /* Unbounded.ArrayAddress := ADR(Sym) */
9260 : 2685 : M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
9261 : 2685 : Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
9262 : 2685 : M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
9263 : 2685 : M2Quads_PushT (static_cast<unsigned int> (1));
9264 : 2685 : M2Quads_BuildDesignatorRecord (tok);
9265 : 2685 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok); /* ADR (Sym). */
9266 : 2685 : if ((SymbolTable_IsUnbounded (SymType)) && (dim == 0)) /* ADR (Sym). */
9267 : : {
9268 : 12 : PushTFADtok (Sym, SymType, UnboundedSym, dim, tok);
9269 : : }
9270 : : else
9271 : : {
9272 : 2673 : PushTFADtok (Sym, SymType, ArraySym, dim, tok);
9273 : : }
9274 : 2685 : M2Quads_PushT (static_cast<unsigned int> (1)); /* 1 parameter for ADR(). */
9275 : 2685 : M2Quads_BuildFunctionCall (false); /* 1 parameter for ADR(). */
9276 : 2685 : BuildAssignmentWithoutBounds (tok, false, true);
9277 : 2685 : AssignHighFields (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9278 : 2685 : }
9279 : :
9280 : :
9281 : : /*
9282 : : BuildPseudoProcedureCall - builds a pseudo procedure call.
9283 : : This procedure does not directly alter the
9284 : : stack, but by calling routines the stack
9285 : : will change in the following way when this
9286 : : procedure returns.
9287 : :
9288 : : The Stack:
9289 : :
9290 : :
9291 : : Entry Exit
9292 : :
9293 : : Ptr ->
9294 : : +----------------+
9295 : : | NoOfParam |
9296 : : |----------------|
9297 : : | Param 1 |
9298 : : |----------------|
9299 : : | Param 2 |
9300 : : |----------------|
9301 : : . .
9302 : : . .
9303 : : . .
9304 : : |----------------|
9305 : : | Param # |
9306 : : |----------------|
9307 : : | ProcSym | Type | Empty
9308 : : |----------------|
9309 : : */
9310 : :
9311 : 16464 : static void BuildPseudoProcedureCall (unsigned int tokno)
9312 : : {
9313 : 16464 : unsigned int NoOfParam;
9314 : 16464 : unsigned int ProcSym;
9315 : :
9316 : 16464 : M2Quads_PopT (&NoOfParam);
9317 : 16464 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
9318 : 16464 : M2Quads_PushT (NoOfParam);
9319 : : /* Compile time stack restored to entry state */
9320 : 16464 : if (ProcSym == M2Base_New)
9321 : : {
9322 : 574 : BuildNewProcedure (tokno);
9323 : : }
9324 : 15890 : else if (ProcSym == M2Base_Dispose)
9325 : : {
9326 : : /* avoid dangling else. */
9327 : 270 : BuildDisposeProcedure (tokno);
9328 : : }
9329 : 15620 : else if (ProcSym == M2Base_Inc)
9330 : : {
9331 : : /* avoid dangling else. */
9332 : 11057 : BuildIncProcedure ();
9333 : : }
9334 : 4563 : else if (ProcSym == M2Base_Dec)
9335 : : {
9336 : : /* avoid dangling else. */
9337 : 3290 : BuildDecProcedure ();
9338 : : }
9339 : 1273 : else if (ProcSym == M2Base_Incl)
9340 : : {
9341 : : /* avoid dangling else. */
9342 : 729 : BuildInclProcedure ();
9343 : : }
9344 : 544 : else if (ProcSym == M2Base_Excl)
9345 : : {
9346 : : /* avoid dangling else. */
9347 : 435 : BuildExclProcedure ();
9348 : : }
9349 : 109 : else if (ProcSym == M2System_Throw)
9350 : : {
9351 : : /* avoid dangling else. */
9352 : 109 : BuildThrowProcedure ();
9353 : : }
9354 : : else
9355 : : {
9356 : : /* avoid dangling else. */
9357 : 0 : M2Error_InternalError ((const char *) "pseudo procedure not implemented yet", 36);
9358 : : }
9359 : 16464 : }
9360 : :
9361 : :
9362 : : /*
9363 : : GetItemPointedTo - returns the symbol type that is being pointed to
9364 : : by Sym.
9365 : : */
9366 : :
9367 : 2194 : static unsigned int GetItemPointedTo (unsigned int Sym)
9368 : : {
9369 : 4396 : if (SymbolTable_IsPointer (Sym))
9370 : : {
9371 : 2194 : return SymbolTable_GetSType (Sym);
9372 : : }
9373 : 2202 : else if ((SymbolTable_IsVar (Sym)) || (SymbolTable_IsType (Sym)))
9374 : : {
9375 : : /* avoid dangling else. */
9376 : 2202 : return GetItemPointedTo (SymbolTable_GetSType (Sym));
9377 : : }
9378 : : else
9379 : : {
9380 : : /* avoid dangling else. */
9381 : : return SymbolTable_NulSym;
9382 : : }
9383 : : /* static analysis guarentees a RETURN statement will be used before here. */
9384 : : __builtin_unreachable ();
9385 : : }
9386 : :
9387 : :
9388 : : /*
9389 : : BuildThrowProcedure - builds the pseudo procedure call M2RTS.Throw.
9390 : : The Stack:
9391 : :
9392 : :
9393 : : Entry Exit
9394 : :
9395 : : Ptr ->
9396 : : +----------------+
9397 : : | NoOfParam |
9398 : : |----------------|
9399 : : | Param 1 |
9400 : : |----------------|
9401 : : | Param 2 |
9402 : : |----------------|
9403 : : . .
9404 : : . .
9405 : : . .
9406 : : |----------------|
9407 : : | Param # |
9408 : : |----------------|
9409 : : | ProcSym | Type | Empty
9410 : : |----------------|
9411 : : */
9412 : :
9413 : 109 : static void BuildThrowProcedure (void)
9414 : : {
9415 : 109 : unsigned int functok;
9416 : 109 : unsigned int op;
9417 : 109 : unsigned int NoOfParam;
9418 : :
9419 : 109 : M2Quads_PopT (&NoOfParam);
9420 : 109 : functok = OperandTtok (NoOfParam+1);
9421 : 109 : if (NoOfParam == 1)
9422 : : {
9423 : 109 : op = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
9424 : 109 : GenQuadO (functok, M2Quads_ThrowOp, SymbolTable_NulSym, SymbolTable_NulSym, op, false);
9425 : : }
9426 : : else
9427 : : {
9428 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure %{1Ea} takes one INTEGER parameter", 55, M2System_Throw);
9429 : : }
9430 : 109 : M2Quads_PopN (NoOfParam+1);
9431 : 109 : }
9432 : :
9433 : :
9434 : : /*
9435 : : BuildNewProcedure - builds the pseudo procedure call NEW.
9436 : : This procedure is traditionally a "macro" for
9437 : : NEW(x, ...) --> ALLOCATE(x, TSIZE(x^, ...))
9438 : : One method of implementation is to emulate a "macro"
9439 : : processor by pushing the relevant input tokens
9440 : : back onto the input stack.
9441 : : However this causes two problems:
9442 : :
9443 : : (i) Unnecessary code is produced for x^
9444 : : (ii) SIZE must be imported from SYSTEM
9445 : : Therefore we chose an alternative method of
9446 : : implementation;
9447 : : generate quadruples for ALLOCATE(x, TSIZE(x^, ...))
9448 : : this, although slightly more efficient,
9449 : : is more complex and circumvents problems (i) and (ii).
9450 : :
9451 : : The Stack:
9452 : :
9453 : :
9454 : : Entry Exit
9455 : :
9456 : : Ptr ->
9457 : : +----------------+
9458 : : | NoOfParam |
9459 : : |----------------|
9460 : : | Param 1 |
9461 : : |----------------|
9462 : : | Param 2 |
9463 : : |----------------|
9464 : : . .
9465 : : . .
9466 : : . .
9467 : : |----------------|
9468 : : | Param # |
9469 : : |----------------|
9470 : : | ProcSym | Type | Empty
9471 : : |----------------|
9472 : : */
9473 : :
9474 : 574 : static void BuildNewProcedure (unsigned int functok)
9475 : : {
9476 : 574 : unsigned int NoOfParam;
9477 : 574 : unsigned int SizeSym;
9478 : 574 : unsigned int PtrSym;
9479 : 574 : unsigned int ProcSym;
9480 : 574 : unsigned int paramtok;
9481 : 574 : unsigned int combinedtok;
9482 : :
9483 : 574 : M2Quads_PopT (&NoOfParam);
9484 : 574 : if (NoOfParam >= 1)
9485 : : {
9486 : 574 : ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "ALLOCATE", 8));
9487 : 574 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
9488 : : {
9489 : 574 : PtrSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
9490 : 574 : paramtok = OperandTtok (1);
9491 : 574 : if (IsReallyPointer (PtrSym))
9492 : : {
9493 : 574 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
9494 : : /*
9495 : : Build macro: ALLOCATE( PtrSym, SIZE(PtrSym^) )
9496 : : */
9497 : 574 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, paramtok); /* Procedure */
9498 : : /* x^ */
9499 : 574 : M2Quads_PushTtok (GetItemPointedTo (PtrSym), paramtok);
9500 : 574 : M2Quads_PushT (static_cast<unsigned int> (1)); /* One parameter */
9501 : 574 : M2Quads_BuildFunctionCall (false); /* One parameter */
9502 : 574 : M2Quads_PopT (&SizeSym);
9503 : 574 : M2Quads_PushTtok (ProcSym, combinedtok); /* ALLOCATE */
9504 : 574 : M2Quads_PushTtok (PtrSym, paramtok); /* x */
9505 : 574 : M2Quads_PushTtok (SizeSym, paramtok); /* TSIZE(x^) */
9506 : 574 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
9507 : 574 : M2Quads_BuildProcedureCall (combinedtok); /* Two parameters */
9508 : : }
9509 : : else
9510 : : {
9511 : 0 : M2MetaError_MetaErrorT0 (paramtok, (const char *) "parameter to {%EkNEW} must be a pointer", 39);
9512 : : }
9513 : : }
9514 : : else
9515 : : {
9516 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}ALLOCATE procedure not found for NEW substitution", 53);
9517 : : }
9518 : : }
9519 : : else
9520 : : {
9521 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the pseudo procedure {%EkNEW} has one or more parameters", 56);
9522 : : }
9523 : 574 : M2Quads_PopN (NoOfParam+1);
9524 : 574 : }
9525 : :
9526 : :
9527 : : /*
9528 : : BuildDisposeProcedure - builds the pseudo procedure call DISPOSE.
9529 : : This procedure is traditionally a "macro" for
9530 : : DISPOSE(x) --> DEALLOCATE(x, TSIZE(x^))
9531 : : One method of implementation is to emulate a "macro"
9532 : : processor by pushing the relevant input tokens
9533 : : back onto the input stack.
9534 : : However this causes two problems:
9535 : :
9536 : : (i) Unnecessary code is produced for x^
9537 : : (ii) TSIZE must be imported from SYSTEM
9538 : : Therefore we chose an alternative method of
9539 : : implementation;
9540 : : generate quadruples for DEALLOCATE(x, TSIZE(x^))
9541 : : this, although slightly more efficient,
9542 : : is more complex and circumvents problems (i)
9543 : : and (ii).
9544 : :
9545 : : The Stack:
9546 : :
9547 : :
9548 : : Entry Exit
9549 : :
9550 : : Ptr ->
9551 : : +----------------+
9552 : : | NoOfParam |
9553 : : |----------------|
9554 : : | Param 1 |
9555 : : |----------------|
9556 : : | Param 2 |
9557 : : |----------------|
9558 : : . .
9559 : : . .
9560 : : . .
9561 : : |----------------|
9562 : : | Param # |
9563 : : |----------------|
9564 : : | ProcSym | Type | Empty
9565 : : |----------------|
9566 : : */
9567 : :
9568 : 270 : static void BuildDisposeProcedure (unsigned int functok)
9569 : : {
9570 : 270 : unsigned int NoOfParam;
9571 : 270 : unsigned int SizeSym;
9572 : 270 : unsigned int PtrSym;
9573 : 270 : unsigned int ProcSym;
9574 : 270 : unsigned int combinedtok;
9575 : 270 : unsigned int paramtok;
9576 : :
9577 : 270 : M2Quads_PopT (&NoOfParam);
9578 : 270 : if (NoOfParam >= 1)
9579 : : {
9580 : 270 : ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "DEALLOCATE", 10));
9581 : 270 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
9582 : : {
9583 : 270 : PtrSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
9584 : 270 : paramtok = OperandTtok (1);
9585 : 270 : if (IsReallyPointer (PtrSym))
9586 : : {
9587 : 270 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
9588 : : /*
9589 : : Build macro: DEALLOCATE( PtrSym, TSIZE(PtrSym^) )
9590 : : */
9591 : 270 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, paramtok); /* Procedure */
9592 : : /* x^ */
9593 : 270 : M2Quads_PushTtok (GetItemPointedTo (PtrSym), paramtok);
9594 : 270 : M2Quads_PushT (static_cast<unsigned int> (1)); /* One parameter */
9595 : 270 : M2Quads_BuildFunctionCall (false); /* One parameter */
9596 : 270 : M2Quads_PopT (&SizeSym);
9597 : 270 : M2Quads_PushTtok (ProcSym, combinedtok); /* DEALLOCATE */
9598 : 270 : M2Quads_PushTtok (PtrSym, paramtok); /* x */
9599 : 270 : M2Quads_PushTtok (SizeSym, paramtok); /* TSIZE(x^) */
9600 : 270 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
9601 : 270 : M2Quads_BuildProcedureCall (combinedtok); /* Two parameters */
9602 : : }
9603 : : else
9604 : : {
9605 : 0 : M2MetaError_MetaErrorT0 (paramtok, (const char *) "argument to {%EkDISPOSE} must be a pointer", 42);
9606 : : }
9607 : : }
9608 : : else
9609 : : {
9610 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}DEALLOCATE procedure not found for DISPOSE substitution", 59);
9611 : : }
9612 : : }
9613 : : else
9614 : : {
9615 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the pseudo procedure {%EkDISPOSE} has one or more parameters", 60);
9616 : : }
9617 : 270 : M2Quads_PopN (NoOfParam+1);
9618 : 270 : }
9619 : :
9620 : :
9621 : : /*
9622 : : CheckRangeIncDec - performs des := des <tok> expr
9623 : : with range checking (if enabled).
9624 : :
9625 : : Stack
9626 : : Entry Exit
9627 : :
9628 : : +------------+
9629 : : empty | des + expr |
9630 : : |------------|
9631 : : */
9632 : :
9633 : 14347 : static void CheckRangeIncDec (unsigned int tokenpos, unsigned int des, unsigned int expr, NameKey_Name tok)
9634 : : {
9635 : 14347 : unsigned int dtype;
9636 : 14347 : unsigned int etype;
9637 : :
9638 : 14347 : dtype = SymbolTable_GetDType (des);
9639 : 14347 : etype = SymbolTable_GetDType (expr);
9640 : 14347 : if ((etype == SymbolTable_NulSym) && (SymbolTable_IsPointer (SymbolTable_GetTypeMode (des))))
9641 : : {
9642 : 24 : expr = ConvertToAddress (tokenpos, expr);
9643 : 24 : etype = M2System_Address;
9644 : : }
9645 : 14347 : if (M2Options_WholeValueChecking && ! MustNotCheckBounds)
9646 : : {
9647 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
9648 : 1476 : if (tok == M2Reserved_PlusTok)
9649 : : {
9650 : 792 : BuildRange (M2Range_InitIncRangeCheck (des, expr));
9651 : : }
9652 : : else
9653 : : {
9654 : 684 : BuildRange (M2Range_InitDecRangeCheck (des, expr));
9655 : : }
9656 : : }
9657 : 14347 : if (M2Base_IsExpressionCompatible (dtype, etype))
9658 : : {
9659 : : /* the easy case simulate a straightforward macro */
9660 : 12953 : M2Quads_PushTF (des, dtype);
9661 : 12953 : M2Quads_PushT (tok);
9662 : 12953 : M2Quads_PushTF (expr, etype);
9663 : 12953 : doBuildBinaryOp (false, true);
9664 : : }
9665 : : else
9666 : : {
9667 : 1394 : if ((((M2Base_IsOrdinalType (dtype)) || (dtype == M2System_Address)) || (SymbolTable_IsPointer (dtype))) && (((M2Base_IsOrdinalType (etype)) || (etype == M2System_Address)) || (SymbolTable_IsPointer (etype))))
9668 : : {
9669 : 1394 : M2Quads_PushTF (des, dtype);
9670 : 1394 : M2Quads_PushT (tok);
9671 : 1394 : M2Quads_PushTF (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym));
9672 : 1394 : M2Quads_PushT (dtype);
9673 : 1394 : M2Quads_PushT (expr);
9674 : 1394 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
9675 : 1394 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
9676 : 1394 : doBuildBinaryOp (false, true);
9677 : : }
9678 : : else
9679 : : {
9680 : 0 : if (tok == M2Reserved_PlusTok)
9681 : : {
9682 : 0 : M2MetaError_MetaError0 ((const char *) "cannot perform {%EkINC} using non ordinal types", 47);
9683 : : }
9684 : : else
9685 : : {
9686 : 0 : M2MetaError_MetaError0 ((const char *) "cannot perform {%EkDEC} using non ordinal types", 47);
9687 : : }
9688 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (tokenpos, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym), static_cast<unsigned int> (SymbolTable_NulSym), tokenpos);
9689 : : }
9690 : : }
9691 : 14347 : }
9692 : :
9693 : :
9694 : : /*
9695 : : BuildIncProcedure - builds the pseudo procedure call INC.
9696 : : INC is a procedure which increments a variable.
9697 : : It takes one or two parameters:
9698 : : INC(a, b) or INC(a)
9699 : : a := a+b or a := a+1
9700 : :
9701 : : The Stack:
9702 : :
9703 : :
9704 : : Entry Exit
9705 : :
9706 : : Ptr ->
9707 : : +----------------+
9708 : : | NoOfParam |
9709 : : |----------------|
9710 : : | Param 1 |
9711 : : |----------------|
9712 : : | Param 2 |
9713 : : |----------------|
9714 : : . .
9715 : : . .
9716 : : . .
9717 : : |----------------|
9718 : : | Param # |
9719 : : |----------------|
9720 : : | ProcSym | Type | Empty
9721 : : |----------------|
9722 : : */
9723 : :
9724 : 11057 : static void BuildIncProcedure (void)
9725 : : {
9726 : 11057 : unsigned int proctok;
9727 : 11057 : unsigned int NoOfParam;
9728 : 11057 : unsigned int dtype;
9729 : 11057 : unsigned int OperandSym;
9730 : 11057 : unsigned int VarSym;
9731 : 11057 : unsigned int TempSym;
9732 : :
9733 : 11057 : M2Quads_PopT (&NoOfParam);
9734 : 11057 : proctok = OperandTtok (NoOfParam+1);
9735 : 11057 : if ((NoOfParam == 1) || (NoOfParam == 2))
9736 : : {
9737 : 11057 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam)); /* bottom/first parameter */
9738 : 11057 : if (SymbolTable_IsVar (VarSym)) /* bottom/first parameter */
9739 : : {
9740 : 11057 : dtype = SymbolTable_GetDType (VarSym);
9741 : 11057 : if (NoOfParam == 2)
9742 : : {
9743 : 2393 : OperandSym = DereferenceLValue (M2Quads_OperandTok (1), M2Quads_OperandT (1));
9744 : : }
9745 : : else
9746 : : {
9747 : 8664 : PushOne (proctok, dtype, (const char *) "the {%EkINC} will cause an overflow {%1ad}", 42);
9748 : 8664 : M2Quads_PopT (&OperandSym);
9749 : : }
9750 : 11057 : M2Quads_PushT (VarSym);
9751 : 11057 : TempSym = DereferenceLValue (M2Quads_OperandTok (NoOfParam), VarSym);
9752 : 11057 : CheckRangeIncDec (proctok, TempSym, OperandSym, M2Reserved_PlusTok); /* TempSym + OperandSym */
9753 : 11057 : BuildAssignmentWithoutBounds (proctok, false, true); /* VarSym := TempSym + OperandSym */
9754 : : }
9755 : : else
9756 : : {
9757 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "base procedure {%EkINC} expects a variable as a parameter but was given {%1Ed}", 78, VarSym);
9758 : : }
9759 : : }
9760 : : else
9761 : : {
9762 : 0 : M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkINC} expects 1 or 2 parameters", 53);
9763 : : }
9764 : 11057 : M2Quads_PopN (NoOfParam+1);
9765 : 11057 : }
9766 : :
9767 : :
9768 : : /*
9769 : : BuildDecProcedure - builds the pseudo procedure call DEC.
9770 : : DEC is a procedure which decrements a variable.
9771 : : It takes one or two parameters:
9772 : : DEC(a, b) or DEC(a)
9773 : : a := a-b or a := a-1
9774 : :
9775 : : The Stack:
9776 : :
9777 : :
9778 : : Entry Exit
9779 : :
9780 : : Ptr ->
9781 : : +----------------+
9782 : : | NoOfParam |
9783 : : |----------------|
9784 : : | Param 1 |
9785 : : |----------------|
9786 : : | Param 2 |
9787 : : |----------------|
9788 : : . .
9789 : : . .
9790 : : . .
9791 : : |----------------|
9792 : : | Param # |
9793 : : |----------------|
9794 : : | ProcSym | Type | Empty
9795 : : |----------------|
9796 : : */
9797 : :
9798 : 3290 : static void BuildDecProcedure (void)
9799 : : {
9800 : 3290 : unsigned int proctok;
9801 : 3290 : unsigned int NoOfParam;
9802 : 3290 : unsigned int dtype;
9803 : 3290 : unsigned int OperandSym;
9804 : 3290 : unsigned int VarSym;
9805 : 3290 : unsigned int TempSym;
9806 : :
9807 : 3290 : M2Quads_PopT (&NoOfParam);
9808 : 3290 : proctok = OperandTtok (NoOfParam+1);
9809 : 3290 : if ((NoOfParam == 1) || (NoOfParam == 2))
9810 : : {
9811 : 3290 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam)); /* bottom/first parameter */
9812 : 3290 : if (SymbolTable_IsVar (VarSym)) /* bottom/first parameter */
9813 : : {
9814 : 3290 : dtype = SymbolTable_GetDType (VarSym);
9815 : 3290 : if (NoOfParam == 2)
9816 : : {
9817 : 1107 : OperandSym = DereferenceLValue (M2Quads_OperandTok (1), M2Quads_OperandT (1));
9818 : : }
9819 : : else
9820 : : {
9821 : 2183 : PushOne (proctok, dtype, (const char *) "the {%EkDEC} will cause an overflow {%1ad}", 42);
9822 : 2183 : M2Quads_PopT (&OperandSym);
9823 : : }
9824 : 3290 : M2Quads_PushT (VarSym);
9825 : 3290 : TempSym = DereferenceLValue (M2Quads_OperandTok (NoOfParam), VarSym);
9826 : 3290 : CheckRangeIncDec (proctok, TempSym, OperandSym, M2Reserved_MinusTok); /* TempSym - OperandSym */
9827 : 3290 : BuildAssignmentWithoutBounds (proctok, false, true); /* VarSym := TempSym - OperandSym */
9828 : : }
9829 : : else
9830 : : {
9831 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "base procedure {%EkDEC} expects a variable as a parameter but was given {%1Ed}", 78, VarSym);
9832 : : }
9833 : : }
9834 : : else
9835 : : {
9836 : 0 : M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkDEC} expects 1 or 2 parameters", 53);
9837 : : }
9838 : 3290 : M2Quads_PopN (NoOfParam+1);
9839 : 3290 : }
9840 : :
9841 : :
9842 : : /*
9843 : : DereferenceLValue - checks to see whether, operand, is declare as an LValue
9844 : : and if so it dereferences it.
9845 : : */
9846 : :
9847 : 19993 : static unsigned int DereferenceLValue (unsigned int tok, unsigned int operand)
9848 : : {
9849 : 19993 : unsigned int sym;
9850 : :
9851 : 19993 : if ((SymbolTable_GetMode (operand)) == SymbolTable_LeftValue)
9852 : : {
9853 : : /* dereference the pointer */
9854 : 1218 : sym = SymbolTable_MakeTemporary (tok, AreConstant (SymbolTable_IsConst (operand)));
9855 : 609 : SymbolTable_PutVar (sym, SymbolTable_GetSType (operand));
9856 : 609 : M2Quads_PushTtok (sym, tok);
9857 : 609 : M2Quads_PushTtok (operand, tok);
9858 : 609 : BuildAssignmentWithoutBounds (tok, false, true);
9859 : 609 : return sym;
9860 : : }
9861 : : else
9862 : : {
9863 : : return operand;
9864 : : }
9865 : : /* static analysis guarentees a RETURN statement will be used before here. */
9866 : : __builtin_unreachable ();
9867 : : }
9868 : :
9869 : :
9870 : : /*
9871 : : BuildInclProcedure - builds the pseudo procedure call INCL.
9872 : : INCL is a procedure which adds bit b into a BITSET a.
9873 : : It takes two parameters:
9874 : : INCL(a, b)
9875 : :
9876 : : a := a + {b}
9877 : :
9878 : : The Stack:
9879 : :
9880 : :
9881 : : Entry Exit
9882 : :
9883 : : Ptr ->
9884 : : +----------------+
9885 : : | NoOfParam |
9886 : : |----------------|
9887 : : | Param 1 |
9888 : : |----------------|
9889 : : | Param 2 |
9890 : : |----------------|
9891 : : | ProcSym | Type | Empty
9892 : : |----------------|
9893 : : */
9894 : :
9895 : 729 : static void BuildInclProcedure (void)
9896 : : {
9897 : 729 : unsigned int proctok;
9898 : 729 : unsigned int optok;
9899 : 729 : unsigned int NoOfParam;
9900 : 729 : unsigned int DerefSym;
9901 : 729 : unsigned int OperandSym;
9902 : 729 : unsigned int VarSym;
9903 : :
9904 : 729 : M2Quads_PopT (&NoOfParam);
9905 : 729 : proctok = OperandTtok (NoOfParam+1);
9906 : 729 : if (NoOfParam == 2)
9907 : : {
9908 : 729 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
9909 : 729 : MarkArrayWritten (M2Quads_OperandA (2));
9910 : 729 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
9911 : 729 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
9912 : 729 : if (SymbolTable_IsVar (VarSym))
9913 : : {
9914 : 723 : if (SymbolTable_IsSet (SymbolTable_GetDType (VarSym)))
9915 : : {
9916 : 723 : DerefSym = DereferenceLValue (optok, OperandSym);
9917 : 723 : BuildRange (M2Range_InitInclCheck (VarSym, DerefSym));
9918 : 723 : GenQuadO (proctok, M2Quads_InclOp, VarSym, SymbolTable_NulSym, DerefSym, false);
9919 : : }
9920 : : else
9921 : : {
9922 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "the first parameter to {%EkINCL} must be a set variable but is {%1Ed}", 69, VarSym);
9923 : : }
9924 : : }
9925 : : else
9926 : : {
9927 : 6 : M2MetaError_MetaErrorT1 (proctok, (const char *) "base procedure {%EkINCL} expects a variable as a parameter but is {%1Ed}", 72, VarSym);
9928 : : }
9929 : : }
9930 : : else
9931 : : {
9932 : 0 : M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkINCL} expects 1 or 2 parameters", 54);
9933 : : }
9934 : 729 : M2Quads_PopN (NoOfParam+1);
9935 : 729 : }
9936 : :
9937 : :
9938 : : /*
9939 : : BuildExclProcedure - builds the pseudo procedure call EXCL.
9940 : : INCL is a procedure which removes bit b from SET a.
9941 : : It takes two parameters:
9942 : : EXCL(a, b)
9943 : :
9944 : : a := a - {b}
9945 : :
9946 : : The Stack:
9947 : :
9948 : :
9949 : : Entry Exit
9950 : :
9951 : : Ptr ->
9952 : : +----------------+
9953 : : | NoOfParam |
9954 : : |----------------|
9955 : : | Param 1 |
9956 : : |----------------|
9957 : : | Param 2 |
9958 : : |----------------|
9959 : : | ProcSym | Type | Empty
9960 : : |----------------|
9961 : : */
9962 : :
9963 : 435 : static void BuildExclProcedure (void)
9964 : : {
9965 : 435 : unsigned int proctok;
9966 : 435 : unsigned int optok;
9967 : 435 : unsigned int NoOfParam;
9968 : 435 : unsigned int DerefSym;
9969 : 435 : unsigned int OperandSym;
9970 : 435 : unsigned int VarSym;
9971 : :
9972 : 435 : M2Quads_PopT (&NoOfParam);
9973 : 435 : proctok = OperandTtok (NoOfParam+1);
9974 : 435 : if (NoOfParam == 2)
9975 : : {
9976 : 435 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
9977 : 435 : MarkArrayWritten (M2Quads_OperandA (2));
9978 : 435 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
9979 : 435 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
9980 : 435 : if (SymbolTable_IsVar (VarSym))
9981 : : {
9982 : 435 : if (SymbolTable_IsSet (SymbolTable_GetDType (VarSym)))
9983 : : {
9984 : 435 : DerefSym = DereferenceLValue (optok, OperandSym);
9985 : 435 : BuildRange (M2Range_InitExclCheck (VarSym, DerefSym));
9986 : 435 : GenQuadO (proctok, M2Quads_ExclOp, VarSym, SymbolTable_NulSym, DerefSym, false);
9987 : : }
9988 : : else
9989 : : {
9990 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "the first parameter to {%EkEXCL} must be a set variable but is {%1Ed}", 69, VarSym);
9991 : : }
9992 : : }
9993 : : else
9994 : : {
9995 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "base procedure {%EkEXCL} expects a variable as a parameter but is {%1Ed}", 72, VarSym);
9996 : : }
9997 : : }
9998 : : else
9999 : : {
10000 : 0 : M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkEXCL} expects 1 or 2 parameters", 54);
10001 : : }
10002 : 435 : M2Quads_PopN (NoOfParam+1);
10003 : 435 : }
10004 : :
10005 : :
10006 : : /*
10007 : : BuildTypeCoercion - builds the type coersion.
10008 : : Modula-2 allows types to be coersed with no runtime
10009 : : penility.
10010 : : It insists that the TSIZE(t1)=TSIZE(t2) where
10011 : : t2 variable := t2(variable of type t1).
10012 : : The ReturnVar on the stack is of type t2.
10013 : :
10014 : : The Stack:
10015 : :
10016 : :
10017 : : Entry Exit
10018 : :
10019 : : Ptr ->
10020 : : +----------------+
10021 : : | NoOfParam |
10022 : : |----------------|
10023 : : | Param 1 |
10024 : : |----------------|
10025 : : | Param 2 |
10026 : : |----------------|
10027 : : . .
10028 : : . .
10029 : : . .
10030 : : |----------------|
10031 : : | Param # | <- Ptr
10032 : : |----------------| +------------+
10033 : : | ProcSym | Type | | ReturnVar |
10034 : : |----------------| |------------|
10035 : :
10036 : : Quadruples:
10037 : :
10038 : : CoerceOp ReturnVar Type Param1
10039 : :
10040 : : A type coercion will only be legal if the different
10041 : : types have exactly the same size.
10042 : : Since we can only decide this after M2Eval has processed
10043 : : the symbol table then we create a quadruple explaining
10044 : : the coercion taking place, the code generator can test
10045 : : this assertion and report an error if the type sizes
10046 : : differ.
10047 : : */
10048 : :
10049 : 1130 : static void BuildTypeCoercion (void)
10050 : : {
10051 : 1130 : unsigned int resulttok;
10052 : 1130 : unsigned int proctok;
10053 : 1130 : unsigned int exptok;
10054 : 1130 : unsigned int r;
10055 : 1130 : unsigned int exp;
10056 : 1130 : unsigned int NoOfParam;
10057 : 1130 : unsigned int ReturnVar;
10058 : 1130 : unsigned int ProcSym;
10059 : :
10060 : 1130 : M2Quads_PopT (&NoOfParam);
10061 : 1130 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
10062 : 1130 : proctok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
10063 : 1130 : if (! (SymbolTable_IsAModula2Type (ProcSym)))
10064 : : {
10065 : 0 : M2MetaError_MetaError1 ((const char *) "coersion expecting a type, seen {%1Ea} which is {%1Ed}", 54, ProcSym);
10066 : : }
10067 : 1130 : if (NoOfParam == 1)
10068 : : {
10069 : 1130 : PopTrwtok (&exp, &r, &exptok);
10070 : 1130 : MarkAsRead (r);
10071 : 1130 : resulttok = M2LexBuf_MakeVirtualTok (proctok, proctok, exptok);
10072 : 1130 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_RightValue);
10073 : 1130 : SymbolTable_PutVar (ReturnVar, ProcSym); /* Set ReturnVar's TYPE. */
10074 : 1130 : M2Quads_PopN (1); /* Pop procedure. */
10075 : 1130 : if ((SymbolTable_IsConst (exp)) || (SymbolTable_IsVar (exp))) /* Pop procedure. */
10076 : : {
10077 : 1130 : GenQuad (M2Quads_CoerceOp, ReturnVar, ProcSym, exp);
10078 : : }
10079 : : else
10080 : : {
10081 : 0 : M2MetaError_MetaError2 ((const char *) "trying to coerse {%1EMRad} which is not a variable or constant into {%2ad}", 74, exp, ProcSym);
10082 : 0 : M2MetaError_MetaError2 ((const char *) "trying to coerse {%1ECad} which is not a variable or constant into {%2ad}", 73, exp, ProcSym);
10083 : : }
10084 : 1130 : M2Quads_PushTFtok (ReturnVar, ProcSym, resulttok);
10085 : : }
10086 : : else
10087 : : {
10088 : 0 : M2MetaError_MetaError0 ((const char *) "{%E}only one parameter expected in a TYPE coersion", 50);
10089 : : }
10090 : 1130 : }
10091 : :
10092 : :
10093 : : /*
10094 : : BuildRealFunctionCall - builds a function call.
10095 : : The Stack:
10096 : :
10097 : :
10098 : : Entry Exit
10099 : :
10100 : : Ptr ->
10101 : : +----------------+
10102 : : | NoOfParam |
10103 : : |----------------|
10104 : : | Param 1 |
10105 : : |----------------|
10106 : : | Param 2 |
10107 : : |----------------|
10108 : : . .
10109 : : . .
10110 : : . .
10111 : : |----------------|
10112 : : | Param # | <- Ptr
10113 : : |----------------| +------------+
10114 : : | ProcSym | Type | | ReturnVar |
10115 : : |----------------| |------------|
10116 : : */
10117 : :
10118 : 38268 : static void BuildRealFunctionCall (unsigned int tokno, bool ConstExpr)
10119 : : {
10120 : 38268 : unsigned int NoOfParam;
10121 : 38268 : unsigned int ProcSym;
10122 : :
10123 : 38268 : M2Quads_PopT (&NoOfParam);
10124 : 38268 : M2Quads_PushT (NoOfParam);
10125 : 38268 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+2));
10126 : 38268 : ProcSym = PCSymBuild_SkipConst (ProcSym);
10127 : 38268 : if (SymbolTable_IsVar (ProcSym))
10128 : : {
10129 : : /* Procedure Variable therefore get its type to see if it is a FOR "C" call. */
10130 : 76 : ProcSym = SymbolTable_SkipType (M2Quads_OperandF (NoOfParam+2));
10131 : : }
10132 : 38268 : if ((SymbolTable_IsDefImp (SymbolTable_GetScope (ProcSym))) && (SymbolTable_IsDefinitionForC (SymbolTable_GetScope (ProcSym))))
10133 : : {
10134 : 4900 : BuildRealFuncProcCall (tokno, true, true, ConstExpr);
10135 : : }
10136 : : else
10137 : : {
10138 : 33368 : BuildRealFuncProcCall (tokno, true, false, ConstExpr);
10139 : : }
10140 : 38268 : }
10141 : :
10142 : :
10143 : : /*
10144 : : BuildPseudoFunctionCall - builds the pseudo function
10145 : : The Stack:
10146 : :
10147 : :
10148 : : Entry Exit
10149 : :
10150 : : Ptr ->
10151 : : +----------------+
10152 : : | NoOfParam |
10153 : : |----------------|
10154 : : | Param 1 |
10155 : : |----------------|
10156 : : | Param 2 |
10157 : : |----------------|
10158 : : . .
10159 : : . .
10160 : : . .
10161 : : |----------------|
10162 : : | Param # | <- Ptr
10163 : : |----------------| +------------+
10164 : : | ProcSym | Type | | ReturnVar |
10165 : : |----------------| |------------|
10166 : :
10167 : : */
10168 : :
10169 : 31604 : static void BuildPseudoFunctionCall (bool ConstExpr)
10170 : : {
10171 : 31604 : unsigned int NoOfParam;
10172 : 31604 : unsigned int ProcSym;
10173 : :
10174 : 31604 : M2Quads_PopT (&NoOfParam);
10175 : 31604 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
10176 : 31604 : ProcSym = PCSymBuild_SkipConst (ProcSym);
10177 : 31604 : M2Quads_PushT (NoOfParam);
10178 : : /* Compile time stack restored to entry state. */
10179 : 31604 : if (ProcSym == M2Base_High)
10180 : : {
10181 : 2286 : BuildHighFunction ();
10182 : : }
10183 : 29318 : else if (ProcSym == M2Base_LengthS)
10184 : : {
10185 : : /* avoid dangling else. */
10186 : 322 : BuildLengthFunction (ProcSym, ConstExpr);
10187 : : }
10188 : 28996 : else if (ProcSym == M2System_Adr)
10189 : : {
10190 : : /* avoid dangling else. */
10191 : 9336 : BuildAdrFunction ();
10192 : : }
10193 : 19660 : else if (ProcSym == M2Size_Size)
10194 : : {
10195 : : /* avoid dangling else. */
10196 : 2110 : BuildSizeFunction ();
10197 : : }
10198 : 17550 : else if (ProcSym == M2System_TSize)
10199 : : {
10200 : : /* avoid dangling else. */
10201 : 3412 : BuildTSizeFunction ();
10202 : : }
10203 : 14138 : else if (ProcSym == M2System_TBitSize)
10204 : : {
10205 : : /* avoid dangling else. */
10206 : 12 : BuildTBitSizeFunction ();
10207 : : }
10208 : 14126 : else if (ProcSym == M2Base_Convert)
10209 : : {
10210 : : /* avoid dangling else. */
10211 : 12 : BuildConvertFunction (ProcSym, ConstExpr);
10212 : : }
10213 : 14114 : else if (ProcSym == M2Base_Odd)
10214 : : {
10215 : : /* avoid dangling else. */
10216 : 34 : BuildOddFunction (ProcSym, ConstExpr);
10217 : : }
10218 : 14080 : else if (ProcSym == M2Base_Abs)
10219 : : {
10220 : : /* avoid dangling else. */
10221 : 122 : BuildAbsFunction (ProcSym, ConstExpr);
10222 : : }
10223 : 13958 : else if (ProcSym == M2Base_Cap)
10224 : : {
10225 : : /* avoid dangling else. */
10226 : 124 : BuildCapFunction (ProcSym, ConstExpr);
10227 : : }
10228 : 13834 : else if (ProcSym == M2Base_Val)
10229 : : {
10230 : : /* avoid dangling else. */
10231 : 3237 : BuildValFunction (ProcSym, ConstExpr);
10232 : : }
10233 : 10597 : else if (ProcSym == M2Base_Chr)
10234 : : {
10235 : : /* avoid dangling else. */
10236 : 422 : BuildChrFunction (ProcSym, ConstExpr);
10237 : : }
10238 : 10175 : else if (M2Base_IsOrd (ProcSym))
10239 : : {
10240 : : /* avoid dangling else. */
10241 : 3032 : BuildOrdFunction (ProcSym, ConstExpr);
10242 : : }
10243 : 7143 : else if (M2Base_IsInt (ProcSym))
10244 : : {
10245 : : /* avoid dangling else. */
10246 : 6 : BuildIntFunction (ProcSym, ConstExpr);
10247 : : }
10248 : 7137 : else if (M2Base_IsTrunc (ProcSym))
10249 : : {
10250 : : /* avoid dangling else. */
10251 : 60 : BuildTruncFunction (ProcSym, ConstExpr);
10252 : : }
10253 : 7077 : else if (M2Base_IsFloat (ProcSym))
10254 : : {
10255 : : /* avoid dangling else. */
10256 : 64 : BuildFloatFunction (ProcSym, ConstExpr);
10257 : : }
10258 : 7013 : else if (ProcSym == M2Base_Min)
10259 : : {
10260 : : /* avoid dangling else. */
10261 : 1082 : BuildMinFunction ();
10262 : : }
10263 : 5931 : else if (ProcSym == M2Base_Max)
10264 : : {
10265 : : /* avoid dangling else. */
10266 : 4175 : BuildMaxFunction ();
10267 : : }
10268 : 1756 : else if (ProcSym == M2System_AddAdr)
10269 : : {
10270 : : /* avoid dangling else. */
10271 : 36 : BuildAddAdrFunction (ProcSym, ConstExpr);
10272 : : }
10273 : 1720 : else if (ProcSym == M2System_SubAdr)
10274 : : {
10275 : : /* avoid dangling else. */
10276 : 12 : BuildSubAdrFunction (ProcSym, ConstExpr);
10277 : : }
10278 : 1708 : else if (ProcSym == M2System_DifAdr)
10279 : : {
10280 : : /* avoid dangling else. */
10281 : 12 : BuildDifAdrFunction (ProcSym, ConstExpr);
10282 : : }
10283 : 1696 : else if (ProcSym == M2System_Cast)
10284 : : {
10285 : : /* avoid dangling else. */
10286 : 144 : BuildCastFunction (ProcSym, ConstExpr);
10287 : : }
10288 : 1552 : else if (ProcSym == M2System_Shift)
10289 : : {
10290 : : /* avoid dangling else. */
10291 : 696 : BuildShiftFunction ();
10292 : : }
10293 : 856 : else if (ProcSym == M2System_Rotate)
10294 : : {
10295 : : /* avoid dangling else. */
10296 : 232 : BuildRotateFunction ();
10297 : : }
10298 : 624 : else if (ProcSym == M2System_MakeAdr)
10299 : : {
10300 : : /* avoid dangling else. */
10301 : 12 : BuildMakeAdrFunction ();
10302 : : }
10303 : 612 : else if (ProcSym == M2Base_Re)
10304 : : {
10305 : : /* avoid dangling else. */
10306 : 60 : BuildReFunction (ProcSym, ConstExpr);
10307 : : }
10308 : 552 : else if (ProcSym == M2Base_Im)
10309 : : {
10310 : : /* avoid dangling else. */
10311 : 60 : BuildImFunction (ProcSym, ConstExpr);
10312 : : }
10313 : 492 : else if (ProcSym == M2Base_Cmplx)
10314 : : {
10315 : : /* avoid dangling else. */
10316 : 492 : BuildCmplxFunction (ProcSym, ConstExpr);
10317 : : }
10318 : : else
10319 : : {
10320 : : /* avoid dangling else. */
10321 : 0 : M2Error_InternalError ((const char *) "pseudo function not implemented yet", 35);
10322 : : }
10323 : 31598 : }
10324 : :
10325 : :
10326 : : /*
10327 : : BuildAddAdrFunction - builds the pseudo procedure call ADDADR.
10328 : :
10329 : : PROCEDURE ADDADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
10330 : :
10331 : : Which returns address given by (addr + offset),
10332 : : [ the standard says that it _may_
10333 : : "raise an exception if this address is not valid."
10334 : : currently we do not generate any exception code ]
10335 : :
10336 : : The Stack:
10337 : :
10338 : : Entry Exit
10339 : :
10340 : : Ptr ->
10341 : : +----------------+
10342 : : | NoOfParam |
10343 : : |----------------|
10344 : : | Param 1 |
10345 : : |----------------|
10346 : : | Param 2 | <- Ptr
10347 : : |----------------| +------------+
10348 : : | ProcSym | Type | | ReturnVar |
10349 : : |----------------| |------------|
10350 : : */
10351 : :
10352 : 36 : static void BuildAddAdrFunction (unsigned int ProcSym, bool ConstExpr)
10353 : : {
10354 : 36 : unsigned int combinedtok;
10355 : 36 : unsigned int functok;
10356 : 36 : unsigned int vartok;
10357 : 36 : unsigned int optok;
10358 : 36 : unsigned int opa;
10359 : 36 : unsigned int ReturnVar;
10360 : 36 : unsigned int NoOfParam;
10361 : 36 : unsigned int OperandSym;
10362 : 36 : unsigned int VarSym;
10363 : :
10364 : 36 : M2Quads_PopT (&NoOfParam);
10365 : 36 : functok = OperandTtok (NoOfParam+1);
10366 : 36 : if (NoOfParam == 2)
10367 : : {
10368 : 36 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10369 : 36 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
10370 : 36 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10371 : 36 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10372 : 36 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
10373 : 36 : M2Quads_PopN (NoOfParam+1);
10374 : 36 : if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
10375 : : {
10376 : : /* Fake return result. */
10377 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10378 : : }
10379 : 36 : else if (SymbolTable_IsVar (VarSym))
10380 : : {
10381 : : /* avoid dangling else. */
10382 : 36 : if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
10383 : : {
10384 : 36 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
10385 : 36 : SymbolTable_PutVar (ReturnVar, M2System_Address);
10386 : 36 : opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
10387 : 72 : GenQuadOtok (combinedtok, M2Quads_AddOp, ReturnVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
10388 : 36 : M2Quads_PushTFtok (ReturnVar, M2System_Address, combinedtok);
10389 : : }
10390 : : else
10391 : : {
10392 : 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 {%1Etsd}", 113, VarSym);
10393 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10394 : : }
10395 : : }
10396 : : else
10397 : : {
10398 : : /* avoid dangling else. */
10399 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure ADDADR expects a variable of type ADDRESS or POINTER as its first parameter", 96);
10400 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10401 : : }
10402 : : }
10403 : : else
10404 : : {
10405 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure {%EkADDADR} expects 2 parameters", 53);
10406 : 0 : M2Quads_PopN (NoOfParam+1);
10407 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, functok);
10408 : : }
10409 : 36 : }
10410 : :
10411 : :
10412 : : /*
10413 : : BuildSubAdrFunction - builds the pseudo procedure call ADDADR.
10414 : :
10415 : : PROCEDURE SUBADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
10416 : :
10417 : : Which returns address given by (addr - offset),
10418 : : [ the standard says that it _may_
10419 : : "raise an exception if this address is not valid."
10420 : : currently we do not generate any exception code ]
10421 : :
10422 : : The Stack:
10423 : :
10424 : : Entry Exit
10425 : :
10426 : : Ptr ->
10427 : : +----------------+
10428 : : | NoOfParam |
10429 : : |----------------|
10430 : : | Param 1 |
10431 : : |----------------|
10432 : : | Param 2 | <- Ptr
10433 : : |----------------| +------------+
10434 : : | ProcSym | Type | | ReturnVar |
10435 : : |----------------| |------------|
10436 : : */
10437 : :
10438 : 12 : static void BuildSubAdrFunction (unsigned int ProcSym, bool ConstExpr)
10439 : : {
10440 : 12 : unsigned int functok;
10441 : 12 : unsigned int combinedtok;
10442 : 12 : unsigned int optok;
10443 : 12 : unsigned int vartok;
10444 : 12 : unsigned int ReturnVar;
10445 : 12 : unsigned int NoOfParam;
10446 : 12 : unsigned int OperandSym;
10447 : 12 : unsigned int opa;
10448 : 12 : unsigned int VarSym;
10449 : :
10450 : 12 : M2Quads_PopT (&NoOfParam);
10451 : 12 : functok = OperandTtok (NoOfParam+1);
10452 : 12 : if (NoOfParam == 2)
10453 : : {
10454 : 12 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10455 : 12 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10456 : 12 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10457 : 12 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
10458 : 12 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
10459 : 12 : M2Quads_PopN (NoOfParam+1);
10460 : 12 : if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
10461 : : {
10462 : : /* Fake return result. */
10463 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10464 : : }
10465 : 12 : else if (SymbolTable_IsVar (VarSym))
10466 : : {
10467 : : /* avoid dangling else. */
10468 : 12 : if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
10469 : : {
10470 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
10471 : 12 : SymbolTable_PutVar (ReturnVar, M2System_Address);
10472 : 12 : opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
10473 : 24 : GenQuadOtok (combinedtok, M2Quads_SubOp, ReturnVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
10474 : 12 : M2Quads_PushTFtok (ReturnVar, M2System_Address, combinedtok);
10475 : : }
10476 : : else
10477 : : {
10478 : 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 {%1Etsd}", 118, VarSym);
10479 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (vartok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, vartok);
10480 : : }
10481 : : }
10482 : : else
10483 : : {
10484 : : /* avoid dangling else. */
10485 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
10486 : 0 : M2MetaError_MetaErrorT0 (combinedtok, (const char *) "{%E}SYSTEM procedure {%EkSUBADR} expects a variable of type ADDRESS or POINTER as its first parameter", 101);
10487 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10488 : : }
10489 : : }
10490 : : else
10491 : : {
10492 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure {%EkSUBADR} expects 2 parameters", 53);
10493 : 0 : M2Quads_PopN (NoOfParam+1);
10494 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, functok);
10495 : : }
10496 : 12 : }
10497 : :
10498 : :
10499 : : /*
10500 : : BuildDifAdrFunction - builds the pseudo procedure call DIFADR.
10501 : :
10502 : : PROCEDURE DIFADR (addr1, addr2: ADDRESS): INTEGER ;
10503 : :
10504 : : Which returns address given by (addr1 - addr2),
10505 : : [ the standard says that it _may_
10506 : : "raise an exception if this address is invalid or
10507 : : address space is non-contiguous."
10508 : : currently we do not generate any exception code ]
10509 : :
10510 : : The Stack:
10511 : :
10512 : : Entry Exit
10513 : :
10514 : : Ptr ->
10515 : : +----------------+
10516 : : | NoOfParam |
10517 : : |----------------|
10518 : : | Param 1 |
10519 : : |----------------|
10520 : : | Param 2 | <- Ptr
10521 : : |----------------| +------------+
10522 : : | ProcSym | Type | | ReturnVar |
10523 : : |----------------| |------------|
10524 : : */
10525 : :
10526 : 12 : static void BuildDifAdrFunction (unsigned int ProcSym, bool ConstExpr)
10527 : : {
10528 : 12 : unsigned int functok;
10529 : 12 : unsigned int optok;
10530 : 12 : unsigned int vartok;
10531 : 12 : unsigned int combinedtok;
10532 : 12 : unsigned int TempVar;
10533 : 12 : unsigned int NoOfParam;
10534 : 12 : unsigned int OperandSym;
10535 : 12 : unsigned int opa;
10536 : 12 : unsigned int VarSym;
10537 : :
10538 : 12 : M2Quads_PopT (&NoOfParam);
10539 : 12 : functok = OperandTtok (NoOfParam+1);
10540 : 12 : if (NoOfParam >= 1)
10541 : : {
10542 : 12 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10543 : 12 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10544 : : }
10545 : : else
10546 : : {
10547 : : optok = functok;
10548 : : }
10549 : 12 : if (NoOfParam == 2)
10550 : : {
10551 : 12 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10552 : 12 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
10553 : 12 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
10554 : 12 : M2Quads_PopN (NoOfParam+1);
10555 : 12 : if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
10556 : : {
10557 : : /* Fake return result. */
10558 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10559 : : }
10560 : 12 : else if (SymbolTable_IsVar (VarSym))
10561 : : {
10562 : : /* avoid dangling else. */
10563 : 12 : if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
10564 : : {
10565 : 12 : if ((IsReallyPointer (OperandSym)) || ((SymbolTable_GetSType (OperandSym)) == M2System_Address))
10566 : : {
10567 : 12 : TempVar = SymbolTable_MakeTemporary (vartok, SymbolTable_RightValue);
10568 : 12 : SymbolTable_PutVar (TempVar, M2System_Address);
10569 : 12 : opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
10570 : 24 : GenQuadOtok (combinedtok, M2Quads_SubOp, TempVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
10571 : : /*
10572 : : Build macro: CONVERT( INTEGER, TempVar )
10573 : : */
10574 : 12 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
10575 : 12 : M2Quads_PushTtok (M2Base_Integer, functok);
10576 : 12 : M2Quads_PushTtok (TempVar, vartok);
10577 : 12 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
10578 : 12 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* Two parameters */
10579 : : }
10580 : : else
10581 : : {
10582 : 0 : M2MetaError_MetaError1 ((const char *) "the second parameter to {%EkDIFADR} {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsd}", 119, OperandSym);
10583 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10584 : : }
10585 : : }
10586 : : else
10587 : : {
10588 : 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 {%1Etsd}", 118, VarSym);
10589 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10590 : : }
10591 : : }
10592 : : else
10593 : : {
10594 : : /* avoid dangling else. */
10595 : 0 : M2MetaError_MetaError0 ((const char *) "{%E}SYSTEM procedure {%EkDIFADR} expects a variable of type ADDRESS or POINTER as its first parameter", 101);
10596 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10597 : : }
10598 : : }
10599 : : else
10600 : : {
10601 : 0 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
10602 : 0 : M2MetaError_MetaErrorT0 (combinedtok, (const char *) "{%E}SYSTEM procedure {%EkDIFADR} expects 2 parameters", 53);
10603 : 0 : M2Quads_PopN (NoOfParam+1);
10604 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10605 : : }
10606 : 12 : }
10607 : :
10608 : :
10609 : : /*
10610 : : BuildHighFunction - checks the stack in preparation for generating
10611 : : quadruples which perform HIGH.
10612 : : This procedure does not alter the stack but
10613 : : determines whether, a, in HIGH(a) is an ArraySym
10614 : : or UnboundedSym.
10615 : : Both cases are different and appropriate quadruple
10616 : : generating routines are called.
10617 : :
10618 : : The Stack:
10619 : :
10620 : :
10621 : : Entry Exit
10622 : :
10623 : : Ptr ->
10624 : : +----------------+
10625 : : | NoOfParam |
10626 : : |----------------|
10627 : : | Param 1 |
10628 : : |----------------|
10629 : : | Param 2 |
10630 : : |----------------|
10631 : : . .
10632 : : . .
10633 : : . .
10634 : : |----------------|
10635 : : | Param # | <- Ptr
10636 : : |----------------| +------------+
10637 : : | ProcSym | Type | | ReturnVar |
10638 : : |----------------| |------------|
10639 : :
10640 : : */
10641 : :
10642 : 2286 : static void BuildHighFunction (void)
10643 : : {
10644 : 2286 : unsigned int functok;
10645 : 2286 : unsigned int combinedtok;
10646 : 2286 : unsigned int paramtok;
10647 : 2286 : unsigned int ProcSym;
10648 : 2286 : unsigned int Type;
10649 : 2286 : unsigned int NoOfParam;
10650 : 2286 : unsigned int Param;
10651 : :
10652 : 2286 : M2Quads_PopT (&NoOfParam);
10653 : 2286 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
10654 : 2286 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
10655 : 2286 : BuildSizeCheckEnd (ProcSym); /* quadruple generation now on */
10656 : 2286 : if (NoOfParam == 1) /* quadruple generation now on */
10657 : : {
10658 : 2286 : Param = static_cast<unsigned int> (M2Quads_OperandT (1));
10659 : 2286 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10660 : 2286 : combinedtok = M2LexBuf_MakeVirtualTok (paramtok, functok, paramtok);
10661 : 2286 : Type = SymbolTable_GetDType (Param);
10662 : : /* Restore stack to original form */
10663 : 2286 : M2Quads_PushT (NoOfParam);
10664 : 2286 : if (((! (SymbolTable_IsVar (Param))) && (! (SymbolTable_IsConstString (Param)))) && (! (SymbolTable_IsConst (Param))))
10665 : : {
10666 : : /* we cannot test for IsConst(Param) AND (GetSType(Param)=Char) as the type might not be assigned yet */
10667 : 0 : M2MetaError_MetaError1 ((const char *) "base procedure {%EkHIGH} expects a variable or string constant as its parameter {%1d:rather than {%1d}} {%1asa}", 111, Param);
10668 : : }
10669 : 2286 : else if (SymbolTable_IsUnbounded (Type))
10670 : : {
10671 : : /* avoid dangling else. */
10672 : 2181 : BuildHighFromUnbounded (combinedtok);
10673 : : }
10674 : : else
10675 : : {
10676 : : /* avoid dangling else. */
10677 : 105 : BuildConstHighFromSym (combinedtok);
10678 : : }
10679 : : }
10680 : : else
10681 : : {
10682 : 0 : M2MetaError_MetaError0 ((const char *) "base procedure {%EkHIGH} requires one parameter", 47);
10683 : 0 : M2Quads_PopN (2);
10684 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
10685 : : }
10686 : 2286 : }
10687 : :
10688 : :
10689 : : /*
10690 : : BuildConstHighFromSym - builds the pseudo function HIGH from an Sym.
10691 : : Sym is a constant or an array which has constant bounds
10692 : : and therefore it can be calculated at compile time.
10693 : :
10694 : : The Stack:
10695 : :
10696 : :
10697 : : Entry Exit
10698 : :
10699 : : Ptr ->
10700 : : +----------------+
10701 : : | NoOfParam |
10702 : : |----------------|
10703 : : | Param 1 |
10704 : : |----------------|
10705 : : | Param 2 |
10706 : : |----------------|
10707 : : . .
10708 : : . .
10709 : : . .
10710 : : |----------------|
10711 : : | Param # | <- Ptr
10712 : : |----------------| +------------+
10713 : : | ProcSym | Type | | ReturnVar |
10714 : : |----------------| |------------|
10715 : : */
10716 : :
10717 : 105 : static void BuildConstHighFromSym (unsigned int tok)
10718 : : {
10719 : 105 : unsigned int NoOfParam;
10720 : 105 : unsigned int ReturnVar;
10721 : :
10722 : 105 : M2Quads_PopT (&NoOfParam);
10723 : 105 : ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
10724 : 105 : SymbolTable_PutConst (ReturnVar, M2Base_Cardinal);
10725 : 105 : GenHigh (tok, ReturnVar, 1, M2Quads_OperandT (1));
10726 : 105 : M2Quads_PopN (NoOfParam+1);
10727 : 105 : M2Quads_PushTtok (ReturnVar, tok);
10728 : 105 : }
10729 : :
10730 : :
10731 : : /*
10732 : : BuildHighFromUnbounded - builds the pseudo function HIGH from an
10733 : : UnboundedSym.
10734 : :
10735 : : The Stack:
10736 : :
10737 : :
10738 : : Entry Exit
10739 : :
10740 : : Ptr ->
10741 : : +----------------+
10742 : : | NoOfParam |
10743 : : |----------------|
10744 : : | Param # | <- Ptr
10745 : : |----------------| +------------+
10746 : : | ProcSym | Type | | ReturnVar |
10747 : : |----------------| |------------|
10748 : :
10749 : : */
10750 : :
10751 : 2181 : static void BuildHighFromUnbounded (unsigned int tok)
10752 : : {
10753 : 2181 : unsigned int Dim;
10754 : 2181 : unsigned int NoOfParam;
10755 : 2181 : unsigned int ReturnVar;
10756 : :
10757 : 2181 : M2Quads_PopT (&NoOfParam);
10758 : 2181 : M2Debug_Assert (NoOfParam == 1);
10759 : 2181 : ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
10760 : 2181 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
10761 : 2181 : Dim = static_cast<unsigned int> (OperandD (1));
10762 : 2181 : Dim += 1;
10763 : 2181 : if (Dim > 1)
10764 : : {
10765 : 36 : GenHigh (tok, ReturnVar, Dim, M2Quads_OperandA (1));
10766 : : }
10767 : : else
10768 : : {
10769 : 2145 : GenHigh (tok, ReturnVar, Dim, M2Quads_OperandT (1));
10770 : : }
10771 : 2181 : M2Quads_PopN (2);
10772 : 2181 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), tok);
10773 : 2181 : }
10774 : :
10775 : :
10776 : : /*
10777 : : GetQualidentImport - returns the symbol as if it were qualified from, module.n.
10778 : : This is used to reference runtime support procedures and an
10779 : : error is generated if the symbol cannot be obtained.
10780 : : */
10781 : :
10782 : 40192 : static unsigned int GetQualidentImport (unsigned int tokno, NameKey_Name n, NameKey_Name module)
10783 : : {
10784 : 40192 : unsigned int ModSym;
10785 : :
10786 : 40192 : ModSym = M2Batch_MakeDefinitionSource (tokno, module);
10787 : 40192 : if (ModSym == SymbolTable_NulSym)
10788 : : {
10789 : 0 : M2MetaError_MetaErrorNT2 (tokno, (const char *) "module %a cannot be found and is needed to import %a", 52, module, n);
10790 : 0 : M2Error_FlushErrors ();
10791 : 0 : return SymbolTable_NulSym;
10792 : : }
10793 : 40192 : M2Debug_Assert (SymbolTable_IsDefImp (ModSym));
10794 : 40192 : if (((SymbolTable_GetExported (tokno, ModSym, n)) == SymbolTable_NulSym) || (SymbolTable_IsUnknown (SymbolTable_GetExported (tokno, ModSym, n))))
10795 : : {
10796 : 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);
10797 : 0 : M2Error_FlushErrors ();
10798 : 0 : return SymbolTable_NulSym;
10799 : : }
10800 : 40192 : return SymbolTable_GetExported (tokno, M2Batch_MakeDefinitionSource (tokno, module), n);
10801 : : /* static analysis guarentees a RETURN statement will be used before here. */
10802 : : __builtin_unreachable ();
10803 : : }
10804 : :
10805 : :
10806 : : /*
10807 : : ConstExprError - return TRUE if a constant expression is being built and Var is a variable.
10808 : : */
10809 : :
10810 : 50205 : static bool ConstExprError (unsigned int Func, unsigned int Var, unsigned int optok, bool ConstExpr)
10811 : : {
10812 : 50205 : if (ConstExpr && (SymbolTable_IsVar (Var)))
10813 : : {
10814 : 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 {%2da}", 147, Func, Var);
10815 : 108 : return true;
10816 : : }
10817 : : else
10818 : : {
10819 : 50097 : return false;
10820 : : }
10821 : : /* static analysis guarentees a RETURN statement will be used before here. */
10822 : : __builtin_unreachable ();
10823 : : }
10824 : :
10825 : :
10826 : : /*
10827 : : DeferMakeLengthConst - creates a constant which contains the length of string, sym.
10828 : : */
10829 : :
10830 : 42 : static unsigned int DeferMakeLengthConst (unsigned int tok, unsigned int sym)
10831 : : {
10832 : 42 : unsigned int const_;
10833 : :
10834 : 42 : const_ = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
10835 : 42 : SymbolTable_PutVar (const_, M2Base_ZType);
10836 : 84 : GenQuadO (tok, M2Quads_StringLengthOp, const_, 0, sym, false);
10837 : 42 : return const_;
10838 : : /* static analysis guarentees a RETURN statement will be used before here. */
10839 : : __builtin_unreachable ();
10840 : : }
10841 : :
10842 : :
10843 : : /*
10844 : : BuildLengthFunction - builds the inline standard function LENGTH.
10845 : :
10846 : : The Stack:
10847 : :
10848 : :
10849 : : Entry Exit
10850 : :
10851 : : Ptr ->
10852 : : +----------------+
10853 : : | NoOfParam |
10854 : : |----------------|
10855 : : | Param 1 | <- Ptr
10856 : : |----------------| +------------+
10857 : : | ProcSym | Type | | ReturnVar |
10858 : : |----------------| |------------|
10859 : :
10860 : : */
10861 : :
10862 : 322 : static void BuildLengthFunction (unsigned int Function, bool ConstExpr)
10863 : : {
10864 : 322 : unsigned int combinedtok;
10865 : 322 : unsigned int paramtok;
10866 : 322 : unsigned int functok;
10867 : 322 : unsigned int ProcSym;
10868 : 322 : unsigned int Type;
10869 : 322 : unsigned int NoOfParam;
10870 : 322 : unsigned int Param;
10871 : 322 : unsigned int ReturnVar;
10872 : :
10873 : 322 : M2Quads_PopT (&NoOfParam);
10874 : 322 : Param = static_cast<unsigned int> (M2Quads_OperandT (1));
10875 : 322 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10876 : 322 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
10877 : : /* Restore stack to origional form. */
10878 : 322 : M2Quads_PushT (NoOfParam);
10879 : 322 : Type = SymbolTable_GetSType (Param); /* Get the type from the symbol, not the stack. */
10880 : 322 : if (NoOfParam != 1) /* Get the type from the symbol, not the stack. */
10881 : : {
10882 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "base procedure {%1EkLENGTH} expects 1 parameter, seen {%1n} parameters", 70, NoOfParam);
10883 : : }
10884 : 322 : if (NoOfParam >= 1)
10885 : : {
10886 : 322 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, paramtok);
10887 : 322 : if ((SymbolTable_IsConst (Param)) && ((SymbolTable_GetSType (Param)) == M2Base_Char))
10888 : : {
10889 : 6 : M2Quads_PopT (&NoOfParam);
10890 : 6 : M2Quads_PopN (NoOfParam+1);
10891 : 6 : ReturnVar = SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal);
10892 : 6 : M2Quads_PushTtok (ReturnVar, combinedtok);
10893 : : }
10894 : 316 : else if (SymbolTable_IsConstString (Param))
10895 : : {
10896 : : /* avoid dangling else. */
10897 : 24 : M2Quads_PopT (&NoOfParam);
10898 : 24 : ReturnVar = DeferMakeLengthConst (combinedtok, M2Quads_OperandT (1));
10899 : 24 : M2Quads_PopN (NoOfParam+1);
10900 : 24 : M2Quads_PushTtok (ReturnVar, combinedtok);
10901 : : }
10902 : : else
10903 : : {
10904 : : /* avoid dangling else. */
10905 : 292 : ProcSym = GetQualidentImport (functok, NameKey_MakeKey ((const char *) "Length", 6), NameKey_MakeKey ((const char *) "M2RTS", 5));
10906 : 292 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
10907 : : {
10908 : 292 : M2Quads_PopT (&NoOfParam);
10909 : 292 : if (SymbolTable_IsConst (Param))
10910 : : {
10911 : : /* This can be folded in M2GenGCC. */
10912 : 0 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_ImmediateValue);
10913 : 0 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
10914 : 0 : GenQuad (M2Quads_StandardFunctionOp, ReturnVar, ProcSym, Param);
10915 : 0 : M2Quads_PopN (NoOfParam+1);
10916 : 0 : M2Quads_PushTtok (ReturnVar, combinedtok);
10917 : : }
10918 : 292 : else if (ConstExprError (Function, Param, paramtok, ConstExpr))
10919 : : {
10920 : : /* avoid dangling else. */
10921 : : /* Fake a result as we have detected and reported an error. */
10922 : 6 : M2Quads_PopN (NoOfParam+1);
10923 : 6 : ReturnVar = SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal);
10924 : 6 : M2Quads_PushTtok (ReturnVar, combinedtok);
10925 : : }
10926 : : else
10927 : : {
10928 : : /* avoid dangling else. */
10929 : : /* We must resolve this at runtime or in the GCC optimizer. */
10930 : 286 : M2Quads_PopTF (&Param, &Type);
10931 : 286 : M2Quads_PopN (NoOfParam);
10932 : 286 : M2Quads_PushTtok (ProcSym, functok);
10933 : 286 : M2Quads_PushTFtok (Param, Type, paramtok);
10934 : 286 : M2Quads_PushT (NoOfParam);
10935 : 286 : BuildRealFunctionCall (functok, false);
10936 : : }
10937 : : }
10938 : : else
10939 : : {
10940 : 0 : M2Quads_PopT (&NoOfParam);
10941 : 0 : M2Quads_PopN (NoOfParam+1);
10942 : 0 : M2Quads_PushTtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), combinedtok);
10943 : 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);
10944 : : }
10945 : : }
10946 : : }
10947 : : else
10948 : : {
10949 : : /* NoOfParam is _very_ wrong, we flush all outstanding errors */
10950 : 0 : M2Error_FlushErrors ();
10951 : : }
10952 : 322 : }
10953 : :
10954 : :
10955 : : /*
10956 : : BuildOddFunction - builds the pseudo procedure call ODD.
10957 : : This procedure is actually a "macro" for
10958 : : ORD(x) --> VAL(BOOLEAN, x MOD 2)
10959 : : However we cannot push tokens back onto the input stack
10960 : : because the compiler is currently building a function
10961 : : call and expecting a ReturnVar on the stack.
10962 : : Hence we manipulate the stack and call
10963 : : BuildConvertFunction.
10964 : :
10965 : : The Stack:
10966 : :
10967 : :
10968 : : Entry Exit
10969 : :
10970 : : Ptr ->
10971 : : +----------------+
10972 : : | NoOfParam |
10973 : : |----------------|
10974 : : | Param 1 |
10975 : : |----------------|
10976 : : | Param 2 |
10977 : : |----------------|
10978 : : . .
10979 : : . .
10980 : : . .
10981 : : |----------------|
10982 : : | Param # |
10983 : : |----------------|
10984 : : | ProcSym | Type | Empty
10985 : : |----------------|
10986 : : */
10987 : :
10988 : 34 : static void BuildOddFunction (unsigned int ProcSym, bool ConstExpr)
10989 : : {
10990 : 34 : unsigned int combinedtok;
10991 : 34 : unsigned int optok;
10992 : 34 : unsigned int functok;
10993 : 34 : unsigned int NoOfParam;
10994 : 34 : unsigned int Res;
10995 : 34 : unsigned int Var;
10996 : :
10997 : 34 : M2Quads_PopT (&NoOfParam);
10998 : 34 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
10999 : 34 : if (NoOfParam == 1)
11000 : : {
11001 : 34 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11002 : 34 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11003 : 34 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
11004 : 34 : if (ConstExprError (ProcSym, Var, optok, ConstExpr))
11005 : : {
11006 : : /* Nothing to do. */
11007 : 6 : M2Quads_PushTtok (M2Base_False, combinedtok);
11008 : : }
11009 : 28 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11010 : : {
11011 : : /* avoid dangling else. */
11012 : 28 : M2Quads_PopN (NoOfParam+1);
11013 : : /* compute (x MOD 2) */
11014 : 28 : M2Quads_PushTFtok (Var, SymbolTable_GetSType (Var), optok);
11015 : 28 : M2Quads_PushT (M2Reserved_ModTok);
11016 : 28 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (optok, NameKey_MakeKey ((const char *) "2", 1), M2Base_ZType), M2Base_ZType, optok);
11017 : 28 : M2Quads_BuildBinaryOp ();
11018 : 28 : M2Quads_PopT (&Res);
11019 : : /* compute IF ...=0 */
11020 : 28 : M2Quads_PushTtok (Res, optok);
11021 : 28 : M2Quads_PushT (M2Reserved_EqualTok);
11022 : 28 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (optok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType), M2Base_ZType, optok);
11023 : 28 : M2Quads_BuildRelOp (combinedtok);
11024 : 28 : M2Quads_BuildThenIf ();
11025 : 28 : Res = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
11026 : 28 : SymbolTable_PutVar (Res, M2Base_Boolean);
11027 : 28 : M2Quads_PushTtok (Res, combinedtok);
11028 : 28 : M2Quads_PushTtok (M2Base_False, combinedtok);
11029 : 28 : M2Quads_BuildAssignment (combinedtok);
11030 : 28 : M2Quads_BuildElse ();
11031 : 28 : M2Quads_PushTtok (Res, combinedtok);
11032 : 28 : M2Quads_PushTtok (M2Base_True, combinedtok);
11033 : 28 : M2Quads_BuildAssignment (combinedtok);
11034 : 28 : M2Quads_BuildEndIf ();
11035 : 28 : M2Quads_PushTtok (Res, combinedtok);
11036 : : }
11037 : : else
11038 : : {
11039 : : /* avoid dangling else. */
11040 : 0 : M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%1EkODD} must be a variable or constant, seen {%1ad}", 70, Var);
11041 : 0 : M2Quads_PushTtok (M2Base_False, combinedtok);
11042 : : }
11043 : : }
11044 : : else
11045 : : {
11046 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%E1kODD} only has one parameter, seen {%1n} parameters", 76, NoOfParam);
11047 : 0 : M2Quads_PushTtok (M2Base_False, functok);
11048 : : }
11049 : 34 : }
11050 : :
11051 : :
11052 : : /*
11053 : : BuildAbsFunction - builds a call to the standard function ABS.
11054 : :
11055 : : We cannot implement it as a macro or inline an
11056 : : IF THEN statement as the IF THEN ELSE requires
11057 : : we write the value to the same variable (or constant)
11058 : : twice. The macro implementation will fail as
11059 : : the compiler maybe building a function
11060 : : call and expecting a ReturnVar on the stack.
11061 : : The only method to implement this is to pass it to the
11062 : : gcc backend.
11063 : :
11064 : : The Stack:
11065 : :
11066 : :
11067 : : Entry Exit
11068 : :
11069 : : Ptr ->
11070 : : +----------------+
11071 : : | NoOfParam |
11072 : : |----------------|
11073 : : | Param 1 |
11074 : : |----------------|
11075 : : | Param 2 |
11076 : : |----------------|
11077 : : . .
11078 : : . .
11079 : : . .
11080 : : |----------------|
11081 : : | Param # |
11082 : : |----------------|
11083 : : | ProcSym | Type | Empty
11084 : : |----------------|
11085 : : */
11086 : :
11087 : 122 : static void BuildAbsFunction (unsigned int ProcSym, bool ConstExpr)
11088 : : {
11089 : 122 : unsigned int vartok;
11090 : 122 : unsigned int functok;
11091 : 122 : unsigned int combinedtok;
11092 : 122 : unsigned int NoOfParam;
11093 : 122 : unsigned int Res;
11094 : 122 : unsigned int Var;
11095 : :
11096 : 122 : M2Quads_PopT (&NoOfParam);
11097 : 122 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11098 : 122 : if (NoOfParam == 1)
11099 : : {
11100 : 122 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11101 : 122 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11102 : 122 : M2Quads_PopN (NoOfParam+1);
11103 : 122 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
11104 : 122 : if (ConstExprError (ProcSym, Var, vartok, ConstExpr))
11105 : : {
11106 : : /* Create fake result. */
11107 : 24 : Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11108 : 12 : SymbolTable_PutVar (Res, SymbolTable_GetSType (Var));
11109 : 12 : M2Quads_PushTFtok (Res, SymbolTable_GetSType (Var), combinedtok);
11110 : : }
11111 : 110 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11112 : : {
11113 : : /* avoid dangling else. */
11114 : 220 : Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11115 : 110 : SymbolTable_PutVar (Res, SymbolTable_GetSType (Var));
11116 : 220 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, Res, ProcSym, Var, false);
11117 : 110 : M2Quads_PushTFtok (Res, SymbolTable_GetSType (Var), combinedtok);
11118 : : }
11119 : : else
11120 : : {
11121 : : /* avoid dangling else. */
11122 : 0 : M2MetaError_MetaErrorT1 (vartok, (const char *) "the parameter to {%AkABS} must be a variable or constant, seen {%1ad}", 69, Var);
11123 : : }
11124 : : }
11125 : : else
11126 : : {
11127 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkABS} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
11128 : : }
11129 : 122 : }
11130 : :
11131 : :
11132 : : /*
11133 : : BuildCapFunction - builds the pseudo procedure call CAP.
11134 : : We generate a the following quad:
11135 : :
11136 : :
11137 : : StandardFunctionOp ReturnVal Cap Param1
11138 : :
11139 : : The Stack:
11140 : :
11141 : :
11142 : : Entry Exit
11143 : :
11144 : : Ptr ->
11145 : : +----------------+
11146 : : | NoOfParam = 1 |
11147 : : |----------------|
11148 : : | Param 1 |
11149 : : |----------------| +-------------+
11150 : : | ProcSym | Type | | ReturnVal |
11151 : : |----------------| |-------------|
11152 : : */
11153 : :
11154 : 124 : static void BuildCapFunction (unsigned int ProcSym, bool ConstExpr)
11155 : : {
11156 : 124 : unsigned int optok;
11157 : 124 : unsigned int functok;
11158 : 124 : unsigned int combinedtok;
11159 : 124 : unsigned int NoOfParam;
11160 : 124 : unsigned int Res;
11161 : 124 : unsigned int Var;
11162 : :
11163 : 124 : M2Quads_PopT (&NoOfParam);
11164 : 124 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11165 : 124 : if (NoOfParam == 1)
11166 : : {
11167 : 124 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11168 : 124 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11169 : 124 : M2Quads_PopN (NoOfParam+1);
11170 : 124 : if (ConstExprError (ProcSym, Var, optok, ConstExpr))
11171 : : {
11172 : : /* Create fake result. */
11173 : 12 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11174 : 24 : Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11175 : 12 : SymbolTable_PutVar (Res, M2Base_Char);
11176 : 12 : M2Quads_PushTFtok (Res, M2Base_Char, combinedtok);
11177 : : }
11178 : 112 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11179 : : {
11180 : : /* avoid dangling else. */
11181 : 112 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11182 : 224 : Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11183 : 112 : SymbolTable_PutVar (Res, M2Base_Char);
11184 : 224 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, Res, ProcSym, Var, false);
11185 : 112 : M2Quads_PushTFtok (Res, M2Base_Char, combinedtok);
11186 : : }
11187 : : else
11188 : : {
11189 : : /* avoid dangling else. */
11190 : 0 : M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%AkCAP} must be a variable or constant, seen {%1ad}", 69, Var);
11191 : : }
11192 : : }
11193 : : else
11194 : : {
11195 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkCAP} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
11196 : : }
11197 : 124 : }
11198 : :
11199 : :
11200 : : /*
11201 : : BuildChrFunction - builds the pseudo procedure call CHR.
11202 : : This procedure is actually a "macro" for
11203 : : CHR(x) --> CONVERT(CHAR, x)
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 : 422 : static void BuildChrFunction (unsigned int ProcSym, bool ConstExpr)
11234 : : {
11235 : 422 : unsigned int functok;
11236 : 422 : unsigned int combinedtok;
11237 : 422 : unsigned int optok;
11238 : 422 : unsigned int ReturnVar;
11239 : 422 : unsigned int NoOfParam;
11240 : 422 : unsigned int Var;
11241 : :
11242 : 422 : M2Quads_PopT (&NoOfParam);
11243 : 422 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11244 : 422 : if (NoOfParam == 1)
11245 : : {
11246 : 422 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11247 : 422 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11248 : 422 : M2Quads_PopN (NoOfParam+1);
11249 : 422 : if (ConstExprError (ProcSym, Var, optok, ConstExpr))
11250 : : {
11251 : : /* Generate fake result. */
11252 : 12 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11253 : 24 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11254 : 12 : SymbolTable_PutVar (ReturnVar, M2Base_Char);
11255 : 12 : M2Quads_PushTFtok (ReturnVar, M2Base_Char, combinedtok);
11256 : : }
11257 : 410 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11258 : : {
11259 : : /* avoid dangling else. */
11260 : : /*
11261 : : Build macro: CONVERT( CHAR, Var )
11262 : : */
11263 : 410 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
11264 : 410 : M2Quads_PushTtok (M2Base_Char, functok);
11265 : 410 : M2Quads_PushTtok (Var, optok);
11266 : 410 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
11267 : 410 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* Two parameters */
11268 : : }
11269 : : else
11270 : : {
11271 : : /* avoid dangling else. */
11272 : 0 : M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%AkCHR} must be a variable or constant, seen {%1ad}", 69, Var);
11273 : : }
11274 : : }
11275 : : else
11276 : : {
11277 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkCHR} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
11278 : : }
11279 : 422 : }
11280 : :
11281 : :
11282 : : /*
11283 : : BuildOrdFunction - builds the pseudo procedure call ORD.
11284 : : This procedure is actually a "macro" for
11285 : : ORD(x) --> CONVERT(GetSType(sym), x)
11286 : : However we cannot push tokens back onto the input stack
11287 : : because the compiler is currently building a function
11288 : : call and expecting a ReturnVar on the stack.
11289 : : Hence we manipulate the stack and call
11290 : : BuildConvertFunction.
11291 : :
11292 : : The Stack:
11293 : :
11294 : :
11295 : : Entry Exit
11296 : :
11297 : : Ptr ->
11298 : : +----------------+
11299 : : | NoOfParam |
11300 : : |----------------|
11301 : : | Param 1 |
11302 : : |----------------|
11303 : : | Param 2 |
11304 : : |----------------|
11305 : : . .
11306 : : . .
11307 : : . .
11308 : : |----------------|
11309 : : | Param # |
11310 : : |----------------|
11311 : : | ProcSym | Type | Empty
11312 : : |----------------|
11313 : : */
11314 : :
11315 : 3032 : static void BuildOrdFunction (unsigned int Sym, bool ConstExpr)
11316 : : {
11317 : 3032 : unsigned int combinedtok;
11318 : 3032 : unsigned int functok;
11319 : 3032 : unsigned int optok;
11320 : 3032 : unsigned int ReturnVar;
11321 : 3032 : unsigned int NoOfParam;
11322 : 3032 : unsigned int Type;
11323 : 3032 : unsigned int Var;
11324 : :
11325 : 3032 : M2Quads_PopT (&NoOfParam);
11326 : 3032 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11327 : 3032 : if (NoOfParam == 1)
11328 : : {
11329 : 3032 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11330 : 3032 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11331 : 3032 : M2Quads_PopN (NoOfParam+1);
11332 : 3032 : if (ConstExprError (Sym, Var, optok, ConstExpr))
11333 : : {
11334 : : /* Generate fake result. */
11335 : 12 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11336 : 24 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11337 : 12 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
11338 : 12 : M2Quads_PushTFtok (ReturnVar, M2Base_Cardinal, combinedtok);
11339 : : }
11340 : 3020 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11341 : : {
11342 : : /* avoid dangling else. */
11343 : 3020 : Type = SymbolTable_GetSType (Sym);
11344 : : /*
11345 : : Build macro: CONVERT( CARDINAL, Var )
11346 : : */
11347 : 3020 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
11348 : 3020 : M2Quads_PushTtok (Type, optok);
11349 : 3020 : M2Quads_PushTtok (Var, optok);
11350 : 3020 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
11351 : 3020 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* Two parameters */
11352 : : }
11353 : : else
11354 : : {
11355 : : /* avoid dangling else. */
11356 : 0 : M2MetaError_MetaErrorT2 (optok, (const char *) "the parameter to {%1Aa} must be a variable or constant, seen {%2ad}", 67, Sym, Var);
11357 : : }
11358 : : }
11359 : : else
11360 : : {
11361 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the pseudo procedure {%1Aa} only has one parameter, seen {%2n} parameters", 73, Sym, NoOfParam);
11362 : : }
11363 : 3032 : }
11364 : :
11365 : :
11366 : : /*
11367 : : BuildIntFunction - builds the pseudo procedure call INT.
11368 : : This procedure is actually a "macro" for
11369 : : INT(x) --> CONVERT(INTEGER, x)
11370 : : However we cannot push tokens back onto the input stack
11371 : : because the compiler is currently building a function
11372 : : call and expecting a ReturnVar on the stack.
11373 : : Hence we manipulate the stack and call
11374 : : BuildConvertFunction.
11375 : :
11376 : : The Stack:
11377 : :
11378 : :
11379 : : Entry Exit
11380 : :
11381 : : Ptr ->
11382 : : +----------------+
11383 : : | NoOfParam |
11384 : : |----------------|
11385 : : | Param 1 |
11386 : : |----------------|
11387 : : | Param 2 |
11388 : : |----------------|
11389 : : . .
11390 : : . .
11391 : : . .
11392 : : |----------------|
11393 : : | Param # |
11394 : : |----------------|
11395 : : | ProcSym | Type | Empty
11396 : : |----------------|
11397 : : */
11398 : :
11399 : 6 : static void BuildIntFunction (unsigned int Sym, bool ConstExpr)
11400 : : {
11401 : 6 : unsigned int combinedtok;
11402 : 6 : unsigned int functok;
11403 : 6 : unsigned int optok;
11404 : 6 : unsigned int ReturnVar;
11405 : 6 : unsigned int NoOfParam;
11406 : 6 : unsigned int Type;
11407 : 6 : unsigned int Var;
11408 : :
11409 : 6 : M2Quads_PopT (&NoOfParam);
11410 : 6 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11411 : 6 : if (NoOfParam == 1)
11412 : : {
11413 : 6 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11414 : 6 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11415 : 6 : M2Quads_PopN (NoOfParam+1);
11416 : 6 : if (ConstExprError (Sym, Var, optok, ConstExpr))
11417 : : {
11418 : : /* Generate fake result. */
11419 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11420 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11421 : 6 : SymbolTable_PutVar (ReturnVar, M2Base_Integer);
11422 : 6 : M2Quads_PushTFtok (ReturnVar, M2Base_Integer, combinedtok);
11423 : : }
11424 : 0 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11425 : : {
11426 : : /* avoid dangling else. */
11427 : 0 : Type = SymbolTable_GetSType (Sym); /* return type of function */
11428 : : /* Build macro: CONVERT( CARDINAL, Var ). */
11429 : 0 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
11430 : 0 : M2Quads_PushTtok (Type, functok);
11431 : 0 : M2Quads_PushTtok (Var, optok);
11432 : 0 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
11433 : 0 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* Two parameters */
11434 : : }
11435 : : else
11436 : : {
11437 : : /* avoid dangling else. */
11438 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, optok, optok);
11439 : 0 : M2MetaError_MetaErrorT2 (optok, (const char *) "the parameter to {%1Ea} must be a variable or constant, seen {%2ad}", 67, Sym, Var);
11440 : 0 : M2Quads_PushTtok (combinedtok, SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType));
11441 : : }
11442 : : }
11443 : : else
11444 : : {
11445 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the pseudo procedure {%1Ea} only has one parameter, seen {%2n} parameters", 73, Sym, NoOfParam);
11446 : 0 : M2Quads_PushTtok (functok, SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType));
11447 : : }
11448 : 6 : }
11449 : :
11450 : :
11451 : : /*
11452 : : BuildMakeAdrFunction - builds the pseudo procedure call MAKEADR.
11453 : :
11454 : : The Stack:
11455 : :
11456 : :
11457 : : Entry Exit
11458 : :
11459 : : Ptr ->
11460 : : +----------------+
11461 : : | NoOfParam |
11462 : : |----------------|
11463 : : | Param 1 |
11464 : : |----------------|
11465 : : | Param 2 |
11466 : : |----------------|
11467 : : . .
11468 : : . .
11469 : : . .
11470 : : |----------------|
11471 : : | Param # |
11472 : : |----------------|
11473 : : | ProcSym | Type | Empty
11474 : : |----------------|
11475 : : */
11476 : :
11477 : 12 : static void BuildMakeAdrFunction (void)
11478 : : {
11479 : 12 : unsigned int functok;
11480 : 12 : unsigned int starttok;
11481 : 12 : unsigned int endtok;
11482 : 12 : unsigned int resulttok;
11483 : 12 : bool AreConst;
11484 : 12 : unsigned int i;
11485 : 12 : unsigned int pi;
11486 : 12 : unsigned int NoOfParameters;
11487 : 12 : unsigned int ReturnVar;
11488 : :
11489 : 12 : M2Quads_PopT (&NoOfParameters);
11490 : 12 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParameters+1));
11491 : 12 : if (NoOfParameters > 0)
11492 : : {
11493 : 12 : starttok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParameters+1)); /* ADR token. */
11494 : 12 : endtok = static_cast<unsigned int> (M2Quads_OperandTok (1)); /* last parameter. */
11495 : 24 : GenQuad (M2Quads_ParamOp, 0, M2System_MakeAdr, M2System_MakeAdr); /* last parameter. */
11496 : 12 : i = NoOfParameters;
11497 : : /* stack index referencing stacked parameter, i */
11498 : 12 : pi = 1;
11499 : 24 : while (i > 0)
11500 : : {
11501 : 12 : GenQuadO (M2Quads_OperandTok (pi), M2Quads_ParamOp, i, M2System_MakeAdr, M2Quads_OperandT (pi), true);
11502 : 12 : i -= 1;
11503 : 12 : pi += 1;
11504 : : }
11505 : : AreConst = true;
11506 : : i = 1;
11507 : 24 : while (i <= NoOfParameters)
11508 : : {
11509 : 12 : if (SymbolTable_IsVar (M2Quads_OperandT (i)))
11510 : : {
11511 : : AreConst = false;
11512 : : }
11513 : 0 : else if (! (SymbolTable_IsConst (M2Quads_OperandT (i))))
11514 : : {
11515 : : /* avoid dangling else. */
11516 : 0 : M2MetaError_MetaError1 ((const char *) "problem in the {%1EN} argument for {%kMAKEADR}, all arguments to {%kMAKEADR} must be either variables or constants", 114, i);
11517 : : }
11518 : 12 : i += 1;
11519 : : }
11520 : : /* ReturnVar - will have the type of the procedure */
11521 : 12 : resulttok = M2LexBuf_MakeVirtualTok (starttok, starttok, endtok);
11522 : 12 : ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (AreConst));
11523 : 12 : SymbolTable_PutVar (ReturnVar, SymbolTable_GetSType (M2System_MakeAdr));
11524 : 24 : GenQuadO (resulttok, M2Quads_FunctValueOp, ReturnVar, SymbolTable_NulSym, M2System_MakeAdr, true);
11525 : 12 : M2Quads_PopN (NoOfParameters+1);
11526 : 12 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (M2System_MakeAdr), resulttok);
11527 : : }
11528 : : else
11529 : : {
11530 : 0 : M2MetaError_MetaError1 ((const char *) "the pseudo procedure {%EkMAKEADR} requires at least one parameter, seen {%1n}", 77, NoOfParameters);
11531 : 0 : M2Quads_PopN (1);
11532 : 0 : M2Quads_PushTFtok (M2Base_Nil, SymbolTable_GetSType (M2System_MakeAdr), functok);
11533 : : }
11534 : 12 : }
11535 : :
11536 : :
11537 : : /*
11538 : : BuildShiftFunction - builds the pseudo procedure call SHIFT.
11539 : :
11540 : : PROCEDURE SHIFT (val: <any type>;
11541 : : num: INTEGER): <any type> ;
11542 : :
11543 : : "Returns a bit sequence obtained from val by
11544 : : shifting up or down (left or right) by the
11545 : : absolute value of num, introducing
11546 : : zeros as necessary. The direction is down if
11547 : : the sign of num is negative, otherwise the
11548 : : direction is up."
11549 : :
11550 : : The Stack:
11551 : :
11552 : : Entry Exit
11553 : :
11554 : : Ptr ->
11555 : : +----------------+
11556 : : | NoOfParam |
11557 : : |----------------|
11558 : : | Param 1 |
11559 : : |----------------|
11560 : : | Param 2 | <- Ptr
11561 : : |----------------| +------------+
11562 : : | ProcSym | Type | | ReturnVar |
11563 : : |----------------| |------------|
11564 : : */
11565 : :
11566 : 696 : static void BuildShiftFunction (void)
11567 : : {
11568 : 696 : unsigned int combinedtok;
11569 : 696 : unsigned int paramtok;
11570 : 696 : unsigned int functok;
11571 : 696 : unsigned int vartok;
11572 : 696 : unsigned int exptok;
11573 : 696 : unsigned int r;
11574 : 696 : unsigned int procSym;
11575 : 696 : unsigned int returnVar;
11576 : 696 : unsigned int NoOfParam;
11577 : 696 : unsigned int derefExp;
11578 : 696 : unsigned int Exp;
11579 : 696 : unsigned int varSet;
11580 : :
11581 : 696 : M2Quads_PopT (&NoOfParam);
11582 : 696 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11583 : 696 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11584 : 696 : if (NoOfParam == 2)
11585 : : {
11586 : 696 : PopTrwtok (&Exp, &r, &exptok);
11587 : 696 : MarkAsRead (r);
11588 : 696 : M2Quads_PopTtok (&varSet, &vartok);
11589 : 696 : M2Quads_PopT (&procSym);
11590 : 696 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
11591 : 696 : if (((SymbolTable_GetSType (varSet)) != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_GetDType (varSet))))
11592 : : {
11593 : 696 : derefExp = DereferenceLValue (exptok, Exp);
11594 : 696 : BuildRange (M2Range_InitShiftCheck (varSet, derefExp));
11595 : 696 : returnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
11596 : 696 : SymbolTable_PutVar (returnVar, SymbolTable_GetSType (varSet));
11597 : 1392 : GenQuadO (combinedtok, M2Quads_LogicalShiftOp, returnVar, varSet, derefExp, true);
11598 : 696 : M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (varSet), combinedtok);
11599 : : }
11600 : : else
11601 : : {
11602 : 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}", 119, varSet);
11603 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, combinedtok);
11604 : : }
11605 : : }
11606 : : else
11607 : : {
11608 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
11609 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%kSHIFT} requires at least two parameters, seen {%1En}", 76, NoOfParam);
11610 : 0 : M2Quads_PopN (NoOfParam+1);
11611 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, combinedtok);
11612 : : }
11613 : 696 : }
11614 : :
11615 : :
11616 : : /*
11617 : : BuildRotateFunction - builds the pseudo procedure call ROTATE.
11618 : :
11619 : : PROCEDURE ROTATE (val: <any type>;
11620 : : num: INTEGER): <any type> ;
11621 : :
11622 : : "Returns a bit sequence obtained from val
11623 : : by rotating up or down (left or right) by
11624 : : the absolute value of num. The direction is
11625 : : down if the sign of num is negative, otherwise
11626 : : the direction is up."
11627 : :
11628 : : The Stack:
11629 : :
11630 : : Entry Exit
11631 : :
11632 : : Ptr ->
11633 : : +----------------+
11634 : : | NoOfParam |
11635 : : |----------------|
11636 : : | Param 1 |
11637 : : |----------------|
11638 : : | Param 2 | <- Ptr
11639 : : |----------------| +------------+
11640 : : | ProcSym | Type | | ReturnVar |
11641 : : |----------------| |------------|
11642 : : */
11643 : :
11644 : 232 : static void BuildRotateFunction (void)
11645 : : {
11646 : 232 : unsigned int combinedtok;
11647 : 232 : unsigned int functok;
11648 : 232 : unsigned int vartok;
11649 : 232 : unsigned int exptok;
11650 : 232 : unsigned int r;
11651 : 232 : unsigned int procSym;
11652 : 232 : unsigned int returnVar;
11653 : 232 : unsigned int NoOfParam;
11654 : 232 : unsigned int derefExp;
11655 : 232 : unsigned int Exp;
11656 : 232 : unsigned int varSet;
11657 : :
11658 : 232 : M2Quads_PopT (&NoOfParam);
11659 : 232 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11660 : 232 : if (NoOfParam == 2)
11661 : : {
11662 : 232 : PopTrwtok (&Exp, &r, &exptok);
11663 : 232 : MarkAsRead (r);
11664 : 232 : M2Quads_PopTtok (&varSet, &vartok);
11665 : 232 : M2Quads_PopT (&procSym);
11666 : 232 : if (((SymbolTable_GetSType (varSet)) != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_GetDType (varSet))))
11667 : : {
11668 : 232 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
11669 : 232 : derefExp = DereferenceLValue (exptok, Exp);
11670 : 232 : BuildRange (M2Range_InitRotateCheck (varSet, derefExp));
11671 : 232 : returnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
11672 : 232 : SymbolTable_PutVar (returnVar, SymbolTable_GetSType (varSet));
11673 : 464 : GenQuadO (combinedtok, M2Quads_LogicalRotateOp, returnVar, varSet, derefExp, true);
11674 : 232 : M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (varSet), combinedtok);
11675 : : }
11676 : : else
11677 : : {
11678 : 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}", 119, varSet);
11679 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
11680 : : }
11681 : : }
11682 : : else
11683 : : {
11684 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "SYSTEM procedure {%EkROTATE} expects 2 parameters and was given {%1n} parameters", 80, NoOfParam);
11685 : 0 : M2Quads_PopN (NoOfParam+1);
11686 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
11687 : : }
11688 : 232 : }
11689 : :
11690 : :
11691 : : /*
11692 : : BuildValFunction - builds the pseudo procedure call VAL.
11693 : : This procedure is actually a "macro" for
11694 : : VAL(Type, x) --> CONVERT(Type, x)
11695 : : However we cannot push tokens back onto the input stack
11696 : : because the compiler is currently building a function
11697 : : call and expecting a ReturnVar on the stack.
11698 : : Hence we manipulate the stack and call
11699 : : BuildConvertFunction.
11700 : :
11701 : : The Stack:
11702 : :
11703 : :
11704 : : Entry Exit
11705 : :
11706 : : Ptr ->
11707 : : +----------------+
11708 : : | NoOfParam |
11709 : : |----------------|
11710 : : | Param 1 |
11711 : : |----------------|
11712 : : | Param 2 |
11713 : : |----------------|
11714 : : . .
11715 : : . .
11716 : : . .
11717 : : |----------------|
11718 : : | Param # |
11719 : : |----------------|
11720 : : | ProcSym | Type | Empty
11721 : : |----------------|
11722 : : */
11723 : :
11724 : 3237 : static void BuildValFunction (unsigned int ProcSym, bool ConstExpr)
11725 : : {
11726 : 3237 : unsigned int combinedtok;
11727 : 3237 : unsigned int functok;
11728 : 3237 : unsigned int ReturnVar;
11729 : 3237 : unsigned int NoOfParam;
11730 : 3237 : unsigned int Exp;
11731 : 3237 : unsigned int Type;
11732 : 3237 : unsigned int tok;
11733 : 3237 : unsigned int r;
11734 : 3237 : unsigned int typetok;
11735 : 3237 : unsigned int exptok;
11736 : :
11737 : 3237 : M2Quads_PopT (&NoOfParam);
11738 : 3237 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11739 : 3237 : if (NoOfParam == 2)
11740 : : {
11741 : 3237 : PopTrwtok (&Exp, &r, &exptok);
11742 : 3237 : MarkAsRead (r);
11743 : 3237 : M2Quads_PopTtok (&Type, &typetok);
11744 : 3237 : M2Quads_PopTtok (&ProcSym, &tok);
11745 : 3237 : if (SymbolTable_IsUnknown (Type))
11746 : : {
11747 : : /* non recoverable error. */
11748 : 6 : M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type found in builtin procedure function {%AkVAL} {%1ad}", 67, Type);
11749 : : }
11750 : 3231 : else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
11751 : : {
11752 : : /* avoid dangling else. */
11753 : : /* Generate fake result. */
11754 : 6 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
11755 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
11756 : 6 : SymbolTable_PutVar (ReturnVar, Type);
11757 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
11758 : : }
11759 : 3225 : 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))))
11760 : : {
11761 : : /* avoid dangling else. */
11762 : : /*
11763 : : Build macro: CONVERT( Type, Var )
11764 : : */
11765 : 3225 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
11766 : 3225 : M2Quads_PushTtok (Type, typetok);
11767 : 3225 : M2Quads_PushTtok (Exp, exptok);
11768 : 3225 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
11769 : 3225 : BuildConvertFunction (M2Base_Convert, ConstExpr);
11770 : : }
11771 : : else
11772 : : {
11773 : : /* avoid dangling else. */
11774 : : /* non recoverable error. */
11775 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkVAL} has the following formal parameter declaration {%kVAL} (type, expression)", 104);
11776 : : }
11777 : : }
11778 : : else
11779 : : {
11780 : : /* non recoverable error. */
11781 : 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);
11782 : : }
11783 : 3231 : }
11784 : :
11785 : :
11786 : : /*
11787 : : BuildCastFunction - builds the pseudo procedure call CAST.
11788 : : This procedure is actually a "macro" for
11789 : : CAST(Type, x) --> Type(x)
11790 : : However we cannot push tokens back onto the input stack
11791 : : because the compiler is currently building a function
11792 : : call and expecting a ReturnVar on the stack.
11793 : : Hence we manipulate the stack and call
11794 : : BuildConvertFunction.
11795 : :
11796 : : The Stack:
11797 : :
11798 : :
11799 : : Entry Exit
11800 : :
11801 : : Ptr ->
11802 : : +----------------+
11803 : : | NoOfParam |
11804 : : |----------------|
11805 : : | Param 1 |
11806 : : |----------------|
11807 : : | Param 2 |
11808 : : |----------------|
11809 : : . .
11810 : : . .
11811 : : . .
11812 : : |----------------|
11813 : : | Param # |
11814 : : |----------------|
11815 : : | ProcSym | Type | Empty
11816 : : |----------------|
11817 : : */
11818 : :
11819 : 144 : static void BuildCastFunction (unsigned int ProcSym, bool ConstExpr)
11820 : : {
11821 : 144 : unsigned int combinedtok;
11822 : 144 : unsigned int exptok;
11823 : 144 : unsigned int typetok;
11824 : 144 : unsigned int functok;
11825 : 144 : unsigned int ReturnVar;
11826 : 144 : unsigned int NoOfParam;
11827 : 144 : unsigned int Exp;
11828 : 144 : unsigned int Type;
11829 : :
11830 : 144 : M2Quads_PopT (&NoOfParam);
11831 : 144 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11832 : 144 : if (NoOfParam == 2)
11833 : : {
11834 : 144 : Type = static_cast<unsigned int> (M2Quads_OperandT (2));
11835 : 144 : typetok = static_cast<unsigned int> (M2Quads_OperandTok (2));
11836 : 144 : Exp = static_cast<unsigned int> (M2Quads_OperandT (1));
11837 : 144 : exptok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11838 : 144 : if (SymbolTable_IsUnknown (Type))
11839 : : {
11840 : : /* non recoverable error. */
11841 : 0 : M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type {%1Aad} found in {%kCAST}", 41, Type);
11842 : : }
11843 : 144 : else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
11844 : : {
11845 : : /* avoid dangling else. */
11846 : : /* Generate fake result. */
11847 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
11848 : 0 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
11849 : 0 : SymbolTable_PutVar (ReturnVar, Type);
11850 : 0 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
11851 : : }
11852 : 144 : else if (((((((SymbolTable_IsSet (Type)) || (SymbolTable_IsEnumeration (Type))) || (SymbolTable_IsSubrange (Type))) || (SymbolTable_IsType (Type))) || (SymbolTable_IsPointer (Type))) || (SymbolTable_IsArray (Type))) || (SymbolTable_IsProcType (Type)))
11853 : : {
11854 : : /* avoid dangling else. */
11855 : 144 : if (SymbolTable_IsConst (Exp))
11856 : : {
11857 : 18 : M2Quads_PopN (NoOfParam+1);
11858 : : /*
11859 : : Build macro: Type( Var )
11860 : : */
11861 : 18 : M2Quads_PushTFtok (Type, static_cast<unsigned int> (SymbolTable_NulSym), typetok);
11862 : 18 : M2Quads_PushTtok (Exp, exptok);
11863 : 18 : M2Quads_PushT (static_cast<unsigned int> (1)); /* one parameter */
11864 : 18 : BuildTypeCoercion (); /* one parameter */
11865 : : }
11866 : 126 : else if ((SymbolTable_IsVar (Exp)) || (SymbolTable_IsProcedure (Exp)))
11867 : : {
11868 : : /* avoid dangling else. */
11869 : 126 : M2Quads_PopN (NoOfParam+1);
11870 : 126 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, exptok);
11871 : 126 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
11872 : 126 : SymbolTable_PutVar (ReturnVar, Type);
11873 : 252 : GenQuadO (combinedtok, M2Quads_CastOp, ReturnVar, Type, Exp, false);
11874 : 126 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
11875 : : }
11876 : : else
11877 : : {
11878 : : /* avoid dangling else. */
11879 : : /* non recoverable error. */
11880 : 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);
11881 : : }
11882 : : }
11883 : : else
11884 : : {
11885 : : /* avoid dangling else. */
11886 : : /* non recoverable error. */
11887 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkCAST} has the following formal parameter declaration {%kCAST} (type, expression)", 106);
11888 : : }
11889 : : }
11890 : : else
11891 : : {
11892 : : /* non recoverable error. */
11893 : 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);
11894 : : }
11895 : 144 : }
11896 : :
11897 : :
11898 : : /*
11899 : : BuildConvertFunction - builds the pseudo function CONVERT.
11900 : : CONVERT( Type, Variable ) ;
11901 : :
11902 : : The Stack:
11903 : :
11904 : :
11905 : : Entry Exit
11906 : :
11907 : : Ptr ->
11908 : : +----------------+
11909 : : | NoOfParam |
11910 : : |----------------|
11911 : : | Param 1 |
11912 : : |----------------|
11913 : : | Param 2 |
11914 : : |----------------|
11915 : : . .
11916 : : . .
11917 : : . .
11918 : : |----------------|
11919 : : | Param # | <- Ptr
11920 : : |----------------| +---------------------+
11921 : : | ProcSym | Type | | ReturnVar | Param1 |
11922 : : |----------------| |---------------------|
11923 : :
11924 : : Quadruples:
11925 : :
11926 : : ConvertOp ReturnVar Param1 Param2
11927 : :
11928 : : Converts variable Param2 into a variable Param1
11929 : : with a type Param1.
11930 : : */
11931 : :
11932 : 41450 : static void BuildConvertFunction (unsigned int ProcSym, bool ConstExpr)
11933 : : {
11934 : 41450 : unsigned int combinedtok;
11935 : 41450 : unsigned int functok;
11936 : 41450 : unsigned int typetok;
11937 : 41450 : unsigned int exptok;
11938 : 41450 : unsigned int t;
11939 : 41450 : unsigned int r;
11940 : 41450 : unsigned int Exp;
11941 : 41450 : unsigned int Type;
11942 : 41450 : unsigned int NoOfParam;
11943 : 41450 : unsigned int ReturnVar;
11944 : :
11945 : 41450 : M2Quads_PopT (&NoOfParam);
11946 : 41450 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11947 : 41450 : if (NoOfParam == 2)
11948 : : {
11949 : 41450 : PopTrwtok (&Exp, &r, &exptok);
11950 : 41450 : MarkAsRead (r);
11951 : 41450 : M2Quads_PopTtok (&Type, &typetok);
11952 : 41450 : M2Quads_PopT (&ProcSym);
11953 : 41450 : if (SymbolTable_IsUnknown (Type))
11954 : : {
11955 : : /* non recoverable error. */
11956 : 0 : M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type {%1Aad} found in {%kCONVERT}", 44, Type);
11957 : : }
11958 : 41450 : else if (SymbolTable_IsUnknown (Exp))
11959 : : {
11960 : : /* avoid dangling else. */
11961 : : /* non recoverable error. */
11962 : 0 : M2MetaError_MetaErrorT1 (typetok, (const char *) "unknown {%1Ad} {%1ad} found in {%kCONVERT}", 42, Exp);
11963 : : }
11964 : 41450 : else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
11965 : : {
11966 : : /* avoid dangling else. */
11967 : : /* Generate fake result. */
11968 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
11969 : 0 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
11970 : 0 : SymbolTable_PutVar (ReturnVar, Type);
11971 : 0 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
11972 : : }
11973 : 41450 : 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))))
11974 : : {
11975 : : /* avoid dangling else. */
11976 : : /* firstly dereference Var */
11977 : 41450 : if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
11978 : : {
11979 : 0 : t = SymbolTable_MakeTemporary (exptok, SymbolTable_RightValue);
11980 : 0 : SymbolTable_PutVar (t, SymbolTable_GetSType (Exp));
11981 : 0 : CheckPointerThroughNil (exptok, Exp);
11982 : 0 : doIndrX (exptok, t, Exp);
11983 : 0 : Exp = t;
11984 : : }
11985 : 41450 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
11986 : 82900 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
11987 : 41450 : SymbolTable_PutVar (ReturnVar, Type);
11988 : 82900 : GenQuadO (combinedtok, M2Quads_ConvertOp, ReturnVar, Type, Exp, true);
11989 : 41450 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
11990 : : }
11991 : : else
11992 : : {
11993 : : /* avoid dangling else. */
11994 : : /* non recoverable error. */
11995 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkCONVERT} has the following formal parameter declaration {%kCONVERT} (type, expression)", 112);
11996 : : }
11997 : : }
11998 : : else
11999 : : {
12000 : : /* non recoverable error. */
12001 : 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);
12002 : : }
12003 : 41450 : }
12004 : :
12005 : :
12006 : : /*
12007 : : CheckBaseTypeValue - checks to see whether the value, min, really exists.
12008 : : */
12009 : :
12010 : 1765 : static unsigned int CheckBaseTypeValue (unsigned int tok, unsigned int type, unsigned int min, unsigned int func)
12011 : : {
12012 : 1765 : if (((type == M2Base_Real) || (type == M2Base_LongReal)) || (type == M2Base_ShortReal))
12013 : : {
12014 : 78 : SymbolTable_PushValue (min);
12015 : 78 : if (! (M2ALU_IsValueAndTreeKnown ()))
12016 : : {
12017 : 0 : M2MetaError_MetaErrorT2 (tok, (const char *) "{%1Ead} ({%2ad}) cannot be calculated at compile time for the target architecture", 81, func, type);
12018 : 0 : return SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType);
12019 : : }
12020 : : }
12021 : : return min;
12022 : : /* static analysis guarentees a RETURN statement will be used before here. */
12023 : : __builtin_unreachable ();
12024 : : }
12025 : :
12026 : :
12027 : : /*
12028 : : GetTypeMin - returns the minimium value of type.
12029 : : */
12030 : :
12031 : 1082 : static unsigned int GetTypeMin (unsigned int tok, unsigned int func, unsigned int type)
12032 : : {
12033 : 1146 : unsigned int min;
12034 : 1146 : unsigned int max;
12035 : :
12036 : 1146 : if (SymbolTable_IsSubrange (type))
12037 : : {
12038 : 234 : min = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
12039 : 234 : SymbolTable_PutVar (min, type);
12040 : 468 : GenQuad (M2Quads_SubrangeLowOp, min, SymbolTable_NulSym, type);
12041 : 234 : return min;
12042 : : }
12043 : 912 : else if (SymbolTable_IsSet (SymbolTable_SkipType (type)))
12044 : : {
12045 : : /* avoid dangling else. */
12046 : 48 : return GetTypeMin (tok, func, SymbolTable_GetSType (SymbolTable_SkipType (type)));
12047 : : }
12048 : 864 : else if ((M2Base_IsBaseType (type)) || (SymbolTable_IsEnumeration (type)))
12049 : : {
12050 : : /* avoid dangling else. */
12051 : 668 : M2Base_GetBaseTypeMinMax (type, &min, &max);
12052 : 668 : min = CheckBaseTypeValue (tok, type, min, func);
12053 : 668 : return min;
12054 : : }
12055 : 196 : else if (M2System_IsSystemType (type))
12056 : : {
12057 : : /* avoid dangling else. */
12058 : 180 : M2System_GetSystemTypeMinMax (type, &min, &max);
12059 : 180 : return min;
12060 : : }
12061 : 16 : else if ((SymbolTable_GetSType (type)) == SymbolTable_NulSym)
12062 : : {
12063 : : /* avoid dangling else. */
12064 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "unable to obtain the {%AkMIN} value for type {%1ad}", 51, type);
12065 : : /* non recoverable error. */
12066 : 0 : M2Error_InternalError ((const char *) "MetaErrorT1 {%AkMIN} should call abort", 38);
12067 : : }
12068 : : else
12069 : : {
12070 : : /* avoid dangling else. */
12071 : 16 : return GetTypeMin (tok, func, SymbolTable_GetSType (type));
12072 : : }
12073 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
12074 : : __builtin_unreachable ();
12075 : : }
12076 : :
12077 : :
12078 : : /*
12079 : : GetTypeMax - returns the maximum value of type.
12080 : : */
12081 : :
12082 : 4175 : static unsigned int GetTypeMax (unsigned int tok, unsigned int func, unsigned int type)
12083 : : {
12084 : 6769 : unsigned int min;
12085 : 6769 : unsigned int max;
12086 : :
12087 : 6769 : if (SymbolTable_IsSubrange (type))
12088 : : {
12089 : 2882 : max = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
12090 : 2882 : SymbolTable_PutVar (max, type);
12091 : 5764 : GenQuad (M2Quads_SubrangeHighOp, max, SymbolTable_NulSym, type);
12092 : 2882 : return max;
12093 : : }
12094 : 3887 : else if (SymbolTable_IsSet (SymbolTable_SkipType (type)))
12095 : : {
12096 : : /* avoid dangling else. */
12097 : 2578 : return GetTypeMax (tok, func, SymbolTable_GetSType (SymbolTable_SkipType (type)));
12098 : : }
12099 : 1309 : else if ((M2Base_IsBaseType (type)) || (SymbolTable_IsEnumeration (type)))
12100 : : {
12101 : : /* avoid dangling else. */
12102 : 1097 : M2Base_GetBaseTypeMinMax (type, &min, &max);
12103 : 1097 : min = CheckBaseTypeValue (tok, type, min, func);
12104 : 1097 : return max;
12105 : : }
12106 : 212 : else if (M2System_IsSystemType (type))
12107 : : {
12108 : : /* avoid dangling else. */
12109 : 196 : M2System_GetSystemTypeMinMax (type, &min, &max);
12110 : 196 : return max;
12111 : : }
12112 : 16 : else if ((SymbolTable_GetSType (type)) == SymbolTable_NulSym)
12113 : : {
12114 : : /* avoid dangling else. */
12115 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "unable to obtain the {%AkMAX} value for type {%1ad}", 51, type);
12116 : : /* non recoverable error. */
12117 : 0 : M2Error_InternalError ((const char *) "MetaErrorT1 {%AkMAX} should call abort", 38);
12118 : : }
12119 : : else
12120 : : {
12121 : : /* avoid dangling else. */
12122 : 16 : return GetTypeMax (tok, func, SymbolTable_GetSType (type));
12123 : : }
12124 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
12125 : : __builtin_unreachable ();
12126 : : }
12127 : :
12128 : :
12129 : : /*
12130 : : BuildMinFunction - builds the pseudo function call Min.
12131 : :
12132 : : The Stack:
12133 : :
12134 : : Entry Exit
12135 : :
12136 : : Ptr ->
12137 : : +----------------+
12138 : : | NoOfParam=1 |
12139 : : |----------------|
12140 : : | Param 1 |
12141 : : |----------------|
12142 : : | ProcSym | Type | Empty
12143 : : |----------------|
12144 : : */
12145 : :
12146 : 1082 : static void BuildMinFunction (void)
12147 : : {
12148 : 1082 : unsigned int combinedtok;
12149 : 1082 : unsigned int functok;
12150 : 1082 : unsigned int vartok;
12151 : 1082 : unsigned int func;
12152 : 1082 : unsigned int min;
12153 : 1082 : unsigned int NoOfParam;
12154 : 1082 : unsigned int Var;
12155 : :
12156 : 1082 : M2Quads_PopT (&NoOfParam);
12157 : 1082 : func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12158 : 1082 : functok = OperandTtok (NoOfParam+1);
12159 : 1082 : if (NoOfParam == 1)
12160 : : {
12161 : 1082 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12162 : 1082 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12163 : 1082 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12164 : 1082 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok); /* destroy arguments to this function */
12165 : 1082 : if (SymbolTable_IsAModula2Type (Var))
12166 : : {
12167 : 1082 : min = GetTypeMin (vartok, func, Var);
12168 : 1082 : M2Quads_PushTFtok (min, SymbolTable_GetSType (min), combinedtok);
12169 : : }
12170 : 0 : else if (SymbolTable_IsVar (Var))
12171 : : {
12172 : : /* avoid dangling else. */
12173 : 0 : min = GetTypeMin (vartok, func, SymbolTable_GetSType (Var));
12174 : 0 : M2Quads_PushTFtok (min, SymbolTable_GetSType (Var), combinedtok);
12175 : : }
12176 : : else
12177 : : {
12178 : : /* avoid dangling else. */
12179 : : /* non recoverable error. */
12180 : 0 : M2MetaError_MetaErrorT1 (vartok, (const char *) "parameter to {%AkMIN} must be a type or a variable, seen {%1ad}", 63, Var);
12181 : : }
12182 : : }
12183 : : else
12184 : : {
12185 : : /* non recoverable error. */
12186 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkMIN} only has one parameter, seen {%1n}", 82, NoOfParam);
12187 : : }
12188 : 1082 : }
12189 : :
12190 : :
12191 : : /*
12192 : : BuildMaxFunction - builds the pseudo function call Max.
12193 : :
12194 : : The Stack:
12195 : :
12196 : : Entry Exit
12197 : :
12198 : : Ptr ->
12199 : : +----------------+
12200 : : | NoOfParam=1 |
12201 : : |----------------|
12202 : : | Param 1 |
12203 : : |----------------|
12204 : : | ProcSym | Type | Empty
12205 : : |----------------|
12206 : : */
12207 : :
12208 : 4175 : static void BuildMaxFunction (void)
12209 : : {
12210 : 4175 : unsigned int combinedtok;
12211 : 4175 : unsigned int functok;
12212 : 4175 : unsigned int vartok;
12213 : 4175 : unsigned int func;
12214 : 4175 : unsigned int max;
12215 : 4175 : unsigned int NoOfParam;
12216 : 4175 : unsigned int Var;
12217 : :
12218 : 4175 : M2Quads_PopT (&NoOfParam);
12219 : 4175 : func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12220 : 4175 : functok = OperandTtok (NoOfParam+1);
12221 : 4175 : if (NoOfParam == 1)
12222 : : {
12223 : 4175 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12224 : 4175 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12225 : 4175 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12226 : 4175 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok); /* destroy arguments to this function */
12227 : 4175 : if (SymbolTable_IsAModula2Type (Var))
12228 : : {
12229 : 4175 : max = GetTypeMax (vartok, func, Var);
12230 : 4175 : M2Quads_PushTFtok (max, SymbolTable_GetSType (max), combinedtok);
12231 : : }
12232 : 0 : else if (SymbolTable_IsVar (Var))
12233 : : {
12234 : : /* avoid dangling else. */
12235 : 0 : max = GetTypeMax (vartok, func, SymbolTable_GetSType (Var));
12236 : 0 : M2Quads_PushTFtok (max, SymbolTable_GetSType (Var), combinedtok);
12237 : : }
12238 : : else
12239 : : {
12240 : : /* avoid dangling else. */
12241 : : /* non recoverable error. */
12242 : 0 : M2MetaError_MetaErrorT1 (vartok, (const char *) "parameter to {%AkMAX} must be a type or a variable, seen {%1ad}", 63, Var);
12243 : : }
12244 : : }
12245 : : else
12246 : : {
12247 : : /* non recoverable error. */
12248 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkMAX} only has one parameter, seen {%1n}", 81, NoOfParam);
12249 : : }
12250 : 4175 : }
12251 : :
12252 : :
12253 : : /*
12254 : : BuildTruncFunction - builds the pseudo procedure call TRUNC.
12255 : : This procedure is actually a "macro" for
12256 : : TRUNC(x) --> CONVERT(INTEGER, x)
12257 : : However we cannot push tokens back onto the input stack
12258 : : because the compiler is currently building a function
12259 : : call and expecting a ReturnVar on the stack.
12260 : : Hence we manipulate the stack and call
12261 : : BuildConvertFunction.
12262 : :
12263 : : The Stack:
12264 : :
12265 : :
12266 : : Entry Exit
12267 : :
12268 : : Ptr ->
12269 : : +----------------+
12270 : : | NoOfParam |
12271 : : |----------------|
12272 : : | Param 1 |
12273 : : |----------------|
12274 : : | Param 2 |
12275 : : |----------------|
12276 : : . .
12277 : : . .
12278 : : . .
12279 : : |----------------|
12280 : : | Param # |
12281 : : |----------------|
12282 : : | ProcSym | Type | Empty
12283 : : |----------------|
12284 : : */
12285 : :
12286 : 60 : static void BuildTruncFunction (unsigned int Sym, bool ConstExpr)
12287 : : {
12288 : 60 : unsigned int combinedtok;
12289 : 60 : unsigned int vartok;
12290 : 60 : unsigned int functok;
12291 : 60 : unsigned int NoOfParam;
12292 : 60 : unsigned int ReturnVar;
12293 : 60 : unsigned int ProcSym;
12294 : 60 : unsigned int Type;
12295 : 60 : unsigned int Var;
12296 : :
12297 : 60 : M2Quads_PopT (&NoOfParam);
12298 : 60 : M2Debug_Assert (M2Base_IsTrunc (M2Quads_OperandT (NoOfParam+1)));
12299 : 60 : functok = OperandTtok (NoOfParam+1);
12300 : 60 : if (NoOfParam == 1)
12301 : : {
12302 : 60 : ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "CONVERT", 7));
12303 : 60 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
12304 : : {
12305 : 60 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12306 : 60 : vartok = OperandTtok (1);
12307 : 60 : Type = SymbolTable_GetSType (Sym);
12308 : 60 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12309 : 60 : if (ConstExprError (Sym, Var, vartok, ConstExpr))
12310 : : {
12311 : : /* Generate fake result. */
12312 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
12313 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12314 : 6 : SymbolTable_PutVar (ReturnVar, Type);
12315 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12316 : : }
12317 : 54 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
12318 : : {
12319 : : /* avoid dangling else. */
12320 : 54 : if (M2Base_IsRealType (SymbolTable_GetSType (Var)))
12321 : : {
12322 : : /* build macro: CONVERT( INTEGER, Var ). */
12323 : 54 : M2Quads_PushTFtok (ProcSym, static_cast<unsigned int> (SymbolTable_NulSym), functok);
12324 : 54 : M2Quads_PushTtok (Type, functok);
12325 : 54 : M2Quads_PushTtok (Var, vartok);
12326 : 54 : M2Quads_PushT (static_cast<unsigned int> (2)); /* two parameters */
12327 : 54 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* two parameters */
12328 : : }
12329 : : else
12330 : : {
12331 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "argument to {%1Ead} must be a float point type", 46, Sym);
12332 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), Type), Type, functok);
12333 : : }
12334 : : }
12335 : : else
12336 : : {
12337 : : /* avoid dangling else. */
12338 : 0 : M2MetaError_MetaErrorT2 (vartok, (const char *) "argument to {%1Ead} must be a variable or constant, seen {%2ad}", 63, Sym, Var);
12339 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), Type), Type, functok);
12340 : : }
12341 : : }
12342 : : else
12343 : : {
12344 : 0 : M2Error_InternalError ((const char *) "CONVERT procedure not found for TRUNC substitution", 50);
12345 : : }
12346 : : }
12347 : : else
12348 : : {
12349 : : /* non recoverable error. */
12350 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkTRUNC} only has one parameter, seen {%1n}", 84, NoOfParam);
12351 : : }
12352 : 60 : }
12353 : :
12354 : :
12355 : : /*
12356 : : BuildFloatFunction - builds the pseudo procedure call FLOAT.
12357 : : This procedure is actually a "macro" for
12358 : : FLOAT(x) --> CONVERT(REAL, x)
12359 : : However we cannot push tokens back onto the input stack
12360 : : because the compiler is currently building a function
12361 : : call and expecting a ReturnVar on the stack.
12362 : : Hence we manipulate the stack and call
12363 : : BuildConvertFunction.
12364 : :
12365 : : The Stack:
12366 : :
12367 : :
12368 : : Entry Exit
12369 : :
12370 : : Ptr ->
12371 : : +----------------+
12372 : : | NoOfParam |
12373 : : |----------------|
12374 : : | Param 1 |
12375 : : |----------------|
12376 : : | Param 2 |
12377 : : |----------------|
12378 : : . .
12379 : : . .
12380 : : . .
12381 : : |----------------|
12382 : : | Param # |
12383 : : |----------------|
12384 : : | ProcSym | Type | Empty
12385 : : |----------------|
12386 : : */
12387 : :
12388 : 64 : static void BuildFloatFunction (unsigned int Sym, bool ConstExpr)
12389 : : {
12390 : 64 : unsigned int combinedtok;
12391 : 64 : unsigned int vartok;
12392 : 64 : unsigned int functok;
12393 : 64 : unsigned int NoOfParam;
12394 : 64 : unsigned int ReturnVar;
12395 : 64 : unsigned int Type;
12396 : 64 : unsigned int Var;
12397 : 64 : unsigned int ProcSym;
12398 : :
12399 : 64 : M2Quads_PopT (&NoOfParam);
12400 : 64 : functok = OperandTtok (NoOfParam+1);
12401 : 64 : Type = SymbolTable_GetSType (Sym);
12402 : 64 : if (NoOfParam == 1)
12403 : : {
12404 : 64 : ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "CONVERT", 7));
12405 : 64 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
12406 : : {
12407 : 64 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12408 : 64 : vartok = OperandTtok (1);
12409 : 64 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function. */
12410 : 64 : if (ConstExprError (Sym, Var, vartok, ConstExpr))
12411 : : {
12412 : : /* Generate fake result. */
12413 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
12414 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12415 : 6 : SymbolTable_PutVar (ReturnVar, Type);
12416 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12417 : : }
12418 : 58 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
12419 : : {
12420 : : /* avoid dangling else. */
12421 : : /* build macro: CONVERT (REAL, Var). */
12422 : 58 : M2Quads_PushTFtok (ProcSym, static_cast<unsigned int> (SymbolTable_NulSym), functok);
12423 : 58 : M2Quads_PushTtok (Type, functok);
12424 : 58 : M2Quads_PushTtok (Var, vartok);
12425 : 58 : M2Quads_PushT (static_cast<unsigned int> (2)); /* two parameters. */
12426 : 58 : BuildConvertFunction (ProcSym, ConstExpr); /* two parameters. */
12427 : : }
12428 : : else
12429 : : {
12430 : : /* avoid dangling else. */
12431 : 0 : M2MetaError_MetaErrorT1 (vartok, (const char *) "argument to {%1Ead} must be a variable or constant", 50, ProcSym);
12432 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0.0", 3), Type), Type, functok);
12433 : : }
12434 : : }
12435 : : else
12436 : : {
12437 : 0 : M2Error_InternalError ((const char *) "CONVERT procedure not found for FLOAT substitution", 50);
12438 : : }
12439 : : }
12440 : : else
12441 : : {
12442 : 0 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function. */
12443 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter", 61, Sym); /* destroy arguments to this function. */
12444 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0.0", 3), Type), Type, functok);
12445 : : }
12446 : 64 : }
12447 : :
12448 : :
12449 : : /*
12450 : : BuildReFunction - builds the pseudo procedure call RE.
12451 : :
12452 : : The Stack:
12453 : :
12454 : :
12455 : : Entry Exit
12456 : :
12457 : : Ptr ->
12458 : : +----------------+
12459 : : | NoOfParam |
12460 : : |----------------|
12461 : : | Param 1 |
12462 : : |----------------|
12463 : : | Param 2 |
12464 : : |----------------|
12465 : : . .
12466 : : . .
12467 : : . .
12468 : : |----------------|
12469 : : | Param # |
12470 : : |----------------|
12471 : : | ProcSym | Type | Empty
12472 : : |----------------|
12473 : : */
12474 : :
12475 : 60 : static void BuildReFunction (unsigned int Sym, bool ConstExpr)
12476 : : {
12477 : 60 : unsigned int func;
12478 : 60 : unsigned int combinedtok;
12479 : 60 : unsigned int vartok;
12480 : 60 : unsigned int functok;
12481 : 60 : unsigned int NoOfParam;
12482 : 60 : unsigned int ReturnVar;
12483 : 60 : unsigned int Type;
12484 : 60 : unsigned int Var;
12485 : :
12486 : 60 : M2Quads_PopT (&NoOfParam);
12487 : 60 : functok = OperandTtok (NoOfParam+1);
12488 : 60 : func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12489 : 60 : if (NoOfParam == 1)
12490 : : {
12491 : 60 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12492 : 60 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12493 : 60 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
12494 : 60 : Type = M2Base_ComplexToScalar (SymbolTable_GetDType (Var));
12495 : 60 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12496 : 60 : if (ConstExprError (Sym, Var, vartok, ConstExpr))
12497 : : {
12498 : : /* Generate fake result. */
12499 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
12500 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12501 : 6 : SymbolTable_PutVar (ReturnVar, Type);
12502 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12503 : : }
12504 : 54 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
12505 : : {
12506 : : /* avoid dangling else. */
12507 : 108 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12508 : 54 : SymbolTable_PutVar (ReturnVar, Type);
12509 : 108 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Re, Var, false);
12510 : 54 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12511 : : }
12512 : : else
12513 : : {
12514 : : /* avoid dangling else. */
12515 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, combinedtok);
12516 : 0 : M2MetaError_MetaErrorT2 (vartok, (const char *) "the parameter to the builtin procedure function {%1Ead} must be a constant or a variable, seen {%2ad}", 101, func, Var);
12517 : : }
12518 : : }
12519 : : else
12520 : : {
12521 : 0 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12522 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, functok); /* destroy arguments to this function */
12523 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter, seen {%2n}", 73, func, NoOfParam);
12524 : : }
12525 : 60 : }
12526 : :
12527 : :
12528 : : /*
12529 : : BuildImFunction - builds the pseudo procedure call IM.
12530 : :
12531 : : The Stack:
12532 : :
12533 : :
12534 : : Entry Exit
12535 : :
12536 : : Ptr ->
12537 : : +----------------+
12538 : : | NoOfParam |
12539 : : |----------------|
12540 : : | Param 1 |
12541 : : |----------------|
12542 : : | Param 2 |
12543 : : |----------------|
12544 : : . .
12545 : : . .
12546 : : . .
12547 : : |----------------|
12548 : : | Param # |
12549 : : |----------------|
12550 : : | ProcSym | Type | Empty
12551 : : |----------------|
12552 : : */
12553 : :
12554 : 60 : static void BuildImFunction (unsigned int Sym, bool ConstExpr)
12555 : : {
12556 : 60 : unsigned int func;
12557 : 60 : unsigned int combinedtok;
12558 : 60 : unsigned int vartok;
12559 : 60 : unsigned int functok;
12560 : 60 : unsigned int NoOfParam;
12561 : 60 : unsigned int ReturnVar;
12562 : 60 : unsigned int Type;
12563 : 60 : unsigned int Var;
12564 : :
12565 : 60 : M2Quads_PopT (&NoOfParam);
12566 : 60 : functok = OperandTtok (NoOfParam+1);
12567 : 60 : func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12568 : 60 : if (NoOfParam == 1)
12569 : : {
12570 : 60 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12571 : 60 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12572 : 60 : Type = M2Base_ComplexToScalar (SymbolTable_GetDType (Var));
12573 : 60 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
12574 : 60 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12575 : 60 : if (ConstExprError (Sym, Var, vartok, ConstExpr))
12576 : : {
12577 : : /* Generate fake result. */
12578 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
12579 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12580 : 6 : SymbolTable_PutVar (ReturnVar, Type);
12581 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12582 : : }
12583 : 54 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
12584 : : {
12585 : : /* avoid dangling else. */
12586 : 108 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12587 : 54 : SymbolTable_PutVar (ReturnVar, M2Base_ComplexToScalar (SymbolTable_GetDType (Var)));
12588 : 108 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Im, Var, false);
12589 : 54 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), combinedtok);
12590 : : }
12591 : : else
12592 : : {
12593 : : /* avoid dangling else. */
12594 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, combinedtok);
12595 : 0 : M2MetaError_MetaErrorT2 (vartok, (const char *) "the parameter to the builtin procedure function {%1Ead} must be a constant or a variable, seen {%2ad}", 101, func, Var);
12596 : : }
12597 : : }
12598 : : else
12599 : : {
12600 : 0 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12601 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, functok); /* destroy arguments to this function */
12602 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter, seen {%2n}", 73, func, NoOfParam);
12603 : : }
12604 : 60 : }
12605 : :
12606 : :
12607 : : /*
12608 : : BuildCmplxFunction - builds the pseudo procedure call CMPLX.
12609 : :
12610 : : The Stack:
12611 : :
12612 : :
12613 : : Entry Exit
12614 : :
12615 : : Ptr ->
12616 : : +----------------+
12617 : : | NoOfParam |
12618 : : |----------------|
12619 : : | Param 1 |
12620 : : |----------------|
12621 : : | Param 2 |
12622 : : |----------------|
12623 : : . .
12624 : : . .
12625 : : . .
12626 : : |----------------|
12627 : : | Param # |
12628 : : |----------------|
12629 : : | ProcSym | Type | Empty
12630 : : |----------------|
12631 : : */
12632 : :
12633 : 492 : static void BuildCmplxFunction (unsigned int func, bool ConstExpr)
12634 : : {
12635 : 492 : bool failure;
12636 : 492 : unsigned int functok;
12637 : 492 : unsigned int rtok;
12638 : 492 : unsigned int ltok;
12639 : 492 : unsigned int combinedtok;
12640 : 492 : unsigned int NoOfParam;
12641 : 492 : unsigned int type;
12642 : 492 : unsigned int ReturnVar;
12643 : 492 : unsigned int l;
12644 : 492 : unsigned int r;
12645 : :
12646 : 492 : M2Quads_PopT (&NoOfParam);
12647 : 492 : functok = OperandTtok (NoOfParam+1);
12648 : 492 : if (NoOfParam == 2)
12649 : : {
12650 : 492 : l = static_cast<unsigned int> (M2Quads_OperandT (2));
12651 : 492 : ltok = OperandTtok (2);
12652 : 492 : r = static_cast<unsigned int> (M2Quads_OperandT (1));
12653 : 492 : rtok = OperandTtok (1);
12654 : 492 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, rtok);
12655 : 492 : M2Quads_PopN (NoOfParam+1); /* Destroy arguments to this function. */
12656 : 492 : type = M2Base_GetCmplxReturnType (SymbolTable_GetDType (l), SymbolTable_GetDType (r)); /* Destroy arguments to this function. */
12657 : 570 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant ((SymbolTable_IsConst (l)) && (SymbolTable_IsConst (r))));
12658 : 492 : SymbolTable_PutVar (ReturnVar, type);
12659 : 492 : failure = false;
12660 : 492 : if (ConstExprError (func, l, ltok, ConstExpr))
12661 : : {
12662 : : /* ConstExprError has generated an error message we will fall through
12663 : : and check the right operand. */
12664 : : failure = true;
12665 : : }
12666 : 492 : if (ConstExprError (func, r, rtok, ConstExpr))
12667 : : {
12668 : : /* Right operand is in error as a variable. */
12669 : : failure = true;
12670 : : }
12671 : 486 : if (failure)
12672 : : {
12673 : : /* Generate a fake result if either operand was a variable (and we
12674 : : are in a const expression). */
12675 : 6 : M2Quads_PushTFtok (ReturnVar, type, combinedtok);
12676 : : }
12677 : 486 : else if (((SymbolTable_IsVar (l)) || (SymbolTable_IsConst (l))) && ((SymbolTable_IsVar (r)) || (SymbolTable_IsConst (r))))
12678 : : {
12679 : : /* avoid dangling else. */
12680 : 486 : M2Base_CheckExpressionCompatible (combinedtok, SymbolTable_GetSType (l), SymbolTable_GetSType (r));
12681 : 486 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Cmplx, SymbolTable_Make2Tuple (l, r), true);
12682 : 486 : M2Quads_PushTFtok (ReturnVar, type, combinedtok);
12683 : : }
12684 : : else
12685 : : {
12686 : : /* avoid dangling else. */
12687 : 0 : if ((SymbolTable_IsVar (l)) || (SymbolTable_IsConst (l)))
12688 : : {
12689 : 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);
12690 : : }
12691 : : else
12692 : : {
12693 : 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);
12694 : : }
12695 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_CType), M2Base_CType, combinedtok);
12696 : : }
12697 : : }
12698 : : else
12699 : : {
12700 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure {%1Ead} requires two parameters, seen {%2n}", 65, func, NoOfParam);
12701 : 0 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12702 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_CType), M2Base_CType, functok); /* destroy arguments to this function */
12703 : : }
12704 : 492 : }
12705 : :
12706 : :
12707 : : /*
12708 : : BuildAdrFunction - builds the pseudo function ADR
12709 : : The Stack:
12710 : :
12711 : :
12712 : : Entry Exit
12713 : :
12714 : : Ptr ->
12715 : : +----------------+
12716 : : | NoOfParam |
12717 : : |----------------|
12718 : : | Param 1 |
12719 : : |----------------|
12720 : : | Param 2 |
12721 : : |----------------|
12722 : : . .
12723 : : . .
12724 : : . .
12725 : : |----------------|
12726 : : | Param # | <- Ptr
12727 : : |----------------| +------------+
12728 : : | ProcSym | Type | | ReturnVar |
12729 : : |----------------| |------------|
12730 : :
12731 : : */
12732 : :
12733 : 152650 : static void BuildAdrFunction (void)
12734 : : {
12735 : 152650 : unsigned int endtok;
12736 : 152650 : unsigned int combinedTok;
12737 : 152650 : unsigned int procTok;
12738 : 152650 : unsigned int t;
12739 : 152650 : unsigned int UnboundedSym;
12740 : 152650 : unsigned int Dim;
12741 : 152650 : unsigned int Field;
12742 : 152650 : unsigned int noOfParameters;
12743 : 152650 : unsigned int procSym;
12744 : 152650 : unsigned int returnVar;
12745 : 152650 : unsigned int Type;
12746 : 152650 : unsigned int rw;
12747 : :
12748 : 152650 : M2Quads_DisplayStack ();
12749 : 152650 : M2Quads_PopT (&noOfParameters);
12750 : 152650 : procSym = static_cast<unsigned int> (M2Quads_OperandT (noOfParameters+1));
12751 : 152650 : procTok = static_cast<unsigned int> (M2Quads_OperandTok (noOfParameters+1)); /* token of procedure ADR. */
12752 : 152650 : endtok = static_cast<unsigned int> (M2Quads_OperandTok (1)); /* last parameter. */
12753 : 152650 : combinedTok = M2LexBuf_MakeVirtualTok (procTok, procTok, endtok); /* last parameter. */
12754 : 152650 : if (noOfParameters != 1)
12755 : : {
12756 : 0 : M2MetaError_MetaErrorNT0 (combinedTok, (const char *) "SYSTEM procedure ADR expects 1 parameter", 40);
12757 : 0 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
12758 : 0 : M2Quads_PushTF (M2Base_Nil, M2System_Address); /* destroy the arguments and function */
12759 : : }
12760 : 152650 : else if (SymbolTable_IsConstString (M2Quads_OperandT (1)))
12761 : : {
12762 : : /* avoid dangling else. */
12763 : 145250 : returnVar = MakeLeftValue (combinedTok, M2Quads_OperandT (1), SymbolTable_RightValue, SymbolTable_GetSType (procSym));
12764 : 145250 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
12765 : 145250 : M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (returnVar), combinedTok); /* destroy the arguments and function */
12766 : : }
12767 : 7400 : else if ((! (SymbolTable_IsVar (M2Quads_OperandT (1)))) && (! (SymbolTable_IsProcedure (M2Quads_OperandT (1)))))
12768 : : {
12769 : : /* avoid dangling else. */
12770 : 0 : M2MetaError_MetaErrorNT0 (combinedTok, (const char *) "SYSTEM procedure ADR expects a variable, procedure or a constant string as its parameter", 88);
12771 : 0 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
12772 : 0 : M2Quads_PushTFtok (M2Base_Nil, M2System_Address, combinedTok); /* destroy the arguments and function */
12773 : : }
12774 : 7400 : else if (SymbolTable_IsProcedure (M2Quads_OperandT (1)))
12775 : : {
12776 : : /* avoid dangling else. */
12777 : 24 : returnVar = MakeLeftValue (combinedTok, M2Quads_OperandT (1), SymbolTable_RightValue, SymbolTable_GetSType (procSym));
12778 : 24 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
12779 : 24 : M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (returnVar), combinedTok); /* destroy the arguments and function */
12780 : : }
12781 : : else
12782 : : {
12783 : : /* avoid dangling else. */
12784 : 7376 : Type = SymbolTable_GetSType (M2Quads_OperandT (1));
12785 : 7376 : Dim = static_cast<unsigned int> (OperandD (1));
12786 : 7376 : MarkArrayWritten (M2Quads_OperandT (1));
12787 : 7376 : MarkArrayWritten (M2Quads_OperandA (1));
12788 : : /* if the operand is an unbounded which has not been indexed
12789 : : then we will lookup its address from the unbounded record.
12790 : : Otherwise we obtain the address of the operand.
12791 : : */
12792 : 7376 : if ((SymbolTable_IsUnbounded (Type)) && (Dim == 0))
12793 : : {
12794 : : /* we will reference the address field of the unbounded structure */
12795 : 2349 : UnboundedSym = static_cast<unsigned int> (M2Quads_OperandT (1));
12796 : 2349 : rw = static_cast<unsigned int> (OperandRW (1));
12797 : 2349 : PushTFrw (UnboundedSym, SymbolTable_GetSType (UnboundedSym), rw);
12798 : 2349 : Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
12799 : 2349 : M2Quads_PushTF (Field, SymbolTable_GetSType (Field));
12800 : 2349 : M2Quads_PushT (static_cast<unsigned int> (1));
12801 : 2349 : M2Quads_BuildDesignatorRecord (combinedTok);
12802 : 2349 : PopTrw (&returnVar, &rw);
12803 : 2349 : if ((SymbolTable_GetMode (returnVar)) == SymbolTable_LeftValue)
12804 : : {
12805 : 0 : t = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
12806 : 0 : SymbolTable_PutVar (t, SymbolTable_GetSType (procSym));
12807 : 0 : doIndrX (combinedTok, t, returnVar);
12808 : 0 : returnVar = t;
12809 : : }
12810 : : else
12811 : : {
12812 : : /* we need to cast returnVar into ADDRESS */
12813 : 2349 : t = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
12814 : 2349 : SymbolTable_PutVar (t, SymbolTable_GetSType (procSym));
12815 : 2349 : GenQuadO (combinedTok, M2Quads_ConvertOp, t, SymbolTable_GetSType (procSym), returnVar, false);
12816 : 2349 : returnVar = t;
12817 : : }
12818 : : }
12819 : : else
12820 : : {
12821 : 5027 : returnVar = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
12822 : 5027 : SymbolTable_PutVar (returnVar, SymbolTable_GetSType (procSym));
12823 : 5027 : if ((SymbolTable_GetMode (M2Quads_OperandT (1))) == SymbolTable_LeftValue)
12824 : : {
12825 : 519 : SymbolTable_PutVar (returnVar, SymbolTable_GetSType (procSym));
12826 : 519 : GenQuadO (combinedTok, M2Quads_ConvertOp, returnVar, SymbolTable_GetSType (procSym), M2Quads_OperandT (1), false);
12827 : : }
12828 : : else
12829 : : {
12830 : 4508 : GenQuadO (combinedTok, M2Quads_AddrOp, returnVar, SymbolTable_NulSym, M2Quads_OperandT (1), false);
12831 : : }
12832 : 5027 : SymbolTable_PutWriteQuad (M2Quads_OperandT (1), SymbolTable_GetMode (M2Quads_OperandT (1)), NextQuad-1);
12833 : 5027 : rw = static_cast<unsigned int> (OperandMergeRW (1));
12834 : 5027 : M2Debug_Assert (SymbolTable_IsLegal (rw));
12835 : : }
12836 : 7376 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
12837 : 7376 : PushTFrwtok (returnVar, SymbolTable_GetSType (returnVar), rw, combinedTok); /* destroy the arguments and function */
12838 : : }
12839 : 152650 : }
12840 : :
12841 : :
12842 : : /*
12843 : : BuildSizeFunction - builds the pseudo function SIZE
12844 : : The Stack:
12845 : :
12846 : :
12847 : : Entry Exit
12848 : :
12849 : : Ptr ->
12850 : : +----------------+
12851 : : | NoOfParam |
12852 : : |----------------|
12853 : : | Param 1 |
12854 : : |----------------|
12855 : : | Param 2 |
12856 : : |----------------|
12857 : : . .
12858 : : . .
12859 : : . .
12860 : : |----------------|
12861 : : | Param # | <- Ptr
12862 : : |----------------| +------------+
12863 : : | ProcSym | Type | | ReturnVar |
12864 : : |----------------| |------------|
12865 : : */
12866 : :
12867 : 2110 : static void BuildSizeFunction (void)
12868 : : {
12869 : 2110 : unsigned int resulttok;
12870 : 2110 : unsigned int paramtok;
12871 : 2110 : unsigned int functok;
12872 : 2110 : unsigned int dim;
12873 : 2110 : unsigned int Type;
12874 : 2110 : unsigned int NoOfParam;
12875 : 2110 : unsigned int ProcSym;
12876 : 2110 : unsigned int ReturnVar;
12877 : :
12878 : 2110 : M2Quads_PopT (&NoOfParam);
12879 : 2110 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12880 : 2110 : functok = OperandTtok (NoOfParam+1);
12881 : 2110 : if (NoOfParam != 1)
12882 : : {
12883 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "{%E} SYSTEM procedure function {%kSIZE} requires one parameter, seen {%1n}", 74, NoOfParam);
12884 : 0 : resulttok = functok;
12885 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
12886 : : }
12887 : 2110 : else if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
12888 : : {
12889 : : /* avoid dangling else. */
12890 : 1088 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12891 : 1088 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
12892 : 1088 : BuildSizeCheckEnd (ProcSym); /* Quadruple generation now on. */
12893 : 1088 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue); /* Quadruple generation now on. */
12894 : 1088 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, M2Quads_OperandT (1), true);
12895 : : }
12896 : 1022 : else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
12897 : : {
12898 : : /* avoid dangling else. */
12899 : 1022 : BuildSizeCheckEnd (ProcSym); /* Quadruple generation now on. */
12900 : 1022 : Type = SymbolTable_GetSType (M2Quads_OperandT (1)); /* Quadruple generation now on. */
12901 : 1022 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12902 : 1022 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
12903 : 1022 : if (SymbolTable_IsUnbounded (Type))
12904 : : {
12905 : : /* Eg. SIZE(a) ; where a is unbounded dereference HIGH and multiply by the TYPE. */
12906 : 168 : dim = static_cast<unsigned int> (OperandD (1));
12907 : 168 : if (dim == 0)
12908 : : {
12909 : 72 : ReturnVar = calculateMultipicand (resulttok, M2Quads_OperandT (1), Type, dim);
12910 : : }
12911 : : else
12912 : : {
12913 : 96 : ReturnVar = calculateMultipicand (resulttok, M2Quads_OperandA (1), Type, dim);
12914 : : }
12915 : : }
12916 : : else
12917 : : {
12918 : 854 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
12919 : 854 : if (Type == SymbolTable_NulSym)
12920 : : {
12921 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "cannot get the type and size of {%1Ead}", 39, M2Quads_OperandT (1));
12922 : : }
12923 : 854 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, Type, true);
12924 : : }
12925 : : }
12926 : : else
12927 : : {
12928 : : /* avoid dangling else. */
12929 : 0 : resulttok = functok;
12930 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure {%kSIZE} expects a variable as its parameter, seen {%1Ed}", 78, M2Quads_OperandT (1));
12931 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
12932 : : }
12933 : 2110 : M2Quads_PopN (NoOfParam+1); /* Destroy the arguments and function. */
12934 : 2110 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok); /* Destroy the arguments and function. */
12935 : 2110 : }
12936 : :
12937 : :
12938 : : /*
12939 : : BuildTSizeFunction - builds the pseudo function TSIZE
12940 : : The Stack:
12941 : :
12942 : :
12943 : : Entry Exit
12944 : :
12945 : : Ptr ->
12946 : : +----------------+
12947 : : | NoOfParam |
12948 : : |----------------|
12949 : : | Param 1 |
12950 : : |----------------|
12951 : : | Param 2 |
12952 : : |----------------|
12953 : : . .
12954 : : . .
12955 : : . .
12956 : : |----------------|
12957 : : | Param # | <- Ptr
12958 : : |----------------| +------------+
12959 : : | ProcSym | Type | | ReturnVar |
12960 : : |----------------| |------------|
12961 : :
12962 : : */
12963 : :
12964 : 3412 : static void BuildTSizeFunction (void)
12965 : : {
12966 : 3412 : unsigned int resulttok;
12967 : 3412 : unsigned int paramtok;
12968 : 3412 : unsigned int functok;
12969 : 3412 : unsigned int NoOfParam;
12970 : 3412 : unsigned int ProcSym;
12971 : 3412 : unsigned int Record;
12972 : 3412 : unsigned int ReturnVar;
12973 : :
12974 : 3412 : M2Quads_PopT (&NoOfParam);
12975 : 3412 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12976 : 3412 : functok = OperandTtok (NoOfParam);
12977 : 3412 : BuildSizeCheckEnd (ProcSym); /* quadruple generation now on */
12978 : 3412 : if (NoOfParam == 1) /* quadruple generation now on */
12979 : : {
12980 : 3412 : paramtok = OperandTtok (1);
12981 : 3412 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
12982 : 3412 : if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
12983 : : {
12984 : 3384 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
12985 : 3384 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
12986 : 3384 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, M2Quads_OperandT (1), false);
12987 : : }
12988 : 28 : else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
12989 : : {
12990 : : /* avoid dangling else. */
12991 : 28 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
12992 : 28 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
12993 : 28 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, SymbolTable_GetSType (M2Quads_OperandT (1)), false);
12994 : : }
12995 : : else
12996 : : {
12997 : : /* avoid dangling else. */
12998 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTSIZE} expects a variable as its first parameter, seen {%1Ed}", 94, M2Quads_OperandT (1));
12999 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13000 : : }
13001 : : }
13002 : 0 : else if (NoOfParam == 0)
13003 : : {
13004 : : /* avoid dangling else. */
13005 : 0 : resulttok = functok;
13006 : 0 : M2MetaError_MetaErrorT0 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTSIZE} expects either one or two parameters, seen none", 87);
13007 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13008 : : }
13009 : : else
13010 : : {
13011 : : /* avoid dangling else. */
13012 : 0 : Record = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
13013 : 0 : paramtok = OperandTtok (1);
13014 : 0 : resulttok = OperandTtok (NoOfParam);
13015 : 0 : if (SymbolTable_IsRecord (Record))
13016 : : {
13017 : 0 : paramtok = OperandTtok (1);
13018 : 0 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13019 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13020 : 0 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
13021 : 0 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, Record, false);
13022 : : }
13023 : : else
13024 : : {
13025 : 0 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13026 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTSIZE} expects the first parameter to be a record type, seen {%1d}", 99, Record);
13027 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13028 : : }
13029 : : }
13030 : 3412 : M2Quads_PopN (NoOfParam+1); /* destroy the arguments and function */
13031 : 3412 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok); /* destroy the arguments and function */
13032 : 3412 : }
13033 : :
13034 : :
13035 : : /*
13036 : : BuildTBitSizeFunction - builds the pseudo function TBITSIZE
13037 : : The Stack:
13038 : :
13039 : :
13040 : : Entry Exit
13041 : :
13042 : : Ptr ->
13043 : : +----------------+
13044 : : | NoOfParam |
13045 : : |----------------|
13046 : : | Param 1 |
13047 : : |----------------|
13048 : : | Param 2 |
13049 : : |----------------|
13050 : : . .
13051 : : . .
13052 : : . .
13053 : : |----------------|
13054 : : | Param # | <- Ptr
13055 : : |----------------| +------------+
13056 : : | ProcSym | Type | | ReturnVar |
13057 : : |----------------| |------------|
13058 : :
13059 : : */
13060 : :
13061 : 12 : static void BuildTBitSizeFunction (void)
13062 : : {
13063 : 12 : unsigned int resulttok;
13064 : 12 : unsigned int paramtok;
13065 : 12 : unsigned int functok;
13066 : 12 : unsigned int NoOfParam;
13067 : 12 : unsigned int ProcSym;
13068 : 12 : unsigned int Record;
13069 : 12 : unsigned int ReturnVar;
13070 : :
13071 : 12 : M2Quads_PopT (&NoOfParam);
13072 : 12 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
13073 : 12 : functok = OperandTtok (NoOfParam);
13074 : 12 : BuildSizeCheckEnd (ProcSym); /* quadruple generation now on */
13075 : 12 : if (NoOfParam == 1) /* quadruple generation now on */
13076 : : {
13077 : 12 : paramtok = OperandTtok (1);
13078 : 12 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13079 : 12 : if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
13080 : : {
13081 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13082 : 0 : GenQuadO (resulttok, M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1), false);
13083 : : }
13084 : 12 : else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
13085 : : {
13086 : : /* avoid dangling else. */
13087 : 12 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13088 : 12 : GenQuadO (resulttok, M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1), false);
13089 : : }
13090 : : else
13091 : : {
13092 : : /* avoid dangling else. */
13093 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTBITSIZE} expects a variable as its first parameter, seen {%1d}", 96, M2Quads_OperandT (1));
13094 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13095 : : }
13096 : : }
13097 : 0 : else if (NoOfParam == 0)
13098 : : {
13099 : : /* avoid dangling else. */
13100 : 0 : resulttok = functok;
13101 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure function {%kTBITSIZE} expects either one or two parameters, seen none", 90);
13102 : 0 : ReturnVar = SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13103 : : }
13104 : : else
13105 : : {
13106 : : /* avoid dangling else. */
13107 : 0 : Record = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
13108 : 0 : paramtok = OperandTtok (1);
13109 : 0 : resulttok = OperandTtok (NoOfParam);
13110 : 0 : if (SymbolTable_IsRecord (Record))
13111 : : {
13112 : 0 : paramtok = OperandTtok (1);
13113 : 0 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13114 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13115 : 0 : GenQuad (M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1));
13116 : : }
13117 : : else
13118 : : {
13119 : 0 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13120 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTBITSIZE} expects the first parameter to be a record type, seen {%1d}", 102, Record);
13121 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13122 : : }
13123 : : }
13124 : 12 : M2Quads_PopN (NoOfParam+1); /* destroy the arguments and function */
13125 : 12 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok); /* destroy the arguments and function */
13126 : 12 : }
13127 : :
13128 : :
13129 : : /*
13130 : : ExpectingParameterType -
13131 : : */
13132 : :
13133 : 70344 : static void ExpectingParameterType (unsigned int BlockSym, unsigned int Type)
13134 : : {
13135 : 70344 : if (! (SymbolTable_IsAModula2Type (Type)))
13136 : : {
13137 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13138 : 0 : if (((Type == SymbolTable_NulSym) || (SymbolTable_IsPartialUnbounded (Type))) || (SymbolTable_IsUnknown (Type)))
13139 : : {
13140 : 0 : M2MetaError_MetaError1 ((const char *) "the type used in the formal parameter declaration in {%1Md} {%1a} is unknown", 76, BlockSym);
13141 : : }
13142 : : else
13143 : : {
13144 : 0 : 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);
13145 : : }
13146 : : }
13147 : 70344 : }
13148 : :
13149 : :
13150 : : /*
13151 : : ExpectingVariableType -
13152 : : */
13153 : :
13154 : 69197 : static void ExpectingVariableType (unsigned int BlockSym, unsigned int Type)
13155 : : {
13156 : 69197 : if (! (SymbolTable_IsAModula2Type (Type)))
13157 : : {
13158 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13159 : 12 : if (Type == SymbolTable_NulSym)
13160 : : {
13161 : 0 : M2MetaError_MetaError1 ((const char *) "the type used during the variable declaration section in procedure {%1EMad} is unknown", 86, BlockSym);
13162 : 0 : M2MetaError_MetaError1 ((const char *) "the type used during the variable declaration section in procedure {%1Ead} is unknown", 85, BlockSym);
13163 : : }
13164 : 12 : else if ((SymbolTable_IsPartialUnbounded (Type)) || (SymbolTable_IsUnknown (Type)))
13165 : : {
13166 : : /* avoid dangling else. */
13167 : 0 : M2MetaError_MetaError2 ((const char *) "the type {%1EMad} used during variable declaration section in procedure {%2ad} is unknown", 89, Type, BlockSym);
13168 : 0 : M2MetaError_MetaError2 ((const char *) "the type {%1Ead} used during variable declaration section in procedure {%2Mad} is unknown", 89, Type, BlockSym);
13169 : : }
13170 : : else
13171 : : {
13172 : : /* avoid dangling else. */
13173 : 12 : 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);
13174 : : }
13175 : : }
13176 : 69197 : }
13177 : :
13178 : :
13179 : : /*
13180 : : CheckVariablesAndParameterTypesInBlock - checks to make sure that block, BlockSym, has
13181 : : parameters types and variable types which are legal.
13182 : : */
13183 : :
13184 : 136541 : static void CheckVariablesAndParameterTypesInBlock (unsigned int BlockSym)
13185 : : {
13186 : 136541 : unsigned int i;
13187 : 136541 : unsigned int n;
13188 : 136541 : unsigned int ParamNo;
13189 : :
13190 : 136541 : if (SymbolTable_IsProcedure (BlockSym))
13191 : : {
13192 : 63527 : ParamNo = SymbolTable_NoOfParam (BlockSym);
13193 : : }
13194 : : else
13195 : : {
13196 : : ParamNo = 0;
13197 : : }
13198 : 136541 : i = 1;
13199 : 1027382 : do {
13200 : 1027382 : n = SymbolTable_GetNth (BlockSym, i);
13201 : 1027382 : if (((n != SymbolTable_NulSym) && (! (SymbolTable_IsTemporary (n)))) && ((SymbolTable_IsProcedure (BlockSym)) || (((SymbolTable_IsDefImp (BlockSym)) && ((SymbolTable_GetMainModule ()) == BlockSym)) || (SymbolTable_IsModule (BlockSym)))))
13202 : : {
13203 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13204 : 139541 : if (i <= ParamNo)
13205 : : {
13206 : : /* n is a parameter */
13207 : 70344 : ExpectingParameterType (BlockSym, SymbolTable_GetSType (n));
13208 : : }
13209 : : else
13210 : : {
13211 : : /* n is a local variable */
13212 : 69197 : ExpectingVariableType (BlockSym, SymbolTable_GetSType (n));
13213 : : }
13214 : : }
13215 : 1027382 : i += 1;
13216 : 1027382 : } while (! (n == SymbolTable_NulSym));
13217 : 136541 : }
13218 : :
13219 : :
13220 : : /*
13221 : : IsNeverAltered - returns TRUE if variable, sym, is never altered
13222 : : between quadruples: Start..End
13223 : : */
13224 : :
13225 : 0 : static bool IsNeverAltered (unsigned int sym, unsigned int Start, unsigned int End)
13226 : : {
13227 : 0 : unsigned int WriteStart;
13228 : 0 : unsigned int WriteEnd;
13229 : :
13230 : 0 : SymbolTable_GetWriteLimitQuads (sym, SymbolTable_GetMode (sym), Start, End, &WriteStart, &WriteEnd);
13231 : 0 : return (WriteStart == 0) && (WriteEnd == 0);
13232 : : /* static analysis guarentees a RETURN statement will be used before here. */
13233 : : __builtin_unreachable ();
13234 : : }
13235 : :
13236 : :
13237 : : /*
13238 : : IsConditionVariable - returns TRUE if the condition at quadruple, q, is variable.
13239 : : */
13240 : :
13241 : 0 : static bool IsConditionVariable (unsigned int q, unsigned int Start, unsigned int End)
13242 : : {
13243 : 0 : M2Quads_QuadOperator op;
13244 : 0 : unsigned int op1;
13245 : 0 : unsigned int op2;
13246 : 0 : unsigned int op3;
13247 : 0 : bool LeftFixed;
13248 : 0 : bool RightFixed;
13249 : :
13250 : 0 : M2Quads_GetQuad (q, &op, &op1, &op2, &op3);
13251 : 0 : if (op == M2Quads_GotoOp)
13252 : : {
13253 : : return false;
13254 : : }
13255 : : else
13256 : : {
13257 : 0 : LeftFixed = SymbolTable_IsConst (op1);
13258 : 0 : RightFixed = SymbolTable_IsConst (op2);
13259 : 0 : if (! LeftFixed)
13260 : : {
13261 : 0 : LeftFixed = IsNeverAltered (op1, Start, End);
13262 : : }
13263 : 0 : if (! RightFixed)
13264 : : {
13265 : 0 : RightFixed = IsNeverAltered (op2, Start, End);
13266 : : }
13267 : 0 : return ! (LeftFixed && RightFixed);
13268 : : }
13269 : : /* static analysis guarentees a RETURN statement will be used before here. */
13270 : : __builtin_unreachable ();
13271 : : }
13272 : :
13273 : :
13274 : : /*
13275 : : IsInfiniteLoop - returns TRUE if an infinite loop is found.
13276 : : Given a backwards jump at, End, it returns a BOOLEAN which depends on
13277 : : whether a jump is found to jump beyond, End. If a conditonal jump is found
13278 : : to pass over, End, the condition is tested for global variables, procedure variables and
13279 : : constants.
13280 : :
13281 : : constant - ignored
13282 : : variables - tested to see whether they are altered inside the loop
13283 : : global variable - the procedure tests to see whether it is altered as above
13284 : : but will also test to see whether this loop calls a procedure
13285 : : in which case it believes the loop NOT to be infinite
13286 : : (as this procedure call might alter the global variable)
13287 : :
13288 : : Note that this procedure can easily be fooled by the user altering variables
13289 : : with pointers.
13290 : : */
13291 : :
13292 : 0 : static bool IsInfiniteLoop (unsigned int End)
13293 : : {
13294 : 0 : bool SeenCall;
13295 : 0 : bool IsGlobal;
13296 : 0 : unsigned int Current;
13297 : 0 : unsigned int Start;
13298 : 0 : M2Quads_QuadOperator op;
13299 : 0 : unsigned int op1;
13300 : 0 : unsigned int op2;
13301 : 0 : unsigned int op3;
13302 : :
13303 : 0 : SeenCall = false;
13304 : 0 : IsGlobal = false;
13305 : 0 : M2Quads_GetQuad (End, &op, &op1, &op2, &Start);
13306 : 0 : Current = Start;
13307 : 0 : while (Current != End)
13308 : : {
13309 : 0 : M2Quads_GetQuad (Current, &op, &op1, &op2, &op3);
13310 : : /* remember that this function is only called once we have optimized the redundant gotos and conditionals */
13311 : 0 : if ((M2Quads_IsConditional (Current)) && ! IsGlobal)
13312 : : {
13313 : 0 : IsGlobal = ((SymbolTable_IsVar (op1)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op1))))) || ((SymbolTable_IsVar (op2)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op2)))));
13314 : : }
13315 : 0 : if (op == M2Quads_CallOp)
13316 : : {
13317 : 0 : SeenCall = true;
13318 : : }
13319 : 0 : if ((op == M2Quads_GotoOp) || ((M2Quads_IsConditional (Current)) && (IsConditionVariable (Current, Start, End))))
13320 : : {
13321 : 0 : if ((op3 > End) || (op3 < Start))
13322 : : {
13323 : : return false; /* may jump out of this loop, good */
13324 : : }
13325 : : }
13326 : 0 : Current = M2Quads_GetNextQuad (Current);
13327 : : }
13328 : 0 : M2Quads_GetQuad (End, &op, &op1, &op2, &op3);
13329 : 0 : if (M2Quads_IsConditional (End))
13330 : : {
13331 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13332 : 0 : if (IsConditionVariable (End, Start, End))
13333 : : {
13334 : : return false;
13335 : : }
13336 : : else
13337 : : {
13338 : 0 : if (! IsGlobal)
13339 : : {
13340 : 0 : IsGlobal = ((SymbolTable_IsVar (op1)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op1))))) || ((SymbolTable_IsVar (op2)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op2)))));
13341 : : }
13342 : : }
13343 : : }
13344 : : /* we have found a likely infinite loop if no conditional uses a global and no procedure call was seen */
13345 : 0 : return ! (IsGlobal && SeenCall);
13346 : : /* static analysis guarentees a RETURN statement will be used before here. */
13347 : : __builtin_unreachable ();
13348 : : }
13349 : :
13350 : :
13351 : : /*
13352 : : CheckVariablesInBlock - given a block, BlockSym, check whether all variables are used.
13353 : : */
13354 : :
13355 : 136541 : static void CheckVariablesInBlock (unsigned int BlockSym)
13356 : : {
13357 : 0 : CheckVariablesAndParameterTypesInBlock (BlockSym);
13358 : 0 : }
13359 : :
13360 : :
13361 : : /*
13362 : : CheckFunctionReturn - checks to see that a RETURN statement was present in a function.
13363 : : */
13364 : :
13365 : 63527 : static void CheckFunctionReturn (unsigned int ProcSym)
13366 : : {
13367 : 63527 : M2Quads_QuadOperator Op;
13368 : 63527 : unsigned int Op1;
13369 : 63527 : unsigned int Op2;
13370 : 63527 : unsigned int Op3;
13371 : 63527 : unsigned int Scope;
13372 : 63527 : unsigned int Start;
13373 : 63527 : unsigned int End;
13374 : :
13375 : 63527 : if ((SymbolTable_GetSType (ProcSym)) != SymbolTable_NulSym)
13376 : : {
13377 : : /* yes it is a function */
13378 : 11528 : SymbolTable_GetProcedureQuads (ProcSym, &Scope, &Start, &End);
13379 : 11528 : M2Quads_GetQuad (Start, &Op, &Op1, &Op2, &Op3);
13380 : 11528 : if (Start == 0)
13381 : : {
13382 : 0 : M2Error_InternalError ((const char *) "incorrect start quad", 20);
13383 : : }
13384 : 426417 : while (((Start != End) && (Op != M2Quads_ReturnValueOp)) && (Op != M2Quads_InlineOp))
13385 : : {
13386 : 414889 : Start = M2Quads_GetNextQuad (Start);
13387 : 414889 : M2Quads_GetQuad (Start, &Op, &Op1, &Op2, &Op3);
13388 : : }
13389 : 11528 : if ((Op != M2Quads_ReturnValueOp) && (Op != M2Quads_InlineOp))
13390 : : {
13391 : : /* an InlineOp can always be used to emulate a RETURN */
13392 : 0 : M2MetaError_MetaError1 ((const char *) "procedure function {%1Ea} does not RETURN a value", 49, ProcSym);
13393 : : }
13394 : : }
13395 : 63527 : }
13396 : :
13397 : :
13398 : : /*
13399 : : CheckReturnType - checks to see that the return type from currentProc is
13400 : : assignment compatible with actualType.
13401 : : */
13402 : :
13403 : 17903 : static void CheckReturnType (unsigned int tokno, unsigned int currentProc, unsigned int actualVal, unsigned int actualType)
13404 : : {
13405 : 17903 : unsigned int procType;
13406 : 17903 : DynamicStrings_String s1;
13407 : 17903 : DynamicStrings_String s2;
13408 : 17903 : NameKey_Name n1;
13409 : 17903 : NameKey_Name n2;
13410 : :
13411 : 17903 : procType = SymbolTable_GetSType (currentProc);
13412 : 17903 : if (procType == SymbolTable_NulSym)
13413 : : {
13414 : 0 : M2MetaError_MetaError1 ((const char *) "attempting to RETURN a value from procedure {%1Ea} which was not a declared as a procedure function", 99, currentProc);
13415 : : }
13416 : 17903 : else if (M2Base_AssignmentRequiresWarning (actualType, SymbolTable_GetSType (currentProc)))
13417 : : {
13418 : : /* avoid dangling else. */
13419 : 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);
13420 : : }
13421 : 17903 : else if (! (M2Base_IsAssignmentCompatible (actualType, procType)))
13422 : : {
13423 : : /* avoid dangling else. */
13424 : 0 : n1 = SymbolTable_GetSymName (actualType);
13425 : 0 : n2 = SymbolTable_GetSymName (procType);
13426 : 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));
13427 : : }
13428 : 17903 : else if ((SymbolTable_IsProcedure (actualVal)) && (! (M2Base_IsAssignmentCompatible (actualVal, procType))))
13429 : : {
13430 : : /* avoid dangling else. */
13431 : : /*
13432 : : MetaWarnings2('attempting to RETURN a value with an incompatible type {%1ad} from function {%2a} which returns {%2ta}',
13433 : : actualVal, currentProc)
13434 : :
13435 : : --fixme-- introduce MetaWarning, MetaWarning2, MetaWarning3 into M2MetaError
13436 : : */
13437 : 0 : s1 = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (actualVal)));
13438 : 0 : s2 = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (procType)));
13439 : 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)));
13440 : : }
13441 : 17903 : else if ((SymbolTable_IsProcedure (actualVal)) && (! (M2Base_IsAssignmentCompatible (actualVal, SymbolTable_GetSType (CurrentProc)))))
13442 : : {
13443 : : /* avoid dangling else. */
13444 : 0 : n1 = SymbolTable_GetSymName (actualVal);
13445 : 0 : n2 = SymbolTable_GetSymName (SymbolTable_GetSType (currentProc));
13446 : 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));
13447 : : }
13448 : : else
13449 : : {
13450 : : /* avoid dangling else. */
13451 : : /* this checks the types are compatible, not the data contents. */
13452 : 17903 : BuildRange (M2Range_InitTypesAssignmentCheck (tokno, currentProc, actualVal));
13453 : : }
13454 : 17903 : }
13455 : :
13456 : :
13457 : : /*
13458 : : IsReadOnly - a helper procedure function to detect constants.
13459 : : */
13460 : :
13461 : 214875 : static bool IsReadOnly (unsigned int sym)
13462 : : {
13463 : 214875 : return (SymbolTable_IsConst (sym)) || ((SymbolTable_IsVar (sym)) && (SymbolTable_IsVarConst (sym)));
13464 : : /* static analysis guarentees a RETURN statement will be used before here. */
13465 : : __builtin_unreachable ();
13466 : : }
13467 : :
13468 : :
13469 : : /*
13470 : : BuildDesignatorError - removes the designator from the stack and replaces
13471 : : it with an error symbol.
13472 : : */
13473 : :
13474 : 18 : static void BuildDesignatorError (const char *message_, unsigned int _message_high)
13475 : : {
13476 : 18 : unsigned int combinedTok;
13477 : 18 : unsigned int arrayTok;
13478 : 18 : unsigned int exprTok;
13479 : 18 : unsigned int e;
13480 : 18 : unsigned int d;
13481 : 18 : unsigned int error;
13482 : 18 : unsigned int Sym;
13483 : 18 : unsigned int Type;
13484 : 18 : char message[_message_high+1];
13485 : :
13486 : : /* make a local copy of each unbounded array. */
13487 : 18 : memcpy (message, message_, _message_high+1);
13488 : :
13489 : 18 : M2Quads_PopTtok (&e, &exprTok);
13490 : 18 : PopTFDtok (&Sym, &Type, &d, &arrayTok);
13491 : 18 : combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, exprTok);
13492 : 18 : error = SymbolTable_MakeError (combinedTok, NameKey_MakeKey ((const char *) message, _message_high));
13493 : 18 : PushTFDtok (error, Type, d, arrayTok);
13494 : 18 : }
13495 : :
13496 : :
13497 : : /*
13498 : : BuildStaticArray - Builds the array referencing for static arrays.
13499 : : The Stack is expected to contain:
13500 : :
13501 : :
13502 : : Entry Exit
13503 : : ===== ====
13504 : :
13505 : : Ptr ->
13506 : : +--------------+
13507 : : | e | <- Ptr
13508 : : |--------------| +------------+
13509 : : | Sym | Type | | S | T |
13510 : : |--------------| |------------|
13511 : : */
13512 : :
13513 : 36924 : static void BuildStaticArray (void)
13514 : : {
13515 : 36924 : unsigned int combinedTok;
13516 : 36924 : unsigned int indexTok;
13517 : 36924 : unsigned int arrayTok;
13518 : 36924 : unsigned int rw;
13519 : 36924 : unsigned int Dim;
13520 : 36924 : unsigned int Array;
13521 : 36924 : unsigned int Index;
13522 : 36924 : unsigned int BackEndType;
13523 : 36924 : unsigned int Type;
13524 : 36924 : unsigned int Adr;
13525 : :
13526 : 36924 : Index = static_cast<unsigned int> (M2Quads_OperandT (1));
13527 : 36924 : indexTok = OperandTtok (1);
13528 : 36924 : Array = static_cast<unsigned int> (M2Quads_OperandT (2));
13529 : 36924 : arrayTok = OperandTtok (2);
13530 : 36924 : Type = SymbolTable_SkipType (M2Quads_OperandF (2));
13531 : 36924 : rw = static_cast<unsigned int> (OperandMergeRW (2));
13532 : 36924 : M2Debug_Assert (SymbolTable_IsLegal (rw));
13533 : 36924 : Dim = static_cast<unsigned int> (OperandD (2));
13534 : 36924 : Dim += 1;
13535 : 36924 : if ((SymbolTable_GetMode (Index)) == SymbolTable_LeftValue)
13536 : : {
13537 : 161 : Index = MakeRightValue (indexTok, Index, SymbolTable_GetSType (Index));
13538 : : }
13539 : 36924 : BuildRange (M2Range_InitStaticArraySubscriptRangeCheck (SymbolTable_GetArraySubscript (Type), Index, Dim));
13540 : : /* now make Adr point to the address of the indexed element */
13541 : 36924 : combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, indexTok);
13542 : 36924 : Adr = SymbolTable_MakeTemporary (combinedTok, SymbolTable_LeftValue);
13543 : 36924 : if (SymbolTable_IsVar (Array))
13544 : : {
13545 : : /* BuildDesignatorArray may have detected des is a constant. */
13546 : 36924 : SymbolTable_PutVarConst (Adr, SymbolTable_IsVarConst (Array));
13547 : : }
13548 : 36924 : SymbolTable_PutVarArrayRef (Adr, true);
13549 : : /*
13550 : : From now on it must reference the array element by its lvalue
13551 : : - so we create the type of the referenced entity
13552 : : */
13553 : 36924 : BackEndType = SymbolTable_MakePointer (combinedTok, NameKey_NulName);
13554 : 36924 : SymbolTable_PutPointer (BackEndType, SymbolTable_GetDType (Type));
13555 : : /* PutVar(Adr, BackEndType) ; */
13556 : 36924 : SymbolTable_PutLeftValueFrontBackType (Adr, SymbolTable_GetDType (Type), BackEndType);
13557 : 73848 : GenQuadO (combinedTok, M2Quads_ArrayOp, Adr, Index, Array, true);
13558 : 36924 : M2Quads_PopN (2); /* remove all parameters to this procedure */
13559 : 36924 : PushTFDrwtok (Adr, SymbolTable_GetSType (Adr), Dim, rw, combinedTok); /* remove all parameters to this procedure */
13560 : 36924 : }
13561 : :
13562 : :
13563 : : /*
13564 : : calculateMultipicand - generates quadruples which calculate the
13565 : : multiplicand for the array at dimension, dim.
13566 : : */
13567 : :
13568 : 9008 : static unsigned int calculateMultipicand (unsigned int tok, unsigned int arraySym, unsigned int arrayType, unsigned int dim)
13569 : : {
13570 : 9008 : unsigned int ti;
13571 : 9008 : unsigned int tj;
13572 : 9008 : unsigned int tk;
13573 : 9008 : unsigned int tl;
13574 : :
13575 : 9008 : if (dim == (SymbolTable_GetDimension (arrayType)))
13576 : : {
13577 : : /* ti has no type since constant */
13578 : 8036 : ti = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
13579 : 8036 : SymbolTable_PutVar (ti, M2Base_Cardinal);
13580 : 8036 : GenQuadO (tok, M2Quads_ElementSizeOp, ti, arrayType, 1, true);
13581 : : }
13582 : : else
13583 : : {
13584 : 972 : dim += 1;
13585 : 972 : tk = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
13586 : 972 : SymbolTable_PutVar (tk, M2Base_Cardinal);
13587 : 972 : GenHigh (tok, tk, dim, arraySym);
13588 : 972 : tl = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
13589 : 972 : SymbolTable_PutVar (tl, M2Base_Cardinal);
13590 : 972 : GenQuadOtok (tok, M2Quads_AddOp, tl, tk, SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal), true, tok, tok, tok);
13591 : 972 : tj = calculateMultipicand (tok, arraySym, arrayType, dim);
13592 : 972 : ti = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
13593 : 972 : SymbolTable_PutVar (ti, M2Base_Cardinal);
13594 : 972 : GenQuadO (tok, M2Quads_MultOp, ti, tj, tl, true);
13595 : : }
13596 : 9008 : return ti;
13597 : : /* static analysis guarentees a RETURN statement will be used before here. */
13598 : : __builtin_unreachable ();
13599 : : }
13600 : :
13601 : :
13602 : : /*
13603 : : ConvertToAddress - convert sym to an address.
13604 : : */
13605 : :
13606 : 7658 : static unsigned int ConvertToAddress (unsigned int tokpos, unsigned int sym)
13607 : : {
13608 : 7658 : unsigned int adr;
13609 : :
13610 : 7658 : if ((SymbolTable_GetSType (sym)) == M2System_Address)
13611 : : {
13612 : : return sym;
13613 : : }
13614 : : else
13615 : : {
13616 : 7646 : M2Quads_PushTF (SymbolTable_RequestSym (tokpos, NameKey_MakeKey ((const char *) "CONVERT", 7)), static_cast<unsigned int> (SymbolTable_NulSym));
13617 : 7646 : M2Quads_PushT (M2System_Address);
13618 : 7646 : M2Quads_PushTtok (sym, tokpos);
13619 : 7646 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
13620 : 7646 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
13621 : 7646 : M2Quads_PopT (&adr);
13622 : 7646 : return adr;
13623 : : }
13624 : : /* static analysis guarentees a RETURN statement will be used before here. */
13625 : : __builtin_unreachable ();
13626 : : }
13627 : :
13628 : :
13629 : : /*
13630 : : BuildDynamicArray - Builds the array referencing for dynamic arrays.
13631 : : The Stack is expected to contain:
13632 : :
13633 : :
13634 : : Entry Exit
13635 : : ===== ====
13636 : :
13637 : : Ptr ->
13638 : : +-----------------------+
13639 : : | Index | <- Ptr
13640 : : |-----------------------| +---------------------------+
13641 : : | ArraySym | Type | Dim | | S | T | ArraySym | Dim+1 |
13642 : : |-----------------------| |---------------------------|
13643 : :
13644 : :
13645 : : if Dim=1
13646 : : then
13647 : : S := base of ArraySym + TSIZE(Type)*Index
13648 : : else
13649 : : S := S + TSIZE(Type)*Index
13650 : : fi
13651 : : */
13652 : :
13653 : 7574 : static void BuildDynamicArray (void)
13654 : : {
13655 : 7574 : unsigned int combinedTok;
13656 : 7574 : unsigned int arrayTok;
13657 : 7574 : unsigned int indexTok;
13658 : 7574 : unsigned int Sym;
13659 : 7574 : unsigned int idx;
13660 : 7574 : unsigned int Type;
13661 : 7574 : unsigned int Adr;
13662 : 7574 : unsigned int ArraySym;
13663 : 7574 : unsigned int BackEndType;
13664 : 7574 : unsigned int UnboundedType;
13665 : 7574 : unsigned int PtrToBase;
13666 : 7574 : unsigned int Base;
13667 : 7574 : unsigned int Dim;
13668 : 7574 : unsigned int rw;
13669 : 7574 : unsigned int ti;
13670 : 7574 : unsigned int tj;
13671 : 7574 : unsigned int tk;
13672 : 7574 : unsigned int tka;
13673 : :
13674 : 7574 : M2Quads_DisplayStack ();
13675 : 7574 : Sym = static_cast<unsigned int> (M2Quads_OperandT (2));
13676 : 7574 : Type = SymbolTable_SkipType (M2Quads_OperandF (2));
13677 : 7574 : arrayTok = static_cast<unsigned int> (M2Quads_OperandTok (2));
13678 : 7574 : indexTok = static_cast<unsigned int> (M2Quads_OperandTok (1));
13679 : 7574 : combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, indexTok);
13680 : 7574 : Dim = static_cast<unsigned int> (OperandD (2));
13681 : 7574 : rw = static_cast<unsigned int> (OperandMergeRW (2));
13682 : 7574 : M2Debug_Assert (SymbolTable_IsLegal (rw));
13683 : 7574 : Dim += 1;
13684 : 7574 : if (Dim == 1)
13685 : : {
13686 : : /*
13687 : : Base has type address since
13688 : : BuildDesignatorRecord references by address.
13689 : :
13690 : : Build a record for retrieving the address of dynamic array.
13691 : : BuildDesignatorRecord will generate the required quadruples,
13692 : : therefore build sets up the stack for BuildDesignatorRecord
13693 : : which will generate the quads to access the record.
13694 : : */
13695 : 7436 : ArraySym = Sym;
13696 : 7436 : UnboundedType = SymbolTable_GetUnboundedRecordType (SymbolTable_GetSType (Sym));
13697 : 7436 : PushTFrwtok (Sym, UnboundedType, rw, arrayTok);
13698 : 7436 : M2Quads_PushTF (SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (Sym)), SymbolTable_GetSType (SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (Sym))));
13699 : 7436 : M2Quads_PushT (static_cast<unsigned int> (1)); /* One record field to dereference */
13700 : 7436 : M2Quads_BuildDesignatorRecord (combinedTok); /* One record field to dereference */
13701 : 7436 : M2Quads_PopT (&PtrToBase);
13702 : 7436 : M2Quads_DisplayStack ();
13703 : : /* Now actually copy Unbounded.ArrayAddress into base */
13704 : 7436 : if ((SymbolTable_GetMode (PtrToBase)) == SymbolTable_LeftValue)
13705 : : {
13706 : 0 : Base = SymbolTable_MakeTemporary (arrayTok, SymbolTable_RightValue);
13707 : 0 : SymbolTable_PutVar (Base, M2System_Address); /* has type ADDRESS */
13708 : 0 : CheckPointerThroughNil (arrayTok, PtrToBase); /* has type ADDRESS */
13709 : 0 : GenQuad (M2Quads_IndrXOp, Base, M2System_Address, PtrToBase); /* Base = *PtrToBase */
13710 : : }
13711 : : else
13712 : : {
13713 : 7436 : M2Debug_Assert ((SymbolTable_GetMode (PtrToBase)) != SymbolTable_ImmediateValue);
13714 : 7436 : Base = PtrToBase;
13715 : : }
13716 : : }
13717 : : else
13718 : : {
13719 : : /* Base already calculated previously and pushed to stack */
13720 : 138 : UnboundedType = SymbolTable_SkipType (M2Quads_OperandF (2));
13721 : 138 : Base = Sym;
13722 : 138 : ArraySym = static_cast<unsigned int> (M2Quads_OperandA (2));
13723 : : }
13724 : 7574 : M2Debug_Assert ((SymbolTable_GetSType (Sym)) == Type);
13725 : 7574 : ti = calculateMultipicand (indexTok, Sym, Type, Dim);
13726 : 7574 : idx = static_cast<unsigned int> (M2Quads_OperandT (1));
13727 : 7574 : if (SymbolTable_IsConst (idx))
13728 : : {
13729 : : /* tj has no type since constant */
13730 : 646 : tj = SymbolTable_MakeTemporary (indexTok, SymbolTable_ImmediateValue);
13731 : 646 : tk = SymbolTable_MakeTemporary (indexTok, SymbolTable_ImmediateValue);
13732 : 646 : SymbolTable_PutVar (tj, M2Base_Cardinal);
13733 : 646 : SymbolTable_PutVar (tk, M2Base_Cardinal);
13734 : : }
13735 : : else
13736 : : {
13737 : : /* tj has Cardinal type since we have multiplied array indices */
13738 : 6928 : tj = SymbolTable_MakeTemporary (indexTok, SymbolTable_RightValue);
13739 : 6928 : if ((SymbolTable_GetSType (idx)) != M2Base_Cardinal)
13740 : : {
13741 : 486 : M2Quads_PushTF (SymbolTable_RequestSym (indexTok, NameKey_MakeKey ((const char *) "CONVERT", 7)), static_cast<unsigned int> (SymbolTable_NulSym));
13742 : 486 : M2Quads_PushT (M2Base_Cardinal);
13743 : 486 : M2Quads_PushTtok (idx, indexTok);
13744 : 486 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
13745 : 486 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
13746 : 486 : M2Quads_PopT (&idx);
13747 : : }
13748 : 6928 : SymbolTable_PutVar (tj, M2Base_Cardinal);
13749 : 6928 : tk = SymbolTable_MakeTemporary (indexTok, SymbolTable_RightValue);
13750 : 6928 : SymbolTable_PutVar (tk, M2Base_Cardinal);
13751 : : }
13752 : 7574 : BuildRange (M2Range_InitDynamicArraySubscriptRangeCheck (ArraySym, idx, Dim));
13753 : 7574 : M2Quads_PushTtok (tj, indexTok);
13754 : 7574 : M2Quads_PushTtok (idx, indexTok);
13755 : 7574 : BuildAssignmentWithoutBounds (indexTok, false, true);
13756 : 15148 : GenQuad (M2Quads_MultOp, tk, ti, tj);
13757 : 15148 : Adr = SymbolTable_MakeTemporary (combinedTok, SymbolTable_LeftValue);
13758 : 7574 : SymbolTable_PutVarArrayRef (Adr, true);
13759 : : /*
13760 : : Ok must reference by address
13761 : : - but we contain the type of the referenced entity
13762 : : */
13763 : 7574 : BackEndType = SymbolTable_MakePointer (combinedTok, NameKey_NulName);
13764 : 7574 : SymbolTable_PutPointer (BackEndType, SymbolTable_GetSType (Type));
13765 : : /* Create a temporary pointer for addition. */
13766 : 7574 : tka = ConvertToAddress (combinedTok, tk);
13767 : 7574 : if (Dim == (SymbolTable_GetDimension (Type)))
13768 : : {
13769 : 7256 : SymbolTable_PutLeftValueFrontBackType (Adr, SymbolTable_GetSType (Type), BackEndType);
13770 : 14512 : GenQuadOtok (combinedTok, M2Quads_AddOp, Adr, Base, tka, false, combinedTok, combinedTok, combinedTok);
13771 : 7256 : M2Quads_PopN (2);
13772 : 7256 : PushTFADrwtok (Adr, SymbolTable_GetSType (Adr), ArraySym, Dim, rw, combinedTok);
13773 : : }
13774 : : else
13775 : : {
13776 : : /* more to index */
13777 : 318 : SymbolTable_PutLeftValueFrontBackType (Adr, Type, BackEndType);
13778 : 636 : GenQuadOtok (combinedTok, M2Quads_AddOp, Adr, Base, tka, false, combinedTok, combinedTok, combinedTok);
13779 : 318 : M2Quads_PopN (2);
13780 : 318 : PushTFADrwtok (Adr, SymbolTable_GetSType (Adr), ArraySym, Dim, rw, combinedTok);
13781 : : }
13782 : 7574 : }
13783 : :
13784 : :
13785 : : /*
13786 : : DebugLocation -
13787 : : */
13788 : :
13789 : 41013 : static void DebugLocation (unsigned int tok, const char *message_, unsigned int _message_high)
13790 : : {
13791 : 41013 : char message[_message_high+1];
13792 : :
13793 : : /* make a local copy of each unbounded array. */
13794 : 41013 : memcpy (message, message_, _message_high+1);
13795 : :
13796 : 41013 : if (DebugTokPos)
13797 : : {
13798 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) message, _message_high), tok);
13799 : : }
13800 : 41013 : }
13801 : :
13802 : :
13803 : : /*
13804 : : PushWith - pushes sym and type onto the with stack. It checks for
13805 : : previous declaration of this record type.
13806 : : */
13807 : :
13808 : 4871 : static void PushWith (unsigned int Sym, unsigned int Type, unsigned int Ref, unsigned int Tok)
13809 : : {
13810 : 4871 : unsigned int i;
13811 : 4871 : unsigned int n;
13812 : 4871 : M2Quads_WithFrame f;
13813 : :
13814 : 4871 : if (M2Options_Pedantic)
13815 : : {
13816 : 0 : n = M2StackAddress_NoOfItemsInStackAddress (WithStack);
13817 : 0 : i = 1; /* Top of the stack. */
13818 : : /* Search for other declarations of the with using Type. */
13819 : 0 : while (i <= n)
13820 : : {
13821 : 0 : f = static_cast<M2Quads_WithFrame> (M2StackAddress_PeepAddress (WithStack, i));
13822 : 0 : if (f->RecordSym == Type)
13823 : : {
13824 : 0 : M2MetaError_MetaErrorT1 (Tok, (const char *) "cannot have nested {%kWITH} statements referencing the same {%kRECORD} {%1Ead}", 78, Sym);
13825 : 0 : M2MetaError_MetaErrorT1 (f->RecordTokPos, (const char *) "cannot have nested {%kWITH} statements referencing the same {%kRECORD} {%1Ead}", 78, f->RecordSym);
13826 : : }
13827 : 0 : i += 1;
13828 : : }
13829 : : }
13830 : 4871 : Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T4));
13831 : 4871 : f->RecordSym = Sym;
13832 : 4871 : f->RecordType = Type;
13833 : 4871 : f->RecordRef = Ref;
13834 : 4871 : f->rw = Sym;
13835 : 4871 : f->RecordTokPos = Tok;
13836 : 4871 : M2StackAddress_PushAddress (WithStack, reinterpret_cast<void *> (f));
13837 : 4871 : }
13838 : :
13839 : 4871 : static void PopWith (void)
13840 : : {
13841 : 4871 : M2Quads_WithFrame f;
13842 : :
13843 : 4871 : f = static_cast<M2Quads_WithFrame> (M2StackAddress_PopAddress (WithStack));
13844 : 4871 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T4));
13845 : 4871 : }
13846 : :
13847 : :
13848 : : /*
13849 : : BuildAccessWithField - similar to BuildDesignatorRecord except it
13850 : : does not perform the address operation.
13851 : : The address will have been computed at the
13852 : : beginning of the WITH statement.
13853 : : It also stops the GenQuad procedure from examining the
13854 : : with stack.
13855 : :
13856 : : The Stack
13857 : :
13858 : : Entry
13859 : :
13860 : : Ptr ->
13861 : : +--------------+
13862 : : | Field | Type1| <- Ptr
13863 : : |-------|------| +-------------+
13864 : : | Adr | Type2| | Sym | Type1|
13865 : : |--------------| |-------------|
13866 : : */
13867 : :
13868 : 25436 : static void BuildAccessWithField (void)
13869 : : {
13870 : 25436 : unsigned int rectok;
13871 : 25436 : unsigned int fieldtok;
13872 : 25436 : bool OldSuppressWith;
13873 : 25436 : unsigned int rw;
13874 : 25436 : unsigned int Field;
13875 : 25436 : unsigned int FieldType;
13876 : 25436 : unsigned int Record;
13877 : 25436 : unsigned int RecordType;
13878 : 25436 : unsigned int Ref;
13879 : :
13880 : 25436 : OldSuppressWith = SuppressWith;
13881 : 25436 : SuppressWith = true;
13882 : : /*
13883 : : now the WITH cannot look at the stack of outstanding WITH records.
13884 : : */
13885 : 25436 : M2Quads_PopTFtok (&Field, &FieldType, &fieldtok);
13886 : 25436 : PopTFrwtok (&Record, &RecordType, &rw, &rectok);
13887 : 25436 : Ref = SymbolTable_MakeComponentRef (SymbolTable_MakeComponentRecord (fieldtok, SymbolTable_RightValue, Record), Field);
13888 : 25436 : SymbolTable_PutVarConst (Ref, IsReadOnly (Record));
13889 : 50872 : GenQuadO (fieldtok, M2Quads_RecordFieldOp, Ref, Record, Field, true);
13890 : 25436 : PushTFrwtok (Ref, FieldType, rw, fieldtok);
13891 : 25436 : SuppressWith = OldSuppressWith;
13892 : 25436 : }
13893 : :
13894 : :
13895 : : /*
13896 : : PushConstructor -
13897 : : */
13898 : :
13899 : 29270 : static void PushConstructor (unsigned int sym)
13900 : : {
13901 : 29270 : M2Quads_ConstructorFrame c;
13902 : :
13903 : 29270 : Storage_ALLOCATE ((void **) &c, sizeof (M2Quads__T1));
13904 : 29270 : c->type = SymbolTable_SkipType (sym);
13905 : 29270 : c->index = 1;
13906 : 29270 : M2StackAddress_PushAddress (ConstructorStack, reinterpret_cast<void *> (c));
13907 : 29270 : }
13908 : :
13909 : :
13910 : : /*
13911 : : AddFieldTo - adds field, e, to, value.
13912 : : */
13913 : :
13914 : 23462 : static unsigned int AddFieldTo (unsigned int value, unsigned int e)
13915 : : {
13916 : 23462 : if (SymbolTable_IsSet (SymbolTable_GetDType (value)))
13917 : : {
13918 : 9858 : SymbolTable_PutConstSet (value);
13919 : 9858 : M2Quads_PushT (value);
13920 : 9858 : M2Quads_PushT (e);
13921 : 9858 : M2Quads_BuildInclBit ();
13922 : 9858 : M2Quads_PopT (&value);
13923 : : }
13924 : : else
13925 : : {
13926 : 13604 : SymbolTable_PushValue (value);
13927 : 13604 : M2ALU_AddField (M2LexBuf_GetTokenNo (), e);
13928 : 13604 : SymbolTable_PopValue (value);
13929 : : }
13930 : 23462 : return value;
13931 : : /* static analysis guarentees a RETURN statement will be used before here. */
13932 : : __builtin_unreachable ();
13933 : : }
13934 : :
13935 : :
13936 : : /*
13937 : : CheckLogicalOperator - returns a logical operator if the operands imply
13938 : : a logical operation should be performed.
13939 : : */
13940 : :
13941 : 58883 : static NameKey_Name CheckLogicalOperator (NameKey_Name Tok, unsigned int left, unsigned int lefttype)
13942 : : {
13943 : 58883 : if ((((Tok == M2Reserved_PlusTok) || (Tok == M2Reserved_TimesTok)) || (Tok == M2Reserved_DivideTok)) || (Tok == M2Reserved_MinusTok))
13944 : : {
13945 : : /* --fixme-- when we add complex arithmetic, we must check constructor is not a complex constant. */
13946 : 49487 : if ((((lefttype != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_SkipType (lefttype)))) || (SymbolTable_IsConstSet (left))) || (SymbolTable_IsConstructor (left)))
13947 : : {
13948 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13949 : 1090 : if (Tok == M2Reserved_PlusTok)
13950 : : {
13951 : 952 : return LogicalOrTok;
13952 : : }
13953 : 138 : else if (Tok == M2Reserved_DivideTok)
13954 : : {
13955 : : /* avoid dangling else. */
13956 : 12 : return LogicalXorTok;
13957 : : }
13958 : 126 : else if (Tok == M2Reserved_TimesTok)
13959 : : {
13960 : : /* avoid dangling else. */
13961 : 60 : return LogicalAndTok;
13962 : : }
13963 : 66 : else if (Tok == M2Reserved_MinusTok)
13964 : : {
13965 : : /* avoid dangling else. */
13966 : 66 : return LogicalDifferenceTok;
13967 : : }
13968 : : }
13969 : : }
13970 : : return Tok;
13971 : : /* static analysis guarentees a RETURN statement will be used before here. */
13972 : : __builtin_unreachable ();
13973 : : }
13974 : :
13975 : :
13976 : : /*
13977 : : CheckDivModRem - initiates calls to check the divisor for DIV, MOD, REM
13978 : : expressions.
13979 : : */
13980 : :
13981 : 58523 : static void CheckDivModRem (unsigned int TokPos, NameKey_Name tok, unsigned int d, unsigned int e)
13982 : : {
13983 : 58523 : if (tok == M2Reserved_DivTok)
13984 : : {
13985 : 5426 : BuildRange (M2Range_InitWholeZeroDivisionCheck (TokPos, d, e));
13986 : : }
13987 : 53097 : else if (tok == M2Reserved_ModTok)
13988 : : {
13989 : : /* avoid dangling else. */
13990 : 2022 : BuildRange (M2Range_InitWholeZeroDivisionCheck (TokPos, d, e));
13991 : : }
13992 : 51075 : else if (tok == M2Reserved_RemTok)
13993 : : {
13994 : : /* avoid dangling else. */
13995 : 96 : BuildRange (M2Range_InitWholeZeroRemainderCheck (TokPos, d, e));
13996 : : }
13997 : 58523 : }
13998 : :
13999 : :
14000 : : /*
14001 : : doConvert - convert, sym, to a new symbol with, type.
14002 : : Return the new symbol.
14003 : : */
14004 : :
14005 : 3704 : static unsigned int doConvert (unsigned int type, unsigned int sym)
14006 : : {
14007 : 3704 : if ((SymbolTable_GetSType (sym)) != type)
14008 : : {
14009 : 524 : M2Quads_PushTF (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym));
14010 : 524 : M2Quads_PushT (type);
14011 : 524 : M2Quads_PushT (sym);
14012 : 524 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
14013 : 524 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
14014 : 524 : M2Quads_PopT (&sym);
14015 : : }
14016 : 3704 : return sym;
14017 : : /* static analysis guarentees a RETURN statement will be used before here. */
14018 : : __builtin_unreachable ();
14019 : : }
14020 : :
14021 : :
14022 : : /*
14023 : : doBuildBinaryOp - build the binary op, with or without type
14024 : : checking.
14025 : : */
14026 : :
14027 : 68981 : static void doBuildBinaryOp (bool checkTypes, bool checkOverflow)
14028 : : {
14029 : 68981 : DynamicStrings_String s;
14030 : 68981 : NameKey_Name NewOp;
14031 : 68981 : NameKey_Name Operator;
14032 : 68981 : unsigned int OperatorPos;
14033 : 68981 : unsigned int OldPos;
14034 : 68981 : unsigned int leftrw;
14035 : 68981 : unsigned int rightrw;
14036 : 68981 : unsigned int t1;
14037 : 68981 : unsigned int f1;
14038 : 68981 : unsigned int t2;
14039 : 68981 : unsigned int f2;
14040 : 68981 : unsigned int lefttype;
14041 : 68981 : unsigned int righttype;
14042 : 68981 : unsigned int left;
14043 : 68981 : unsigned int right;
14044 : 68981 : unsigned int leftpos;
14045 : 68981 : unsigned int rightpos;
14046 : 68981 : unsigned int value;
14047 : :
14048 : 68981 : Operator = static_cast<NameKey_Name> (M2Quads_OperandT (2));
14049 : 68981 : if (Operator == M2Reserved_OrTok)
14050 : : {
14051 : 2924 : CheckBooleanId ();
14052 : 2924 : PopBooltok (&t1, &f1, &rightpos);
14053 : 2924 : M2Quads_PopTtok (&Operator, &OperatorPos);
14054 : 2924 : PopBooltok (&t2, &f2, &leftpos);
14055 : 2924 : M2Debug_Assert (f2 == 0);
14056 : 2924 : OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
14057 : 2924 : PushBooltok (Merge (t1, t2), f1, OperatorPos);
14058 : : }
14059 : 66057 : else if ((Operator == M2Reserved_AndTok) || (Operator == M2Reserved_AmbersandTok))
14060 : : {
14061 : : /* avoid dangling else. */
14062 : 7174 : CheckBooleanId ();
14063 : 7174 : PopBooltok (&t1, &f1, &rightpos);
14064 : 7174 : M2Quads_PopTtok (&Operator, &OperatorPos);
14065 : 7174 : PopBooltok (&t2, &f2, &leftpos);
14066 : 7174 : M2Debug_Assert (t2 == 0);
14067 : 7174 : OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
14068 : 7174 : PushBooltok (t1, Merge (f1, f2), OperatorPos);
14069 : : }
14070 : : else
14071 : : {
14072 : : /* avoid dangling else. */
14073 : 58883 : PopTFrwtok (&right, &righttype, &rightrw, &rightpos);
14074 : 58883 : M2Quads_PopTtok (&Operator, &OperatorPos);
14075 : 58883 : PopTFrwtok (&left, &lefttype, &leftrw, &leftpos);
14076 : 58883 : MarkAsRead (rightrw);
14077 : 58883 : MarkAsRead (leftrw);
14078 : 58883 : NewOp = CheckLogicalOperator (Operator, left, lefttype); /* right, righttype, */
14079 : 58883 : if (NewOp == Operator)
14080 : : {
14081 : : /* avoid dangling else. */
14082 : : /*
14083 : : BinaryOps and UnaryOps only work with immediate and
14084 : : offset addressing. This is fine for calculating
14085 : : array and record offsets but we need to get the real
14086 : : values to perform normal arithmetic. Not address
14087 : : arithmetic.
14088 : :
14089 : : However the set operators will dereference LValues
14090 : : (to optimize large set arithemetic)
14091 : : */
14092 : 57793 : if ((SymbolTable_GetMode (right)) == SymbolTable_LeftValue)
14093 : : {
14094 : 286 : value = SymbolTable_MakeTemporary (rightpos, SymbolTable_RightValue);
14095 : 286 : SymbolTable_PutVar (value, righttype);
14096 : 286 : CheckPointerThroughNil (rightpos, right);
14097 : 286 : doIndrX (rightpos, value, right);
14098 : 286 : right = value;
14099 : : }
14100 : 57793 : if ((SymbolTable_GetMode (left)) == SymbolTable_LeftValue)
14101 : : {
14102 : 612 : value = SymbolTable_MakeTemporary (leftpos, SymbolTable_RightValue);
14103 : 612 : SymbolTable_PutVar (value, lefttype);
14104 : 612 : CheckPointerThroughNil (leftpos, left);
14105 : 612 : doIndrX (leftpos, value, left);
14106 : 612 : left = value;
14107 : : }
14108 : : }
14109 : : /* CheckForGenericNulSet(e1, e2, t1, t2) */
14110 : 58883 : OldPos = OperatorPos;
14111 : 58883 : OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
14112 : 58883 : if (((Operator == M2Reserved_PlusTok) && (SymbolTable_IsConstString (left))) && (SymbolTable_IsConstString (right)))
14113 : : {
14114 : 288 : value = SymbolTable_MakeConstString (OperatorPos, NameKey_NulName);
14115 : 288 : SymbolTable_PutConstStringKnown (OperatorPos, value, NameKey_NulName, false, false);
14116 : 288 : GenQuadOtok (OperatorPos, MakeOp (M2Reserved_PlusTok), value, left, right, false, OperatorPos, leftpos, rightpos);
14117 : : }
14118 : : else
14119 : : {
14120 : 58595 : if (checkTypes)
14121 : : {
14122 : 38692 : BuildRange (M2Range_InitTypesExpressionCheck (OperatorPos, left, right, false, false));
14123 : : }
14124 : 92652 : value = SymbolTable_MakeTemporaryFromExpressions (OperatorPos, right, left, AreConstant ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right))));
14125 : 58523 : CheckDivModRem (OperatorPos, NewOp, value, right);
14126 : 58523 : if (DebugTokPos)
14127 : : {
14128 : : s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (M2LexBuf_GetTokenName (Operator)));
14129 : : M2Error_WarnStringAt (s, OldPos);
14130 : : s = DynamicStrings_InitString ((const char *) "left", 4);
14131 : : M2Error_WarnStringAt (s, leftpos);
14132 : : s = DynamicStrings_InitString ((const char *) "right", 5);
14133 : : M2Error_WarnStringAt (s, rightpos);
14134 : : s = DynamicStrings_InitString ((const char *) "caret", 5);
14135 : : M2Error_WarnStringAt (s, OldPos);
14136 : : s = DynamicStrings_InitString ((const char *) "combined", 8);
14137 : : M2Error_WarnStringAt (s, OperatorPos);
14138 : : }
14139 : : /* MetaErrorT1 (GetDeclaredMod (t), 'in binary with a {%1a}', t) */
14140 : 58523 : GenQuadOtok (OperatorPos, MakeOp (NewOp), value, left, right, checkOverflow, OperatorPos, leftpos, rightpos);
14141 : : }
14142 : 58811 : M2Quads_PushTFtok (value, SymbolTable_GetSType (value), OperatorPos);
14143 : : }
14144 : 68909 : }
14145 : :
14146 : :
14147 : : /*
14148 : : AreConstant - returns immediate addressing mode if b is true else
14149 : : offset mode is returned. b determines whether the
14150 : : operands are all constant - in which case we can use
14151 : : a constant temporary variable.
14152 : : */
14153 : :
14154 : 111052 : static SymbolTable_ModeOfAddr AreConstant (bool b)
14155 : : {
14156 : 111052 : if (b)
14157 : : {
14158 : : return SymbolTable_ImmediateValue;
14159 : : }
14160 : : else
14161 : : {
14162 : 88332 : return SymbolTable_RightValue;
14163 : : }
14164 : : /* static analysis guarentees a RETURN statement will be used before here. */
14165 : : __builtin_unreachable ();
14166 : : }
14167 : :
14168 : :
14169 : : /*
14170 : : ConvertBooleanToVariable - converts a BoolStack(i) from a Boolean True|False
14171 : : exit pair into a variable containing the value TRUE or
14172 : : FALSE. The parameter, i, is relative to the top
14173 : : of the stack.
14174 : : */
14175 : :
14176 : 6190 : static void ConvertBooleanToVariable (unsigned int tok, unsigned int i)
14177 : : {
14178 : 6190 : unsigned int Des;
14179 : 6190 : M2Quads_BoolFrame f;
14180 : :
14181 : 6190 : M2Debug_Assert (IsBoolean (i));
14182 : : /* We need to convert the boolean top of stack into a variable or
14183 : : constant boolean. */
14184 : 12380 : Des = SymbolTable_MakeTemporary (tok, AreConstant (M2Quads_IsInConstExpression ()));
14185 : 6190 : SymbolTable_PutVar (Des, M2Base_Boolean);
14186 : 6190 : M2Quads_PushTtok (Des, tok); /* we have just increased the stack so we must use i+1 */
14187 : 6190 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, i+1)); /* we have just increased the stack so we must use i+1 */
14188 : 12380 : PushBool (f->TrueExit, f->FalseExit);
14189 : 6190 : BuildAssignmentWithoutBounds (tok, false, true); /* restored stack */
14190 : 6190 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, i)); /* restored stack */
14191 : 6190 : f->TrueExit = Des; /* Alter Stack(i) to contain the variable. */
14192 : 6190 : f->FalseExit = M2Base_Boolean; /* Alter Stack(i) to contain the variable. */
14193 : 6190 : f->BooleanOp = false; /* No longer a Boolean True|False pair. */
14194 : 6190 : f->Unbounded = SymbolTable_NulSym; /* No longer a Boolean True|False pair. */
14195 : 6190 : f->Dimension = 0;
14196 : 6190 : f->ReadWrite = SymbolTable_NulSym;
14197 : 6190 : f->tokenno = tok;
14198 : 6190 : f->Annotation = DynamicStrings_KillString (f->Annotation);
14199 : 6190 : f->Annotation = DynamicStrings_InitString ((const char *) "%1s(%1d)|%2s(%2d)||boolean var|type", 35);
14200 : 6190 : }
14201 : :
14202 : :
14203 : : /*
14204 : : BuildRelOpFromBoolean - builds a relational operator sequence of quadruples
14205 : : instead of using a temporary boolean variable.
14206 : : This function can only be used when we perform
14207 : : the following translation:
14208 : :
14209 : : (a=b) # (c=d) alternatively (a=b) = (c=d)
14210 : : ^ ^
14211 : :
14212 : : it only allows # = to be used as >= <= > < all
14213 : : assume a particular value for TRUE and FALSE.
14214 : : (In which case the user should specify ORD)
14215 : :
14216 : :
14217 : : before
14218 : :
14219 : : q if r1 op1 op2 t2
14220 : : q+1 Goto f2
14221 : : q+2 if r2 op3 op4 t1
14222 : : q+3 Goto f1
14223 : :
14224 : : after (in case of =)
14225 : :
14226 : : q if r1 op1 op2 q+2
14227 : : q+1 Goto q+4
14228 : : q+2 if r2 op3 op4 t
14229 : : q+3 Goto f
14230 : : q+4 if r2 op3 op4 f
14231 : : q+5 Goto t
14232 : :
14233 : : after (in case of #)
14234 : :
14235 : : q if r1 op1 op2 q+2
14236 : : q+1 Goto q+4
14237 : : q+2 if r2 op3 op4 f
14238 : : q+3 Goto t
14239 : : q+4 if r2 op3 op4 t
14240 : : q+5 Goto f
14241 : :
14242 : : The Stack is expected to contain:
14243 : :
14244 : :
14245 : : Entry Exit
14246 : : ===== ====
14247 : :
14248 : : Ptr ->
14249 : : +------------+
14250 : : | t1 | f1 |
14251 : : |------------|
14252 : : | Operator | <- Ptr
14253 : : |------------| +------------+
14254 : : | t2 | f2 | | t | f |
14255 : : |------------| |------------|
14256 : :
14257 : :
14258 : : */
14259 : :
14260 : 0 : static void BuildRelOpFromBoolean (unsigned int tokpos)
14261 : : {
14262 : 0 : unsigned int Tok;
14263 : 0 : unsigned int t1;
14264 : 0 : unsigned int f1;
14265 : 0 : unsigned int t2;
14266 : 0 : unsigned int f2;
14267 : 0 : M2Quads_QuadFrame f;
14268 : :
14269 : 0 : M2Debug_Assert ((IsBoolean (1)) && (IsBoolean (3)));
14270 : 0 : if ((M2Quads_OperandT (2)) == M2Reserved_EqualTok)
14271 : : {
14272 : : /* are the two boolean expressions the same? */
14273 : 0 : PopBool (&t1, &f1);
14274 : 0 : M2Quads_PopT (&Tok);
14275 : 0 : PopBool (&t2, &f2);
14276 : : /* give the false exit a second chance */
14277 : 0 : BackPatch (t2, t1); /* q if _ _ q+2 */
14278 : 0 : BackPatch (f2, NextQuad); /* q+1 if _ _ q+4 */
14279 : 0 : M2Debug_Assert (NextQuad == (f1+1)); /* q+1 if _ _ q+4 */
14280 : 0 : f = GetQF (t1);
14281 : 0 : GenQuadO (tokpos, f->Operator, f->Operand1, f->Operand2, 0, false);
14282 : 0 : GenQuadO (tokpos, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
14283 : 0 : PushBooltok (Merge (NextQuad-1, t1), Merge (NextQuad-2, f1), tokpos);
14284 : : }
14285 : 0 : else if (((M2Quads_OperandT (2)) == M2Reserved_HashTok) || ((M2Quads_OperandT (2)) == M2Reserved_LessGreaterTok))
14286 : : {
14287 : : /* avoid dangling else. */
14288 : : /* are the two boolean expressions different? */
14289 : 0 : PopBool (&t1, &f1);
14290 : 0 : M2Quads_PopT (&Tok);
14291 : 0 : PopBool (&t2, &f2);
14292 : : /* give the false exit a second chance */
14293 : 0 : BackPatch (t2, t1); /* q if _ _ q+2 */
14294 : 0 : BackPatch (f2, NextQuad); /* q+1 if _ _ q+4 */
14295 : 0 : M2Debug_Assert (NextQuad == (f1+1)); /* q+1 if _ _ q+4 */
14296 : 0 : f = GetQF (t1);
14297 : 0 : GenQuadO (tokpos, f->Operator, f->Operand1, f->Operand2, 0, false);
14298 : 0 : GenQuadO (tokpos, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
14299 : 0 : PushBooltok (Merge (NextQuad-2, f1), Merge (NextQuad-1, t1), tokpos);
14300 : : }
14301 : : else
14302 : : {
14303 : : /* avoid dangling else. */
14304 : 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);
14305 : : }
14306 : 0 : }
14307 : :
14308 : :
14309 : : /*
14310 : : CheckVariableOrConstantOrProcedure - checks to make sure sym is a variable, constant or procedure.
14311 : : */
14312 : :
14313 : 135868 : static void CheckVariableOrConstantOrProcedure (unsigned int tokpos, unsigned int sym)
14314 : : {
14315 : 135868 : unsigned int type;
14316 : :
14317 : 135868 : type = SymbolTable_GetSType (sym);
14318 : 135868 : if (SymbolTable_IsUnknown (sym))
14319 : : {
14320 : 0 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1EUad} has not been declared", 30, sym);
14321 : 0 : SymbolTable_UnknownReported (sym);
14322 : : }
14323 : 135868 : else if ((M2System_IsPseudoSystemFunction (sym)) || (M2Base_IsPseudoBaseFunction (sym)))
14324 : : {
14325 : : /* avoid dangling else. */
14326 : 0 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1Ead} expected a variable, procedure, constant or expression, not an intrinsic procedure function", 99, sym);
14327 : : }
14328 : 135868 : else if (((((! (SymbolTable_IsConst (sym))) && (! (SymbolTable_IsVar (sym)))) && (! (SymbolTable_IsProcedure (sym)))) && (! (SymbolTable_IsTemporary (sym)))) && ! MustNotCheckBounds)
14329 : : {
14330 : : /* avoid dangling else. */
14331 : 0 : M2MetaError_MetaErrorsT1 (tokpos, (const char *) "{%1Ead} expected a variable, procedure, constant or expression", 62, (const char *) "and it was declared as a {%1Dd}", 31, sym);
14332 : : }
14333 : 135868 : else if ((type != SymbolTable_NulSym) && (SymbolTable_IsArray (type)))
14334 : : {
14335 : : /* avoid dangling else. */
14336 : 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 {%1Dd}", 27, sym);
14337 : : }
14338 : 135868 : else if (((SymbolTable_IsConstString (sym)) && (SymbolTable_IsConstStringKnown (sym))) && ((SymbolTable_GetStringLength (tokpos, sym)) > 1))
14339 : : {
14340 : : /* avoid dangling else. */
14341 : 0 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1EU} not expecting a string constant as an operand for either comparison or binary operation", 94, sym);
14342 : : }
14343 : 135868 : }
14344 : :
14345 : :
14346 : : /*
14347 : : MakeOp - returns the equalent quadruple operator to a token, t.
14348 : : */
14349 : :
14350 : 126745 : static M2Quads_QuadOperator MakeOp (NameKey_Name t)
14351 : : {
14352 : 126745 : if (t == ArithPlusTok)
14353 : : {
14354 : : return M2Quads_ArithAddOp;
14355 : : }
14356 : 124893 : else if (t == M2Reserved_PlusTok)
14357 : : {
14358 : : /* avoid dangling else. */
14359 : : return M2Quads_AddOp;
14360 : : }
14361 : 103717 : else if (t == M2Reserved_MinusTok)
14362 : : {
14363 : : /* avoid dangling else. */
14364 : : return M2Quads_SubOp;
14365 : : }
14366 : 90379 : else if (t == M2Reserved_DivTok)
14367 : : {
14368 : : /* avoid dangling else. */
14369 : : return M2Quads_DivM2Op;
14370 : : }
14371 : 84953 : else if (t == M2Reserved_DivideTok)
14372 : : {
14373 : : /* avoid dangling else. */
14374 : : return M2Quads_DivTruncOp;
14375 : : }
14376 : 81557 : else if (t == M2Reserved_RemTok)
14377 : : {
14378 : : /* avoid dangling else. */
14379 : : return M2Quads_ModTruncOp;
14380 : : }
14381 : 81461 : else if (t == M2Reserved_ModTok)
14382 : : {
14383 : : /* avoid dangling else. */
14384 : : return M2Quads_ModM2Op;
14385 : : }
14386 : 79439 : else if (t == M2Reserved_TimesTok)
14387 : : {
14388 : : /* avoid dangling else. */
14389 : : return M2Quads_MultOp;
14390 : : }
14391 : 69012 : else if (t == M2Reserved_HashTok)
14392 : : {
14393 : : /* avoid dangling else. */
14394 : : return M2Quads_IfNotEquOp;
14395 : : }
14396 : 59545 : else if (t == M2Reserved_LessGreaterTok)
14397 : : {
14398 : : /* avoid dangling else. */
14399 : : return M2Quads_IfNotEquOp;
14400 : : }
14401 : 59461 : else if (t == M2Reserved_GreaterEqualTok)
14402 : : {
14403 : : /* avoid dangling else. */
14404 : : return M2Quads_IfGreEquOp;
14405 : : }
14406 : 51745 : else if (t == M2Reserved_LessEqualTok)
14407 : : {
14408 : : /* avoid dangling else. */
14409 : : return M2Quads_IfLessEquOp;
14410 : : }
14411 : 47973 : else if (t == M2Reserved_EqualTok)
14412 : : {
14413 : : /* avoid dangling else. */
14414 : : return M2Quads_IfEquOp;
14415 : : }
14416 : 12549 : else if (t == M2Reserved_LessTok)
14417 : : {
14418 : : /* avoid dangling else. */
14419 : : return M2Quads_IfLessOp;
14420 : : }
14421 : 7180 : else if (t == M2Reserved_GreaterTok)
14422 : : {
14423 : : /* avoid dangling else. */
14424 : : return M2Quads_IfGreOp;
14425 : : }
14426 : 2484 : else if (t == M2Reserved_InTok)
14427 : : {
14428 : : /* avoid dangling else. */
14429 : : return M2Quads_IfInOp;
14430 : : }
14431 : 1078 : else if (t == LogicalOrTok)
14432 : : {
14433 : : /* avoid dangling else. */
14434 : : return M2Quads_LogicalOrOp;
14435 : : }
14436 : 138 : else if (t == LogicalAndTok)
14437 : : {
14438 : : /* avoid dangling else. */
14439 : : return M2Quads_LogicalAndOp;
14440 : : }
14441 : 78 : else if (t == LogicalXorTok)
14442 : : {
14443 : : /* avoid dangling else. */
14444 : : return M2Quads_LogicalXorOp;
14445 : : }
14446 : 66 : else if (t == LogicalDifferenceTok)
14447 : : {
14448 : : /* avoid dangling else. */
14449 : : return M2Quads_LogicalDiffOp;
14450 : : }
14451 : : else
14452 : : {
14453 : : /* avoid dangling else. */
14454 : 0 : M2Error_InternalError ((const char *) "binary operation not implemented yet", 36);
14455 : : }
14456 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
14457 : : __builtin_unreachable ();
14458 : : }
14459 : :
14460 : :
14461 : : /*
14462 : : GenQuadO - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
14463 : : */
14464 : :
14465 : 3705609 : static void GenQuadO (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow)
14466 : : {
14467 : 946027 : GenQuadOTrash (TokPos, Operation, Op1, Op2, Op3, overflow, SymbolTable_NulSym);
14468 : 566499 : }
14469 : :
14470 : :
14471 : : /*
14472 : : GenQuadOTrash - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
14473 : : */
14474 : :
14475 : 3706959 : static void GenQuadOTrash (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow, unsigned int trash)
14476 : : {
14477 : 3706959 : M2Quads_QuadFrame f;
14478 : :
14479 : : /* WriteString('Potential Quad: ') ; */
14480 : 3706959 : if (QuadrupleGeneration)
14481 : : {
14482 : 3705119 : if (NextQuad != Head)
14483 : : {
14484 : 3692323 : f = GetQF (NextQuad-1);
14485 : 3692323 : f->Next = NextQuad;
14486 : : }
14487 : 3705119 : PutQuadO (NextQuad, Operation, Op1, Op2, Op3, overflow);
14488 : 3705119 : f = GetQF (NextQuad);
14489 : 3705119 : f->Trash = trash;
14490 : 3705119 : f->Next = 0;
14491 : 3705119 : f->LineNo = M2LexBuf_GetLineNo ();
14492 : 3705119 : if (TokPos == M2LexBuf_UnknownTokenNo)
14493 : : {
14494 : 2094292 : f->TokenNo = M2LexBuf_GetTokenNo ();
14495 : : }
14496 : : else
14497 : : {
14498 : 1610827 : f->TokenNo = TokPos;
14499 : : }
14500 : 3705119 : if (M2Options_GetDebugTraceQuad ())
14501 : : {
14502 : 0 : M2Printf_printf0 ((const char *) "generating: ", 12);
14503 : 0 : M2Quads_DisplayQuad (NextQuad);
14504 : : }
14505 : : /* MetaErrorT1 (TokenNo, '{%1On}', NextQuad) */
14506 : 3705119 : if (NextQuad == BreakAtQuad)
14507 : : {
14508 : 3705119 : stop ();
14509 : : }
14510 : 3705119 : NewQuad (&NextQuad);
14511 : : }
14512 : 3706959 : }
14513 : :
14514 : :
14515 : : /*
14516 : : GenQuad - Generate a quadruple with Operation, Op1, Op2, Op3.
14517 : : */
14518 : :
14519 : 2034619 : static void GenQuad (M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3)
14520 : : {
14521 : 1289959 : GenQuadO (M2LexBuf_UnknownTokenNo, Operation, Op1, Op2, Op3, true);
14522 : 453470 : }
14523 : :
14524 : :
14525 : : /*
14526 : : GenQuadOtok - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
14527 : : */
14528 : :
14529 : 675004 : 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)
14530 : : {
14531 : 589167 : GenQuadOTypetok (TokPos, Operation, Op1, Op2, Op3, overflow, true, Op1Pos, Op2Pos, Op3Pos);
14532 : 436999 : }
14533 : :
14534 : :
14535 : : /*
14536 : : GenQuadOTypetok - assigns the fields of the quadruple with
14537 : : the parameters.
14538 : : */
14539 : :
14540 : 676856 : 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)
14541 : : {
14542 : 676856 : M2Quads_QuadFrame f;
14543 : :
14544 : : /* WriteString('Potential Quad: ') ; */
14545 : 676856 : if (QuadrupleGeneration)
14546 : : {
14547 : 676172 : if (NextQuad != Head)
14548 : : {
14549 : 676172 : f = GetQF (NextQuad-1);
14550 : 676172 : f->Next = NextQuad;
14551 : : }
14552 : 676172 : PutQuadOType (NextQuad, Operation, Op1, Op2, Op3, overflow, typecheck);
14553 : 676172 : f = GetQF (NextQuad);
14554 : 676172 : f->Next = 0;
14555 : 676172 : f->LineNo = M2LexBuf_GetLineNo ();
14556 : 676172 : if (TokPos == M2LexBuf_UnknownTokenNo)
14557 : : {
14558 : 24512 : f->TokenNo = M2LexBuf_GetTokenNo ();
14559 : : }
14560 : : else
14561 : : {
14562 : 651660 : f->TokenNo = TokPos;
14563 : : }
14564 : 676172 : f->op1pos = Op1Pos;
14565 : 676172 : f->op2pos = Op2Pos;
14566 : 676172 : f->op3pos = Op3Pos;
14567 : 676172 : if (M2Options_GetDebugTraceQuad ())
14568 : : {
14569 : 0 : M2Printf_printf0 ((const char *) "generating: ", 12);
14570 : 0 : M2Quads_DisplayQuad (NextQuad);
14571 : : }
14572 : : /* MetaErrorT1 (TokenNo, '{%1On}', NextQuad) */
14573 : 676172 : if (NextQuad == BreakAtQuad)
14574 : : {
14575 : 676172 : stop ();
14576 : : }
14577 : 676172 : NewQuad (&NextQuad);
14578 : : }
14579 : 676856 : }
14580 : :
14581 : :
14582 : : /*
14583 : : DumpUntil - dump all quadruples until we seen the ending quadruple
14584 : : with procsym in the third operand.
14585 : : Return the quad number containing the match.
14586 : : */
14587 : :
14588 : 0 : static unsigned int DumpUntil (M2Quads_QuadOperator ending, unsigned int procsym, unsigned int quad)
14589 : : {
14590 : 0 : M2Quads_QuadOperator op;
14591 : 0 : unsigned int op1;
14592 : 0 : unsigned int op2;
14593 : 0 : unsigned int op3;
14594 : 0 : M2Quads_QuadFrame f;
14595 : :
14596 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "\\n...\\n\\n", 9);
14597 : 0 : do {
14598 : 0 : M2Quads_GetQuad (quad, &op, &op1, &op2, &op3);
14599 : 0 : M2Quads_DisplayQuad (quad);
14600 : 0 : f = GetQF (quad);
14601 : 0 : quad = f->Next;
14602 : 0 : } while (! ((op == ending) && (op3 == procsym)));
14603 : 0 : return quad;
14604 : : /* static analysis guarentees a RETURN statement will be used before here. */
14605 : : __builtin_unreachable ();
14606 : : }
14607 : :
14608 : :
14609 : : /*
14610 : : GetCtorInit - return the init procedure for the module.
14611 : : */
14612 : :
14613 : 0 : static unsigned int GetCtorInit (unsigned int sym)
14614 : : {
14615 : 0 : unsigned int ctor;
14616 : 0 : unsigned int init;
14617 : 0 : unsigned int fini;
14618 : 0 : unsigned int dep;
14619 : :
14620 : 0 : SymbolTable_GetModuleCtors (sym, &ctor, &init, &fini, &dep);
14621 : 0 : return init;
14622 : : /* static analysis guarentees a RETURN statement will be used before here. */
14623 : : __builtin_unreachable ();
14624 : : }
14625 : :
14626 : :
14627 : : /*
14628 : : GetCtorFini - return the fini procedure for the module.
14629 : : */
14630 : :
14631 : 0 : static unsigned int GetCtorFini (unsigned int sym)
14632 : : {
14633 : 0 : unsigned int ctor;
14634 : 0 : unsigned int init;
14635 : 0 : unsigned int fini;
14636 : 0 : unsigned int dep;
14637 : :
14638 : 0 : SymbolTable_GetModuleCtors (sym, &ctor, &init, &fini, &dep);
14639 : 0 : return fini;
14640 : : /* static analysis guarentees a RETURN statement will be used before here. */
14641 : : __builtin_unreachable ();
14642 : : }
14643 : :
14644 : :
14645 : : /*
14646 : : DumpQuadrupleFilter -
14647 : : */
14648 : :
14649 : 0 : static void DumpQuadrupleFilter (void)
14650 : : {
14651 : 0 : M2Quads_QuadFrame f;
14652 : 0 : unsigned int i;
14653 : 0 : M2Quads_QuadOperator op;
14654 : 0 : unsigned int op1;
14655 : 0 : unsigned int op2;
14656 : 0 : unsigned int op3;
14657 : :
14658 : 0 : i = Head;
14659 : 0 : while (i != 0)
14660 : : {
14661 : 0 : M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
14662 : 0 : if ((op == M2Quads_ProcedureScopeOp) && (M2LangDump_IsDumpRequired (op3, true)))
14663 : : {
14664 : 0 : i = DumpUntil (M2Quads_KillLocalVarOp, op3, i);
14665 : : }
14666 : 0 : else if ((op == M2Quads_InitStartOp) && (M2LangDump_IsDumpRequired (GetCtorInit (op3), true)))
14667 : : {
14668 : : /* avoid dangling else. */
14669 : 0 : i = DumpUntil (M2Quads_InitEndOp, op3, i);
14670 : : }
14671 : 0 : else if ((op == M2Quads_FinallyStartOp) && (M2LangDump_IsDumpRequired (GetCtorFini (op3), true)))
14672 : : {
14673 : : /* avoid dangling else. */
14674 : 0 : i = DumpUntil (M2Quads_FinallyEndOp, op3, i);
14675 : : }
14676 : : else
14677 : : {
14678 : : /* avoid dangling else. */
14679 : 0 : f = GetQF (i);
14680 : 0 : i = f->Next;
14681 : : }
14682 : : }
14683 : 0 : }
14684 : :
14685 : :
14686 : : /*
14687 : : DumpQuadrupleAll - dump all quadruples.
14688 : : */
14689 : :
14690 : 0 : static void DumpQuadrupleAll (void)
14691 : : {
14692 : 0 : M2Quads_QuadFrame f;
14693 : 0 : unsigned int i;
14694 : :
14695 : 0 : i = Head;
14696 : 0 : while (i != 0)
14697 : : {
14698 : 0 : M2Quads_DisplayQuad (i);
14699 : 0 : f = GetQF (i);
14700 : 0 : i = f->Next;
14701 : : }
14702 : 0 : }
14703 : :
14704 : :
14705 : : /*
14706 : : BackPatch - Makes each of the quadruples on the list pointed to by
14707 : : StartQuad, take quadruple Value as a target.
14708 : : */
14709 : :
14710 : 309818 : static void BackPatch (unsigned int QuadNo, unsigned int Value)
14711 : : {
14712 : 309818 : unsigned int i;
14713 : 309818 : M2Quads_QuadFrame f;
14714 : :
14715 : 309818 : if (QuadrupleGeneration)
14716 : : {
14717 : 489422 : while (QuadNo != 0)
14718 : : {
14719 : 179604 : f = GetQF (QuadNo);
14720 : 179604 : i = f->Operand3; /* Next Link along the BackPatch */
14721 : 179604 : ManipulateReference (QuadNo, Value); /* Filling in the BackPatch. */
14722 : 179604 : QuadNo = i;
14723 : : }
14724 : : }
14725 : 309818 : }
14726 : :
14727 : :
14728 : : /*
14729 : : Merge - joins two quad lists, QuadList2 to the end of QuadList1.
14730 : : A QuadList of value zero is a nul list.
14731 : : */
14732 : :
14733 : 39767 : static unsigned int Merge (unsigned int QuadList1, unsigned int QuadList2)
14734 : : {
14735 : 39767 : unsigned int i;
14736 : 39767 : unsigned int j;
14737 : 39767 : M2Quads_QuadFrame f;
14738 : :
14739 : 39767 : if (QuadList1 == 0)
14740 : : {
14741 : : return QuadList2;
14742 : : }
14743 : 20226 : else if (QuadList2 == 0)
14744 : : {
14745 : : /* avoid dangling else. */
14746 : : return QuadList1;
14747 : : }
14748 : : else
14749 : : {
14750 : : /* avoid dangling else. */
14751 : : i = QuadList1;
14752 : 43252 : do {
14753 : 43252 : j = i;
14754 : 43252 : f = GetQF (i);
14755 : 43252 : i = f->Operand3;
14756 : 43252 : } while (! (i == 0));
14757 : 17592 : ManipulateReference (j, QuadList2);
14758 : 17592 : return QuadList1;
14759 : : }
14760 : : /* static analysis guarentees a RETURN statement will be used before here. */
14761 : : __builtin_unreachable ();
14762 : : }
14763 : :
14764 : :
14765 : : /*
14766 : : DisplayProcedureAttributes -
14767 : : */
14768 : :
14769 : 0 : static void DisplayProcedureAttributes (unsigned int proc)
14770 : : {
14771 : 0 : if (SymbolTable_IsCtor (proc))
14772 : : {
14773 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (ctor)", 7);
14774 : : }
14775 : 0 : if (SymbolTable_IsPublic (proc))
14776 : : {
14777 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (public)", 9);
14778 : : }
14779 : 0 : if (SymbolTable_IsExtern (proc))
14780 : : {
14781 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (extern)", 9);
14782 : : }
14783 : 0 : if (SymbolTable_IsMonoName (proc))
14784 : : {
14785 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (mononame)", 11);
14786 : : }
14787 : 0 : }
14788 : :
14789 : :
14790 : : /*
14791 : : WriteQuad - Writes out the Quad BufferQuad.
14792 : : */
14793 : :
14794 : 0 : static void WriteQuad (unsigned int BufferQuad)
14795 : : {
14796 : 0 : NameKey_Name n1;
14797 : 0 : NameKey_Name n2;
14798 : 0 : M2Quads_QuadFrame f;
14799 : 0 : NameKey_Name n;
14800 : 0 : unsigned int l;
14801 : :
14802 : 0 : f = GetQF (BufferQuad);
14803 : 0 : M2Quads_WriteOperator (f->Operator);
14804 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " [%d]", 5, (const unsigned char *) &f->NoOfTimesReferenced, (sizeof (f->NoOfTimesReferenced)-1));
14805 : 0 : if (f->ConstExpr)
14806 : : {
14807 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " const ", 7);
14808 : : }
14809 : : else
14810 : : {
14811 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 7);
14812 : : }
14813 : 0 : switch (f->Operator)
14814 : : {
14815 : 0 : case M2Quads_HighOp:
14816 : 0 : M2Quads_WriteOperand (f->Operand1);
14817 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %4d ", 7, (const unsigned char *) &f->Operand2, (sizeof (f->Operand2)-1));
14818 : 0 : M2Quads_WriteOperand (f->Operand3);
14819 : 0 : break;
14820 : :
14821 : 0 : case M2Quads_InitAddressOp:
14822 : 0 : case M2Quads_SavePriorityOp:
14823 : 0 : case M2Quads_RestorePriorityOp:
14824 : 0 : case M2Quads_SubrangeLowOp:
14825 : 0 : case M2Quads_SubrangeHighOp:
14826 : 0 : case M2Quads_BecomesOp:
14827 : 0 : case M2Quads_InclOp:
14828 : 0 : case M2Quads_ExclOp:
14829 : 0 : case M2Quads_UnboundedOp:
14830 : 0 : case M2Quads_ReturnValueOp:
14831 : 0 : case M2Quads_FunctValueOp:
14832 : 0 : case M2Quads_NegateOp:
14833 : 0 : case M2Quads_AddrOp:
14834 : 0 : case M2Quads_StringConvertCnulOp:
14835 : 0 : case M2Quads_StringConvertM2nulOp:
14836 : 0 : case M2Quads_StringLengthOp:
14837 : 0 : M2Quads_WriteOperand (f->Operand1);
14838 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
14839 : 0 : M2Quads_WriteOperand (f->Operand3);
14840 : 0 : break;
14841 : :
14842 : 0 : case M2Quads_ElementSizeOp:
14843 : 0 : case M2Quads_IfInOp:
14844 : 0 : case M2Quads_IfNotInOp:
14845 : 0 : case M2Quads_IfNotEquOp:
14846 : 0 : case M2Quads_IfEquOp:
14847 : 0 : case M2Quads_IfLessOp:
14848 : 0 : case M2Quads_IfGreOp:
14849 : 0 : case M2Quads_IfLessEquOp:
14850 : 0 : case M2Quads_IfGreEquOp:
14851 : 0 : M2Quads_WriteOperand (f->Operand1);
14852 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
14853 : 0 : M2Quads_WriteOperand (f->Operand2);
14854 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %4d", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
14855 : 0 : break;
14856 : :
14857 : 0 : case M2Quads_InlineOp:
14858 : 0 : case M2Quads_RetryOp:
14859 : 0 : case M2Quads_TryOp:
14860 : 0 : case M2Quads_GotoOp:
14861 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d", 3, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
14862 : 0 : break;
14863 : :
14864 : 0 : case M2Quads_StatementNoteOp:
14865 : 0 : l = M2LexBuf_TokenToLineNo (f->Operand3, 0);
14866 : 0 : n = M2LexBuf_GetTokenName (f->Operand3);
14867 : 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));
14868 : 0 : break;
14869 : :
14870 : 0 : case M2Quads_LineNumberOp:
14871 : 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));
14872 : 0 : break;
14873 : :
14874 : 0 : case M2Quads_EndFileOp:
14875 : 0 : n1 = SymbolTable_GetSymName (f->Operand3);
14876 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%a", 2, (const unsigned char *) &n1, (sizeof (n1)-1));
14877 : 0 : break;
14878 : :
14879 : 0 : case M2Quads_ThrowOp:
14880 : 0 : case M2Quads_ReturnOp:
14881 : 0 : case M2Quads_CallOp:
14882 : 0 : case M2Quads_KillLocalVarOp:
14883 : 0 : M2Quads_WriteOperand (f->Operand3);
14884 : 0 : break;
14885 : :
14886 : 0 : case M2Quads_ProcedureScopeOp:
14887 : 0 : n1 = SymbolTable_GetSymName (f->Operand2);
14888 : 0 : n2 = SymbolTable_GetSymName (f->Operand3);
14889 : 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));
14890 : 0 : DisplayProcedureAttributes (f->Operand3);
14891 : 0 : break;
14892 : :
14893 : 0 : case M2Quads_NewLocalVarOp:
14894 : 0 : case M2Quads_FinallyStartOp:
14895 : 0 : case M2Quads_FinallyEndOp:
14896 : 0 : case M2Quads_InitEndOp:
14897 : 0 : case M2Quads_InitStartOp:
14898 : 0 : n1 = SymbolTable_GetSymName (f->Operand2);
14899 : 0 : n2 = SymbolTable_GetSymName (f->Operand3);
14900 : 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));
14901 : 0 : break;
14902 : :
14903 : 0 : case M2Quads_ModuleScopeOp:
14904 : 0 : case M2Quads_StartModFileOp:
14905 : 0 : n1 = SymbolTable_GetSymName (f->Operand3);
14906 : 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));
14907 : 0 : break;
14908 : :
14909 : 0 : case M2Quads_StartDefFileOp:
14910 : 0 : n1 = SymbolTable_GetSymName (f->Operand3);
14911 : 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));
14912 : 0 : break;
14913 : :
14914 : 0 : case M2Quads_OptParamOp:
14915 : 0 : case M2Quads_ParamOp:
14916 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d ", 5, (const unsigned char *) &f->Operand1, (sizeof (f->Operand1)-1));
14917 : 0 : M2Quads_WriteOperand (f->Operand2);
14918 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
14919 : 0 : M2Quads_WriteOperand (f->Operand3);
14920 : 0 : break;
14921 : :
14922 : 0 : case M2Quads_SizeOp:
14923 : 0 : case M2Quads_RecordFieldOp:
14924 : 0 : case M2Quads_IndrXOp:
14925 : 0 : case M2Quads_XIndrOp:
14926 : 0 : case M2Quads_ArrayOp:
14927 : 0 : case M2Quads_LogicalShiftOp:
14928 : 0 : case M2Quads_LogicalRotateOp:
14929 : 0 : case M2Quads_LogicalOrOp:
14930 : 0 : case M2Quads_LogicalAndOp:
14931 : 0 : case M2Quads_LogicalXorOp:
14932 : 0 : case M2Quads_LogicalDiffOp:
14933 : 0 : case M2Quads_ArithAddOp:
14934 : 0 : case M2Quads_CoerceOp:
14935 : 0 : case M2Quads_ConvertOp:
14936 : 0 : case M2Quads_CastOp:
14937 : 0 : case M2Quads_AddOp:
14938 : 0 : case M2Quads_SubOp:
14939 : 0 : case M2Quads_MultOp:
14940 : 0 : case M2Quads_DivM2Op:
14941 : 0 : case M2Quads_ModM2Op:
14942 : 0 : case M2Quads_ModFloorOp:
14943 : 0 : case M2Quads_DivCeilOp:
14944 : 0 : case M2Quads_ModCeilOp:
14945 : 0 : case M2Quads_DivFloorOp:
14946 : 0 : case M2Quads_ModTruncOp:
14947 : 0 : case M2Quads_DivTruncOp:
14948 : 0 : M2Quads_WriteOperand (f->Operand1);
14949 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
14950 : 0 : M2Quads_WriteOperand (f->Operand2);
14951 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
14952 : 0 : M2Quads_WriteOperand (f->Operand3);
14953 : 0 : break;
14954 : :
14955 : : case M2Quads_DummyOp:
14956 : : case M2Quads_CodeOnOp:
14957 : : case M2Quads_CodeOffOp:
14958 : : case M2Quads_ProfileOnOp:
14959 : : case M2Quads_ProfileOffOp:
14960 : : case M2Quads_OptimizeOnOp:
14961 : : case M2Quads_OptimizeOffOp:
14962 : : break;
14963 : :
14964 : 0 : case M2Quads_BuiltinConstOp:
14965 : 0 : M2Quads_WriteOperand (f->Operand1);
14966 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %a", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
14967 : 0 : break;
14968 : :
14969 : 0 : case M2Quads_BuiltinTypeInfoOp:
14970 : 0 : M2Quads_WriteOperand (f->Operand1);
14971 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %a", 5, (const unsigned char *) &f->Operand2, (sizeof (f->Operand2)-1));
14972 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %a", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
14973 : 0 : break;
14974 : :
14975 : 0 : case M2Quads_StandardFunctionOp:
14976 : 0 : M2Quads_WriteOperand (f->Operand1);
14977 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
14978 : 0 : M2Quads_WriteOperand (f->Operand2);
14979 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
14980 : 0 : M2Quads_WriteOperand (f->Operand3);
14981 : 0 : break;
14982 : :
14983 : : case M2Quads_CatchBeginOp:
14984 : : case M2Quads_CatchEndOp:
14985 : : break;
14986 : :
14987 : 0 : case M2Quads_RangeCheckOp:
14988 : 0 : case M2Quads_ErrorOp:
14989 : 0 : M2Range_WriteRangeCheck (f->Operand3);
14990 : 0 : break;
14991 : :
14992 : 0 : case M2Quads_SaveExceptionOp:
14993 : 0 : case M2Quads_RestoreExceptionOp:
14994 : 0 : M2Quads_WriteOperand (f->Operand1);
14995 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
14996 : 0 : M2Quads_WriteOperand (f->Operand3);
14997 : 0 : break;
14998 : :
14999 : :
15000 : 0 : default:
15001 : 0 : M2Error_InternalError ((const char *) "quadruple not recognised", 24);
15002 : 0 : break;
15003 : : }
15004 : 0 : }
15005 : :
15006 : :
15007 : : /*
15008 : : WriteOperand - displays the operands name, symbol id and mode of addressing.
15009 : : */
15010 : :
15011 : 0 : static void WriteMode (SymbolTable_ModeOfAddr Mode)
15012 : : {
15013 : 0 : switch (Mode)
15014 : : {
15015 : 0 : case SymbolTable_ImmediateValue:
15016 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "i", 1);
15017 : 0 : break;
15018 : :
15019 : 0 : case SymbolTable_NoValue:
15020 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "n", 1);
15021 : 0 : break;
15022 : :
15023 : 0 : case SymbolTable_RightValue:
15024 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "r", 1);
15025 : 0 : break;
15026 : :
15027 : 0 : case SymbolTable_LeftValue:
15028 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "l", 1);
15029 : 0 : break;
15030 : :
15031 : :
15032 : 0 : default:
15033 : 0 : M2Error_InternalError ((const char *) "unrecognised mode", 17);
15034 : 0 : break;
15035 : : }
15036 : 0 : }
15037 : :
15038 : :
15039 : : /*
15040 : : PushExit - pushes the exit value onto the EXIT stack.
15041 : : */
15042 : :
15043 : 585 : static void PushExit (unsigned int Exit)
15044 : : {
15045 : 0 : M2StackWord_PushWord (ExitStack, Exit);
15046 : 94 : }
15047 : :
15048 : :
15049 : : /*
15050 : : PopExit - pops the exit value from the EXIT stack.
15051 : : */
15052 : :
15053 : 585 : static unsigned int PopExit (void)
15054 : : {
15055 : 0 : return M2StackWord_PopWord (ExitStack);
15056 : : /* static analysis guarentees a RETURN statement will be used before here. */
15057 : : __builtin_unreachable ();
15058 : : }
15059 : :
15060 : :
15061 : : /*
15062 : : PushFor - pushes the exit value onto the FOR stack.
15063 : : */
15064 : :
15065 : 7408 : static void PushFor (unsigned int Exit)
15066 : : {
15067 : 0 : M2StackWord_PushWord (ForStack, Exit);
15068 : 0 : }
15069 : :
15070 : :
15071 : : /*
15072 : : PopFor - pops the exit value from the FOR stack.
15073 : : */
15074 : :
15075 : 7408 : static unsigned int PopFor (void)
15076 : : {
15077 : 0 : return M2StackWord_PopWord (ForStack);
15078 : : /* static analysis guarentees a RETURN statement will be used before here. */
15079 : : __builtin_unreachable ();
15080 : : }
15081 : :
15082 : :
15083 : : /*
15084 : : OperandTno - returns the ident operand stored in the true position
15085 : : on the boolean stack. This is exactly the same as
15086 : : OperandT but it has no IsBoolean checking.
15087 : : */
15088 : :
15089 : 58772322 : static unsigned int OperandTno (unsigned int pos)
15090 : : {
15091 : 58772322 : M2Quads_BoolFrame f;
15092 : :
15093 : 58772322 : M2Debug_Assert (pos > 0);
15094 : 58772322 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15095 : 58772322 : return static_cast<unsigned int> (f->TrueExit);
15096 : : /* static analysis guarentees a RETURN statement will be used before here. */
15097 : : __builtin_unreachable ();
15098 : : }
15099 : :
15100 : :
15101 : : /*
15102 : : OperandFno - returns the ident operand stored in the false position
15103 : : on the boolean stack. This is exactly the same as
15104 : : OperandF but it has no IsBoolean checking.
15105 : : */
15106 : :
15107 : 139777 : static unsigned int OperandFno (unsigned int pos)
15108 : : {
15109 : 139777 : M2Quads_BoolFrame f;
15110 : :
15111 : 139777 : M2Debug_Assert (pos > 0);
15112 : 139777 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15113 : 139777 : return static_cast<unsigned int> (f->FalseExit);
15114 : : /* static analysis guarentees a RETURN statement will be used before here. */
15115 : : __builtin_unreachable ();
15116 : : }
15117 : :
15118 : :
15119 : : /*
15120 : : OperandTtok - returns the token associated with the position, pos
15121 : : on the boolean stack.
15122 : : */
15123 : :
15124 : 21411418 : static unsigned int OperandTtok (unsigned int pos)
15125 : : {
15126 : 21411418 : M2Quads_BoolFrame f;
15127 : :
15128 : 21411418 : M2Debug_Assert (pos > 0);
15129 : 21411418 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15130 : 21411418 : return f->tokenno;
15131 : : /* static analysis guarentees a RETURN statement will be used before here. */
15132 : : __builtin_unreachable ();
15133 : : }
15134 : :
15135 : :
15136 : : /*
15137 : : PopBooltok - Pops a True and a False exit quad number from the True/False
15138 : : stack.
15139 : : */
15140 : :
15141 : 165264 : static void PopBooltok (unsigned int *True, unsigned int *False, unsigned int *tokno)
15142 : : {
15143 : 165264 : M2Quads_BoolFrame f;
15144 : :
15145 : 165264 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15146 : 165264 : (*True) = f->TrueExit;
15147 : 165264 : (*False) = f->FalseExit;
15148 : 165264 : (*tokno) = f->tokenno;
15149 : 165264 : M2Debug_Assert (f->BooleanOp);
15150 : 165264 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15151 : 165264 : }
15152 : :
15153 : :
15154 : : /*
15155 : : PushBooltok - Push a True and a False exit quad numbers onto the
15156 : : True/False stack.
15157 : : */
15158 : :
15159 : 171454 : static void PushBooltok (unsigned int True, unsigned int False, unsigned int tokno)
15160 : : {
15161 : 171454 : M2Quads_BoolFrame f;
15162 : :
15163 : 171454 : M2Debug_Assert (True <= NextQuad);
15164 : 171454 : M2Debug_Assert (False <= NextQuad);
15165 : 171454 : f = newBoolFrame ();
15166 : 171454 : f->TrueExit = True;
15167 : 171454 : f->FalseExit = False;
15168 : 171454 : f->BooleanOp = true;
15169 : 171454 : f->tokenno = tokno;
15170 : 171454 : f->Annotation = static_cast<DynamicStrings_String> (NULL);
15171 : 171454 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
15172 : 171454 : M2Quads_Annotate ((const char *) "<q%1d>|<q%2d>||true quad|false quad", 35);
15173 : 171454 : }
15174 : :
15175 : :
15176 : : /*
15177 : : PopBool - Pops a True and a False exit quad number from the True/False
15178 : : stack.
15179 : : */
15180 : :
15181 : 139860 : static void PopBool (unsigned int *True, unsigned int *False)
15182 : : {
15183 : 139860 : unsigned int tokno;
15184 : :
15185 : 8177 : PopBooltok (True, False, &tokno);
15186 : 0 : }
15187 : :
15188 : :
15189 : : /*
15190 : : PushBool - Push a True and a False exit quad numbers onto the
15191 : : True/False stack.
15192 : : */
15193 : :
15194 : 88214 : static void PushBool (unsigned int True, unsigned int False)
15195 : : {
15196 : 6190 : PushBooltok (True, False, M2LexBuf_UnknownTokenNo);
15197 : 10098 : }
15198 : :
15199 : :
15200 : : /*
15201 : : IsBoolean - returns true is the Stack position pos contains a Boolean
15202 : : Exit. False is returned if an Ident is stored.
15203 : : */
15204 : :
15205 : 82246091 : static bool IsBoolean (unsigned int pos)
15206 : : {
15207 : 82246091 : M2Quads_BoolFrame f;
15208 : :
15209 : 82246091 : M2Debug_Assert (pos > 0);
15210 : 82246091 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15211 : 82246091 : return f->BooleanOp;
15212 : : /* static analysis guarentees a RETURN statement will be used before here. */
15213 : : __builtin_unreachable ();
15214 : : }
15215 : :
15216 : :
15217 : : /*
15218 : : OperandD - returns possible array dimension associated with the ident
15219 : : operand stored on the boolean stack.
15220 : : */
15221 : :
15222 : 551600 : static unsigned int OperandD (unsigned int pos)
15223 : : {
15224 : 551600 : M2Quads_BoolFrame f;
15225 : :
15226 : 551600 : M2Debug_Assert (pos > 0);
15227 : 551600 : M2Debug_Assert (! (IsBoolean (pos)));
15228 : 551600 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15229 : 551600 : return static_cast<unsigned int> (f->Dimension);
15230 : : /* static analysis guarentees a RETURN statement will be used before here. */
15231 : : __builtin_unreachable ();
15232 : : }
15233 : :
15234 : :
15235 : : /*
15236 : : OperandRW - returns the rw operand stored on the boolean stack.
15237 : : */
15238 : :
15239 : 598496 : static unsigned int OperandRW (unsigned int pos)
15240 : : {
15241 : 598496 : M2Quads_BoolFrame f;
15242 : :
15243 : 598496 : M2Debug_Assert (pos > 0);
15244 : 598496 : M2Debug_Assert (! (IsBoolean (pos)));
15245 : 598496 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15246 : 598496 : return static_cast<unsigned int> (f->ReadWrite);
15247 : : /* static analysis guarentees a RETURN statement will be used before here. */
15248 : : __builtin_unreachable ();
15249 : : }
15250 : :
15251 : :
15252 : : /*
15253 : : OperandMergeRW - returns the rw operand if not NulSym else it
15254 : : returns True.
15255 : : */
15256 : :
15257 : 578596 : static unsigned int OperandMergeRW (unsigned int pos)
15258 : : {
15259 : 578596 : if ((OperandRW (pos)) == SymbolTable_NulSym)
15260 : : {
15261 : 561045 : return M2Quads_OperandT (pos);
15262 : : }
15263 : : else
15264 : : {
15265 : 17551 : return OperandRW (pos);
15266 : : }
15267 : : /* static analysis guarentees a RETURN statement will be used before here. */
15268 : : __builtin_unreachable ();
15269 : : }
15270 : :
15271 : :
15272 : : /*
15273 : : UseLineNote - uses the line note and returns it to the free list.
15274 : : */
15275 : :
15276 : 3704 : static void UseLineNote (M2Quads_LineNote l)
15277 : : {
15278 : 3704 : M2Quads_QuadFrame f;
15279 : :
15280 : 3704 : f = GetQF (NextQuad-1);
15281 : 3704 : if ((f->Operator == M2Quads_LineNumberOp) && (f->Operand1 == ((unsigned int ) (l->File))))
15282 : : {} /* empty. */
15283 : : else
15284 : : {
15285 : : /* do nothing */
15286 : : if (false)
15287 : : {
15288 : : GenQuad (M2Quads_LineNumberOp, (unsigned int ) (l->File), SymbolTable_NulSym, (unsigned int ) (l->Line));
15289 : : }
15290 : : }
15291 : 3704 : l->Next = FreeLineList;
15292 : 3704 : FreeLineList = l;
15293 : 3704 : }
15294 : :
15295 : :
15296 : : /*
15297 : : PopLineNo - pops a line note from the line stack.
15298 : : */
15299 : :
15300 : 3704 : static M2Quads_LineNote PopLineNo (void)
15301 : : {
15302 : 3704 : M2Quads_LineNote l;
15303 : :
15304 : 3704 : l = static_cast<M2Quads_LineNote> (M2StackAddress_PopAddress (LineStack));
15305 : 3704 : if (l == NULL)
15306 : : {
15307 : 0 : M2Error_InternalError ((const char *) "no line note available", 22);
15308 : : }
15309 : 3704 : return l;
15310 : : /* static analysis guarentees a RETURN statement will be used before here. */
15311 : : __builtin_unreachable ();
15312 : : }
15313 : :
15314 : :
15315 : : /*
15316 : : InitLineNote - creates a line note and initializes it to
15317 : : contain, file, line.
15318 : : */
15319 : :
15320 : 3704 : static M2Quads_LineNote InitLineNote (NameKey_Name file, unsigned int line)
15321 : : {
15322 : 3704 : M2Quads_LineNote l;
15323 : :
15324 : 3704 : if (FreeLineList == NULL)
15325 : : {
15326 : 1868 : Storage_ALLOCATE ((void **) &l, sizeof (M2Quads__T6));
15327 : : }
15328 : : else
15329 : : {
15330 : 1836 : l = FreeLineList;
15331 : 1836 : FreeLineList = FreeLineList->Next;
15332 : : }
15333 : 3704 : l->File = file;
15334 : 3704 : l->Line = line;
15335 : 3704 : return l;
15336 : : /* static analysis guarentees a RETURN statement will be used before here. */
15337 : : __builtin_unreachable ();
15338 : : }
15339 : :
15340 : :
15341 : : /*
15342 : : PushLineNote -
15343 : : */
15344 : :
15345 : 3704 : static void PushLineNote (M2Quads_LineNote l)
15346 : : {
15347 : 0 : M2StackAddress_PushAddress (LineStack, reinterpret_cast<void *> (l));
15348 : 0 : }
15349 : :
15350 : :
15351 : : /*
15352 : : BuildStmtNoteTok - adds a nop (with an assigned tokenno location) to the code.
15353 : : */
15354 : :
15355 : 411095 : static void BuildStmtNoteTok (unsigned int tokenno)
15356 : : {
15357 : 411095 : NameKey_Name filename;
15358 : 411095 : M2Quads_QuadFrame f;
15359 : :
15360 : 411095 : f = GetQF (NextQuad-1);
15361 : : /* no need to have multiple notes at the same position. */
15362 : 411095 : if ((f->Operator != M2Quads_StatementNoteOp) || (f->Operand3 != tokenno))
15363 : : {
15364 : 404806 : filename = NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()));
15365 : 404806 : GenQuad (M2Quads_StatementNoteOp, (unsigned int ) (filename), SymbolTable_NulSym, tokenno);
15366 : : }
15367 : 411095 : }
15368 : :
15369 : :
15370 : : /*
15371 : : GetRecordOrField -
15372 : : */
15373 : :
15374 : 1218 : static unsigned int GetRecordOrField (void)
15375 : : {
15376 : 1218 : unsigned int f;
15377 : :
15378 : 1218 : VarientFieldNo += 1;
15379 : 1218 : f = static_cast<unsigned int> (Lists_GetItemFromList (VarientFields, VarientFieldNo));
15380 : 1218 : if (DebugVarients)
15381 : : {
15382 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
15383 : : if (SymbolTable_IsRecord (f))
15384 : : {
15385 : : 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));
15386 : : }
15387 : : else
15388 : : {
15389 : : 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));
15390 : : }
15391 : : }
15392 : 1218 : return f;
15393 : : /* static analysis guarentees a RETURN statement will be used before here. */
15394 : : __builtin_unreachable ();
15395 : : }
15396 : :
15397 : :
15398 : : /*
15399 : : PushTFAD - Push True, False, Array, Dim, numbers onto the
15400 : : True/False stack. True and False are assumed to
15401 : : contain Symbols or Ident etc.
15402 : : */
15403 : :
15404 : 336 : static void PushTFAD (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim)
15405 : : {
15406 : 336 : M2Quads_BoolFrame f;
15407 : :
15408 : 336 : f = newBoolFrame ();
15409 : 336 : f->TrueExit = static_cast<unsigned int> (True);
15410 : 336 : f->FalseExit = static_cast<unsigned int> (False);
15411 : 336 : f->Unbounded = static_cast<unsigned int> (Array);
15412 : 336 : f->Dimension = static_cast<unsigned int> (Dim);
15413 : 336 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
15414 : 336 : }
15415 : :
15416 : :
15417 : : /*
15418 : : PushTFADtok - Push True, False, Array, Dim, numbers onto the
15419 : : True/False stack. True and False are assumed to
15420 : : contain Symbols or Ident etc.
15421 : : */
15422 : :
15423 : 2685 : static void PushTFADtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int tokno)
15424 : : {
15425 : 2685 : M2Quads_BoolFrame f;
15426 : :
15427 : 2685 : f = newBoolFrame ();
15428 : 2685 : f->TrueExit = static_cast<unsigned int> (True);
15429 : 2685 : f->FalseExit = static_cast<unsigned int> (False);
15430 : 2685 : f->Unbounded = static_cast<unsigned int> (Array);
15431 : 2685 : f->Dimension = static_cast<unsigned int> (Dim);
15432 : 2685 : f->tokenno = tokno;
15433 : 2685 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
15434 : 2685 : }
15435 : :
15436 : :
15437 : : /*
15438 : : PushTFADrwtok - Push True, False, Array, Dim, rw, numbers onto the
15439 : : True/False stack. True and False are assumed to
15440 : : contain Symbols or Ident etc.
15441 : : */
15442 : :
15443 : 7574 : static void PushTFADrwtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int rw, unsigned int Tok)
15444 : : {
15445 : 7574 : M2Quads_BoolFrame f;
15446 : :
15447 : 7574 : f = newBoolFrame ();
15448 : 7574 : f->TrueExit = static_cast<unsigned int> (True);
15449 : 7574 : f->FalseExit = static_cast<unsigned int> (False);
15450 : 7574 : f->Unbounded = static_cast<unsigned int> (Array);
15451 : 7574 : f->Dimension = static_cast<unsigned int> (Dim);
15452 : 7574 : f->ReadWrite = static_cast<unsigned int> (rw);
15453 : 7574 : f->tokenno = Tok;
15454 : 7574 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
15455 : 7574 : }
15456 : :
15457 : :
15458 : : /*
15459 : : PopTFrwtok - Pop a True and False number from the True/False stack.
15460 : : True and False are assumed to contain Symbols or Ident etc.
15461 : : */
15462 : :
15463 : 242651 : static void PopTFrwtok (unsigned int *True, unsigned int *False, unsigned int *rw, unsigned int *tokno)
15464 : : {
15465 : 242651 : M2Quads_BoolFrame f;
15466 : :
15467 : 242651 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15468 : 242651 : (*True) = static_cast<unsigned int> (f->TrueExit);
15469 : 242651 : (*False) = static_cast<unsigned int> (f->FalseExit);
15470 : 242651 : M2Debug_Assert (! f->BooleanOp);
15471 : 242651 : (*rw) = static_cast<unsigned int> (f->ReadWrite);
15472 : 242651 : (*tokno) = f->tokenno;
15473 : 242651 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15474 : 242651 : }
15475 : :
15476 : :
15477 : : /*
15478 : : PushTFrwtok - Push an item onto the stack in the T (true) position,
15479 : : it is assummed to be a token and its token location is recorded.
15480 : : */
15481 : :
15482 : 256914 : static void PushTFrwtok (unsigned int True, unsigned int False, unsigned int rw, unsigned int tokno)
15483 : : {
15484 : 256914 : M2Quads_BoolFrame f;
15485 : :
15486 : 256914 : f = newBoolFrame ();
15487 : 256914 : f->TrueExit = static_cast<unsigned int> (True);
15488 : 256914 : f->FalseExit = static_cast<unsigned int> (False);
15489 : 256914 : f->ReadWrite = static_cast<unsigned int> (rw);
15490 : 256914 : f->tokenno = tokno;
15491 : 256914 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
15492 : 256914 : }
15493 : :
15494 : :
15495 : : /*
15496 : : PushTFDtok - Push True, False, Dim, numbers onto the
15497 : : True/False stack. True and False are assumed to
15498 : : contain Symbols or Ident etc.
15499 : : */
15500 : :
15501 : 192 : static void PushTFDtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int Tok)
15502 : : {
15503 : 192 : M2Quads_BoolFrame f;
15504 : :
15505 : 192 : f = newBoolFrame ();
15506 : 192 : f->TrueExit = static_cast<unsigned int> (True);
15507 : 192 : f->FalseExit = static_cast<unsigned int> (False);
15508 : 192 : f->Dimension = static_cast<unsigned int> (Dim);
15509 : 192 : f->tokenno = Tok;
15510 : 192 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
15511 : 192 : }
15512 : :
15513 : :
15514 : : /*
15515 : : PopTFDtok - Pop a True, False, Dim number from the True/False stack.
15516 : : True and False are assumed to contain Symbols or Ident etc.
15517 : : */
15518 : :
15519 : 192 : static void PopTFDtok (unsigned int *True, unsigned int *False, unsigned int *Dim, unsigned int *Tok)
15520 : : {
15521 : 192 : M2Quads_BoolFrame f;
15522 : :
15523 : 192 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15524 : 192 : (*True) = static_cast<unsigned int> (f->TrueExit);
15525 : 192 : (*False) = static_cast<unsigned int> (f->FalseExit);
15526 : 192 : (*Dim) = static_cast<unsigned int> (f->Dimension);
15527 : 192 : (*Tok) = f->tokenno;
15528 : 192 : M2Debug_Assert (! f->BooleanOp);
15529 : 192 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15530 : 192 : }
15531 : :
15532 : :
15533 : : /*
15534 : : PushTFDrwtok - Push True, False, Dim, numbers onto the
15535 : : True/False stack. True and False are assumed to
15536 : : contain Symbols or Ident etc.
15537 : : */
15538 : :
15539 : 36924 : static void PushTFDrwtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int rw, unsigned int Tok)
15540 : : {
15541 : 36924 : M2Quads_BoolFrame f;
15542 : :
15543 : 36924 : f = newBoolFrame ();
15544 : 36924 : f->TrueExit = static_cast<unsigned int> (True);
15545 : 36924 : f->FalseExit = static_cast<unsigned int> (False);
15546 : 36924 : f->Dimension = static_cast<unsigned int> (Dim);
15547 : 36924 : f->ReadWrite = static_cast<unsigned int> (rw);
15548 : 36924 : f->tokenno = Tok;
15549 : 36924 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
15550 : 36924 : }
15551 : :
15552 : :
15553 : : /*
15554 : : PushTFrw - Push a True and False numbers onto the True/False stack.
15555 : : True and False are assumed to contain Symbols or Ident etc.
15556 : : It also pushes the higher level symbol which is associated
15557 : : with the True symbol. Eg record variable or array variable.
15558 : : */
15559 : :
15560 : 2349 : static void PushTFrw (unsigned int True, unsigned int False, unsigned int rw)
15561 : : {
15562 : 2349 : M2Quads_BoolFrame f;
15563 : :
15564 : 2349 : f = newBoolFrame ();
15565 : 2349 : f->TrueExit = static_cast<unsigned int> (True);
15566 : 2349 : f->FalseExit = static_cast<unsigned int> (False);
15567 : 2349 : f->ReadWrite = rw;
15568 : 2349 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
15569 : 2349 : }
15570 : :
15571 : :
15572 : : /*
15573 : : PopTFrw - Pop a True and False number from the True/False stack.
15574 : : True and False are assumed to contain Symbols or Ident etc.
15575 : : */
15576 : :
15577 : 25436 : static void PopTFrw (unsigned int *True, unsigned int *False, unsigned int *rw)
15578 : : {
15579 : 25436 : M2Quads_BoolFrame f;
15580 : :
15581 : 25436 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15582 : 25436 : (*True) = static_cast<unsigned int> (f->TrueExit);
15583 : 25436 : (*False) = static_cast<unsigned int> (f->FalseExit);
15584 : 25436 : M2Debug_Assert (! f->BooleanOp);
15585 : 25436 : (*rw) = static_cast<unsigned int> (f->ReadWrite);
15586 : 25436 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15587 : 25436 : }
15588 : :
15589 : :
15590 : : /*
15591 : : newBoolFrame - creates a new BoolFrame with all fields initialised to their defaults.
15592 : : */
15593 : :
15594 : 150671426 : static M2Quads_BoolFrame newBoolFrame (void)
15595 : : {
15596 : 150671426 : M2Quads_BoolFrame f;
15597 : :
15598 : 150671426 : Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15599 : 150671426 : f->TrueExit = 0;
15600 : 150671426 : f->FalseExit = 0;
15601 : 150671426 : f->Unbounded = SymbolTable_NulSym;
15602 : 150671426 : f->BooleanOp = false;
15603 : 150671426 : f->Dimension = 0;
15604 : 150671426 : f->ReadWrite = SymbolTable_NulSym;
15605 : 150671426 : f->name = SymbolTable_NulSym;
15606 : 150671426 : f->Annotation = static_cast<DynamicStrings_String> (NULL);
15607 : 150671426 : f->tokenno = M2LexBuf_UnknownTokenNo;
15608 : 150671426 : return f;
15609 : : /* static analysis guarentees a RETURN statement will be used before here. */
15610 : : __builtin_unreachable ();
15611 : : }
15612 : :
15613 : :
15614 : : /*
15615 : : PushTrwtok - Push an item onto the True/False stack. The False value will be zero.
15616 : : */
15617 : :
15618 : 144 : static void PushTrwtok (unsigned int True, unsigned int rw, unsigned int tok)
15619 : : {
15620 : 144 : M2Quads_BoolFrame f;
15621 : :
15622 : 144 : f = newBoolFrame ();
15623 : 144 : f->TrueExit = static_cast<unsigned int> (True);
15624 : 144 : f->ReadWrite = static_cast<unsigned int> (rw);
15625 : 144 : f->tokenno = tok;
15626 : 144 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
15627 : 144 : }
15628 : :
15629 : :
15630 : : /*
15631 : : PopTrw - Pop a True field and rw symbol from the stack.
15632 : : */
15633 : :
15634 : 2349 : static void PopTrw (unsigned int *True, unsigned int *rw)
15635 : : {
15636 : 2349 : M2Quads_BoolFrame f;
15637 : :
15638 : 2349 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15639 : 2349 : (*True) = static_cast<unsigned int> (f->TrueExit);
15640 : 2349 : M2Debug_Assert (! f->BooleanOp);
15641 : 2349 : (*rw) = static_cast<unsigned int> (f->ReadWrite);
15642 : 2349 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15643 : 2349 : }
15644 : :
15645 : :
15646 : : /*
15647 : : PopTrwtok - Pop a True field and rw symbol from the stack.
15648 : : */
15649 : :
15650 : 831311 : static void PopTrwtok (unsigned int *True, unsigned int *rw, unsigned int *tok)
15651 : : {
15652 : 831311 : M2Quads_BoolFrame f;
15653 : :
15654 : 831311 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15655 : 831311 : (*True) = static_cast<unsigned int> (f->TrueExit);
15656 : 831311 : M2Debug_Assert (! f->BooleanOp);
15657 : 831311 : (*rw) = static_cast<unsigned int> (f->ReadWrite);
15658 : 831311 : (*tok) = f->tokenno;
15659 : 831311 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15660 : 831311 : }
15661 : :
15662 : :
15663 : : /*
15664 : : Init - initialize the M2Quads module, all the stacks, all the lists
15665 : : and the quads list.
15666 : : */
15667 : :
15668 : 12963 : static void Init (void)
15669 : : {
15670 : 12963 : LogicalOrTok = NameKey_MakeKey ((const char *) "_LOR", 4);
15671 : 12963 : LogicalAndTok = NameKey_MakeKey ((const char *) "_LAND", 5);
15672 : 12963 : LogicalXorTok = NameKey_MakeKey ((const char *) "_LXOR", 5);
15673 : 12963 : LogicalDifferenceTok = NameKey_MakeKey ((const char *) "_LDIFF", 6);
15674 : 12963 : ArithPlusTok = NameKey_MakeKey ((const char *) "_ARITH_+", 8);
15675 : 12963 : QuadArray = Indexing_InitIndexTuned (1, (1024*1024) / 16, 16);
15676 : 12963 : FreeList = 1;
15677 : 12963 : NewQuad (&NextQuad);
15678 : 12963 : M2Debug_Assert (NextQuad == 1);
15679 : 12963 : BoolStack = M2StackAddress_InitStackAddress ();
15680 : 12963 : ExitStack = M2StackWord_InitStackWord ();
15681 : 12963 : RepeatStack = M2StackWord_InitStackWord ();
15682 : 12963 : WhileStack = M2StackWord_InitStackWord ();
15683 : 12963 : ForStack = M2StackWord_InitStackWord ();
15684 : 12963 : WithStack = M2StackAddress_InitStackAddress ();
15685 : 12963 : ReturnStack = M2StackWord_InitStackWord ();
15686 : 12963 : LineStack = M2StackAddress_InitStackAddress ();
15687 : 12963 : PriorityStack = M2StackWord_InitStackWord ();
15688 : 12963 : TryStack = M2StackWord_InitStackWord ();
15689 : 12963 : CatchStack = M2StackWord_InitStackWord ();
15690 : 12963 : ExceptStack = M2StackWord_InitStackWord ();
15691 : 12963 : ConstructorStack = M2StackAddress_InitStackAddress ();
15692 : 12963 : ConstParamStack = M2StackWord_InitStackWord ();
15693 : 12963 : ConstExprStack = M2StackWord_InitStackWord ();
15694 : : /* StressStack ; */
15695 : 12963 : SuppressWith = false;
15696 : 12963 : Head = 1;
15697 : 12963 : LastQuadNo = 0;
15698 : 12963 : MustNotCheckBounds = false;
15699 : 12963 : InitQuad = 0;
15700 : 12963 : GrowInitialization = 0;
15701 : 12963 : ForInfo = Indexing_InitIndex (1);
15702 : 12963 : QuadrupleGeneration = true;
15703 : 12963 : BuildingHigh = false;
15704 : 12963 : BuildingSize = false;
15705 : 12963 : AutoStack = M2StackWord_InitStackWord ();
15706 : 12963 : IsAutoOn = true;
15707 : 12963 : InConstExpression = false;
15708 : 12963 : InConstParameters = false;
15709 : 12963 : FreeLineList = NULL;
15710 : 12963 : Lists_InitList (&VarientFields);
15711 : 12963 : VarientFieldNo = 0;
15712 : 12963 : NoOfQuads = 0;
15713 : 12963 : }
15714 : :
15715 : :
15716 : : /*
15717 : : SetOptionCoding - builds a code quadruple if the profiling
15718 : : option was given to the compiler.
15719 : : */
15720 : :
15721 : 0 : extern "C" void M2Quads_SetOptionCoding (bool b)
15722 : : {
15723 : 0 : if (b != M2Options_Coding)
15724 : : {
15725 : 0 : if (b)
15726 : : {
15727 : 0 : M2Quads_BuildCodeOn ();
15728 : : }
15729 : : else
15730 : : {
15731 : 0 : M2Quads_BuildCodeOff ();
15732 : : }
15733 : 0 : M2Options_Coding = b;
15734 : : }
15735 : 0 : }
15736 : :
15737 : :
15738 : : /*
15739 : : SetOptionProfiling - builds a profile quadruple if the profiling
15740 : : option was given to the compiler.
15741 : : */
15742 : :
15743 : 0 : extern "C" void M2Quads_SetOptionProfiling (bool b)
15744 : : {
15745 : 0 : if (b != M2Options_Profiling)
15746 : : {
15747 : 0 : if (b)
15748 : : {
15749 : 0 : M2Quads_BuildProfileOn ();
15750 : : }
15751 : : else
15752 : : {
15753 : 0 : M2Quads_BuildProfileOff ();
15754 : : }
15755 : 0 : M2Options_Profiling = b;
15756 : : }
15757 : 0 : }
15758 : :
15759 : :
15760 : : /*
15761 : : SetOptionOptimizing - builds a quadruple to say that the optimization option
15762 : : has been found in a comment.
15763 : : */
15764 : :
15765 : 0 : extern "C" void M2Quads_SetOptionOptimizing (bool b)
15766 : : {
15767 : 0 : if (b)
15768 : : {
15769 : 0 : M2Quads_BuildOptimizeOn ();
15770 : : }
15771 : : else
15772 : : {
15773 : 0 : M2Quads_BuildOptimizeOff ();
15774 : : }
15775 : 0 : }
15776 : :
15777 : :
15778 : : /*
15779 : : Opposite - returns the opposite comparison operator.
15780 : : */
15781 : :
15782 : 60074 : extern "C" M2Quads_QuadOperator M2Quads_Opposite (M2Quads_QuadOperator Operator)
15783 : : {
15784 : 60074 : M2Quads_QuadOperator Op;
15785 : :
15786 : 60074 : switch (Operator)
15787 : : {
15788 : : case M2Quads_IfNotEquOp:
15789 : : Op = M2Quads_IfEquOp;
15790 : : break;
15791 : :
15792 : : case M2Quads_IfEquOp:
15793 : : Op = M2Quads_IfNotEquOp;
15794 : : break;
15795 : :
15796 : : case M2Quads_IfLessEquOp:
15797 : : Op = M2Quads_IfGreOp;
15798 : : break;
15799 : :
15800 : : case M2Quads_IfGreOp:
15801 : : Op = M2Quads_IfLessEquOp;
15802 : : break;
15803 : :
15804 : : case M2Quads_IfGreEquOp:
15805 : : Op = M2Quads_IfLessOp;
15806 : : break;
15807 : :
15808 : : case M2Quads_IfLessOp:
15809 : : Op = M2Quads_IfGreEquOp;
15810 : : break;
15811 : :
15812 : : case M2Quads_IfInOp:
15813 : : Op = M2Quads_IfNotInOp;
15814 : : break;
15815 : :
15816 : : case M2Quads_IfNotInOp:
15817 : : Op = M2Quads_IfInOp;
15818 : : break;
15819 : :
15820 : :
15821 : 0 : default:
15822 : 0 : M2Error_InternalError ((const char *) "unexpected operator", 19);
15823 : 60074 : break;
15824 : : }
15825 : 60074 : return Op;
15826 : : /* static analysis guarentees a RETURN statement will be used before here. */
15827 : : __builtin_unreachable ();
15828 : : }
15829 : :
15830 : :
15831 : : /*
15832 : : IsReferenced - returns true if QuadNo is referenced by another quadruple.
15833 : : */
15834 : :
15835 : 27421129 : extern "C" bool M2Quads_IsReferenced (unsigned int QuadNo)
15836 : : {
15837 : 27421129 : M2Quads_QuadFrame f;
15838 : :
15839 : 27421129 : f = GetQF (QuadNo);
15840 : 27421129 : return ((f->Operator == M2Quads_ProcedureScopeOp) || (f->Operator == M2Quads_NewLocalVarOp)) || (f->NoOfTimesReferenced > 0);
15841 : : /* static analysis guarentees a RETURN statement will be used before here. */
15842 : : __builtin_unreachable ();
15843 : : }
15844 : :
15845 : :
15846 : : /*
15847 : : IsBackReference - returns TRUE if quadruple, q, is referenced from a quad further on.
15848 : : */
15849 : :
15850 : 5765 : extern "C" bool M2Quads_IsBackReference (unsigned int q)
15851 : : {
15852 : 5765 : unsigned int i;
15853 : 5765 : M2Quads_QuadOperator op;
15854 : 5765 : unsigned int op1;
15855 : 5765 : unsigned int op2;
15856 : 5765 : unsigned int op3;
15857 : :
15858 : 5765 : i = q;
15859 : 11186 : while (i != 0)
15860 : : {
15861 : 11186 : M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
15862 : 11186 : switch (op)
15863 : : {
15864 : : case M2Quads_NewLocalVarOp:
15865 : : case M2Quads_KillLocalVarOp:
15866 : : case M2Quads_FinallyStartOp:
15867 : : case M2Quads_FinallyEndOp:
15868 : : case M2Quads_InitEndOp:
15869 : : case M2Quads_InitStartOp:
15870 : : case M2Quads_EndFileOp:
15871 : : case M2Quads_StartDefFileOp:
15872 : : case M2Quads_StartModFileOp:
15873 : : return false; /* run into end of procedure or module */
15874 : 60 : break;
15875 : :
15876 : 60 : case M2Quads_GotoOp:
15877 : 60 : case M2Quads_IfEquOp:
15878 : 60 : case M2Quads_IfLessEquOp:
15879 : 60 : case M2Quads_IfGreEquOp:
15880 : 60 : case M2Quads_IfGreOp:
15881 : 60 : case M2Quads_IfLessOp:
15882 : 60 : case M2Quads_IfNotEquOp:
15883 : 60 : case M2Quads_IfInOp:
15884 : 60 : case M2Quads_IfNotInOp:
15885 : 60 : if (op3 == q) /* run into end of procedure or module */
15886 : : {
15887 : : return true;
15888 : : }
15889 : : break;
15890 : :
15891 : :
15892 : : default:
15893 : : break;
15894 : : }
15895 : 5421 : i = M2Quads_GetNextQuad (i);
15896 : : }
15897 : 0 : M2Error_InternalError ((const char *) "fix this for the sake of efficiency..", 37);
15898 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
15899 : : __builtin_unreachable ();
15900 : : }
15901 : :
15902 : :
15903 : : /*
15904 : : IsUnConditional - returns true if QuadNo is an unconditional jump.
15905 : : */
15906 : :
15907 : 29467648 : extern "C" bool M2Quads_IsUnConditional (unsigned int QuadNo)
15908 : : {
15909 : 29467648 : M2Quads_QuadFrame f;
15910 : :
15911 : 29467648 : f = GetQF (QuadNo);
15912 : 29467648 : switch (f->Operator)
15913 : : {
15914 : : case M2Quads_ThrowOp:
15915 : : case M2Quads_RetryOp:
15916 : : case M2Quads_CallOp:
15917 : : case M2Quads_ReturnOp:
15918 : : case M2Quads_GotoOp:
15919 : : return true;
15920 : 26795149 : break;
15921 : :
15922 : :
15923 : 26795149 : default:
15924 : 26795149 : return false;
15925 : : break;
15926 : : }
15927 : : /* static analysis guarentees a RETURN statement will be used before here. */
15928 : : __builtin_unreachable ();
15929 : : }
15930 : :
15931 : :
15932 : : /*
15933 : : IsConditional - returns true if QuadNo is a conditional jump.
15934 : : */
15935 : :
15936 : 29476851 : extern "C" bool M2Quads_IsConditional (unsigned int QuadNo)
15937 : : {
15938 : 29476851 : M2Quads_QuadFrame f;
15939 : :
15940 : 29476851 : f = GetQF (QuadNo);
15941 : 29476851 : switch (f->Operator)
15942 : : {
15943 : : case M2Quads_IfInOp:
15944 : : case M2Quads_IfNotInOp:
15945 : : case M2Quads_IfEquOp:
15946 : : case M2Quads_IfNotEquOp:
15947 : : case M2Quads_IfLessOp:
15948 : : case M2Quads_IfLessEquOp:
15949 : : case M2Quads_IfGreOp:
15950 : : case M2Quads_IfGreEquOp:
15951 : : return true;
15952 : 28873805 : break;
15953 : :
15954 : :
15955 : 28873805 : default:
15956 : 28873805 : return false;
15957 : : break;
15958 : : }
15959 : : /* static analysis guarentees a RETURN statement will be used before here. */
15960 : : __builtin_unreachable ();
15961 : : }
15962 : :
15963 : :
15964 : : /*
15965 : : IsBackReferenceConditional - returns TRUE if quadruple, q, is referenced from
15966 : : a conditional quad further on.
15967 : : */
15968 : :
15969 : 0 : extern "C" bool M2Quads_IsBackReferenceConditional (unsigned int q)
15970 : : {
15971 : 0 : unsigned int i;
15972 : 0 : M2Quads_QuadOperator op;
15973 : 0 : unsigned int op1;
15974 : 0 : unsigned int op2;
15975 : 0 : unsigned int op3;
15976 : :
15977 : 0 : i = q;
15978 : 0 : while (i != 0)
15979 : : {
15980 : 0 : M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
15981 : 0 : switch (op)
15982 : : {
15983 : : case M2Quads_NewLocalVarOp:
15984 : : case M2Quads_KillLocalVarOp:
15985 : : case M2Quads_FinallyStartOp:
15986 : : case M2Quads_FinallyEndOp:
15987 : : case M2Quads_InitEndOp:
15988 : : case M2Quads_InitStartOp:
15989 : : case M2Quads_EndFileOp:
15990 : : case M2Quads_StartDefFileOp:
15991 : : case M2Quads_StartModFileOp:
15992 : : return false; /* run into end of procedure or module */
15993 : 0 : break;
15994 : :
15995 : 0 : case M2Quads_TryOp:
15996 : 0 : case M2Quads_RetryOp:
15997 : 0 : case M2Quads_GotoOp:
15998 : 0 : case M2Quads_IfEquOp:
15999 : 0 : case M2Quads_IfLessEquOp:
16000 : 0 : case M2Quads_IfGreEquOp:
16001 : 0 : case M2Quads_IfGreOp:
16002 : 0 : case M2Quads_IfLessOp:
16003 : 0 : case M2Quads_IfNotEquOp:
16004 : 0 : case M2Quads_IfInOp:
16005 : 0 : case M2Quads_IfNotInOp:
16006 : 0 : if ((op3 == q) && (M2Quads_IsConditional (q))) /* run into end of procedure or module */
16007 : : {
16008 : : return true;
16009 : : }
16010 : 0 : break;
16011 : :
16012 : :
16013 : : default:
16014 : : return false;
16015 : 0 : break;
16016 : : }
16017 : 0 : i = M2Quads_GetNextQuad (i);
16018 : : }
16019 : 0 : M2Error_InternalError ((const char *) "fix this for the sake of efficiency..", 37);
16020 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
16021 : : __builtin_unreachable ();
16022 : : }
16023 : :
16024 : :
16025 : : /*
16026 : : IsGoto - returns true if QuadNo is a goto operation.
16027 : : */
16028 : :
16029 : 5837 : extern "C" bool M2Quads_IsGoto (unsigned int QuadNo)
16030 : : {
16031 : 5837 : return IsQuadA (QuadNo, M2Quads_GotoOp);
16032 : : /* static analysis guarentees a RETURN statement will be used before here. */
16033 : : __builtin_unreachable ();
16034 : : }
16035 : :
16036 : :
16037 : : /*
16038 : : IsCall - returns true if QuadNo is a call operation.
16039 : : */
16040 : :
16041 : 29473413 : extern "C" bool M2Quads_IsCall (unsigned int QuadNo)
16042 : : {
16043 : 29473413 : return IsQuadA (QuadNo, M2Quads_CallOp);
16044 : : /* static analysis guarentees a RETURN statement will be used before here. */
16045 : : __builtin_unreachable ();
16046 : : }
16047 : :
16048 : :
16049 : : /*
16050 : : IsReturn - returns true if QuadNo is a return operation.
16051 : : */
16052 : :
16053 : 29541290 : extern "C" bool M2Quads_IsReturn (unsigned int QuadNo)
16054 : : {
16055 : 29541290 : return IsQuadA (QuadNo, M2Quads_ReturnOp);
16056 : : /* static analysis guarentees a RETURN statement will be used before here. */
16057 : : __builtin_unreachable ();
16058 : : }
16059 : :
16060 : :
16061 : : /*
16062 : : IsProcedureScope - returns true if QuadNo is a ProcedureScope operation.
16063 : : */
16064 : :
16065 : 0 : extern "C" bool M2Quads_IsProcedureScope (unsigned int QuadNo)
16066 : : {
16067 : 0 : return IsQuadA (QuadNo, M2Quads_ProcedureScopeOp);
16068 : : /* static analysis guarentees a RETURN statement will be used before here. */
16069 : : __builtin_unreachable ();
16070 : : }
16071 : :
16072 : :
16073 : : /*
16074 : : IsNewLocalVar - returns true if QuadNo is a NewLocalVar operation.
16075 : : */
16076 : :
16077 : 0 : extern "C" bool M2Quads_IsNewLocalVar (unsigned int QuadNo)
16078 : : {
16079 : 0 : return IsQuadA (QuadNo, M2Quads_NewLocalVarOp);
16080 : : /* static analysis guarentees a RETURN statement will be used before here. */
16081 : : __builtin_unreachable ();
16082 : : }
16083 : :
16084 : :
16085 : : /*
16086 : : IsKillLocalVar - returns true if QuadNo is a KillLocalVar operation.
16087 : : */
16088 : :
16089 : 71451 : extern "C" bool M2Quads_IsKillLocalVar (unsigned int QuadNo)
16090 : : {
16091 : 71451 : return IsQuadA (QuadNo, M2Quads_KillLocalVarOp);
16092 : : /* static analysis guarentees a RETURN statement will be used before here. */
16093 : : __builtin_unreachable ();
16094 : : }
16095 : :
16096 : :
16097 : : /*
16098 : : IsCatchBegin - returns true if QuadNo is a catch begin quad.
16099 : : */
16100 : :
16101 : 61791 : extern "C" bool M2Quads_IsCatchBegin (unsigned int QuadNo)
16102 : : {
16103 : 61791 : return IsQuadA (QuadNo, M2Quads_CatchBeginOp);
16104 : : /* static analysis guarentees a RETURN statement will be used before here. */
16105 : : __builtin_unreachable ();
16106 : : }
16107 : :
16108 : :
16109 : : /*
16110 : : IsCatchEnd - returns true if QuadNo is a catch end quad.
16111 : : */
16112 : :
16113 : 63495 : extern "C" bool M2Quads_IsCatchEnd (unsigned int QuadNo)
16114 : : {
16115 : 63495 : return IsQuadA (QuadNo, M2Quads_CatchEndOp);
16116 : : /* static analysis guarentees a RETURN statement will be used before here. */
16117 : : __builtin_unreachable ();
16118 : : }
16119 : :
16120 : :
16121 : : /*
16122 : : IsInitStart - returns true if QuadNo is a init start quad.
16123 : : */
16124 : :
16125 : 61791 : extern "C" bool M2Quads_IsInitStart (unsigned int QuadNo)
16126 : : {
16127 : 61791 : return IsQuadA (QuadNo, M2Quads_InitStartOp);
16128 : : /* static analysis guarentees a RETURN statement will be used before here. */
16129 : : __builtin_unreachable ();
16130 : : }
16131 : :
16132 : :
16133 : : /*
16134 : : IsInitEnd - returns true if QuadNo is a init end quad.
16135 : : */
16136 : :
16137 : 61791 : extern "C" bool M2Quads_IsInitEnd (unsigned int QuadNo)
16138 : : {
16139 : 61791 : return IsQuadA (QuadNo, M2Quads_InitEndOp);
16140 : : /* static analysis guarentees a RETURN statement will be used before here. */
16141 : : __builtin_unreachable ();
16142 : : }
16143 : :
16144 : :
16145 : : /*
16146 : : IsFinallyStart - returns true if QuadNo is a finally start quad.
16147 : : */
16148 : :
16149 : 61359 : extern "C" bool M2Quads_IsFinallyStart (unsigned int QuadNo)
16150 : : {
16151 : 61359 : return IsQuadA (QuadNo, M2Quads_FinallyStartOp);
16152 : : /* static analysis guarentees a RETURN statement will be used before here. */
16153 : : __builtin_unreachable ();
16154 : : }
16155 : :
16156 : :
16157 : : /*
16158 : : IsFinallyEnd - returns true if QuadNo is a finally end quad.
16159 : : */
16160 : :
16161 : 60927 : extern "C" bool M2Quads_IsFinallyEnd (unsigned int QuadNo)
16162 : : {
16163 : 60927 : return IsQuadA (QuadNo, M2Quads_FinallyEndOp);
16164 : : /* static analysis guarentees a RETURN statement will be used before here. */
16165 : : __builtin_unreachable ();
16166 : : }
16167 : :
16168 : :
16169 : : /*
16170 : : IsBecomes - return TRUE if QuadNo is a BecomesOp.
16171 : : */
16172 : :
16173 : 72 : extern "C" bool M2Quads_IsBecomes (unsigned int QuadNo)
16174 : : {
16175 : 72 : return IsQuadA (QuadNo, M2Quads_BecomesOp);
16176 : : /* static analysis guarentees a RETURN statement will be used before here. */
16177 : : __builtin_unreachable ();
16178 : : }
16179 : :
16180 : :
16181 : : /*
16182 : : IsDummy - return TRUE if QuadNo is a DummyOp.
16183 : : */
16184 : :
16185 : 0 : extern "C" bool M2Quads_IsDummy (unsigned int QuadNo)
16186 : : {
16187 : 0 : return IsQuadA (QuadNo, M2Quads_DummyOp);
16188 : : /* static analysis guarentees a RETURN statement will be used before here. */
16189 : : __builtin_unreachable ();
16190 : : }
16191 : :
16192 : :
16193 : : /*
16194 : : IsQuadConstExpr - returns TRUE if QuadNo is part of a constant expression.
16195 : : */
16196 : :
16197 : 232282 : extern "C" bool M2Quads_IsQuadConstExpr (unsigned int QuadNo)
16198 : : {
16199 : 232282 : M2Quads_QuadFrame f;
16200 : :
16201 : 232282 : f = GetQF (QuadNo);
16202 : 232282 : return f->ConstExpr;
16203 : : /* static analysis guarentees a RETURN statement will be used before here. */
16204 : : __builtin_unreachable ();
16205 : : }
16206 : :
16207 : :
16208 : : /*
16209 : : SetQuadConstExpr - sets the constexpr field to value.
16210 : : */
16211 : :
16212 : 36 : extern "C" void M2Quads_SetQuadConstExpr (unsigned int QuadNo, bool value)
16213 : : {
16214 : 36 : M2Quads_QuadFrame f;
16215 : :
16216 : 36 : f = GetQF (QuadNo);
16217 : 36 : f->ConstExpr = value;
16218 : 36 : }
16219 : :
16220 : :
16221 : : /*
16222 : : GetQuadDest - returns the jump destination associated with quad.
16223 : : */
16224 : :
16225 : 108 : extern "C" unsigned int M2Quads_GetQuadDest (unsigned int QuadNo)
16226 : : {
16227 : 108 : return M2Quads_GetQuadOp3 (QuadNo);
16228 : : /* static analysis guarentees a RETURN statement will be used before here. */
16229 : : __builtin_unreachable ();
16230 : : }
16231 : :
16232 : :
16233 : : /*
16234 : : GetQuadOp1 - returns the 1st operand associated with quad.
16235 : : */
16236 : :
16237 : 108 : extern "C" unsigned int M2Quads_GetQuadOp1 (unsigned int QuadNo)
16238 : : {
16239 : 108 : M2Quads_QuadFrame f;
16240 : :
16241 : 108 : f = GetQF (QuadNo);
16242 : 108 : return f->Operand1;
16243 : : /* static analysis guarentees a RETURN statement will be used before here. */
16244 : : __builtin_unreachable ();
16245 : : }
16246 : :
16247 : :
16248 : : /*
16249 : : GetQuadOp2 - returns the 2nd operand associated with quad.
16250 : : */
16251 : :
16252 : 0 : extern "C" unsigned int M2Quads_GetQuadOp2 (unsigned int QuadNo)
16253 : : {
16254 : 0 : M2Quads_QuadFrame f;
16255 : :
16256 : 0 : f = GetQF (QuadNo);
16257 : 0 : return f->Operand2;
16258 : : /* static analysis guarentees a RETURN statement will be used before here. */
16259 : : __builtin_unreachable ();
16260 : : }
16261 : :
16262 : :
16263 : : /*
16264 : : GetQuadOp3 - returns the 3rd operand associated with quad.
16265 : : */
16266 : :
16267 : 108 : extern "C" unsigned int M2Quads_GetQuadOp3 (unsigned int QuadNo)
16268 : : {
16269 : 108 : M2Quads_QuadFrame f;
16270 : :
16271 : 108 : f = GetQF (QuadNo);
16272 : 108 : return f->Operand3;
16273 : : /* static analysis guarentees a RETURN statement will be used before here. */
16274 : : __builtin_unreachable ();
16275 : : }
16276 : :
16277 : :
16278 : : /*
16279 : : IsInitialisingConst - returns TRUE if the quadruple is setting
16280 : : a const (op1) with a value.
16281 : : */
16282 : :
16283 : 60495 : extern "C" bool M2Quads_IsInitialisingConst (unsigned int QuadNo)
16284 : : {
16285 : 60495 : M2Quads_QuadOperator op;
16286 : 60495 : unsigned int op1;
16287 : 60495 : unsigned int op2;
16288 : 60495 : unsigned int op3;
16289 : :
16290 : 60495 : M2Quads_GetQuad (QuadNo, &op, &op1, &op2, &op3);
16291 : 60495 : switch (op)
16292 : : {
16293 : 6292 : case M2Quads_StringConvertCnulOp:
16294 : 6292 : case M2Quads_StringConvertM2nulOp:
16295 : 6292 : case M2Quads_StringLengthOp:
16296 : 6292 : case M2Quads_InclOp:
16297 : 6292 : case M2Quads_ExclOp:
16298 : 6292 : case M2Quads_UnboundedOp:
16299 : 6292 : case M2Quads_FunctValueOp:
16300 : 6292 : case M2Quads_NegateOp:
16301 : 6292 : case M2Quads_BecomesOp:
16302 : 6292 : case M2Quads_HighOp:
16303 : 6292 : case M2Quads_SizeOp:
16304 : 6292 : case M2Quads_AddrOp:
16305 : 6292 : case M2Quads_RecordFieldOp:
16306 : 6292 : case M2Quads_ArrayOp:
16307 : 6292 : case M2Quads_LogicalShiftOp:
16308 : 6292 : case M2Quads_LogicalRotateOp:
16309 : 6292 : case M2Quads_LogicalOrOp:
16310 : 6292 : case M2Quads_LogicalAndOp:
16311 : 6292 : case M2Quads_LogicalXorOp:
16312 : 6292 : case M2Quads_CoerceOp:
16313 : 6292 : case M2Quads_ConvertOp:
16314 : 6292 : case M2Quads_CastOp:
16315 : 6292 : case M2Quads_AddOp:
16316 : 6292 : case M2Quads_SubOp:
16317 : 6292 : case M2Quads_MultOp:
16318 : 6292 : case M2Quads_ModFloorOp:
16319 : 6292 : case M2Quads_DivCeilOp:
16320 : 6292 : case M2Quads_ModCeilOp:
16321 : 6292 : case M2Quads_DivFloorOp:
16322 : 6292 : case M2Quads_ModTruncOp:
16323 : 6292 : case M2Quads_DivTruncOp:
16324 : 6292 : case M2Quads_DivM2Op:
16325 : 6292 : case M2Quads_ModM2Op:
16326 : 6292 : case M2Quads_XIndrOp:
16327 : 6292 : case M2Quads_IndrXOp:
16328 : 6292 : case M2Quads_SaveExceptionOp:
16329 : 6292 : case M2Quads_RestoreExceptionOp:
16330 : 6292 : return SymbolTable_IsConst (op1);
16331 : : break;
16332 : :
16333 : :
16334 : : default:
16335 : : return false;
16336 : : break;
16337 : : }
16338 : : /* static analysis guarentees a RETURN statement will be used before here. */
16339 : : __builtin_unreachable ();
16340 : : }
16341 : :
16342 : :
16343 : : /*
16344 : : IsOptimizeOn - returns true if the Optimize flag was true at QuadNo.
16345 : : */
16346 : :
16347 : 0 : extern "C" bool M2Quads_IsOptimizeOn (unsigned int QuadNo)
16348 : : {
16349 : 0 : M2Quads_QuadFrame f;
16350 : 0 : unsigned int n;
16351 : 0 : unsigned int q;
16352 : 0 : bool On;
16353 : :
16354 : 0 : On = M2Options_Optimizing;
16355 : 0 : q = Head;
16356 : 0 : while ((q != 0) && (q != QuadNo))
16357 : : {
16358 : 0 : f = GetQF (q);
16359 : 0 : if (f->Operator == M2Quads_OptimizeOnOp)
16360 : : {
16361 : : On = true;
16362 : : }
16363 : 0 : else if (f->Operator == M2Quads_OptimizeOffOp)
16364 : : {
16365 : : /* avoid dangling else. */
16366 : 0 : On = false;
16367 : : }
16368 : 0 : n = f->Next;
16369 : 0 : q = n;
16370 : : }
16371 : 0 : return On;
16372 : : /* static analysis guarentees a RETURN statement will be used before here. */
16373 : : __builtin_unreachable ();
16374 : : }
16375 : :
16376 : :
16377 : : /*
16378 : : IsProfileOn - returns true if the Profile flag was true at QuadNo.
16379 : : */
16380 : :
16381 : 0 : extern "C" bool M2Quads_IsProfileOn (unsigned int QuadNo)
16382 : : {
16383 : 0 : M2Quads_QuadFrame f;
16384 : 0 : unsigned int n;
16385 : 0 : unsigned int q;
16386 : 0 : bool On;
16387 : :
16388 : 0 : On = M2Options_Profiling;
16389 : 0 : q = Head;
16390 : 0 : while ((q != 0) && (q != QuadNo))
16391 : : {
16392 : 0 : f = GetQF (q);
16393 : 0 : if (f->Operator == M2Quads_ProfileOnOp)
16394 : : {
16395 : : On = true;
16396 : : }
16397 : 0 : else if (f->Operator == M2Quads_ProfileOffOp)
16398 : : {
16399 : : /* avoid dangling else. */
16400 : 0 : On = false;
16401 : : }
16402 : 0 : n = f->Next;
16403 : 0 : q = n;
16404 : : }
16405 : 0 : return On;
16406 : : /* static analysis guarentees a RETURN statement will be used before here. */
16407 : : __builtin_unreachable ();
16408 : : }
16409 : :
16410 : :
16411 : : /*
16412 : : IsCodeOn - returns true if the Code flag was true at QuadNo.
16413 : : */
16414 : :
16415 : 0 : extern "C" bool M2Quads_IsCodeOn (unsigned int QuadNo)
16416 : : {
16417 : 0 : M2Quads_QuadFrame f;
16418 : 0 : unsigned int n;
16419 : 0 : unsigned int q;
16420 : 0 : bool On;
16421 : :
16422 : 0 : On = M2Options_Coding;
16423 : 0 : q = Head;
16424 : 0 : while ((q != 0) && (q != QuadNo))
16425 : : {
16426 : 0 : f = GetQF (q);
16427 : 0 : if (f->Operator == M2Quads_CodeOnOp)
16428 : : {
16429 : : On = true;
16430 : : }
16431 : 0 : else if (f->Operator == M2Quads_CodeOffOp)
16432 : : {
16433 : : /* avoid dangling else. */
16434 : 0 : On = false;
16435 : : }
16436 : 0 : n = f->Next;
16437 : 0 : q = n;
16438 : : }
16439 : 0 : return On;
16440 : : /* static analysis guarentees a RETURN statement will be used before here. */
16441 : : __builtin_unreachable ();
16442 : : }
16443 : :
16444 : :
16445 : : /*
16446 : : IsPseudoQuad - returns true if QuadNo is a compiler directive.
16447 : : ie code, profile and optimize.
16448 : : StartFile, EndFile,
16449 : : */
16450 : :
16451 : 16618672 : extern "C" bool M2Quads_IsPseudoQuad (unsigned int QuadNo)
16452 : : {
16453 : 16618672 : M2Quads_QuadFrame f;
16454 : :
16455 : 16618672 : f = GetQF (QuadNo);
16456 : 16618672 : 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);
16457 : : /* static analysis guarentees a RETURN statement will be used before here. */
16458 : : __builtin_unreachable ();
16459 : : }
16460 : :
16461 : :
16462 : : /*
16463 : : IsDefOrModFile - returns TRUE if QuadNo is a start of Module or Def file
16464 : : directive.
16465 : : */
16466 : :
16467 : 29467648 : extern "C" bool M2Quads_IsDefOrModFile (unsigned int QuadNo)
16468 : : {
16469 : 29467648 : M2Quads_QuadFrame f;
16470 : :
16471 : 29467648 : f = GetQF (QuadNo);
16472 : 29467648 : return (f->Operator == M2Quads_StartDefFileOp) || (f->Operator == M2Quads_StartModFileOp);
16473 : : /* static analysis guarentees a RETURN statement will be used before here. */
16474 : : __builtin_unreachable ();
16475 : : }
16476 : :
16477 : :
16478 : : /*
16479 : : DumpQuadruples - dump all quadruples providing the -fq, -fdump-lang-quad,
16480 : : -fdump-lang-quad= or -fdump-lang-all were issued to the
16481 : : command line.
16482 : : */
16483 : :
16484 : 62144 : extern "C" void M2Quads_DumpQuadruples (const char *title_, unsigned int _title_high)
16485 : : {
16486 : 62144 : char title[_title_high+1];
16487 : :
16488 : : /* make a local copy of each unbounded array. */
16489 : 62144 : memcpy (title, title_, _title_high+1);
16490 : :
16491 : 62144 : if (M2Options_DumpLangQuad)
16492 : : {
16493 : 0 : M2LangDump_CreateDumpQuad ((const char *) title, _title_high);
16494 : 0 : if ((M2Options_GetM2DumpFilter ()) == NULL)
16495 : : {
16496 : 0 : DumpQuadrupleAll ();
16497 : : }
16498 : : else
16499 : : {
16500 : 0 : DumpQuadrupleFilter ();
16501 : : }
16502 : 0 : M2LangDump_CloseDumpQuad ();
16503 : : }
16504 : 62144 : }
16505 : :
16506 : :
16507 : : /*
16508 : : DisplayQuadRange - displays all quads in list range, start..end.
16509 : : */
16510 : :
16511 : 0 : extern "C" void M2Quads_DisplayQuadRange (unsigned int scope, unsigned int start, unsigned int end)
16512 : : {
16513 : 0 : M2Quads_QuadFrame f;
16514 : :
16515 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "Quadruples for scope: %d\\n", 26, (const unsigned char *) &scope, (sizeof (scope)-1));
16516 : 0 : while ((start <= end) && (start != 0))
16517 : : {
16518 : 0 : M2Quads_DisplayQuad (start);
16519 : 0 : f = GetQF (start);
16520 : 0 : start = f->Next;
16521 : : }
16522 : 0 : }
16523 : :
16524 : :
16525 : : /*
16526 : : DisplayQuad - displays a quadruple, QuadNo.
16527 : : */
16528 : :
16529 : 0 : extern "C" void M2Quads_DisplayQuad (unsigned int QuadNo)
16530 : : {
16531 : 0 : DSdbEnter ();
16532 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d ", 5, (const unsigned char *) &QuadNo, (sizeof (QuadNo)-1));
16533 : 0 : WriteQuad (QuadNo);
16534 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "\\n", 2);
16535 : 0 : DSdbExit ();
16536 : 0 : }
16537 : :
16538 : :
16539 : : /*
16540 : : GetLastFileQuad - returns the Quadruple number of the last StartDefFile or
16541 : : StartModFile quadruple.
16542 : : */
16543 : :
16544 : 0 : extern "C" unsigned int M2Quads_GetLastFileQuad (unsigned int QuadNo)
16545 : : {
16546 : 0 : M2Quads_QuadFrame f;
16547 : 0 : unsigned int q;
16548 : 0 : unsigned int i;
16549 : 0 : unsigned int FileQuad;
16550 : :
16551 : 0 : q = Head;
16552 : 0 : FileQuad = 0;
16553 : 0 : do {
16554 : 0 : f = GetQF (q);
16555 : 0 : if ((f->Operator == M2Quads_StartModFileOp) || (f->Operator == M2Quads_StartDefFileOp))
16556 : : {
16557 : 0 : FileQuad = q;
16558 : : }
16559 : 0 : i = f->Next;
16560 : 0 : q = i;
16561 : 0 : } while (! ((i == QuadNo) || (i == 0)));
16562 : 0 : M2Debug_Assert (i != 0);
16563 : 0 : M2Debug_Assert (FileQuad != 0);
16564 : 0 : return FileQuad;
16565 : : /* static analysis guarentees a RETURN statement will be used before here. */
16566 : : __builtin_unreachable ();
16567 : : }
16568 : :
16569 : :
16570 : : /*
16571 : : GetLastQuadNo - returns the last quadruple number referenced
16572 : : by a GetQuad.
16573 : : */
16574 : :
16575 : 0 : extern "C" unsigned int M2Quads_GetLastQuadNo (void)
16576 : : {
16577 : 0 : return LastQuadNo;
16578 : : /* static analysis guarentees a RETURN statement will be used before here. */
16579 : : __builtin_unreachable ();
16580 : : }
16581 : :
16582 : :
16583 : : /*
16584 : : QuadToTokenNo - Converts a QuadNo into the approprate token number of the
16585 : : source file, the line number is returned.
16586 : :
16587 : : This may be used to yield an idea where abouts in the
16588 : : source file the code generetion is
16589 : : processing.
16590 : : */
16591 : :
16592 : 3820954 : extern "C" unsigned int M2Quads_QuadToTokenNo (unsigned int QuadNo)
16593 : : {
16594 : 3820954 : M2Quads_QuadFrame f;
16595 : :
16596 : 3820954 : if ((((LastQuadNo == 0) && (! (M2Pass_IsNoPass ()))) && (! (M2Pass_IsPassCodeGeneration ()))) || (! (Indexing_InBounds (QuadArray, QuadNo))))
16597 : : {
16598 : 0 : return 0;
16599 : : }
16600 : : else
16601 : : {
16602 : 3820954 : f = GetQF (QuadNo);
16603 : 3820954 : return f->TokenNo;
16604 : : }
16605 : : /* static analysis guarentees a RETURN statement will be used before here. */
16606 : : __builtin_unreachable ();
16607 : : }
16608 : :
16609 : :
16610 : : /*
16611 : : QuadToLineNo - Converts a QuadNo into the approprate line number of the
16612 : : source file, the line number is returned.
16613 : :
16614 : : This may be used to yield an idea where abouts in the
16615 : : source file the code generetion is
16616 : : processing.
16617 : : */
16618 : :
16619 : 0 : extern "C" unsigned int M2Quads_QuadToLineNo (unsigned int QuadNo)
16620 : : {
16621 : 0 : M2Quads_QuadFrame f;
16622 : :
16623 : 0 : if ((((LastQuadNo == 0) && (! (M2Pass_IsNoPass ()))) && (! (M2Pass_IsPassCodeGeneration ()))) || (! (Indexing_InBounds (QuadArray, QuadNo))))
16624 : : {
16625 : 0 : return 0;
16626 : : }
16627 : : else
16628 : : {
16629 : 0 : f = GetQF (QuadNo);
16630 : 0 : return f->LineNo;
16631 : : }
16632 : : /* static analysis guarentees a RETURN statement will be used before here. */
16633 : : __builtin_unreachable ();
16634 : : }
16635 : :
16636 : :
16637 : : /*
16638 : : GetQuad - returns the Quadruple QuadNo.
16639 : : */
16640 : :
16641 : 69656909 : extern "C" void M2Quads_GetQuad (unsigned int QuadNo, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3)
16642 : : {
16643 : 69656909 : M2Quads_QuadFrame f;
16644 : :
16645 : 69656909 : f = GetQF (QuadNo);
16646 : 69656909 : LastQuadNo = QuadNo;
16647 : 69656909 : (*Op) = f->Operator;
16648 : 69656909 : (*Oper1) = f->Operand1;
16649 : 69656909 : (*Oper2) = f->Operand2;
16650 : 69656909 : (*Oper3) = f->Operand3;
16651 : 69656909 : }
16652 : :
16653 : :
16654 : : /*
16655 : : GetQuadOp - returns the operator for quad.
16656 : : */
16657 : :
16658 : 0 : extern "C" M2Quads_QuadOperator M2Quads_GetQuadOp (unsigned int quad)
16659 : : {
16660 : 0 : M2Quads_QuadFrame f;
16661 : :
16662 : 0 : f = GetQF (quad);
16663 : 0 : return f->Operator;
16664 : : /* static analysis guarentees a RETURN statement will be used before here. */
16665 : : __builtin_unreachable ();
16666 : : }
16667 : :
16668 : :
16669 : : /*
16670 : : GetM2OperatorDesc - returns the Modula-2 string associated with the quad operator
16671 : : (if possible). It returns NIL if no there is not an obvious match
16672 : : in Modula-2. It is assummed that the string will be used during
16673 : : construction of error messages and therefore keywords are
16674 : : wrapped with a format specifier.
16675 : : */
16676 : :
16677 : 1 : extern "C" DynamicStrings_String M2Quads_GetM2OperatorDesc (M2Quads_QuadOperator op)
16678 : : {
16679 : 1 : switch (op)
16680 : : {
16681 : 0 : case M2Quads_NegateOp:
16682 : 0 : return DynamicStrings_InitString ((const char *) "-", 1);
16683 : 0 : break;
16684 : :
16685 : 0 : case M2Quads_AddOp:
16686 : 0 : return DynamicStrings_InitString ((const char *) "+", 1);
16687 : 0 : break;
16688 : :
16689 : 0 : case M2Quads_SubOp:
16690 : 0 : return DynamicStrings_InitString ((const char *) "-", 1);
16691 : 0 : break;
16692 : :
16693 : 0 : case M2Quads_MultOp:
16694 : 0 : return DynamicStrings_InitString ((const char *) "*", 1);
16695 : 0 : break;
16696 : :
16697 : 0 : case M2Quads_DivM2Op:
16698 : 0 : case M2Quads_DivCeilOp:
16699 : 0 : case M2Quads_DivFloorOp:
16700 : 0 : case M2Quads_DivTruncOp:
16701 : 0 : return DynamicStrings_InitString ((const char *) "{%kDIV}", 7);
16702 : 0 : break;
16703 : :
16704 : 0 : case M2Quads_ModM2Op:
16705 : 0 : case M2Quads_ModCeilOp:
16706 : 0 : case M2Quads_ModFloorOp:
16707 : 0 : return DynamicStrings_InitString ((const char *) "{%kMOD}", 7);
16708 : 0 : break;
16709 : :
16710 : 0 : case M2Quads_ModTruncOp:
16711 : 0 : return DynamicStrings_InitString ((const char *) "{%kREM}", 7);
16712 : 0 : break;
16713 : :
16714 : 0 : case M2Quads_LogicalOrOp:
16715 : 0 : return DynamicStrings_InitString ((const char *) "{%kOR}", 6);
16716 : 0 : break;
16717 : :
16718 : 0 : case M2Quads_LogicalAndOp:
16719 : 0 : return DynamicStrings_InitString ((const char *) "{%kAND}", 7);
16720 : 0 : break;
16721 : :
16722 : 0 : case M2Quads_InclOp:
16723 : 0 : return DynamicStrings_InitString ((const char *) "{%kINCL}", 8);
16724 : 0 : break;
16725 : :
16726 : 0 : case M2Quads_ExclOp:
16727 : 0 : return DynamicStrings_InitString ((const char *) "{%kEXCL}", 8);
16728 : 1 : break;
16729 : :
16730 : 1 : case M2Quads_IfEquOp:
16731 : 1 : return DynamicStrings_InitString ((const char *) "=", 1);
16732 : 0 : break;
16733 : :
16734 : 0 : case M2Quads_IfLessEquOp:
16735 : 0 : return DynamicStrings_InitString ((const char *) "<=", 2);
16736 : 0 : break;
16737 : :
16738 : 0 : case M2Quads_IfGreEquOp:
16739 : 0 : return DynamicStrings_InitString ((const char *) ">=", 2);
16740 : 0 : break;
16741 : :
16742 : 0 : case M2Quads_IfGreOp:
16743 : 0 : return DynamicStrings_InitString ((const char *) ">", 1);
16744 : 0 : break;
16745 : :
16746 : 0 : case M2Quads_IfLessOp:
16747 : 0 : return DynamicStrings_InitString ((const char *) "<", 1);
16748 : 0 : break;
16749 : :
16750 : 0 : case M2Quads_IfNotEquOp:
16751 : 0 : return DynamicStrings_InitString ((const char *) "#", 1);
16752 : 0 : break;
16753 : :
16754 : 0 : case M2Quads_IfInOp:
16755 : 0 : return DynamicStrings_InitString ((const char *) "IN", 2);
16756 : 0 : break;
16757 : :
16758 : 0 : case M2Quads_IfNotInOp:
16759 : 0 : return DynamicStrings_InitString ((const char *) "NOT IN", 6);
16760 : : break;
16761 : :
16762 : :
16763 : : default:
16764 : : return static_cast<DynamicStrings_String> (NULL);
16765 : : break;
16766 : : }
16767 : : /* static analysis guarentees a RETURN statement will be used before here. */
16768 : : __builtin_unreachable ();
16769 : : }
16770 : :
16771 : :
16772 : : /*
16773 : : GetQuadtok - returns the Quadruple QuadNo.
16774 : : */
16775 : :
16776 : 25166905 : 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)
16777 : : {
16778 : 25166905 : M2Quads_QuadFrame f;
16779 : :
16780 : 25166905 : f = GetQF (QuadNo);
16781 : 25166905 : LastQuadNo = QuadNo;
16782 : 25166905 : (*Op) = f->Operator;
16783 : 25166905 : (*Oper1) = f->Operand1;
16784 : 25166905 : (*Oper2) = f->Operand2;
16785 : 25166905 : (*Oper3) = f->Operand3;
16786 : 25166905 : (*Op1Pos) = f->op1pos;
16787 : 25166905 : (*Op2Pos) = f->op2pos;
16788 : 25166905 : (*Op3Pos) = f->op3pos;
16789 : 25166905 : }
16790 : :
16791 : :
16792 : : /*
16793 : : GetQuadOtok - returns the Quadruple QuadNo.
16794 : : */
16795 : :
16796 : 2939840 : 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)
16797 : : {
16798 : 2939840 : M2Quads_QuadFrame f;
16799 : :
16800 : 2939840 : f = GetQF (QuadNo);
16801 : 2939840 : LastQuadNo = QuadNo;
16802 : 2939840 : (*Op) = f->Operator;
16803 : 2939840 : (*Oper1) = f->Operand1;
16804 : 2939840 : (*Oper2) = f->Operand2;
16805 : 2939840 : (*Oper3) = f->Operand3;
16806 : 2939840 : (*Op1Pos) = f->op1pos;
16807 : 2939840 : (*Op2Pos) = f->op2pos;
16808 : 2939840 : (*Op3Pos) = f->op3pos;
16809 : 2939840 : (*tok) = f->TokenNo;
16810 : 2939840 : (*overflowChecking) = f->CheckOverflow;
16811 : 2939840 : (*constExpr) = f->ConstExpr;
16812 : 2939840 : }
16813 : :
16814 : :
16815 : : /*
16816 : : GetQuadOTypetok - returns the fields associated with quadruple QuadNo.
16817 : : */
16818 : :
16819 : 17962 : 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)
16820 : : {
16821 : 17962 : M2Quads_QuadFrame f;
16822 : :
16823 : 17962 : f = GetQF (QuadNo);
16824 : 17962 : LastQuadNo = QuadNo;
16825 : 17962 : (*Op) = f->Operator;
16826 : 17962 : (*Oper1) = f->Operand1;
16827 : 17962 : (*Oper2) = f->Operand2;
16828 : 17962 : (*Oper3) = f->Operand3;
16829 : 17962 : (*Op1Pos) = f->op1pos;
16830 : 17962 : (*Op2Pos) = f->op2pos;
16831 : 17962 : (*Op3Pos) = f->op3pos;
16832 : 17962 : (*tok) = f->TokenNo;
16833 : 17962 : (*overflowChecking) = f->CheckOverflow;
16834 : 17962 : (*typeChecking) = f->CheckType;
16835 : 17962 : (*constExpr) = f->ConstExpr;
16836 : 17962 : }
16837 : :
16838 : :
16839 : : /*
16840 : : PutQuadOtok - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
16841 : : sets a boolean to determinine whether overflow should be checked.
16842 : : */
16843 : :
16844 : 60073 : 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)
16845 : : {
16846 : 60073 : M2Quads_QuadFrame f;
16847 : :
16848 : 60073 : if (QuadNo == BreakAtQuad)
16849 : : {
16850 : 60073 : stop ();
16851 : : }
16852 : 60073 : if (QuadrupleGeneration)
16853 : : {
16854 : 60073 : M2Quads_EraseQuad (QuadNo);
16855 : 60073 : AddQuadInformation (QuadNo, Op, Oper1, Oper2, Oper3);
16856 : 60073 : f = GetQF (QuadNo);
16857 : 60073 : f->Operator = Op;
16858 : 60073 : f->Operand1 = Oper1;
16859 : 60073 : f->Operand2 = Oper2;
16860 : 60073 : f->Operand3 = Oper3;
16861 : 60073 : f->CheckOverflow = overflowChecking;
16862 : 60073 : f->op1pos = Op1Pos;
16863 : 60073 : f->op2pos = Op2Pos;
16864 : 60073 : f->op3pos = Op3Pos;
16865 : 60073 : f->TokenNo = tok;
16866 : 60073 : f->ConstExpr = constExpr;
16867 : : }
16868 : 60073 : }
16869 : :
16870 : :
16871 : : /*
16872 : : PutQuad - overwrites a quadruple QuadNo with Op, Oper1, Oper2, Oper3
16873 : : */
16874 : :
16875 : 10475 : extern "C" void M2Quads_PutQuad (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
16876 : : {
16877 : 10475 : PutQuadO (QuadNo, Op, Oper1, Oper2, Oper3, true);
16878 : 10475 : }
16879 : :
16880 : :
16881 : : /*
16882 : : GetFirstQuad - returns the first quadruple.
16883 : : */
16884 : :
16885 : 64286 : extern "C" unsigned int M2Quads_GetFirstQuad (void)
16886 : : {
16887 : 64286 : return Head;
16888 : : /* static analysis guarentees a RETURN statement will be used before here. */
16889 : : __builtin_unreachable ();
16890 : : }
16891 : :
16892 : :
16893 : : /*
16894 : : GetNextQuad - returns the Quadruple number following QuadNo.
16895 : : */
16896 : :
16897 : 124692638 : extern "C" unsigned int M2Quads_GetNextQuad (unsigned int QuadNo)
16898 : : {
16899 : 124692638 : M2Quads_QuadFrame f;
16900 : :
16901 : 124692638 : f = GetQF (QuadNo);
16902 : 124692638 : return f->Next;
16903 : : /* static analysis guarentees a RETURN statement will be used before here. */
16904 : : __builtin_unreachable ();
16905 : : }
16906 : :
16907 : :
16908 : : /*
16909 : : GetRealQuad - returns the Quadruple number of the real quadruple
16910 : : at QuadNo or beyond.
16911 : : */
16912 : :
16913 : 11198173 : extern "C" unsigned int M2Quads_GetRealQuad (unsigned int QuadNo)
16914 : : {
16915 : 11198173 : M2Quads_QuadFrame f;
16916 : :
16917 : 16607169 : while (QuadNo != 0)
16918 : : {
16919 : 16607169 : if (Indexing_InBounds (QuadArray, QuadNo))
16920 : : {
16921 : 16550363 : f = GetQF (QuadNo);
16922 : 16550363 : if ((((! (M2Quads_IsPseudoQuad (QuadNo))) && (f->Operator != M2Quads_DummyOp)) && (f->Operator != M2Quads_LineNumberOp)) && (f->Operator != M2Quads_StatementNoteOp))
16923 : : {
16924 : 11141367 : return QuadNo;
16925 : : }
16926 : 5408996 : QuadNo += 1;
16927 : : }
16928 : : else
16929 : : {
16930 : : return 0;
16931 : : }
16932 : : }
16933 : : return 0;
16934 : : /* static analysis guarentees a RETURN statement will be used before here. */
16935 : : __builtin_unreachable ();
16936 : : }
16937 : :
16938 : :
16939 : : /*
16940 : : SubQuad - subtracts a quadruple QuadNo from a list Head.
16941 : : */
16942 : :
16943 : 1196741 : extern "C" void M2Quads_SubQuad (unsigned int QuadNo)
16944 : : {
16945 : 1196741 : unsigned int i;
16946 : 1196741 : M2Quads_QuadFrame f;
16947 : 1196741 : M2Quads_QuadFrame g;
16948 : :
16949 : 1196741 : f = GetQF (QuadNo);
16950 : 1196741 : AlterReference (Head, QuadNo, f->Next);
16951 : 1196741 : UndoReadWriteInfo (QuadNo, f->Operator, f->Operand1, f->Operand2, f->Operand3);
16952 : 1196741 : if (Head == QuadNo)
16953 : : {
16954 : 0 : Head = f->Next;
16955 : : }
16956 : : else
16957 : : {
16958 : 1196741 : i = Head;
16959 : 1196741 : g = GetQF (i);
16960 : 1476320395 : while (g->Next != QuadNo)
16961 : : {
16962 : 1473926913 : i = g->Next;
16963 : 1473926913 : g = GetQF (i);
16964 : : }
16965 : 1196741 : g->Next = f->Next;
16966 : : }
16967 : 1196741 : f->Operator = M2Quads_DummyOp;
16968 : 1196741 : NoOfQuads -= 1;
16969 : 1196741 : }
16970 : :
16971 : :
16972 : : /*
16973 : : EraseQuad - erases a quadruple QuadNo, the quadruple is still in the list
16974 : : but wiped clean.
16975 : : */
16976 : :
16977 : 4451839 : extern "C" void M2Quads_EraseQuad (unsigned int QuadNo)
16978 : : {
16979 : 4451839 : M2Quads_QuadFrame f;
16980 : :
16981 : 4451839 : f = GetQF (QuadNo);
16982 : 4451839 : UndoReadWriteInfo (QuadNo, f->Operator, f->Operand1, f->Operand2, f->Operand3);
16983 : 4451839 : f->Operator = M2Quads_DummyOp; /* finally blank it out */
16984 : 4451839 : f->Operand1 = 0; /* finally blank it out */
16985 : 4451839 : f->Operand2 = 0;
16986 : 4451839 : f->Operand3 = 0;
16987 : 4451839 : f->Trash = 0;
16988 : 4451839 : f->op1pos = M2LexBuf_UnknownTokenNo;
16989 : 4451839 : f->op2pos = M2LexBuf_UnknownTokenNo;
16990 : 4451839 : f->op3pos = M2LexBuf_UnknownTokenNo;
16991 : 4451839 : f->ConstExpr = false;
16992 : 4451839 : }
16993 : :
16994 : :
16995 : : /*
16996 : : CountQuads - returns the number of quadruples.
16997 : : */
16998 : :
16999 : 6348473 : extern "C" unsigned int M2Quads_CountQuads (void)
17000 : : {
17001 : 6348473 : return NoOfQuads;
17002 : : /* static analysis guarentees a RETURN statement will be used before here. */
17003 : : __builtin_unreachable ();
17004 : : }
17005 : :
17006 : :
17007 : : /*
17008 : : BuildScaffold - generate the main, init, finish functions if
17009 : : no -c and this is the application module.
17010 : : */
17011 : :
17012 : 13180 : extern "C" void M2Quads_BuildScaffold (unsigned int tok, unsigned int moduleSym)
17013 : : {
17014 : 13180 : if ((SymbolTable_GetMainModule ()) == moduleSym)
17015 : : {
17016 : 12796 : M2Scaffold_DeclareScaffold (tok);
17017 : 12796 : if (M2Options_ScaffoldMain || ! M2Options_cflag)
17018 : : {
17019 : : /* There are module init/fini functions and
17020 : : application init/fini functions.
17021 : : Here we create the application pair. */
17022 : 2412 : BuildM2LinkFunction (tok);
17023 : 2412 : BuildM2MainFunction (tok);
17024 : 2412 : BuildM2InitFunction (tok, moduleSym); /* Application init. */
17025 : 2412 : BuildM2FiniFunction (tok, moduleSym); /* Application fini. */
17026 : : }
17027 : : /* Application fini. */
17028 : 12796 : BuildM2DepFunction (tok, moduleSym); /* Per module dependency. */
17029 : : /* Each module needs a ctor to register the module
17030 : : init/finish/dep with M2RTS. */
17031 : 12796 : BuildM2CtorFunction (tok, moduleSym);
17032 : : }
17033 : 384 : else if (M2Options_WholeProgram)
17034 : : {
17035 : : /* avoid dangling else. */
17036 : 384 : M2Scaffold_DeclareScaffold (tok);
17037 : 384 : BuildM2DepFunction (tok, moduleSym); /* Per module dependency. */
17038 : : /* Each module needs a ctor to register the module
17039 : : init/finish/dep with M2RTS. */
17040 : 384 : BuildM2CtorFunction (tok, moduleSym);
17041 : : }
17042 : 13180 : }
17043 : :
17044 : :
17045 : : /*
17046 : : StartBuildDefFile - generates a StartFileDefOp quadruple indicating the file
17047 : : that has produced the subsequent quadruples.
17048 : : The code generator uses the StartDefFileOp quadruples
17049 : : to relate any error to the appropriate file.
17050 : :
17051 : :
17052 : : Entry Exit
17053 : : ===== ====
17054 : :
17055 : :
17056 : : Ptr -> <- Ptr
17057 : : +------------+ +------------+
17058 : : | ModuleName | | ModuleName |
17059 : : |------------| |------------|
17060 : :
17061 : :
17062 : : Quadruples Produced
17063 : :
17064 : : q StartDefFileOp _ _ ModuleSym
17065 : : */
17066 : :
17067 : 106649 : extern "C" void M2Quads_StartBuildDefFile (unsigned int tok)
17068 : : {
17069 : 106649 : NameKey_Name ModuleName;
17070 : :
17071 : 106649 : M2Quads_PopT (&ModuleName);
17072 : 106649 : M2Quads_PushT (ModuleName);
17073 : 106649 : GenQuadO (tok, M2Quads_StartDefFileOp, tok, SymbolTable_NulSym, SymbolTable_GetModule (ModuleName), false);
17074 : 106649 : }
17075 : :
17076 : :
17077 : : /*
17078 : : StartBuildModFile - generates a StartModFileOp quadruple indicating the file
17079 : : that has produced the subsequent quadruples.
17080 : : The code generator uses the StartModFileOp quadruples
17081 : : to relate any error to the appropriate file.
17082 : :
17083 : :
17084 : : Entry Exit
17085 : : ===== ====
17086 : :
17087 : :
17088 : : Ptr -> <- Ptr
17089 : : +------------+ +------------+
17090 : : | ModuleName | | ModuleName |
17091 : : |------------| |------------|
17092 : :
17093 : :
17094 : : Quadruples Produced
17095 : :
17096 : : q StartModFileOp lineno filename ModuleSym
17097 : : */
17098 : :
17099 : 59198 : extern "C" void M2Quads_StartBuildModFile (unsigned int tok)
17100 : : {
17101 : 59198 : GenQuadO (tok, M2Quads_StartModFileOp, tok, (unsigned int ) (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()))), SymbolTable_GetFileModule (), false);
17102 : 59198 : }
17103 : :
17104 : :
17105 : : /*
17106 : : EndBuildFile - generates an EndFileOp quadruple indicating the file
17107 : : that has produced the previous quadruples has ended.
17108 : :
17109 : : Entry Exit
17110 : : ===== ====
17111 : :
17112 : :
17113 : : Ptr -> <- Ptr
17114 : : +------------+ +------------+
17115 : : | ModuleName | | ModuleName |
17116 : : |------------| |------------|
17117 : :
17118 : :
17119 : : Quadruples Produced
17120 : :
17121 : : q EndFileOp _ _ ModuleSym
17122 : : */
17123 : :
17124 : 165751 : extern "C" void M2Quads_EndBuildFile (unsigned int tok)
17125 : : {
17126 : 165751 : NameKey_Name ModuleName;
17127 : :
17128 : 165751 : ModuleName = static_cast<NameKey_Name> (M2Quads_OperandT (1));
17129 : 165751 : GenQuadO (tok, M2Quads_EndFileOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_GetModule (ModuleName), false);
17130 : 165751 : }
17131 : :
17132 : :
17133 : : /*
17134 : : StartBuildInit - Sets the start of initialization code of the
17135 : : current module to the next quadruple.
17136 : : */
17137 : :
17138 : 59570 : extern "C" void M2Quads_StartBuildInit (unsigned int tok)
17139 : : {
17140 : 59570 : NameKey_Name name;
17141 : 59570 : unsigned int ModuleSym;
17142 : :
17143 : 59570 : M2Quads_PopT (&name);
17144 : 59570 : ModuleSym = SymbolTable_GetCurrentModule ();
17145 : 119140 : M2Debug_Assert ((SymbolTable_IsModule (ModuleSym)) || (SymbolTable_IsDefImp (ModuleSym)));
17146 : 59570 : M2Debug_Assert ((SymbolTable_GetSymName (ModuleSym)) == name);
17147 : 59564 : SymbolTable_PutModuleStartQuad (ModuleSym, NextQuad);
17148 : 59564 : GenQuad (M2Quads_InitStartOp, tok, SymbolTable_GetFileModule (), ModuleSym);
17149 : 59564 : M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
17150 : 59564 : M2Quads_PushT (name);
17151 : 59564 : CheckVariablesAt (ModuleSym);
17152 : 59564 : CheckNeedPriorityBegin (tok, ModuleSym, ModuleSym);
17153 : 59564 : M2StackWord_PushWord (TryStack, NextQuad);
17154 : 59564 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
17155 : 59564 : if (SymbolTable_HasExceptionBlock (ModuleSym))
17156 : : {
17157 : 48 : GenQuad (M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
17158 : : }
17159 : 59564 : }
17160 : :
17161 : :
17162 : : /*
17163 : : EndBuildInit - Sets the end initialization code of a module.
17164 : : */
17165 : :
17166 : 59516 : extern "C" void M2Quads_EndBuildInit (unsigned int tok)
17167 : : {
17168 : 59516 : if (SymbolTable_HasExceptionBlock (SymbolTable_GetCurrentModule ()))
17169 : : {
17170 : 48 : BuildRTExceptLeave (tok, true);
17171 : 48 : GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17172 : : }
17173 : 59516 : BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
17174 : 59516 : CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
17175 : 59516 : SymbolTable_PutModuleEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
17176 : 59516 : CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
17177 : 59516 : GenQuadO (tok, M2Quads_InitEndOp, tok, SymbolTable_GetFileModule (), SymbolTable_GetCurrentModule (), false);
17178 : 59516 : }
17179 : :
17180 : :
17181 : : /*
17182 : : StartBuildFinally - Sets the start of finalization code of the
17183 : : current module to the next quadruple.
17184 : : */
17185 : :
17186 : 13498 : extern "C" void M2Quads_StartBuildFinally (unsigned int tok)
17187 : : {
17188 : 13498 : NameKey_Name name;
17189 : 13498 : unsigned int ModuleSym;
17190 : :
17191 : 13498 : M2Quads_PopT (&name);
17192 : 13498 : ModuleSym = SymbolTable_GetCurrentModule ();
17193 : 26996 : M2Debug_Assert ((SymbolTable_IsModule (ModuleSym)) || (SymbolTable_IsDefImp (ModuleSym)));
17194 : 13498 : M2Debug_Assert ((SymbolTable_GetSymName (ModuleSym)) == name);
17195 : 13498 : SymbolTable_PutModuleFinallyStartQuad (ModuleSym, NextQuad);
17196 : 13498 : GenQuadO (tok, M2Quads_FinallyStartOp, tok, SymbolTable_GetFileModule (), ModuleSym, false);
17197 : 13498 : M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
17198 : 13498 : M2Quads_PushT (name);
17199 : : /* CheckVariablesAt(ModuleSym) ; */
17200 : 13498 : CheckNeedPriorityBegin (tok, ModuleSym, ModuleSym);
17201 : 13498 : M2StackWord_PushWord (TryStack, NextQuad);
17202 : 13498 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
17203 : 13498 : if (SymbolTable_HasExceptionFinally (ModuleSym))
17204 : : {
17205 : 0 : GenQuadO (tok, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
17206 : : }
17207 : 13498 : }
17208 : :
17209 : :
17210 : : /*
17211 : : EndBuildFinally - Sets the end finalization code of a module.
17212 : : */
17213 : :
17214 : 13498 : extern "C" void M2Quads_EndBuildFinally (unsigned int tok)
17215 : : {
17216 : 13498 : if (SymbolTable_HasExceptionFinally (SymbolTable_GetCurrentModule ()))
17217 : : {
17218 : 0 : BuildRTExceptLeave (tok, true);
17219 : 0 : GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17220 : : }
17221 : 13498 : BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
17222 : 13498 : CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
17223 : 13498 : SymbolTable_PutModuleFinallyEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
17224 : 13498 : CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
17225 : 13498 : GenQuadO (tok, M2Quads_FinallyEndOp, tok, SymbolTable_GetFileModule (), SymbolTable_GetCurrentModule (), false);
17226 : 13498 : }
17227 : :
17228 : :
17229 : : /*
17230 : : BuildExceptInitial - adds an CatchBeginOp, CatchEndOp quadruple
17231 : : in the current block.
17232 : : */
17233 : :
17234 : 2558 : extern "C" void M2Quads_BuildExceptInitial (unsigned int tok)
17235 : : {
17236 : 2558 : unsigned int previous;
17237 : :
17238 : : /* we have finished the 'try' block, so now goto the return
17239 : : section which will tidy up (any) priorities before returning.
17240 : : */
17241 : 2558 : GenQuadO (tok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PopWord (ReturnStack), false);
17242 : 2558 : M2StackWord_PushWord (ReturnStack, NextQuad-1);
17243 : : /*
17244 : : this is the 'catch' block.
17245 : : */
17246 : 2558 : BackPatch (M2StackWord_PeepWord (TryStack, 1), NextQuad);
17247 : 2558 : GenQuadO (tok, M2Quads_CatchBeginOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17248 : 2558 : previous = static_cast<unsigned int> (M2StackWord_PopWord (CatchStack));
17249 : 2558 : if (previous != 0)
17250 : : {
17251 : 0 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}only allowed one EXCEPT statement in a procedure or module", 62);
17252 : : }
17253 : 2558 : M2StackWord_PushWord (CatchStack, NextQuad-1);
17254 : 2558 : BuildRTExceptEnter (tok);
17255 : 2558 : }
17256 : :
17257 : :
17258 : : /*
17259 : : BuildExceptFinally - adds an ExceptOp quadruple in a modules
17260 : : finally block.
17261 : : */
17262 : :
17263 : 0 : extern "C" void M2Quads_BuildExceptFinally (unsigned int tok)
17264 : : {
17265 : 0 : M2Quads_BuildExceptInitial (tok);
17266 : 0 : }
17267 : :
17268 : :
17269 : : /*
17270 : : BuildExceptProcedure - adds an ExceptOp quadruple in a procedure
17271 : : block.
17272 : : */
17273 : :
17274 : 132 : extern "C" void M2Quads_BuildExceptProcedure (unsigned int tok)
17275 : : {
17276 : 132 : M2Quads_BuildExceptInitial (tok);
17277 : 132 : }
17278 : :
17279 : :
17280 : : /*
17281 : : BuildRetry - adds an RetryOp quadruple.
17282 : : */
17283 : :
17284 : 120 : extern "C" void M2Quads_BuildRetry (unsigned int tok)
17285 : : {
17286 : 120 : if ((M2StackWord_PeepWord (CatchStack, 1)) == 0)
17287 : : {
17288 : 6 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}the {%kRETRY} statement must occur after an {%kEXCEPT} statement in the same module or procedure block", 106);
17289 : : }
17290 : : else
17291 : : {
17292 : 114 : BuildRTExceptLeave (tok, false);
17293 : 114 : GenQuadO (tok, M2Quads_RetryOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PeepWord (TryStack, 1), false);
17294 : : }
17295 : 120 : }
17296 : :
17297 : :
17298 : : /*
17299 : : BuildReThrow - creates a ThrowOp _ _ NulSym, indicating that
17300 : : the exception needs to be rethrown. The stack
17301 : : is unaltered.
17302 : : */
17303 : :
17304 : 180 : extern "C" void M2Quads_BuildReThrow (unsigned int tokenno)
17305 : : {
17306 : 180 : GenQuadO (tokenno, M2Quads_ThrowOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17307 : 180 : }
17308 : :
17309 : :
17310 : : /*
17311 : : StartBuildInnerInit - Sets the start of initialization code of the
17312 : : inner module to the next quadruple.
17313 : : */
17314 : :
17315 : 0 : extern "C" void M2Quads_StartBuildInnerInit (unsigned int tok)
17316 : : {
17317 : 0 : SymbolTable_PutModuleStartQuad (SymbolTable_GetCurrentModule (), NextQuad);
17318 : 0 : GenQuadO (tok, M2Quads_InitStartOp, tok, SymbolTable_NulSym, SymbolTable_GetCurrentModule (), false);
17319 : 0 : M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
17320 : 0 : CheckNeedPriorityBegin (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
17321 : 0 : M2StackWord_PushWord (TryStack, NextQuad);
17322 : 0 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
17323 : 0 : if (SymbolTable_HasExceptionFinally (SymbolTable_GetCurrentModule ()))
17324 : : {
17325 : 0 : GenQuadO (tok, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
17326 : : }
17327 : 0 : }
17328 : :
17329 : :
17330 : : /*
17331 : : EndBuildInnerInit - Sets the end initialization code of a module.
17332 : : */
17333 : :
17334 : 0 : extern "C" void M2Quads_EndBuildInnerInit (unsigned int tok)
17335 : : {
17336 : 0 : if (SymbolTable_HasExceptionBlock (SymbolTable_GetCurrentModule ()))
17337 : : {
17338 : 0 : BuildRTExceptLeave (tok, true);
17339 : 0 : GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17340 : : }
17341 : 0 : SymbolTable_PutModuleEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
17342 : 0 : CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
17343 : 0 : BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
17344 : 0 : CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
17345 : 0 : GenQuadO (tok, M2Quads_InitEndOp, tok, SymbolTable_NulSym, SymbolTable_GetCurrentModule (), false);
17346 : 0 : }
17347 : :
17348 : :
17349 : : /*
17350 : : BuildBuiltinConst - makes reference to a builtin constant within gm2.
17351 : :
17352 : : Entry Exit
17353 : :
17354 : : Ptr ->
17355 : : +------------+ +------------+
17356 : : | Ident | | Sym |
17357 : : |------------| |------------|
17358 : :
17359 : : Quadruple produced:
17360 : :
17361 : : q Sym BuiltinConstOp Ident
17362 : : */
17363 : :
17364 : 25264 : extern "C" void M2Quads_BuildBuiltinConst (void)
17365 : : {
17366 : 25264 : unsigned int idtok;
17367 : 25264 : unsigned int Id;
17368 : 25264 : unsigned int Sym;
17369 : :
17370 : 25264 : M2Quads_PopTtok (&Id, &idtok);
17371 : 25264 : Sym = SymbolTable_MakeTemporary (idtok, SymbolTable_ImmediateValue);
17372 : 25264 : SymbolTable_PutVar (Sym, M2Base_Integer);
17373 : : /*
17374 : : CASE GetBuiltinConstType(KeyToCharStar(Name(Id))) OF
17375 : :
17376 : : 0: ErrorFormat1(NewError(GetTokenNo()),
17377 : : '%a unrecognised builtin constant', Id) |
17378 : : 1: PutVar(Sym, Integer) |
17379 : : 2: PutVar(Sym, Real)
17380 : :
17381 : : ELSE
17382 : : InternalError ('unrecognised value')
17383 : : END ;
17384 : : */
17385 : 25264 : GenQuadO (idtok, M2Quads_BuiltinConstOp, Sym, SymbolTable_NulSym, Id, false);
17386 : 25264 : M2Quads_PushTtok (Sym, idtok);
17387 : 25264 : }
17388 : :
17389 : :
17390 : : /*
17391 : : BuildBuiltinTypeInfo - make reference to a builtin typeinfo function
17392 : : within gm2.
17393 : :
17394 : : Entry Exit
17395 : :
17396 : : Ptr ->
17397 : : +-------------+
17398 : : | Type |
17399 : : |-------------| +------------+
17400 : : | Ident | | Sym |
17401 : : |-------------| |------------|
17402 : :
17403 : : Quadruple produced:
17404 : :
17405 : : q Sym BuiltinTypeInfoOp Type Ident
17406 : : */
17407 : :
17408 : 180 : extern "C" void M2Quads_BuildBuiltinTypeInfo (void)
17409 : : {
17410 : 180 : unsigned int idtok;
17411 : 180 : unsigned int Ident;
17412 : 180 : unsigned int Type;
17413 : 180 : unsigned int Sym;
17414 : :
17415 : 180 : M2Quads_PopTtok (&Ident, &idtok);
17416 : 180 : M2Quads_PopT (&Type);
17417 : 180 : Sym = SymbolTable_MakeTemporary (M2LexBuf_BuiltinTokenNo, SymbolTable_ImmediateValue);
17418 : 180 : switch (m2builtins_GetBuiltinTypeInfoType (NameKey_KeyToCharStar ((NameKey_Name) (Ident))))
17419 : : {
17420 : 0 : case 0:
17421 : 0 : M2Error_ErrorFormat1 (M2Error_NewError (idtok), (const char *) "%a unrecognised builtin constant", 32, (const unsigned char *) &Ident, (sizeof (Ident)-1));
17422 : 0 : break;
17423 : :
17424 : 96 : case 1:
17425 : 96 : SymbolTable_PutVar (Sym, M2Base_Boolean);
17426 : 96 : break;
17427 : :
17428 : 60 : case 2:
17429 : 60 : SymbolTable_PutVar (Sym, M2Base_ZType);
17430 : 60 : break;
17431 : :
17432 : 24 : case 3:
17433 : 24 : SymbolTable_PutVar (Sym, M2Base_RType);
17434 : 24 : break;
17435 : :
17436 : :
17437 : 0 : default:
17438 : 0 : M2Error_InternalError ((const char *) "unrecognised value", 18);
17439 : 180 : break;
17440 : : }
17441 : 180 : GenQuadO (idtok, M2Quads_BuiltinTypeInfoOp, Sym, Type, Ident, false);
17442 : 180 : M2Quads_PushTtok (Sym, idtok);
17443 : 180 : }
17444 : :
17445 : :
17446 : : /*
17447 : : BuildAssignment - Builds an assignment from the values given on the
17448 : : quad stack. Either an assignment to an
17449 : : arithmetic expression or an assignment to a
17450 : : boolean expression. This procedure should not
17451 : : be called in CONST declarations.
17452 : : The Stack is expected to contain:
17453 : :
17454 : :
17455 : : Either
17456 : :
17457 : : Entry Exit
17458 : : ===== ====
17459 : :
17460 : : Ptr ->
17461 : : +------------+
17462 : : | Expression |
17463 : : |------------|
17464 : : | Designator |
17465 : : |------------| +------------+
17466 : : | | | | <- Ptr
17467 : : |------------| |------------|
17468 : :
17469 : :
17470 : : Quadruples Produced
17471 : :
17472 : : q BecomesOp Designator _ Expression
17473 : :
17474 : : OR
17475 : :
17476 : : Entry Exit
17477 : : ===== ====
17478 : :
17479 : : Ptr ->
17480 : : +------------+
17481 : : | True |False|
17482 : : |------------|
17483 : : | Designator |
17484 : : |------------| +------------+
17485 : : | | | | <- Ptr
17486 : : |------------| |------------|
17487 : :
17488 : :
17489 : : Quadruples Produced
17490 : :
17491 : : q BecomesOp Designator _ TRUE
17492 : : q+1 GotoOp q+3
17493 : : q+2 BecomesOp Designator _ FALSE
17494 : :
17495 : : */
17496 : :
17497 : 97658 : extern "C" void M2Quads_BuildAssignment (unsigned int becomesTokNo)
17498 : : {
17499 : 97658 : unsigned int des;
17500 : 97658 : unsigned int exp;
17501 : 97658 : unsigned int destok;
17502 : 97658 : unsigned int exptok;
17503 : 97658 : unsigned int combinedtok;
17504 : :
17505 : 97658 : des = static_cast<unsigned int> (M2Quads_OperandT (2));
17506 : 97658 : if (IsReadOnly (des))
17507 : : {
17508 : 30 : destok = static_cast<unsigned int> (M2Quads_OperandTok (2));
17509 : 30 : exptok = static_cast<unsigned int> (M2Quads_OperandTok (1));
17510 : 30 : exp = static_cast<unsigned int> (M2Quads_OperandT (1));
17511 : 30 : if (DebugTokPos)
17512 : : {
17513 : : M2MetaError_MetaErrorT1 (destok, (const char *) "destok {%1Ead}", 14, des);
17514 : : M2MetaError_MetaErrorT1 (exptok, (const char *) "exptok {%1Ead}", 14, exp);
17515 : : }
17516 : 30 : combinedtok = M2LexBuf_MakeVirtualTok (becomesTokNo, destok, exptok);
17517 : 30 : if (DebugTokPos)
17518 : : {
17519 : : M2MetaError_MetaErrorT1 (combinedtok, (const char *) "combined {%1Ead}", 16, des);
17520 : : }
17521 : 30 : if (IsBoolean (1))
17522 : : {
17523 : 0 : M2MetaError_MetaErrorT1 (combinedtok, (const char *) "cannot assign expression to a constant designator {%1Ead}", 57, des);
17524 : : }
17525 : : else
17526 : : {
17527 : 30 : exp = static_cast<unsigned int> (M2Quads_OperandT (1));
17528 : 30 : M2MetaError_MetaErrorT2 (combinedtok, (const char *) "cannot assign a constant designator {%1Ead} with an expression {%2Ead}", 70, des, exp);
17529 : : }
17530 : 30 : M2Quads_PopN (2); /* Remove both parameters. */
17531 : : }
17532 : 97628 : else if (SymbolTable_IsError (des))
17533 : : {
17534 : : /* avoid dangling else. */
17535 : 18 : M2Quads_PopN (2); /* Remove both parameters. */
17536 : : }
17537 : : else
17538 : : {
17539 : : /* avoid dangling else. */
17540 : 97610 : doBuildAssignment (becomesTokNo, true, true);
17541 : : }
17542 : 97658 : }
17543 : :
17544 : :
17545 : : /*
17546 : : BuildAssignConstant - used to create constant in the CONST declaration.
17547 : : The stack is expected to contain:
17548 : :
17549 : : Either
17550 : :
17551 : : Entry Exit
17552 : : ===== ====
17553 : :
17554 : : Ptr ->
17555 : : +------------+
17556 : : | Expression |
17557 : : |------------|
17558 : : | Designator |
17559 : : |------------| +------------+
17560 : : | | | | <- Ptr
17561 : : |------------| |------------|
17562 : :
17563 : :
17564 : : Quadruples Produced
17565 : :
17566 : : q BecomesOp Designator _ Expression
17567 : :
17568 : : OR
17569 : :
17570 : : Entry Exit
17571 : : ===== ====
17572 : :
17573 : : Ptr ->
17574 : : +------------+
17575 : : | True |False|
17576 : : |------------|
17577 : : | Designator |
17578 : : |------------| +------------+
17579 : : | | | | <- Ptr
17580 : : |------------| |------------|
17581 : :
17582 : :
17583 : : Quadruples Produced
17584 : :
17585 : : q BecomesOp Designator _ TRUE
17586 : : q+1 GotoOp q+3
17587 : : q+2 BecomesOp Designator _ FALSE
17588 : : */
17589 : :
17590 : 223571 : extern "C" void M2Quads_BuildAssignConstant (unsigned int equalsTokNo)
17591 : : {
17592 : 223571 : doBuildAssignment (equalsTokNo, true, true);
17593 : 223559 : }
17594 : :
17595 : :
17596 : : /*
17597 : : BuildAlignment - builds an assignment to an alignment constant.
17598 : :
17599 : : The Stack is expected to contain:
17600 : :
17601 : :
17602 : : Entry Exit
17603 : : ===== ====
17604 : :
17605 : : Ptr ->
17606 : : +---------------+
17607 : : | Expression |
17608 : : |---------------|
17609 : : | bytealignment |
17610 : : |---------------| empty
17611 : : */
17612 : :
17613 : 72 : extern "C" void M2Quads_BuildAlignment (unsigned int tokno)
17614 : : {
17615 : 72 : NameKey_Name name;
17616 : 72 : unsigned int expr;
17617 : 72 : unsigned int align;
17618 : :
17619 : 72 : M2Quads_PopT (&expr);
17620 : 72 : M2Quads_PopT (&name);
17621 : 72 : if (name != (NameKey_MakeKey ((const char *) "bytealignment", 13)))
17622 : : {
17623 : 0 : M2MetaError_MetaError1 ((const char *) "expecting bytealignment identifier, rather than {%1Ea}", 54, SymbolTable_MakeError (tokno, name));
17624 : : }
17625 : 72 : FifoQueue_GetConstFromFifoQueue (&align);
17626 : 72 : M2Quads_PushT (align);
17627 : 72 : M2Quads_PushT (expr);
17628 : 72 : M2Quads_BuildAssignConstant (tokno);
17629 : 72 : }
17630 : :
17631 : :
17632 : : /*
17633 : : BuildBitLength - builds an assignment to a bit length constant.
17634 : :
17635 : : The Stack is expected to contain:
17636 : :
17637 : :
17638 : : Entry Exit
17639 : : ===== ====
17640 : :
17641 : : Ptr ->
17642 : : +------------+
17643 : : | Expression |
17644 : : |------------| empty
17645 : : */
17646 : :
17647 : 0 : extern "C" void M2Quads_BuildBitLength (unsigned int tokno)
17648 : : {
17649 : 0 : unsigned int expr;
17650 : 0 : unsigned int length;
17651 : :
17652 : 0 : M2Quads_PopT (&expr);
17653 : 0 : FifoQueue_GetConstFromFifoQueue (&length);
17654 : 0 : M2Quads_PushT (length);
17655 : 0 : M2Quads_PushT (expr);
17656 : 0 : M2Quads_BuildAssignConstant (tokno);
17657 : 0 : }
17658 : :
17659 : :
17660 : : /*
17661 : : BuildPragmaField - builds an assignment to an alignment constant.
17662 : :
17663 : : The Stack is expected to contain:
17664 : :
17665 : :
17666 : : Entry Exit
17667 : : ===== ====
17668 : :
17669 : : Ptr ->
17670 : : +------------+
17671 : : | Expression |
17672 : : |------------| empty
17673 : : */
17674 : :
17675 : 12 : extern "C" void M2Quads_BuildPragmaField (void)
17676 : : {
17677 : 12 : unsigned int expr;
17678 : 12 : unsigned int const_;
17679 : 12 : NameKey_Name name;
17680 : :
17681 : 12 : M2Quads_PopT (&expr);
17682 : 12 : M2Quads_PopT (&name);
17683 : 12 : if ((name != (NameKey_MakeKey ((const char *) "unused", 6))) && (name != (NameKey_MakeKey ((const char *) "bytealignment", 13))))
17684 : : {
17685 : 0 : M2MetaError_MetaError0 ((const char *) "only allowed to use the attribute {%Ekbytealignment} in the default record field alignment pragma", 97);
17686 : : }
17687 : 12 : if (expr != SymbolTable_NulSym)
17688 : : {
17689 : 12 : FifoQueue_GetConstFromFifoQueue (&const_);
17690 : 12 : M2Quads_PushT (const_);
17691 : 12 : M2Quads_PushT (expr);
17692 : 12 : M2Quads_BuildAssignConstant (M2LexBuf_GetTokenNo ());
17693 : : }
17694 : 12 : }
17695 : :
17696 : :
17697 : : /*
17698 : : BuildDefaultFieldAlignment - builds an assignment to an alignment constant.
17699 : :
17700 : : The Stack is expected to contain:
17701 : :
17702 : :
17703 : : Entry Exit
17704 : : ===== ====
17705 : :
17706 : : Ptr ->
17707 : : +------------+
17708 : : | Expression |
17709 : : |------------| empty
17710 : : */
17711 : :
17712 : 36 : extern "C" void M2Quads_BuildDefaultFieldAlignment (void)
17713 : : {
17714 : 36 : unsigned int expr;
17715 : 36 : unsigned int align;
17716 : 36 : NameKey_Name name;
17717 : :
17718 : 36 : M2Quads_PopT (&expr);
17719 : 36 : M2Quads_PopT (&name);
17720 : 36 : if (name != (NameKey_MakeKey ((const char *) "bytealignment", 13)))
17721 : : {
17722 : 0 : M2MetaError_MetaError0 ((const char *) "{%E}only allowed to use the attribute {%kbytealignment} in the default record field alignment pragma", 100);
17723 : : }
17724 : 36 : FifoQueue_GetConstFromFifoQueue (&align);
17725 : 36 : M2Quads_PushT (align);
17726 : 36 : M2Quads_PushT (expr);
17727 : 36 : M2Quads_BuildAssignConstant (M2LexBuf_GetTokenNo ());
17728 : 36 : }
17729 : :
17730 : :
17731 : : /*
17732 : : BuildRepeat - Builds the repeat statement from the quad stack.
17733 : : The Stack is expected to contain:
17734 : :
17735 : :
17736 : : Entry Exit
17737 : : ===== ====
17738 : :
17739 : :
17740 : : Empty
17741 : : <- Ptr
17742 : : +------------+
17743 : : | RepeatQuad |
17744 : : |------------|
17745 : :
17746 : : */
17747 : :
17748 : 1151 : extern "C" void M2Quads_BuildRepeat (void)
17749 : : {
17750 : 1151 : M2Quads_PushT (NextQuad);
17751 : 1151 : }
17752 : :
17753 : :
17754 : : /*
17755 : : BuildUntil - Builds the until part of the repeat statement
17756 : : from the quad stack.
17757 : : The Stack is expected to contain:
17758 : :
17759 : :
17760 : : Entry Exit
17761 : : ===== ====
17762 : :
17763 : : Ptr ->
17764 : : +------------+
17765 : : | t | f |
17766 : : |------------|
17767 : : | RepeatQuad | Empty
17768 : : |------------|
17769 : : */
17770 : :
17771 : 1151 : extern "C" void M2Quads_BuildUntil (void)
17772 : : {
17773 : 1151 : unsigned int t;
17774 : 1151 : unsigned int f;
17775 : 1151 : unsigned int Repeat;
17776 : :
17777 : 1151 : CheckBooleanId ();
17778 : 1151 : PopBool (&t, &f);
17779 : 1151 : M2Quads_PopT (&Repeat);
17780 : 1151 : BackPatch (f, Repeat); /* If False then keep on repeating */
17781 : 1151 : BackPatch (t, NextQuad); /* If True then exit repeat */
17782 : 1151 : }
17783 : :
17784 : :
17785 : : /*
17786 : : BuildWhile - Builds the While part of the While statement
17787 : : from the quad stack.
17788 : : The Stack is expected to contain:
17789 : :
17790 : :
17791 : : Entry Exit
17792 : : ===== ====
17793 : :
17794 : : <- Ptr
17795 : : |------------|
17796 : : Empty | WhileQuad |
17797 : : |------------|
17798 : : */
17799 : :
17800 : 5216 : extern "C" void M2Quads_BuildWhile (void)
17801 : : {
17802 : 5216 : M2Quads_PushT (NextQuad);
17803 : 5216 : }
17804 : :
17805 : :
17806 : : /*
17807 : : BuildDoWhile - Builds the Do part of the while statement
17808 : : from the quad stack.
17809 : : The Stack is expected to contain:
17810 : :
17811 : :
17812 : : Entry Exit
17813 : : ===== ====
17814 : :
17815 : : Ptr ->
17816 : : +------------+ +------------+
17817 : : | t | f | | 0 | f |
17818 : : |------------| |------------|
17819 : : | WhileQuad | | WhileQuad |
17820 : : |------------| |------------|
17821 : :
17822 : : Quadruples
17823 : :
17824 : : BackPatch t exit to the NextQuad
17825 : : */
17826 : :
17827 : 5216 : extern "C" void M2Quads_BuildDoWhile (void)
17828 : : {
17829 : 5216 : unsigned int t;
17830 : 5216 : unsigned int f;
17831 : :
17832 : 5216 : CheckBooleanId ();
17833 : 5216 : PopBool (&t, &f);
17834 : 5216 : BackPatch (t, NextQuad);
17835 : 5216 : PushBool (0, f);
17836 : 5216 : }
17837 : :
17838 : :
17839 : : /*
17840 : : BuildEndWhile - Builds the end part of the while statement
17841 : : from the quad stack.
17842 : : The Stack is expected to contain:
17843 : :
17844 : :
17845 : : Entry Exit
17846 : : ===== ====
17847 : :
17848 : : Ptr ->
17849 : : +------------+
17850 : : | t | f |
17851 : : |------------|
17852 : : | WhileQuad | Empty
17853 : : |------------|
17854 : :
17855 : : Quadruples
17856 : :
17857 : : q GotoOp WhileQuad
17858 : : False exit is backpatched with q+1
17859 : : */
17860 : :
17861 : 5216 : extern "C" void M2Quads_BuildEndWhile (void)
17862 : : {
17863 : 5216 : unsigned int While;
17864 : 5216 : unsigned int t;
17865 : 5216 : unsigned int f;
17866 : :
17867 : 5216 : PopBool (&t, &f);
17868 : 5216 : M2Debug_Assert (t == 0);
17869 : 5216 : M2Quads_PopT (&While);
17870 : 5216 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, While);
17871 : 5216 : BackPatch (f, NextQuad);
17872 : 5216 : }
17873 : :
17874 : :
17875 : : /*
17876 : : BuildLoop - Builds the Loop part of the Loop statement
17877 : : from the quad stack.
17878 : : The Stack is expected to contain:
17879 : :
17880 : :
17881 : : Entry Exit
17882 : : ===== ====
17883 : :
17884 : : <- Ptr
17885 : : Empty +------------+
17886 : : | LoopQuad |
17887 : : |------------|
17888 : : */
17889 : :
17890 : 491 : extern "C" void M2Quads_BuildLoop (void)
17891 : : {
17892 : 491 : M2Quads_PushT (NextQuad);
17893 : 491 : PushExit (0); /* Seperate Exit Stack for loop end */
17894 : 491 : }
17895 : :
17896 : :
17897 : : /*
17898 : : BuildExit - Builds the Exit part of the Loop statement.
17899 : : */
17900 : :
17901 : 94 : extern "C" void M2Quads_BuildExit (void)
17902 : : {
17903 : 94 : if (M2StackWord_IsEmptyWord (ExitStack))
17904 : : {
17905 : 0 : M2MetaError_MetaError0 ((const char *) "{%EkEXIT} is only allowed in a {%kLOOP} statement", 49);
17906 : : }
17907 : : else
17908 : : {
17909 : 94 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
17910 : 94 : PushExit (Merge (PopExit (), NextQuad-1));
17911 : : }
17912 : 94 : }
17913 : :
17914 : :
17915 : : /*
17916 : : BuildEndLoop - Builds the End part of the Loop statement
17917 : : from the quad stack.
17918 : : The Stack is expected to contain:
17919 : :
17920 : :
17921 : : Entry Exit
17922 : : ===== ====
17923 : :
17924 : : Ptr ->
17925 : : +------------+
17926 : : | LoopQuad | Empty
17927 : : |------------|
17928 : :
17929 : : Quadruples
17930 : :
17931 : : Goto _ _ LoopQuad
17932 : : */
17933 : :
17934 : 491 : extern "C" void M2Quads_BuildEndLoop (void)
17935 : : {
17936 : 491 : unsigned int Loop;
17937 : :
17938 : 491 : M2Quads_PopT (&Loop);
17939 : 491 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, Loop);
17940 : 491 : BackPatch (PopExit (), NextQuad);
17941 : 491 : }
17942 : :
17943 : :
17944 : : /*
17945 : : BuildThenIf - Builds the Then part of the If statement
17946 : : from the quad stack.
17947 : : The Stack is expected to contain:
17948 : :
17949 : :
17950 : : Entry Exit
17951 : : ===== ====
17952 : :
17953 : : Ptr -> <- Ptr
17954 : : +------------+ +------------+
17955 : : | t | f | | 0 | f |
17956 : : |------------| |------------|
17957 : :
17958 : : Quadruples
17959 : :
17960 : : The true exit is BackPatched to point to
17961 : : the NextQuad.
17962 : : */
17963 : :
17964 : 33297 : extern "C" void M2Quads_BuildThenIf (void)
17965 : : {
17966 : 33297 : unsigned int t;
17967 : 33297 : unsigned int f;
17968 : :
17969 : 33297 : CheckBooleanId ();
17970 : 33297 : PopBool (&t, &f);
17971 : 33297 : BackPatch (t, NextQuad);
17972 : 33297 : PushBool (0, f);
17973 : 33297 : }
17974 : :
17975 : :
17976 : : /*
17977 : : BuildElse - Builds the Else part of the If statement
17978 : : from the quad stack.
17979 : : The Stack is expected to contain:
17980 : :
17981 : :
17982 : : Entry Exit
17983 : : ===== ====
17984 : :
17985 : : Ptr ->
17986 : : +------------+ +------------+
17987 : : | t | f | | t+q | 0 |
17988 : : |------------| |------------|
17989 : :
17990 : : Quadruples
17991 : :
17992 : : q GotoOp _ _ 0
17993 : : q+1 <- BackPatched from f
17994 : : */
17995 : :
17996 : 11040 : extern "C" void M2Quads_BuildElse (void)
17997 : : {
17998 : 11040 : unsigned int t;
17999 : 11040 : unsigned int f;
18000 : :
18001 : 11040 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18002 : 11040 : PopBool (&t, &f);
18003 : 11040 : BackPatch (f, NextQuad);
18004 : 11040 : PushBool (Merge (t, NextQuad-1), 0); /* NextQuad-1 = Goto Quad */
18005 : 11040 : }
18006 : :
18007 : :
18008 : : /*
18009 : : BuildEndIf - Builds the End part of the If statement
18010 : : from the quad stack.
18011 : : The Stack is expected to contain:
18012 : :
18013 : :
18014 : : Entry Exit
18015 : : ===== ====
18016 : :
18017 : : Ptr ->
18018 : : +------------+
18019 : : | t | f | Empty
18020 : : |------------|
18021 : :
18022 : : Quadruples
18023 : :
18024 : : Both t and f are backpatched to point to the NextQuad
18025 : : */
18026 : :
18027 : 30663 : extern "C" void M2Quads_BuildEndIf (void)
18028 : : {
18029 : 30663 : unsigned int t;
18030 : 30663 : unsigned int f;
18031 : :
18032 : 30663 : PopBool (&t, &f);
18033 : 30663 : BackPatch (t, NextQuad);
18034 : 30663 : BackPatch (f, NextQuad);
18035 : 30663 : }
18036 : :
18037 : :
18038 : : /*
18039 : : BuildElsif1 - Builds the Elsif part of the If statement
18040 : : from the quad stack.
18041 : : The Stack is expected to contain:
18042 : :
18043 : :
18044 : : Entry Exit
18045 : : ===== ====
18046 : :
18047 : : Ptr ->
18048 : : +------------+ +------------+
18049 : : | t | f | | t+q | 0 |
18050 : : |------------| |------------|
18051 : :
18052 : : Quadruples
18053 : :
18054 : : q GotoOp _ _ 0
18055 : : q+1 <- BackPatched from f
18056 : : */
18057 : :
18058 : 2634 : extern "C" void M2Quads_BuildElsif1 (void)
18059 : : {
18060 : 2634 : unsigned int t;
18061 : 2634 : unsigned int f;
18062 : :
18063 : 2634 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18064 : 2634 : PopBool (&t, &f);
18065 : 2634 : BackPatch (f, NextQuad);
18066 : 2634 : PushBool (Merge (t, NextQuad-1), 0); /* NextQuad-1 = Goto Quad */
18067 : 2634 : }
18068 : :
18069 : :
18070 : : /*
18071 : : BuildElsif2 - Builds the Elsif until part of the If statement
18072 : : from the quad stack.
18073 : : The Stack is expected to contain:
18074 : :
18075 : :
18076 : : Entry Exit
18077 : : ===== ====
18078 : :
18079 : : Ptr ->
18080 : : +--------------+
18081 : : | 0 | f1 | <- Ptr
18082 : : |--------------| +---------------+
18083 : : | t2 | f2 | | t2 | f1+f2 |
18084 : : |--------------| |---------------|
18085 : : */
18086 : :
18087 : 2634 : extern "C" void M2Quads_BuildElsif2 (void)
18088 : : {
18089 : 2634 : unsigned int t1;
18090 : 2634 : unsigned int f1;
18091 : 2634 : unsigned int t2;
18092 : 2634 : unsigned int f2;
18093 : :
18094 : 2634 : PopBool (&t1, &f1);
18095 : 2634 : M2Debug_Assert (t1 == 0);
18096 : 2634 : PopBool (&t2, &f2);
18097 : 2634 : PushBool (t2, Merge (f1, f2));
18098 : 2634 : }
18099 : :
18100 : :
18101 : : /*
18102 : : BuildForToByDo - Builds the For To By Do part of the For statement
18103 : : from the quad stack.
18104 : : The Stack is expected to contain:
18105 : :
18106 : :
18107 : : Entry Exit
18108 : : ===== ====
18109 : :
18110 : : <- Ptr
18111 : : +----------------+
18112 : : Ptr -> | RangeId |
18113 : : +----------------+ |----------------|
18114 : : | BySym | ByType | | ForQuad |
18115 : : |----------------| |----------------|
18116 : : | e2 | | LastValue |
18117 : : |----------------| |----------------|
18118 : : | e1 | | BySym | ByType |
18119 : : |----------------| |----------------|
18120 : : | Ident | | IdentSym |
18121 : : |----------------| |----------------|
18122 : :
18123 : :
18124 : : x := e1 ;
18125 : : LASTVALUE := ((e2-e1) DIV BySym) * BySym + e1
18126 : : IF BySym<0
18127 : : THEN
18128 : : IF e1<e2
18129 : : THEN
18130 : : goto exit
18131 : : END
18132 : : ELSE
18133 : : IF e1>e2
18134 : : THEN
18135 : : goto exit
18136 : : END
18137 : : END ;
18138 : : LOOP
18139 : : body
18140 : : IF x=LASTVALUE
18141 : : THEN
18142 : : goto exit
18143 : : END ;
18144 : : INC(x, BySym)
18145 : : END
18146 : :
18147 : : Quadruples:
18148 : :
18149 : : q BecomesOp IdentSym _ e1
18150 : : q+ LastValue := ((e1-e2) DIV by) * by + e1
18151 : : q+1 if >= by 0 q+..2
18152 : : q+2 GotoOp q+3
18153 : : q+3 If >= e1 e2 q+5
18154 : : q+4 GotoOp exit
18155 : : q+5 ..
18156 : : q+..1 Goto q+..5
18157 : : q+..2 If >= e2 e1 q+..4
18158 : : q+..3 GotoOp exit
18159 : : q+..4 ..
18160 : :
18161 : : The For Loop is regarded:
18162 : :
18163 : : For ident := e1 To e2 By by Do
18164 : :
18165 : : End
18166 : : */
18167 : :
18168 : 1852 : extern "C" void M2Quads_BuildForToByDo (void)
18169 : : {
18170 : 1852 : M2Quads_LineNote l1;
18171 : 1852 : M2Quads_LineNote l2;
18172 : 1852 : NameKey_Name e1;
18173 : 1852 : NameKey_Name e2;
18174 : 1852 : NameKey_Name Id;
18175 : 1852 : unsigned int e1tok;
18176 : 1852 : unsigned int e2tok;
18177 : 1852 : unsigned int idtok;
18178 : 1852 : unsigned int bytok;
18179 : 1852 : unsigned int FinalValue;
18180 : 1852 : unsigned int exit1;
18181 : 1852 : unsigned int IdSym;
18182 : 1852 : unsigned int BySym;
18183 : 1852 : unsigned int ByType;
18184 : 1852 : unsigned int ForLoop;
18185 : 1852 : unsigned int RangeId;
18186 : 1852 : unsigned int t;
18187 : 1852 : unsigned int f;
18188 : 1852 : unsigned int etype;
18189 : 1852 : unsigned int t1;
18190 : :
18191 : 1852 : l2 = PopLineNo ();
18192 : 1852 : l1 = PopLineNo ();
18193 : 1852 : UseLineNote (l1);
18194 : 1852 : PushFor (0);
18195 : 1852 : M2Quads_PopTFtok (&BySym, &ByType, &bytok);
18196 : 1852 : M2Quads_PopTtok (&e2, &e2tok);
18197 : 1852 : M2Quads_PopTtok (&e1, &e1tok);
18198 : 1852 : M2Quads_PopTtok (&Id, &idtok);
18199 : 1852 : IdSym = SymbolTable_RequestSym (idtok, Id);
18200 : 1852 : RangeId = M2Range_InitForLoopBeginRangeCheck (IdSym, idtok, e1, e1tok, e2, e2tok, BySym, bytok);
18201 : 1852 : BuildRange (RangeId);
18202 : 1852 : M2Quads_PushTtok (IdSym, idtok);
18203 : 1852 : M2Quads_PushTtok (e1, e1tok);
18204 : 1852 : BuildAssignmentWithoutBounds (idtok, true, true);
18205 : 1852 : UseLineNote (l2);
18206 : 2286 : FinalValue = SymbolTable_MakeTemporary (e2tok, AreConstant (((SymbolTable_IsConst (e1)) && (SymbolTable_IsConst (e2))) && (SymbolTable_IsConst (BySym))));
18207 : 1852 : SymbolTable_PutVar (FinalValue, SymbolTable_GetSType (IdSym));
18208 : 1852 : etype = M2Base_MixTypes (SymbolTable_GetSType (e1), SymbolTable_GetSType (e2), e2tok);
18209 : 1852 : e1 = doConvert (etype, e1);
18210 : 1852 : e2 = doConvert (etype, e2);
18211 : 1852 : M2Quads_PushTF (FinalValue, SymbolTable_GetSType (FinalValue));
18212 : 1852 : M2Quads_PushTFtok (e2, SymbolTable_GetSType (e2), e2tok); /* FinalValue := ((e1-e2) DIV By) * By + e1 */
18213 : 1852 : M2Quads_PushT (M2Reserved_MinusTok); /* FinalValue := ((e1-e2) DIV By) * By + e1 */
18214 : 1852 : M2Quads_PushTFtok (e1, SymbolTable_GetSType (e1), e1tok);
18215 : 1852 : doBuildBinaryOp (true, false);
18216 : 1852 : M2Quads_PushT (M2Reserved_DivideTok);
18217 : 1852 : M2Quads_PushTFtok (BySym, ByType, bytok);
18218 : 1852 : doBuildBinaryOp (false, false);
18219 : 1852 : M2Quads_PushT (M2Reserved_TimesTok);
18220 : 1852 : M2Quads_PushTFtok (BySym, ByType, bytok);
18221 : 1852 : doBuildBinaryOp (false, false);
18222 : 1852 : M2Quads_PushT (ArithPlusTok);
18223 : 1852 : M2Quads_PushTFtok (e1, SymbolTable_GetSType (e1), e1tok);
18224 : 1852 : doBuildBinaryOp (false, false);
18225 : 1852 : BuildForLoopToRangeCheck ();
18226 : 1852 : BuildAssignmentWithoutBounds (e1tok, false, false);
18227 : : /* q+2 GotoOp q+3 */
18228 : 1852 : M2Quads_PushTFtok (BySym, ByType, bytok); /* BuildRelOp 1st parameter */
18229 : 1852 : M2Quads_PushT (M2Reserved_GreaterEqualTok); /* 2nd parameter */
18230 : : /* 3rd parameter */
18231 : 1852 : PushZero (bytok, ByType);
18232 : 1852 : M2Quads_BuildRelOp (e2tok); /* choose final expression position. */
18233 : 1852 : PopBool (&t, &f); /* choose final expression position. */
18234 : 1852 : BackPatch (f, NextQuad);
18235 : : /* q+4 GotoOp Exit */
18236 : 1852 : M2Quads_PushTFtok (e1, SymbolTable_GetSType (e1), e1tok); /* BuildRelOp 1st parameter */
18237 : 1852 : M2Quads_PushT (M2Reserved_GreaterEqualTok); /* 2nd parameter */
18238 : 1852 : M2Quads_PushTFtok (e2, SymbolTable_GetSType (e2), e2tok); /* 3rd parameter */
18239 : 1852 : M2Quads_BuildRelOp (e2tok); /* choose final expression position. */
18240 : 1852 : PopBool (&t1, &exit1); /* choose final expression position. */
18241 : 1852 : BackPatch (t1, NextQuad);
18242 : 1852 : PushFor (Merge (PopFor (), exit1)); /* merge exit1 */
18243 : 1852 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0); /* merge exit1 */
18244 : 1852 : ForLoop = NextQuad-1;
18245 : : /* ELSE */
18246 : 1852 : BackPatch (t, NextQuad);
18247 : 1852 : M2Quads_PushTFtok (e2, SymbolTable_GetSType (e2), e2tok); /* BuildRelOp 1st parameter */
18248 : 1852 : M2Quads_PushT (M2Reserved_GreaterEqualTok); /* 2nd parameter */
18249 : 1852 : M2Quads_PushTFtok (e1, SymbolTable_GetSType (e1), e1tok); /* 3rd parameter */
18250 : 1852 : M2Quads_BuildRelOp (e2tok); /* 3rd parameter */
18251 : 1852 : PopBool (&t1, &exit1);
18252 : 1852 : BackPatch (t1, NextQuad);
18253 : 1852 : PushFor (Merge (PopFor (), exit1)); /* merge exit1 */
18254 : 1852 : BackPatch (ForLoop, NextQuad); /* fixes the start of the for loop */
18255 : 1852 : ForLoop = NextQuad;
18256 : : /* and set up the stack */
18257 : 1852 : M2Quads_PushTFtok (IdSym, SymbolTable_GetSym (IdSym), idtok);
18258 : 1852 : M2Quads_PushTFtok (BySym, ByType, bytok);
18259 : 1852 : M2Quads_PushTFtok (FinalValue, SymbolTable_GetSType (FinalValue), e2tok);
18260 : 1852 : M2Quads_PushT (ForLoop);
18261 : 1852 : M2Quads_PushT (RangeId);
18262 : 1852 : }
18263 : :
18264 : :
18265 : : /*
18266 : : BuildPseudoBy - Builds the Non existant part of the By
18267 : : clause of the For statement
18268 : : from the quad stack.
18269 : : The Stack is expected to contain:
18270 : :
18271 : :
18272 : : Entry Exit
18273 : : ===== ====
18274 : :
18275 : : <- Ptr
18276 : : +------------+
18277 : : Ptr -> | BySym | t |
18278 : : +------------+ |------------|
18279 : : | e | t | | e | t |
18280 : : |------------| |------------|
18281 : : */
18282 : :
18283 : 1618 : extern "C" void M2Quads_BuildPseudoBy (void)
18284 : : {
18285 : 1618 : unsigned int expr;
18286 : 1618 : unsigned int type;
18287 : 1618 : unsigned int dotok;
18288 : :
18289 : : /* As there is no BY token this position is the DO at the end of the last expression. */
18290 : 1618 : M2Quads_PopTFtok (&expr, &type, &dotok);
18291 : 1618 : M2Quads_PushTFtok (expr, type, dotok);
18292 : 1618 : if (type == SymbolTable_NulSym)
18293 : : {} /* empty. */
18294 : : /* Use type. */
18295 : 1542 : else if ((SymbolTable_IsEnumeration (SymbolTable_SkipType (type))) || ((SymbolTable_SkipType (type)) == M2Base_Char))
18296 : : {
18297 : : /* avoid dangling else. */
18298 : : }
18299 : 1322 : else if (M2Base_IsOrdinalType (SymbolTable_SkipType (type)))
18300 : : {
18301 : : /* avoid dangling else. */
18302 : 1322 : type = M2Base_ZType;
18303 : : }
18304 : 1618 : PushOne (dotok, type, (const char *) "the implied {%kFOR} loop increment will cause an overflow {%1ad}", 64);
18305 : 1618 : }
18306 : :
18307 : :
18308 : : /*
18309 : : BuildEndFor - Builds the End part of the For statement
18310 : : from the quad stack.
18311 : : The Stack is expected to contain:
18312 : :
18313 : :
18314 : : Entry Exit
18315 : : ===== ====
18316 : :
18317 : : Ptr ->
18318 : : +----------------+
18319 : : | RangeId |
18320 : : |----------------|
18321 : : | ForQuad |
18322 : : |----------------|
18323 : : | LastValue |
18324 : : |----------------|
18325 : : | BySym | ByType |
18326 : : |----------------|
18327 : : | IdSym | Empty
18328 : : |----------------|
18329 : : */
18330 : :
18331 : 1852 : extern "C" void M2Quads_BuildEndFor (unsigned int endpostok)
18332 : : {
18333 : 1852 : unsigned int t;
18334 : 1852 : unsigned int f;
18335 : 1852 : unsigned int tsym;
18336 : 1852 : unsigned int RangeId;
18337 : 1852 : unsigned int IncQuad;
18338 : 1852 : unsigned int ForQuad;
18339 : 1852 : unsigned int LastSym;
18340 : 1852 : unsigned int ByType;
18341 : 1852 : unsigned int BySym;
18342 : 1852 : unsigned int bytok;
18343 : 1852 : unsigned int IdSym;
18344 : 1852 : unsigned int idtok;
18345 : :
18346 : 1852 : M2Quads_PopT (&RangeId);
18347 : 1852 : M2Quads_PopT (&ForQuad);
18348 : 1852 : M2Quads_PopT (&LastSym);
18349 : 1852 : M2Quads_PopTFtok (&BySym, &ByType, &bytok);
18350 : 1852 : M2Quads_PopTtok (&IdSym, &idtok);
18351 : : /* IF IdSym=LastSym THEN exit END */
18352 : 1852 : M2Quads_PushTF (IdSym, SymbolTable_GetSType (IdSym));
18353 : 1852 : M2Quads_PushT (M2Reserved_EqualTok);
18354 : 1852 : M2Quads_PushTF (LastSym, SymbolTable_GetSType (LastSym));
18355 : 1852 : M2Quads_BuildRelOp (endpostok);
18356 : 1852 : PopBool (&t, &f);
18357 : 1852 : BackPatch (t, NextQuad);
18358 : 1852 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18359 : 1852 : PushFor (Merge (PopFor (), NextQuad-1));
18360 : 1852 : BackPatch (f, NextQuad);
18361 : 1852 : if ((SymbolTable_GetMode (IdSym)) == SymbolTable_LeftValue)
18362 : : {
18363 : : /* index variable is a LeftValue, therefore we must dereference it */
18364 : 0 : tsym = SymbolTable_MakeTemporary (idtok, SymbolTable_RightValue);
18365 : 0 : SymbolTable_PutVar (tsym, SymbolTable_GetSType (IdSym));
18366 : 0 : CheckPointerThroughNil (idtok, IdSym);
18367 : 0 : doIndrX (endpostok, tsym, IdSym);
18368 : 0 : BuildRange (M2Range_InitForLoopEndRangeCheck (tsym, BySym)); /* --fixme-- pass endpostok. */
18369 : 0 : IncQuad = NextQuad;
18370 : : /* we have explicitly checked using the above and also
18371 : : this addition can legitimately overflow if a cardinal type
18372 : : is counting down. The above test will generate a more
18373 : : precise error message, so we suppress overflow detection
18374 : : here. */
18375 : 0 : GenQuadOTypetok (bytok, M2Quads_AddOp, tsym, tsym, BySym, false, false, idtok, idtok, bytok);
18376 : 0 : CheckPointerThroughNil (idtok, IdSym);
18377 : 0 : GenQuadOtok (idtok, M2Quads_XIndrOp, IdSym, SymbolTable_GetSType (IdSym), tsym, false, idtok, idtok, idtok);
18378 : : }
18379 : : else
18380 : : {
18381 : 1852 : BuildRange (M2Range_InitForLoopEndRangeCheck (IdSym, BySym));
18382 : 1852 : IncQuad = NextQuad;
18383 : : /* we have explicitly checked using the above and also
18384 : : this addition can legitimately overflow if a cardinal type
18385 : : is counting down. The above test will generate a more
18386 : : precise error message, so we suppress overflow detection
18387 : : here.
18388 : :
18389 : : This quadruple suppresses the generic binary op type
18390 : : check (performed in M2GenGCC.mod) as there
18391 : : will be a more informative/exhaustive check performed by the
18392 : : InitForLoopBeginRangeCheck setup in BuildForToByDo and
18393 : : performed by M2Range.mod. */
18394 : 1852 : GenQuadOTypetok (idtok, M2Quads_AddOp, IdSym, IdSym, BySym, false, false, idtok, idtok, bytok);
18395 : : }
18396 : 1852 : GenQuadO (endpostok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, ForQuad, false);
18397 : 1852 : BackPatch (PopFor (), NextQuad);
18398 : 1852 : AddForInfo (ForQuad, NextQuad-1, IncQuad, IdSym, idtok);
18399 : 1852 : M2Range_PutRangeForIncrement (RangeId, IncQuad);
18400 : 1852 : }
18401 : :
18402 : :
18403 : : /*
18404 : : BuildCaseStart - starts the case statement.
18405 : : It initializes a backpatch list on the compile
18406 : : time stack, the list is used to contain all
18407 : : case break points. The list is later backpatched
18408 : : and contains all positions of the case statement
18409 : : which jump to the end of the case statement.
18410 : : The stack also contains room for a boolean
18411 : : expression, this is needed to allow , operator
18412 : : in the CaseField alternatives.
18413 : :
18414 : : The Stack is expected to contain:
18415 : :
18416 : :
18417 : : Entry Exit
18418 : : ===== ====
18419 : :
18420 : : <- Ptr
18421 : : +------------+
18422 : : | 0 | 0 |
18423 : : |------------|
18424 : : | 0 | 0 |
18425 : : +-------------+ |------------|
18426 : : | Expr | | | Expr | |
18427 : : |-------------| |------------|
18428 : : */
18429 : :
18430 : 561 : extern "C" void M2Quads_BuildCaseStart (void)
18431 : : {
18432 : 561 : BuildRange (M2Range_InitCaseBounds (M2CaseList_PushCase (SymbolTable_NulSym, SymbolTable_NulSym, M2Quads_OperandT (1))));
18433 : 561 : PushBool (0, 0); /* BackPatch list initialized */
18434 : 561 : PushBool (0, 0); /* Room for a boolean expression */
18435 : 561 : }
18436 : :
18437 : :
18438 : : /*
18439 : : BuildCaseStartStatementSequence - starts the statement sequence
18440 : : inside a case clause.
18441 : : BackPatches the true exit to the
18442 : : NextQuad.
18443 : : The Stack:
18444 : :
18445 : : Entry Exit
18446 : :
18447 : : Ptr -> <- Ptr
18448 : : +-----------+ +------------+
18449 : : | t | f | | 0 | f |
18450 : : |-----------| |------------|
18451 : : */
18452 : :
18453 : 2537 : extern "C" void M2Quads_BuildCaseStartStatementSequence (void)
18454 : : {
18455 : 2537 : unsigned int t;
18456 : 2537 : unsigned int f;
18457 : :
18458 : 2537 : PopBool (&t, &f);
18459 : 2537 : BackPatch (t, NextQuad);
18460 : 2537 : PushBool (0, f);
18461 : 2537 : }
18462 : :
18463 : :
18464 : : /*
18465 : : BuildCaseEndStatementSequence - ends the statement sequence
18466 : : inside a case clause.
18467 : : BackPatches the false exit f1 to the
18468 : : NextQuad.
18469 : : Asserts that t1 and f2 is 0
18470 : : Pushes t2+q and 0
18471 : :
18472 : : Quadruples:
18473 : :
18474 : : q GotoOp _ _ 0
18475 : :
18476 : : The Stack:
18477 : :
18478 : : Entry Exit
18479 : :
18480 : : Ptr -> <- Ptr
18481 : : +-----------+ +------------+
18482 : : | t1 | f1 | | 0 | 0 |
18483 : : |-----------| |------------|
18484 : : | t2 | f2 | | t2+q | 0 |
18485 : : |-----------| |------------|
18486 : : */
18487 : :
18488 : 2537 : extern "C" void M2Quads_BuildCaseEndStatementSequence (void)
18489 : : {
18490 : 2537 : unsigned int t1;
18491 : 2537 : unsigned int f1;
18492 : 2537 : unsigned int t2;
18493 : 2537 : unsigned int f2;
18494 : :
18495 : 2537 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18496 : 2537 : PopBool (&t1, &f1);
18497 : 2537 : PopBool (&t2, &f2); /* t2 contains the break list for the case */
18498 : 2537 : BackPatch (f1, NextQuad); /* f1 no longer needed */
18499 : 2537 : M2Debug_Assert (t1 == 0); /* f1 no longer needed */
18500 : 2537 : M2Debug_Assert (f2 == 0);
18501 : 2537 : PushBool (Merge (t2, NextQuad-1), 0); /* NextQuad-1 = Goto Quad */
18502 : 2537 : PushBool (0, 0); /* Room for boolean expression */
18503 : 2537 : }
18504 : :
18505 : :
18506 : : /*
18507 : : BuildCaseRange - builds the range testing quaruples for
18508 : : a case clause.
18509 : :
18510 : : IF (e1>=ce1) AND (e1<=ce2)
18511 : : THEN
18512 : :
18513 : : ELS..
18514 : :
18515 : : The Stack:
18516 : :
18517 : : Entry Exit
18518 : :
18519 : : Ptr ->
18520 : : +-----------+
18521 : : | ce2 | <- Ptr
18522 : : |-----------| +-----------+
18523 : : | ce1 | | t | f |
18524 : : |-----------| |-----------|
18525 : : | t1 | f1 | | t1 | f1 |
18526 : : |-----------| |-----------|
18527 : : | t2 | f2 | | t2 | f2 |
18528 : : |-----------| |-----------|
18529 : : | e1 | | e1 |
18530 : : |-----------| |-----------|
18531 : : */
18532 : :
18533 : 166 : extern "C" void M2Quads_BuildCaseRange (void)
18534 : : {
18535 : 166 : unsigned int ce1;
18536 : 166 : unsigned int ce2;
18537 : 166 : unsigned int combinedtok;
18538 : 166 : unsigned int ce1tok;
18539 : 166 : unsigned int ce2tok;
18540 : 166 : unsigned int e1tok;
18541 : 166 : unsigned int e1;
18542 : 166 : unsigned int t2;
18543 : 166 : unsigned int f2;
18544 : 166 : unsigned int t1;
18545 : 166 : unsigned int f1;
18546 : :
18547 : 166 : M2Quads_PopTtok (&ce2, &ce2tok);
18548 : 166 : M2Quads_PopTtok (&ce1, &ce1tok);
18549 : 166 : combinedtok = M2LexBuf_MakeVirtualTok (ce2tok, ce2tok, ce1tok);
18550 : 166 : M2CaseList_AddRange (ce1, ce2, combinedtok);
18551 : 166 : PopBool (&t1, &f1);
18552 : 166 : PopBool (&t2, &f2);
18553 : 166 : M2Quads_PopTtok (&e1, &e1tok);
18554 : 166 : M2Quads_PushTtok (e1, e1tok); /* leave e1 on bottom of stack when exit procedure */
18555 : 166 : PushBool (t2, f2); /* leave e1 on bottom of stack when exit procedure */
18556 : 166 : PushBool (t1, f1); /* also leave t1 and f1 on the bottom of the stack */
18557 : 166 : M2Quads_PushTtok (e1, e1tok); /* also leave t1 and f1 on the bottom of the stack */
18558 : 166 : M2Quads_PushT (M2Reserved_GreaterEqualTok);
18559 : 166 : M2Quads_PushTtok (ce1, ce1tok);
18560 : 166 : M2Quads_BuildRelOp (combinedtok);
18561 : 166 : M2Quads_PushT (M2Reserved_AndTok);
18562 : 166 : M2Quads_RecordOp ();
18563 : 166 : M2Quads_PushTtok (e1, e1tok);
18564 : 166 : M2Quads_PushT (M2Reserved_LessEqualTok);
18565 : 166 : M2Quads_PushTtok (ce2, ce2tok);
18566 : 166 : M2Quads_BuildRelOp (combinedtok);
18567 : 166 : M2Quads_BuildBinaryOp ();
18568 : 166 : }
18569 : :
18570 : :
18571 : : /*
18572 : : BuildCaseEquality - builds the range testing quadruples for
18573 : : a case clause.
18574 : :
18575 : : IF e1=ce1
18576 : : THEN
18577 : :
18578 : : ELS..
18579 : :
18580 : : The Stack:
18581 : :
18582 : : Entry Exit
18583 : :
18584 : : Ptr ->
18585 : : +-----------+ +-----------+
18586 : : | ce1 | | t | f |
18587 : : |-----------| |-----------|
18588 : : | t1 | f1 | | t1 | f1 |
18589 : : |-----------| |-----------|
18590 : : | t2 | f2 | | t2 | f2 |
18591 : : |-----------| |-----------|
18592 : : | e1 | | e1 |
18593 : : |-----------| |-----------|
18594 : : */
18595 : :
18596 : 2421 : extern "C" void M2Quads_BuildCaseEquality (void)
18597 : : {
18598 : 2421 : unsigned int ce1tok;
18599 : 2421 : unsigned int e1tok;
18600 : 2421 : unsigned int ce1;
18601 : 2421 : unsigned int e1;
18602 : 2421 : unsigned int t2;
18603 : 2421 : unsigned int f2;
18604 : 2421 : unsigned int t1;
18605 : 2421 : unsigned int f1;
18606 : :
18607 : 2421 : M2Quads_PopTtok (&ce1, &ce1tok);
18608 : 2421 : M2CaseList_AddRange (ce1, SymbolTable_NulSym, ce1tok);
18609 : 2421 : PopBool (&t1, &f1);
18610 : 2421 : PopBool (&t2, &f2);
18611 : 2421 : M2Quads_PopTtok (&e1, &e1tok);
18612 : 2421 : M2Quads_PushTtok (e1, e1tok); /* leave e1 on bottom of stack when exit procedure */
18613 : 2421 : PushBool (t2, f2); /* also leave t2 and f2 on the bottom of the stack */
18614 : 2421 : PushBool (t1, f1); /* also leave t2 and f2 on the bottom of the stack */
18615 : 2421 : M2Quads_PushTtok (e1, e1tok);
18616 : 2421 : M2Quads_PushT (M2Reserved_EqualTok);
18617 : 2421 : M2Quads_PushTtok (ce1, ce1tok);
18618 : 2421 : M2Quads_BuildRelOp (ce1tok);
18619 : 2421 : }
18620 : :
18621 : :
18622 : : /*
18623 : : BuildCaseList - merges two case tests into one
18624 : :
18625 : : The Stack:
18626 : :
18627 : : Entry Exit
18628 : :
18629 : : Ptr ->
18630 : : +-----------+
18631 : : | t2 | f2 |
18632 : : |-----------| +-------------+
18633 : : | t1 | f1 | | t1+t2| f1+f2|
18634 : : |-----------| |-------------|
18635 : : */
18636 : :
18637 : 2587 : extern "C" void M2Quads_BuildCaseList (void)
18638 : : {
18639 : 2587 : unsigned int t2;
18640 : 2587 : unsigned int f2;
18641 : 2587 : unsigned int t1;
18642 : 2587 : unsigned int f1;
18643 : :
18644 : 2587 : PopBool (&t2, &f2);
18645 : 2587 : PopBool (&t1, &f1);
18646 : 2587 : PushBool (Merge (t1, t2), Merge (f1, f2));
18647 : 2587 : }
18648 : :
18649 : :
18650 : : /*
18651 : : BuildCaseOr - builds the , in the case clause.
18652 : :
18653 : : The Stack:
18654 : :
18655 : : Entry Exit
18656 : :
18657 : : Ptr -> <- Ptr
18658 : : +-----------+ +------------+
18659 : : | t | f | | t | 0 |
18660 : : |-----------| |------------|
18661 : : */
18662 : :
18663 : 50 : extern "C" void M2Quads_BuildCaseOr (void)
18664 : : {
18665 : 50 : unsigned int t;
18666 : 50 : unsigned int f;
18667 : :
18668 : 50 : PopBool (&t, &f);
18669 : 50 : BackPatch (f, NextQuad);
18670 : 50 : PushBool (t, 0);
18671 : 50 : }
18672 : :
18673 : :
18674 : : /*
18675 : : BuildCaseElse - builds the else of case clause.
18676 : :
18677 : : The Stack:
18678 : :
18679 : : Entry Exit
18680 : :
18681 : : Ptr -> <- Ptr
18682 : : +-----------+ +------------+
18683 : : | t | f | | t | 0 |
18684 : : |-----------| |------------|
18685 : : */
18686 : :
18687 : 561 : extern "C" void M2Quads_BuildCaseElse (void)
18688 : : {
18689 : 561 : unsigned int t;
18690 : 561 : unsigned int f;
18691 : :
18692 : 561 : PopBool (&t, &f);
18693 : 561 : BackPatch (f, NextQuad);
18694 : 561 : PushBool (t, 0);
18695 : 561 : }
18696 : :
18697 : :
18698 : : /*
18699 : : BuildCaseEnd - builds the end of case clause.
18700 : :
18701 : : The Stack:
18702 : :
18703 : : Entry Exit
18704 : :
18705 : : Ptr ->
18706 : : +-----------+
18707 : : | t1 | f1 |
18708 : : |-----------|
18709 : : | t2 | f2 |
18710 : : |-----------|
18711 : : | e1 |
18712 : : |-----------| Empty
18713 : : */
18714 : :
18715 : 561 : extern "C" void M2Quads_BuildCaseEnd (void)
18716 : : {
18717 : 561 : unsigned int e1;
18718 : 561 : unsigned int t;
18719 : 561 : unsigned int f;
18720 : :
18721 : 561 : PopBool (&t, &f);
18722 : 561 : BackPatch (f, NextQuad);
18723 : 561 : BackPatch (t, NextQuad);
18724 : 561 : PopBool (&t, &f);
18725 : 561 : BackPatch (f, NextQuad);
18726 : 561 : BackPatch (t, NextQuad);
18727 : 561 : M2Quads_PopT (&e1);
18728 : 561 : M2CaseList_PopCase ();
18729 : 561 : }
18730 : :
18731 : :
18732 : : /*
18733 : : BuildCaseCheck - builds the case checking code to ensure that
18734 : : the program does not need an else clause at runtime.
18735 : : The stack is unaltered.
18736 : : */
18737 : :
18738 : 333 : extern "C" void M2Quads_BuildCaseCheck (void)
18739 : : {
18740 : 333 : BuildError (M2Range_InitNoElseRangeCheck ());
18741 : 333 : }
18742 : :
18743 : :
18744 : : /*
18745 : : BuildNulParam - Builds a nul parameter on the stack.
18746 : : The Stack:
18747 : :
18748 : : Entry Exit
18749 : :
18750 : : <- Ptr
18751 : : Empty +------------+
18752 : : | 0 |
18753 : : |------------|
18754 : : */
18755 : :
18756 : 14572 : extern "C" void M2Quads_BuildNulParam (void)
18757 : : {
18758 : 14572 : M2Quads_PushT (static_cast<unsigned int> (0));
18759 : 14572 : }
18760 : :
18761 : :
18762 : : /*
18763 : : BuildProcedureCall - builds a procedure call.
18764 : : Although this procedure does not directly
18765 : : destroy the procedure parameters, it calls
18766 : : routine which will manipulate the stack and
18767 : : so the entry and exit states of the stack are shown.
18768 : :
18769 : : The Stack:
18770 : :
18771 : :
18772 : : Entry Exit
18773 : :
18774 : : Ptr ->
18775 : : +----------------+
18776 : : | NoOfParam |
18777 : : |----------------|
18778 : : | Param 1 |
18779 : : |----------------|
18780 : : | Param 2 |
18781 : : |----------------|
18782 : : . .
18783 : : . .
18784 : : . .
18785 : : |----------------|
18786 : : | Param # |
18787 : : |----------------|
18788 : : | ProcSym | Type | Empty
18789 : : |----------------|
18790 : : */
18791 : :
18792 : 146856 : extern "C" void M2Quads_BuildProcedureCall (unsigned int tokno)
18793 : : {
18794 : 146856 : unsigned int NoOfParam;
18795 : 146856 : unsigned int ProcSym;
18796 : :
18797 : 146856 : M2Quads_PopT (&NoOfParam);
18798 : 146856 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
18799 : 146856 : M2Quads_PushT (NoOfParam); /* Compile time stack restored to entry state */
18800 : 146856 : if ((M2Base_IsPseudoBaseProcedure (ProcSym)) || (M2System_IsPseudoSystemProcedure (ProcSym))) /* Compile time stack restored to entry state */
18801 : : {
18802 : 16464 : M2Quads_DisplayStack ();
18803 : 16464 : ManipulatePseudoCallParameters ();
18804 : 16464 : M2Quads_DisplayStack ();
18805 : 16464 : BuildPseudoProcedureCall (tokno);
18806 : 16464 : M2Quads_DisplayStack ();
18807 : : }
18808 : 130392 : else if (SymbolTable_IsUnknown (ProcSym))
18809 : : {
18810 : : /* avoid dangling else. */
18811 : 0 : M2MetaError_MetaError1 ((const char *) "{%1Ua} is not recognised as a procedure, check declaration or import", 68, ProcSym);
18812 : 0 : M2Quads_PopN (NoOfParam+2);
18813 : : }
18814 : : else
18815 : : {
18816 : : /* avoid dangling else. */
18817 : 130392 : M2Quads_DisplayStack ();
18818 : 130392 : BuildRealProcedureCall (tokno);
18819 : 130392 : M2Quads_DisplayStack ();
18820 : : }
18821 : 146856 : }
18822 : :
18823 : :
18824 : : /*
18825 : : CheckBuildFunction - checks to see whether ProcSym is a function
18826 : : and if so it adds a TempSym value which will
18827 : : hold the return value once the function finishes.
18828 : : This procedure also generates an error message
18829 : : if the user is calling a function and ignoring
18830 : : the return result. The additional TempSym
18831 : : is not created if ProcSym is a procedure
18832 : : and the stack is unaltered.
18833 : :
18834 : : The Stack:
18835 : :
18836 : :
18837 : : Entry Exit
18838 : :
18839 : : Ptr ->
18840 : :
18841 : : +----------------+
18842 : : | ProcSym | Type |
18843 : : +----------------+ |----------------|
18844 : : | ProcSym | Type | | TempSym | Type |
18845 : : |----------------| |----------------|
18846 : : */
18847 : :
18848 : 85834 : extern "C" bool M2Quads_CheckBuildFunction (void)
18849 : : {
18850 : 85834 : NameKey_Name n;
18851 : 85834 : unsigned int tokpos;
18852 : 85834 : unsigned int TempSym;
18853 : 85834 : unsigned int ProcSym;
18854 : 85834 : unsigned int Type;
18855 : :
18856 : 85834 : M2Quads_PopTFtok (&ProcSym, &Type, &tokpos);
18857 : 85834 : if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (Type)))
18858 : : {
18859 : : /* avoid dangling else. */
18860 : 596 : if ((SymbolTable_GetSType (Type)) != SymbolTable_NulSym)
18861 : : {
18862 : 0 : TempSym = SymbolTable_MakeTemporary (tokpos, SymbolTable_RightValue);
18863 : 0 : SymbolTable_PutVar (TempSym, SymbolTable_GetSType (Type));
18864 : 0 : M2Quads_PushTFtok (TempSym, SymbolTable_GetSType (Type), tokpos);
18865 : 0 : M2Quads_PushTFtok (ProcSym, Type, tokpos);
18866 : 0 : if (! (SymbolTable_IsReturnOptional (Type)))
18867 : : {
18868 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
18869 : 0 : if (SymbolTable_IsTemporary (ProcSym))
18870 : : {
18871 : 0 : M2Error_ErrorFormat0 (M2Error_NewError (tokpos), (const char *) "function is being called but its return value is ignored", 56);
18872 : : }
18873 : : else
18874 : : {
18875 : 0 : n = SymbolTable_GetSymName (ProcSym);
18876 : 0 : M2Error_ErrorFormat1 (M2Error_NewError (tokpos), (const char *) "function (%a) is being called but its return value is ignored", 61, (const unsigned char *) &n, (sizeof (n)-1));
18877 : : }
18878 : : }
18879 : 0 : return true;
18880 : : }
18881 : : }
18882 : 85238 : else if ((SymbolTable_IsProcedure (ProcSym)) && (Type != SymbolTable_NulSym))
18883 : : {
18884 : : /* avoid dangling else. */
18885 : 0 : TempSym = SymbolTable_MakeTemporary (tokpos, SymbolTable_RightValue);
18886 : 0 : SymbolTable_PutVar (TempSym, Type);
18887 : 0 : M2Quads_PushTFtok (TempSym, Type, tokpos);
18888 : 0 : M2Quads_PushTFtok (ProcSym, Type, tokpos);
18889 : 0 : if (! (SymbolTable_IsReturnOptional (ProcSym)))
18890 : : {
18891 : 0 : n = SymbolTable_GetSymName (ProcSym);
18892 : 0 : M2Error_ErrorFormat1 (M2Error_NewError (tokpos), (const char *) "function (%a) is being called but its return value is ignored", 61, (const unsigned char *) &n, (sizeof (n)-1));
18893 : : }
18894 : 0 : return true;
18895 : : }
18896 : 85834 : M2Quads_PushTFtok (ProcSym, Type, tokpos);
18897 : 85834 : return false;
18898 : : /* static analysis guarentees a RETURN statement will be used before here. */
18899 : : __builtin_unreachable ();
18900 : : }
18901 : :
18902 : :
18903 : : /*
18904 : : BuildFunctionCall - builds a function call.
18905 : : The Stack:
18906 : :
18907 : :
18908 : : Entry Exit
18909 : :
18910 : : Ptr ->
18911 : : +----------------+
18912 : : | NoOfParam |
18913 : : |----------------|
18914 : : | Param 1 |
18915 : : |----------------|
18916 : : | Param 2 |
18917 : : |----------------|
18918 : : . .
18919 : : . .
18920 : : . .
18921 : : |----------------|
18922 : : | Param # | <- Ptr
18923 : : |----------------| +------------+
18924 : : | ProcSym | Type | | ReturnVar |
18925 : : |----------------| |------------|
18926 : : */
18927 : :
18928 : 70704 : extern "C" void M2Quads_BuildFunctionCall (bool ConstExpr)
18929 : : {
18930 : 70704 : unsigned int paramtok;
18931 : 70704 : unsigned int combinedtok;
18932 : 70704 : unsigned int functok;
18933 : 70704 : unsigned int NoOfParam;
18934 : 70704 : unsigned int ProcSym;
18935 : :
18936 : 70704 : M2Quads_PopT (&NoOfParam);
18937 : 70704 : functok = OperandTtok (NoOfParam+1);
18938 : 70704 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
18939 : 70704 : ProcSym = PCSymBuild_SkipConst (ProcSym);
18940 : 70704 : M2Quads_PushT (NoOfParam);
18941 : : /* Compile time stack restored to entry state. */
18942 : 70704 : if (SymbolTable_IsUnknown (ProcSym))
18943 : : {
18944 : 6 : paramtok = OperandTtok (1);
18945 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, paramtok);
18946 : 6 : M2MetaError_MetaErrorT1 (functok, (const char *) "procedure function {%1Ea} is undefined", 38, ProcSym);
18947 : 6 : M2Quads_PopN (NoOfParam+2);
18948 : : /* Fake return value to continue compiling. */
18949 : 6 : M2Quads_PushT (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym));
18950 : : }
18951 : 70698 : else if (SymbolTable_IsAModula2Type (ProcSym))
18952 : : {
18953 : : /* avoid dangling else. */
18954 : 1112 : ManipulatePseudoCallParameters ();
18955 : 1112 : BuildTypeCoercion ();
18956 : : }
18957 : 69586 : else if ((M2System_IsPseudoSystemFunction (ProcSym)) || (M2Base_IsPseudoBaseFunction (ProcSym)))
18958 : : {
18959 : : /* avoid dangling else. */
18960 : 31604 : ManipulatePseudoCallParameters ();
18961 : 31604 : BuildPseudoFunctionCall (ConstExpr);
18962 : : }
18963 : : else
18964 : : {
18965 : : /* avoid dangling else. */
18966 : 37982 : BuildRealFunctionCall (functok, ConstExpr);
18967 : : }
18968 : 70698 : }
18969 : :
18970 : :
18971 : : /*
18972 : : BuildConstFunctionCall - builds a function call and checks that this function can be
18973 : : called inside a ConstExpression.
18974 : :
18975 : : The Stack:
18976 : :
18977 : :
18978 : : Entry Exit
18979 : :
18980 : : Ptr ->
18981 : : +----------------+
18982 : : | NoOfParam |
18983 : : |----------------|
18984 : : | Param 1 |
18985 : : |----------------|
18986 : : | Param 2 |
18987 : : |----------------|
18988 : : . .
18989 : : . .
18990 : : . .
18991 : : |----------------|
18992 : : | Param # | <- Ptr
18993 : : |----------------| +------------+
18994 : : | ProcSym | Type | | ReturnVar |
18995 : : |----------------| |------------|
18996 : :
18997 : : */
18998 : :
18999 : 4035 : extern "C" void M2Quads_BuildConstFunctionCall (void)
19000 : : {
19001 : 4035 : unsigned int functok;
19002 : 4035 : unsigned int combinedtok;
19003 : 4035 : unsigned int paramtok;
19004 : 4035 : unsigned int ConstExpression;
19005 : 4035 : unsigned int NoOfParam;
19006 : 4035 : unsigned int ProcSym;
19007 : :
19008 : 4035 : M2Quads_DisplayStack ();
19009 : 4035 : M2Quads_PopT (&NoOfParam);
19010 : 4035 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
19011 : 4035 : functok = OperandTtok (NoOfParam+1);
19012 : 4035 : if (M2Options_CompilerDebugging)
19013 : : {
19014 : 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));
19015 : : }
19016 : : /* ErrorStringAt (InitString ('constant function'), functok). */
19017 : 4035 : M2Quads_PushT (NoOfParam);
19018 : 4035 : if ((ProcSym != M2Base_Convert) && (((M2Base_IsPseudoBaseFunction (ProcSym)) || (M2System_IsPseudoSystemFunctionConstExpression (ProcSym))) || ((SymbolTable_IsProcedure (ProcSym)) && (SymbolTable_IsProcedureBuiltin (ProcSym)))))
19019 : : {
19020 : 3915 : M2Quads_BuildFunctionCall (true);
19021 : : }
19022 : : else
19023 : : {
19024 : 120 : if (SymbolTable_IsAModula2Type (ProcSym))
19025 : : {
19026 : : /* Type conversion. */
19027 : 120 : if (NoOfParam == 1)
19028 : : {
19029 : 120 : ConstExpression = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
19030 : 120 : paramtok = OperandTtok (NoOfParam+1);
19031 : 120 : M2Quads_PopN (NoOfParam+2);
19032 : : /* Build macro: CONVERT( ProcSym, ConstExpression ). */
19033 : 120 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
19034 : 120 : M2Quads_PushTtok (ProcSym, functok);
19035 : 120 : M2Quads_PushTtok (ConstExpression, paramtok);
19036 : 120 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters. */
19037 : 120 : BuildConvertFunction (M2Base_Convert, true); /* Two parameters. */
19038 : : }
19039 : : else
19040 : : {
19041 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}a constant type conversion can only have one argument", 57);
19042 : : }
19043 : : }
19044 : : else
19045 : : {
19046 : : /* Error issue message and fake return stack. */
19047 : 0 : if (M2Options_Iso)
19048 : : {
19049 : 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}, {%kTRUNC}, {%kVAL} and gcc builtins", 231);
19050 : : }
19051 : : else
19052 : : {
19053 : 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}, {%kVAL} and gcc builtins", 192);
19054 : : }
19055 : 0 : if (NoOfParam > 0)
19056 : : {
19057 : 0 : paramtok = OperandTtok (NoOfParam+1);
19058 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
19059 : : }
19060 : : else
19061 : : {
19062 : 0 : combinedtok = functok;
19063 : : }
19064 : 0 : M2Quads_PopN (NoOfParam+2);
19065 : 0 : M2Quads_PushT (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym)); /* Fake return value to continue compiling. */
19066 : : }
19067 : : }
19068 : 4035 : }
19069 : :
19070 : :
19071 : : /*
19072 : : BuildBooleanVariable - tests to see whether top of stack is a boolean
19073 : : conditional and if so it converts it into a boolean
19074 : : variable.
19075 : : */
19076 : :
19077 : 272626 : extern "C" void M2Quads_BuildBooleanVariable (void)
19078 : : {
19079 : 272626 : if (IsBoolean (1))
19080 : : {
19081 : 6178 : ConvertBooleanToVariable (OperandTtok (1), 1);
19082 : : }
19083 : 272626 : }
19084 : :
19085 : :
19086 : : /*
19087 : : BuildModuleStart - starts current module scope.
19088 : : */
19089 : :
19090 : 59612 : extern "C" void M2Quads_BuildModuleStart (unsigned int tok)
19091 : : {
19092 : 59612 : GenQuadO (tok, M2Quads_ModuleScopeOp, tok, (unsigned int ) (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()))), SymbolTable_GetCurrentModule (), false);
19093 : 59612 : }
19094 : :
19095 : :
19096 : : /*
19097 : : BuildProcedureStart - Builds start of the procedure. Generates a
19098 : : quadruple which indicated the start of
19099 : : this procedure declarations scope.
19100 : : The Stack is expected to contain:
19101 : :
19102 : :
19103 : : Entry Exit
19104 : : ===== ====
19105 : :
19106 : : Ptr -> <- Ptr
19107 : : +------------+ +-----------+
19108 : : | ProcSym | | ProcSym |
19109 : : |------------| |-----------|
19110 : : | Name | | Name |
19111 : : |------------| |-----------|
19112 : :
19113 : :
19114 : : Quadruples:
19115 : :
19116 : : q ProcedureScopeOp Line# Scope ProcSym
19117 : : */
19118 : :
19119 : 63557 : extern "C" void M2Quads_BuildProcedureStart (void)
19120 : : {
19121 : 63557 : unsigned int ProcSym;
19122 : :
19123 : 63557 : M2Quads_PopT (&ProcSym);
19124 : 63557 : M2Debug_Assert (SymbolTable_IsProcedure (ProcSym));
19125 : 63557 : SymbolTable_PutProcedureScopeQuad (ProcSym, NextQuad);
19126 : 63557 : GenQuad (M2Quads_ProcedureScopeOp, M2LexBuf_GetPreviousTokenLineNo (), SymbolTable_GetScope (ProcSym), ProcSym);
19127 : 63557 : M2Quads_PushT (ProcSym);
19128 : 63557 : }
19129 : :
19130 : :
19131 : : /*
19132 : : BuildProcedureBegin - determines the start of the BEGIN END block of
19133 : : the procedure.
19134 : : The Stack is expected to contain:
19135 : :
19136 : :
19137 : : Entry Exit
19138 : : ===== ====
19139 : :
19140 : : Ptr -> <- Ptr
19141 : : +------------+ +-----------+
19142 : : | ProcSym | | ProcSym |
19143 : : |------------| |-----------|
19144 : : | Name | | Name |
19145 : : |------------| |-----------|
19146 : :
19147 : :
19148 : : Quadruples:
19149 : :
19150 : : q NewLocalVarOp TokenNo(BEGIN) _ ProcSym
19151 : : */
19152 : :
19153 : 63557 : extern "C" void M2Quads_BuildProcedureBegin (void)
19154 : : {
19155 : 63557 : unsigned int ProcSym;
19156 : :
19157 : 63557 : M2Quads_PopT (&ProcSym);
19158 : 63557 : M2Debug_Assert (SymbolTable_IsProcedure (ProcSym));
19159 : 63557 : SymbolTable_PutProcedureStartQuad (ProcSym, NextQuad);
19160 : 63557 : SymbolTable_PutProcedureBegin (ProcSym, M2LexBuf_GetTokenNo ());
19161 : 63557 : GenQuad (M2Quads_NewLocalVarOp, M2LexBuf_GetTokenNo (), SymbolTable_GetScope (ProcSym), ProcSym);
19162 : 63557 : CurrentProc = ProcSym;
19163 : 63557 : M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
19164 : 63557 : M2Quads_PushT (ProcSym);
19165 : 63557 : CheckVariablesAt (ProcSym);
19166 : 63557 : CheckNeedPriorityBegin (M2LexBuf_GetTokenNo (), ProcSym, SymbolTable_GetCurrentModule ());
19167 : 63557 : M2StackWord_PushWord (TryStack, NextQuad);
19168 : 63557 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
19169 : 63557 : if (SymbolTable_HasExceptionBlock (ProcSym))
19170 : : {
19171 : 132 : GenQuad (M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
19172 : : }
19173 : 63557 : }
19174 : :
19175 : :
19176 : : /*
19177 : : BuildProcedureEnd - Builds end of the procedure. Destroys space for
19178 : : the local variables.
19179 : : The Stack is expected to contain:
19180 : :
19181 : :
19182 : : Entry Exit
19183 : : ===== ====
19184 : :
19185 : : Ptr -> <- Ptr
19186 : : +------------+ +-----------+
19187 : : | ProcSym | | ProcSym |
19188 : : |------------| |-----------|
19189 : : | Name | | Name |
19190 : : |------------| |-----------|
19191 : :
19192 : :
19193 : : Quadruples:
19194 : :
19195 : : q KillLocalVarOp TokenNo(END) _ ProcSym
19196 : : */
19197 : :
19198 : 63527 : extern "C" void M2Quads_BuildProcedureEnd (void)
19199 : : {
19200 : 63527 : unsigned int tok;
19201 : 63527 : unsigned int ProcSym;
19202 : :
19203 : 63527 : M2Quads_PopTtok (&ProcSym, &tok);
19204 : 63527 : if (SymbolTable_HasExceptionBlock (ProcSym))
19205 : : {
19206 : 132 : BuildRTExceptLeave (tok, true);
19207 : 132 : GenQuad (M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
19208 : : }
19209 : 63527 : if ((SymbolTable_GetSType (ProcSym)) != SymbolTable_NulSym)
19210 : : {
19211 : 11528 : BuildError (M2Range_InitNoReturnRangeCheck ());
19212 : : }
19213 : 63527 : BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
19214 : 63527 : CheckNeedPriorityEnd (tok, ProcSym, SymbolTable_GetCurrentModule ());
19215 : 63527 : CurrentProc = SymbolTable_NulSym;
19216 : 63527 : SymbolTable_PutProcedureEnd (ProcSym, (M2LexBuf_GetTokenNo ())-1); /* --fixme-- */
19217 : 63527 : GenQuad (M2Quads_KillLocalVarOp, (M2LexBuf_GetTokenNo ())-1, SymbolTable_NulSym, ProcSym); /* --fixme-- */
19218 : 63527 : SymbolTable_PutProcedureEndQuad (ProcSym, NextQuad);
19219 : 63527 : GenQuad (M2Quads_ReturnOp, SymbolTable_NulSym, SymbolTable_NulSym, ProcSym);
19220 : 63527 : CheckFunctionReturn (ProcSym);
19221 : 63527 : CheckVariablesInBlock (ProcSym);
19222 : 63527 : M2StackWord_RemoveTop (CatchStack);
19223 : 63527 : M2StackWord_RemoveTop (TryStack);
19224 : 63527 : M2Quads_PushT (ProcSym);
19225 : 63527 : }
19226 : :
19227 : :
19228 : : /*
19229 : : BuildReturn - Builds the Return part of the procedure.
19230 : : tokreturn is the location of the RETURN keyword.
19231 : : The Stack is expected to contain:
19232 : :
19233 : :
19234 : : Entry Exit
19235 : : ===== ====
19236 : :
19237 : : Ptr ->
19238 : : +------------+
19239 : : | e1 | Empty
19240 : : |------------|
19241 : : */
19242 : :
19243 : 18611 : extern "C" void M2Quads_BuildReturn (unsigned int tokreturn)
19244 : : {
19245 : 18611 : unsigned int tokcombined;
19246 : 18611 : unsigned int tokexpr;
19247 : 18611 : unsigned int e2;
19248 : 18611 : unsigned int t2;
19249 : 18611 : unsigned int e1;
19250 : 18611 : unsigned int t1;
19251 : 18611 : unsigned int t;
19252 : 18611 : unsigned int f;
19253 : 18611 : unsigned int Des;
19254 : :
19255 : 18611 : if (IsBoolean (1))
19256 : : {
19257 : 1482 : PopBooltok (&t, &f, &tokexpr);
19258 : : /* Des will be a boolean type */
19259 : 1482 : Des = SymbolTable_MakeTemporary (tokexpr, SymbolTable_RightValue);
19260 : 1482 : SymbolTable_PutVar (Des, M2Base_Boolean);
19261 : 1482 : M2Quads_PushTFtok (Des, M2Base_Boolean, tokexpr);
19262 : 1482 : PushBooltok (t, f, tokexpr);
19263 : 1482 : BuildAssignmentWithoutBounds (tokreturn, false, true);
19264 : 1482 : M2Quads_PushTFtok (Des, M2Base_Boolean, tokexpr);
19265 : : }
19266 : 18611 : M2Quads_PopTFtok (&e1, &t1, &tokexpr);
19267 : 18611 : tokcombined = M2LexBuf_MakeVirtualTok (tokreturn, tokreturn, tokexpr);
19268 : 18611 : if (e1 != SymbolTable_NulSym)
19269 : : {
19270 : : /* this will check that the type returned is compatible with
19271 : : the formal return type of the procedure. */
19272 : 17903 : CheckReturnType (tokcombined, CurrentProc, e1, t1);
19273 : : /* dereference LeftValue if necessary */
19274 : 17903 : if ((SymbolTable_GetMode (e1)) == SymbolTable_LeftValue)
19275 : : {
19276 : 108 : t2 = SymbolTable_GetSType (CurrentProc);
19277 : 108 : e2 = SymbolTable_MakeTemporary (tokexpr, SymbolTable_RightValue);
19278 : 108 : SymbolTable_PutVar (e2, t2);
19279 : 108 : CheckPointerThroughNil (tokexpr, e1);
19280 : 108 : doIndrX (tokexpr, e2, e1);
19281 : : /* here we check the data contents to ensure no overflow. */
19282 : 108 : BuildRange (M2Range_InitReturnRangeCheck (tokcombined, CurrentProc, e2));
19283 : 108 : GenQuadOtok (tokcombined, M2Quads_ReturnValueOp, e2, SymbolTable_NulSym, CurrentProc, false, tokcombined, M2LexBuf_UnknownTokenNo, SymbolTable_GetDeclaredMod (CurrentProc));
19284 : : }
19285 : : else
19286 : : {
19287 : : /* here we check the data contents to ensure no overflow. */
19288 : 17795 : BuildRange (M2Range_InitReturnRangeCheck (tokcombined, CurrentProc, e1));
19289 : 17795 : GenQuadOtok (tokcombined, M2Quads_ReturnValueOp, e1, SymbolTable_NulSym, CurrentProc, false, tokcombined, M2LexBuf_UnknownTokenNo, SymbolTable_GetDeclaredMod (CurrentProc));
19290 : : }
19291 : : }
19292 : 18611 : GenQuadO (tokcombined, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PopWord (ReturnStack), false);
19293 : 18611 : M2StackWord_PushWord (ReturnStack, NextQuad-1);
19294 : 18611 : }
19295 : :
19296 : :
19297 : : /*
19298 : : BuildModulePriority - assigns the current module with a priority
19299 : : from the top of stack.
19300 : :
19301 : : Entry Exit
19302 : : ===== ====
19303 : :
19304 : :
19305 : : Ptr -> Empty
19306 : : +------------+
19307 : : | Priority |
19308 : : |------------|
19309 : : */
19310 : :
19311 : 38 : extern "C" void M2Quads_BuildModulePriority (void)
19312 : : {
19313 : 38 : unsigned int Priority;
19314 : :
19315 : 38 : M2Quads_PopT (&Priority);
19316 : 38 : SymbolTable_PutPriority (SymbolTable_GetCurrentModule (), Priority);
19317 : 38 : }
19318 : :
19319 : :
19320 : : /*
19321 : : StartBuildWith - performs the with statement.
19322 : : The Stack:
19323 : :
19324 : : Entry Exit
19325 : :
19326 : : +------------+
19327 : : | Sym | Type | Empty
19328 : : |------------|
19329 : : */
19330 : :
19331 : 4871 : extern "C" void M2Quads_StartBuildWith (unsigned int withTok)
19332 : : {
19333 : 4871 : unsigned int tok;
19334 : 4871 : unsigned int Sym;
19335 : 4871 : unsigned int Type;
19336 : 4871 : unsigned int Ref;
19337 : :
19338 : 4871 : DebugLocation (static_cast<unsigned int> (M2Reserved_withtok), (const char *) "with", 4);
19339 : 4871 : BuildStmtNoteTok (withTok);
19340 : 4871 : M2Quads_DisplayStack ();
19341 : 4871 : M2Quads_PopTFtok (&Sym, &Type, &tok);
19342 : 4871 : DebugLocation (tok, (const char *) "expression", 10);
19343 : 4871 : Type = SymbolTable_SkipType (Type);
19344 : 4871 : Ref = SymbolTable_MakeTemporary (tok, SymbolTable_LeftValue);
19345 : 4871 : SymbolTable_PutVar (Ref, Type);
19346 : 4871 : if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
19347 : : {
19348 : : /* Copy LeftValue. */
19349 : 4658 : GenQuadO (tok, M2Quads_BecomesOp, Ref, SymbolTable_NulSym, Sym, true);
19350 : : }
19351 : : else
19352 : : {
19353 : : /* Calculate the address of Sym. */
19354 : 213 : GenQuadO (tok, M2Quads_AddrOp, Ref, SymbolTable_NulSym, Sym, true);
19355 : : }
19356 : 4871 : PushWith (Sym, Type, Ref, tok);
19357 : 4871 : DebugLocation (tok, (const char *) "with ref", 8);
19358 : 4871 : if (Type == SymbolTable_NulSym)
19359 : : {
19360 : 0 : M2MetaError_MetaError1 ((const char *) "{%1Ea} {%1d} has a no type, the {%kWITH} statement requires a variable or parameter of a {%kRECORD} type", 104, Sym);
19361 : : }
19362 : 4871 : else if (! (SymbolTable_IsRecord (Type)))
19363 : : {
19364 : : /* avoid dangling else. */
19365 : 0 : M2MetaError_MetaError1 ((const char *) "the {%kWITH} statement requires that {%1Ea} {%1d} be of a {%kRECORD} {%1tsa:type rather than {%1tsa}}", 101, Sym);
19366 : : }
19367 : 4871 : SymbolTable_StartScope (Type);
19368 : 4871 : M2Quads_DisplayStack ();
19369 : 4871 : }
19370 : :
19371 : :
19372 : : /*
19373 : : EndBuildWith - terminates the innermost with scope.
19374 : : */
19375 : :
19376 : 4871 : extern "C" void M2Quads_EndBuildWith (void)
19377 : : {
19378 : 4871 : M2Quads_DisplayStack ();
19379 : 4871 : SymbolTable_EndScope ();
19380 : 4871 : PopWith ();
19381 : 4871 : M2Quads_DisplayStack ();
19382 : 4871 : }
19383 : :
19384 : :
19385 : : /*
19386 : : CheckWithReference - performs the with statement.
19387 : : The Stack:
19388 : :
19389 : : Entry Exit
19390 : :
19391 : : +------------+ +------------+
19392 : : | Sym | Type | | Sym | Type |
19393 : : |------------| |------------|
19394 : : */
19395 : :
19396 : 525024 : extern "C" void M2Quads_CheckWithReference (void)
19397 : : {
19398 : 525024 : M2Quads_WithFrame f;
19399 : 525024 : unsigned int tokpos;
19400 : 525024 : unsigned int i;
19401 : 525024 : unsigned int n;
19402 : 525024 : unsigned int rw;
19403 : 525024 : unsigned int Sym;
19404 : 525024 : unsigned int Type;
19405 : :
19406 : 525024 : n = M2StackAddress_NoOfItemsInStackAddress (WithStack);
19407 : 525024 : if ((n > 0) && ! SuppressWith)
19408 : : {
19409 : 86249 : PopTFrwtok (&Sym, &Type, &rw, &tokpos);
19410 : 86249 : M2Debug_Assert (tokpos != M2LexBuf_UnknownTokenNo);
19411 : : /* inner WITH always has precidence */
19412 : 86249 : i = 1; /* top of stack */
19413 : : /* WriteString('Checking for a with') ; */
19414 : 270000 : while (i <= n)
19415 : : {
19416 : 97502 : f = static_cast<M2Quads_WithFrame> (M2StackAddress_PeepAddress (WithStack, i));
19417 : 97502 : if ((SymbolTable_IsRecordField (Sym)) && ((SymbolTable_GetRecord (SymbolTable_GetParent (Sym))) == f->RecordType))
19418 : : {
19419 : 25436 : if (SymbolTable_IsUnused (Sym))
19420 : : {
19421 : 0 : M2MetaError_MetaError1 ((const char *) "record field {%1Dad} was declared as unused by a pragma", 55, Sym);
19422 : : }
19423 : : /* Fake a RecordSym.op */
19424 : 25436 : PushTFrwtok (f->RecordRef, f->RecordType, f->rw, f->RecordTokPos);
19425 : 25436 : M2Quads_PushTFtok (Sym, Type, tokpos);
19426 : 25436 : BuildAccessWithField ();
19427 : 25436 : PopTFrw (&Sym, &Type, &f->rw);
19428 : 25436 : i = n+1; /* Finish loop. */
19429 : : }
19430 : : else
19431 : : {
19432 : 72066 : i += 1;
19433 : : }
19434 : : }
19435 : 86249 : PushTFrwtok (Sym, Type, rw, tokpos);
19436 : : }
19437 : 525024 : }
19438 : :
19439 : :
19440 : : /*
19441 : : BuildDesignatorRecord - Builds the record referencing.
19442 : : The Stack is expected to contain:
19443 : :
19444 : :
19445 : : Entry Exit
19446 : : ===== ====
19447 : :
19448 : : Ptr ->
19449 : : +--------------+
19450 : : | n |
19451 : : |--------------|
19452 : : | fld1 | type1 |
19453 : : |--------------|
19454 : : . .
19455 : : . .
19456 : : . .
19457 : : |--------------|
19458 : : | fldn | typen | <- Ptr
19459 : : |--------------| +-------------+
19460 : : | Sym | Type | | S | type1|
19461 : : |--------------| |-------------|
19462 : : */
19463 : :
19464 : 91781 : extern "C" void M2Quads_BuildDesignatorRecord (unsigned int dottok)
19465 : : {
19466 : 91781 : unsigned int RecordTok;
19467 : 91781 : unsigned int FieldTok;
19468 : 91781 : unsigned int combinedtok;
19469 : 91781 : unsigned int n;
19470 : 91781 : unsigned int rw;
19471 : 91781 : unsigned int Field;
19472 : 91781 : unsigned int FieldType;
19473 : 91781 : unsigned int RecordSym;
19474 : 91781 : unsigned int Res;
19475 : :
19476 : 91781 : M2Quads_PopT (&n);
19477 : 91781 : RecordSym = static_cast<unsigned int> (M2Quads_OperandT (n+1));
19478 : : /* RecordType could be found by: SkipType (OperandF (n+1)). */
19479 : 91781 : RecordTok = static_cast<unsigned int> (M2Quads_OperandTok (n+1));
19480 : 91781 : rw = static_cast<unsigned int> (OperandMergeRW (n+1));
19481 : 91781 : M2Debug_Assert (SymbolTable_IsLegal (rw));
19482 : 91781 : Field = static_cast<unsigned int> (M2Quads_OperandT (n));
19483 : 91781 : FieldType = SymbolTable_SkipType (M2Quads_OperandF (n));
19484 : 91781 : FieldTok = static_cast<unsigned int> (M2Quads_OperandTok (n));
19485 : 91781 : combinedtok = M2LexBuf_MakeVirtualTok (dottok, RecordTok, FieldTok);
19486 : 91781 : if (n > 1)
19487 : : {
19488 : 0 : M2Error_InternalError ((const char *) "not expecting to see n>1", 24);
19489 : : }
19490 : 91781 : if (SymbolTable_IsUnused (Field))
19491 : : {
19492 : 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);
19493 : : }
19494 : 91781 : Res = SymbolTable_MakeComponentRef (SymbolTable_MakeComponentRecord (combinedtok, SymbolTable_RightValue, RecordSym), Field);
19495 : 91781 : SymbolTable_PutVarConst (Res, IsReadOnly (RecordSym));
19496 : 91781 : GenQuadO (combinedtok, M2Quads_RecordFieldOp, Res, RecordSym, Field, false);
19497 : 91781 : M2Quads_PopN (n+1);
19498 : 91781 : PushTFrwtok (Res, FieldType, rw, combinedtok);
19499 : 91781 : }
19500 : :
19501 : :
19502 : : /*
19503 : : BuildDesignatorArray - Builds the array referencing.
19504 : : The purpose of this procedure is to work out
19505 : : whether the DesignatorArray is a static or
19506 : : dynamic array and to call the appropriate
19507 : : BuildRoutine.
19508 : :
19509 : : The Stack is expected to contain:
19510 : :
19511 : :
19512 : : Entry Exit
19513 : : ===== ====
19514 : :
19515 : : Ptr ->
19516 : : +--------------+
19517 : : | e | <- Ptr
19518 : : |--------------| +------------+
19519 : : | Sym | Type | | S | T |
19520 : : |--------------| |------------|
19521 : : */
19522 : :
19523 : 44516 : extern "C" void M2Quads_BuildDesignatorArray (void)
19524 : : {
19525 : 44516 : unsigned int combinedTok;
19526 : 44516 : unsigned int arrayTok;
19527 : 44516 : unsigned int exprTok;
19528 : 44516 : unsigned int e;
19529 : 44516 : unsigned int type;
19530 : 44516 : unsigned int dim;
19531 : 44516 : unsigned int result;
19532 : 44516 : unsigned int Sym;
19533 : 44516 : unsigned int Type;
19534 : :
19535 : 44516 : if (SymbolTable_IsConst (M2Quads_OperandT (2)))
19536 : : {
19537 : 174 : type = SymbolTable_GetDType (M2Quads_OperandT (2));
19538 : 174 : if (type == SymbolTable_NulSym)
19539 : : {
19540 : 0 : M2Error_InternalError ((const char *) "constant type should have been resolved", 39);
19541 : : }
19542 : 174 : else if (SymbolTable_IsArray (type))
19543 : : {
19544 : : /* avoid dangling else. */
19545 : 174 : M2Quads_PopTtok (&e, &exprTok);
19546 : 174 : PopTFDtok (&Sym, &Type, &dim, &arrayTok);
19547 : 174 : result = SymbolTable_MakeTemporary (exprTok, SymbolTable_RightValue);
19548 : 174 : SymbolTable_PutVar (result, Type);
19549 : 174 : M2Quads_PushTFtok (result, SymbolTable_GetSType (result), exprTok);
19550 : 174 : M2Quads_PushTtok (Sym, arrayTok);
19551 : 174 : combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, exprTok);
19552 : 174 : SymbolTable_PutVarConst (result, true);
19553 : 174 : M2Quads_BuildAssignConstant (combinedTok);
19554 : 174 : PushTFDtok (result, SymbolTable_GetDType (result), dim, arrayTok);
19555 : 174 : M2Quads_PushTtok (e, exprTok);
19556 : : }
19557 : : }
19558 : 44516 : if ((! (SymbolTable_IsVar (M2Quads_OperandT (2)))) && (! (SymbolTable_IsTemporary (M2Quads_OperandT (2)))))
19559 : : {
19560 : 0 : M2MetaError_MetaErrorT1 (OperandTtok (2), (const char *) "can only access arrays using variables or formal parameters not {%1Ead}", 71, M2Quads_OperandT (2));
19561 : 0 : BuildDesignatorError ((const char *) "bad array access", 16);
19562 : : }
19563 : 44516 : Sym = static_cast<unsigned int> (M2Quads_OperandT (2));
19564 : 44516 : Type = SymbolTable_GetDType (Sym);
19565 : 44516 : arrayTok = OperandTtok (2);
19566 : 44516 : if (Type == SymbolTable_NulSym)
19567 : : {
19568 : 0 : if ((arrayTok == M2LexBuf_UnknownTokenNo) || (arrayTok == M2LexBuf_BuiltinTokenNo))
19569 : : {
19570 : 0 : arrayTok = M2LexBuf_GetTokenNo ();
19571 : : }
19572 : 0 : M2MetaError_MetaErrorT0 (arrayTok, (const char *) "type of array is undefined", 26);
19573 : 0 : BuildDesignatorError ((const char *) "bad array access", 16);
19574 : : }
19575 : 44516 : else if (SymbolTable_IsUnbounded (Type))
19576 : : {
19577 : : /* avoid dangling else. */
19578 : 7574 : BuildDynamicArray ();
19579 : : }
19580 : 36942 : else if (SymbolTable_IsArray (Type))
19581 : : {
19582 : : /* avoid dangling else. */
19583 : 36924 : BuildStaticArray ();
19584 : : }
19585 : : else
19586 : : {
19587 : : /* avoid dangling else. */
19588 : 18 : M2MetaError_MetaErrorT1 (arrayTok, (const char *) "can only index static or dynamic arrays, {%1Ead} is not an array but a {%tad}", 77, Sym);
19589 : 18 : BuildDesignatorError ((const char *) "bad array access", 16);
19590 : : }
19591 : 44516 : }
19592 : :
19593 : :
19594 : : /*
19595 : : BuildDesignatorPointer - Builds a pointer reference.
19596 : : The Stack is expected to contain:
19597 : :
19598 : :
19599 : : Entry Exit
19600 : : ===== ====
19601 : :
19602 : : Ptr -> <- Ptr
19603 : : +--------------+ +--------------+
19604 : : | Sym1 | Type1| | Sym2 | Type2|
19605 : : |--------------| |--------------|
19606 : : */
19607 : :
19608 : 13200 : extern "C" void M2Quads_BuildDesignatorPointer (unsigned int ptrtok)
19609 : : {
19610 : 13200 : unsigned int combinedtok;
19611 : 13200 : unsigned int exprtok;
19612 : 13200 : unsigned int rw;
19613 : 13200 : unsigned int Sym1;
19614 : 13200 : unsigned int Type1;
19615 : 13200 : unsigned int Sym2;
19616 : 13200 : unsigned int Type2;
19617 : :
19618 : 13200 : PopTFrwtok (&Sym1, &Type1, &rw, &exprtok);
19619 : 13200 : DebugLocation (exprtok, (const char *) "expression", 10);
19620 : 13200 : Type1 = SymbolTable_SkipType (Type1);
19621 : 13200 : if (Type1 == SymbolTable_NulSym)
19622 : : {
19623 : 0 : M2MetaError_MetaErrorT1 (ptrtok, (const char *) "{%1ad} has no type and therefore cannot be dereferenced by ^", 60, Sym1);
19624 : : }
19625 : 13200 : else if (SymbolTable_IsUnknown (Sym1))
19626 : : {
19627 : : /* avoid dangling else. */
19628 : 0 : M2MetaError_MetaError1 ((const char *) "{%1EMad} is undefined and therefore {%1ad}^ cannot be resolved", 62, Sym1);
19629 : : }
19630 : 13200 : else if (SymbolTable_IsPointer (Type1))
19631 : : {
19632 : : /* avoid dangling else. */
19633 : 13200 : Type2 = SymbolTable_GetSType (Type1);
19634 : 13200 : Sym2 = SymbolTable_MakeTemporary (ptrtok, SymbolTable_LeftValue);
19635 : : /*
19636 : : Ok must reference by address
19637 : : - but we contain the type of the referenced entity
19638 : : */
19639 : 13200 : MarkAsRead (rw);
19640 : 13200 : SymbolTable_PutVarPointerCheck (Sym1, true);
19641 : 13200 : CheckPointerThroughNil (ptrtok, Sym1);
19642 : 13200 : if ((SymbolTable_GetMode (Sym1)) == SymbolTable_LeftValue)
19643 : : {
19644 : 498 : rw = SymbolTable_NulSym;
19645 : 498 : SymbolTable_PutLeftValueFrontBackType (Sym2, Type2, Type1);
19646 : 498 : GenQuadO (ptrtok, M2Quads_IndrXOp, Sym2, Type1, Sym1, false); /* Sym2 := *Sym1 */
19647 : : }
19648 : : else
19649 : : {
19650 : 12702 : SymbolTable_PutLeftValueFrontBackType (Sym2, Type2, SymbolTable_NulSym);
19651 : 12702 : GenQuadO (ptrtok, M2Quads_BecomesOp, Sym2, SymbolTable_NulSym, Sym1, false); /* Sym2 := Sym1 */
19652 : : }
19653 : 13200 : SymbolTable_PutVarPointerCheck (Sym2, true); /* we should check this for */
19654 : : /* Sym2 later on (pointer via NIL) */
19655 : 13200 : combinedtok = M2LexBuf_MakeVirtualTok (exprtok, exprtok, ptrtok);
19656 : 13200 : PushTFrwtok (Sym2, Type2, rw, combinedtok);
19657 : 13200 : DebugLocation (combinedtok, (const char *) "pointer expression", 18);
19658 : : }
19659 : : else
19660 : : {
19661 : : /* avoid dangling else. */
19662 : 0 : M2MetaError_MetaError2 ((const char *) "{%1ad} is not a pointer type but a {%2d}", 40, Sym1, Type1);
19663 : : }
19664 : 13200 : }
19665 : :
19666 : :
19667 : : /*
19668 : : BuildNulExpression - Builds a nul expression on the stack.
19669 : : The Stack:
19670 : :
19671 : : Entry Exit
19672 : :
19673 : : <- Ptr
19674 : : Empty +------------+
19675 : : | NulSym |
19676 : : |------------|
19677 : : tokpos is the position of the RETURN token.
19678 : : */
19679 : :
19680 : 708 : extern "C" void M2Quads_BuildNulExpression (unsigned int tokpos)
19681 : : {
19682 : 708 : M2Quads_PushTtok (static_cast<unsigned int> (SymbolTable_NulSym), tokpos);
19683 : 708 : }
19684 : :
19685 : :
19686 : : /*
19687 : : BuildSetStart - Pushes a Bitset type on the stack.
19688 : :
19689 : : The Stack:
19690 : :
19691 : : Entry Exit
19692 : :
19693 : : Ptr -> <- Ptr
19694 : :
19695 : : Empty +--------------+
19696 : : | Bitset |
19697 : : |--------------|
19698 : : */
19699 : :
19700 : 0 : extern "C" void M2Quads_BuildSetStart (unsigned int tokpos)
19701 : : {
19702 : 0 : M2Quads_PushTtok (M2Bitset_Bitset, tokpos);
19703 : 0 : }
19704 : :
19705 : :
19706 : : /*
19707 : : BuildSetEnd - pops the set value and type from the stack
19708 : : and pushes the value,type pair.
19709 : :
19710 : : Entry Exit
19711 : :
19712 : : Ptr ->
19713 : : +--------------+
19714 : : | Set Value | <- Ptr
19715 : : |--------------| +--------------+
19716 : : | Set Type | | Value | Type |
19717 : : |--------------| |--------------|
19718 : : */
19719 : :
19720 : 0 : extern "C" void M2Quads_BuildSetEnd (void)
19721 : : {
19722 : 0 : unsigned int valuepos;
19723 : 0 : unsigned int typepos;
19724 : 0 : unsigned int combined;
19725 : 0 : unsigned int value;
19726 : 0 : unsigned int type;
19727 : :
19728 : 0 : M2Quads_PopTtok (&value, &valuepos);
19729 : 0 : M2Quads_PopTtok (&type, &typepos);
19730 : 0 : combined = M2LexBuf_MakeVirtual2Tok (typepos, valuepos);
19731 : 0 : M2Quads_PushTFtok (value, type, combined);
19732 : 0 : M2Debug_Assert (SymbolTable_IsSet (type));
19733 : 0 : }
19734 : :
19735 : :
19736 : : /*
19737 : : BuildEmptySet - Builds an empty set on the stack.
19738 : : The Stack:
19739 : :
19740 : : Entry Exit
19741 : :
19742 : : <- Ptr
19743 : : +-------------+
19744 : : Ptr -> | Value |
19745 : : +-----------+ |-------------|
19746 : : | SetType | | SetType |
19747 : : |-----------| |-------------|
19748 : :
19749 : : tokpos points to the opening '{'.
19750 : : */
19751 : :
19752 : 0 : extern "C" void M2Quads_BuildEmptySet (unsigned int tokpos)
19753 : : {
19754 : 0 : NameKey_Name n;
19755 : 0 : unsigned int typepos;
19756 : 0 : unsigned int Type;
19757 : 0 : unsigned int NulSet;
19758 : :
19759 : 0 : M2Quads_PopTtok (&Type, &typepos); /* type of set we are building */
19760 : 0 : if ((Type == SymbolTable_NulSym) && M2Options_Pim)
19761 : : {
19762 : : /* allowed generic {} in PIM Modula-2 */
19763 : 0 : typepos = tokpos;
19764 : : }
19765 : 0 : else if (SymbolTable_IsUnknown (Type))
19766 : : {
19767 : : /* avoid dangling else. */
19768 : 0 : n = SymbolTable_GetSymName (Type);
19769 : 0 : M2Error_WriteFormat1 ((const char *) "set type %a is undefined", 24, (const unsigned char *) &n, (sizeof (n)-1));
19770 : 0 : Type = M2Bitset_Bitset;
19771 : : }
19772 : 0 : else if (! (SymbolTable_IsSet (SymbolTable_SkipType (Type))))
19773 : : {
19774 : : /* avoid dangling else. */
19775 : 0 : n = SymbolTable_GetSymName (Type);
19776 : 0 : M2Error_WriteFormat1 ((const char *) "expecting a set type %a", 23, (const unsigned char *) &n, (sizeof (n)-1));
19777 : 0 : Type = M2Bitset_Bitset;
19778 : : }
19779 : : else
19780 : : {
19781 : : /* avoid dangling else. */
19782 : 0 : Type = SymbolTable_SkipType (Type);
19783 : 0 : M2Debug_Assert (Type != SymbolTable_NulSym);
19784 : : }
19785 : 0 : NulSet = SymbolTable_MakeTemporary (typepos, SymbolTable_ImmediateValue);
19786 : 0 : SymbolTable_PutVar (NulSet, Type);
19787 : 0 : SymbolTable_PutConstSet (NulSet);
19788 : 0 : if (M2Options_CompilerDebugging)
19789 : : {
19790 : 0 : n = SymbolTable_GetSymName (Type);
19791 : 0 : M2Printf_printf1 ((const char *) "set type = %a\\n", 15, (const unsigned char *) &n, (sizeof (n)-1));
19792 : : }
19793 : 0 : M2ALU_PushNulSet (Type); /* onto the ALU stack */
19794 : 0 : SymbolTable_PopValue (NulSet); /* ALU -> symbol table */
19795 : : /* and now construct the M2Quads stack as defined by the comments above */
19796 : 0 : M2Quads_PushTtok (Type, typepos);
19797 : 0 : M2Quads_PushTtok (NulSet, typepos);
19798 : 0 : if (M2Options_CompilerDebugging)
19799 : : {
19800 : 0 : n = SymbolTable_GetSymName (Type);
19801 : 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));
19802 : 0 : M2Quads_DisplayStack (); /* Debugging info */
19803 : : }
19804 : 0 : }
19805 : :
19806 : :
19807 : : /*
19808 : : BuildInclRange - includes a set range with a set.
19809 : :
19810 : :
19811 : : Entry Exit
19812 : : ===== ====
19813 : :
19814 : :
19815 : : Ptr ->
19816 : : +------------+
19817 : : | El2 |
19818 : : |------------|
19819 : : | El1 | <- Ptr
19820 : : |------------| +-------------------+
19821 : : | Set Value | | Value + {El1..El2}|
19822 : : |------------| |-------------------|
19823 : :
19824 : : No quadruples produced as the range info is contained within
19825 : : the set value.
19826 : : */
19827 : :
19828 : 0 : extern "C" void M2Quads_BuildInclRange (void)
19829 : : {
19830 : 0 : NameKey_Name n;
19831 : 0 : unsigned int el1;
19832 : 0 : unsigned int el2;
19833 : 0 : unsigned int value;
19834 : :
19835 : 0 : M2Quads_PopT (&el2);
19836 : 0 : M2Quads_PopT (&el1);
19837 : 0 : M2Quads_PopT (&value);
19838 : 0 : if (! (SymbolTable_IsConstSet (value)))
19839 : : {
19840 : 0 : n = SymbolTable_GetSymName (el1);
19841 : 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));
19842 : : }
19843 : 0 : if ((SymbolTable_IsConst (el1)) && (SymbolTable_IsConst (el2)))
19844 : : {
19845 : 0 : SymbolTable_PushValue (value); /* onto ALU stack */
19846 : 0 : M2ALU_AddBitRange (M2LexBuf_GetTokenNo (), el1, el2); /* onto ALU stack */
19847 : 0 : SymbolTable_PopValue (value); /* ALU -> symboltable */
19848 : : }
19849 : : else
19850 : : {
19851 : 0 : if (! (SymbolTable_IsConst (el1)))
19852 : : {
19853 : 0 : n = SymbolTable_GetSymName (el1);
19854 : 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));
19855 : : }
19856 : 0 : if (! (SymbolTable_IsConst (el2)))
19857 : : {
19858 : 0 : n = SymbolTable_GetSymName (el2);
19859 : 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));
19860 : : }
19861 : : }
19862 : 0 : M2Quads_PushT (value);
19863 : 0 : }
19864 : :
19865 : :
19866 : : /*
19867 : : BuildInclBit - includes a bit into the set.
19868 : :
19869 : : Entry Exit
19870 : : ===== ====
19871 : :
19872 : :
19873 : : Ptr ->
19874 : : +------------+
19875 : : | Element | <- Ptr
19876 : : |------------| +------------+
19877 : : | Value | | Value |
19878 : : |------------| |------------|
19879 : :
19880 : : */
19881 : :
19882 : 9858 : extern "C" void M2Quads_BuildInclBit (void)
19883 : : {
19884 : 9858 : unsigned int tok;
19885 : 9858 : unsigned int el;
19886 : 9858 : unsigned int value;
19887 : 9858 : unsigned int t;
19888 : :
19889 : 9858 : M2Quads_PopT (&el);
19890 : 9858 : M2Quads_PopT (&value);
19891 : 9858 : tok = M2LexBuf_GetTokenNo ();
19892 : 9858 : if (SymbolTable_IsConst (el))
19893 : : {
19894 : 9811 : SymbolTable_PushValue (value); /* onto ALU stack */
19895 : 9811 : M2ALU_AddBit (tok, el); /* onto ALU stack */
19896 : 9811 : SymbolTable_PopValue (value); /* ALU -> symboltable */
19897 : : }
19898 : : else
19899 : : {
19900 : 47 : if ((SymbolTable_GetMode (el)) == SymbolTable_LeftValue)
19901 : : {
19902 : 0 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
19903 : 0 : SymbolTable_PutVar (t, SymbolTable_GetSType (el));
19904 : 0 : CheckPointerThroughNil (tok, el);
19905 : 0 : doIndrX (tok, t, el);
19906 : 0 : el = t;
19907 : : }
19908 : 47 : if (SymbolTable_IsConst (value))
19909 : : {
19910 : : /* move constant into a variable to achieve the include */
19911 : 47 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
19912 : 47 : SymbolTable_PutVar (t, SymbolTable_GetSType (value));
19913 : 47 : GenQuad (M2Quads_BecomesOp, t, SymbolTable_NulSym, value);
19914 : 47 : value = t;
19915 : : }
19916 : 47 : GenQuad (M2Quads_InclOp, value, SymbolTable_NulSym, el);
19917 : : }
19918 : 9858 : M2Quads_PushT (value);
19919 : 9858 : }
19920 : :
19921 : :
19922 : : /*
19923 : : SilentBuildConstructor - places NulSym into the constructor fifo queue.
19924 : : */
19925 : :
19926 : 0 : extern "C" void M2Quads_SilentBuildConstructor (void)
19927 : : {
19928 : 0 : FifoQueue_PutConstructorIntoFifoQueue (SymbolTable_NulSym);
19929 : 0 : }
19930 : :
19931 : :
19932 : : /*
19933 : : SilentBuildConstructorStart - removes an entry from the constructor fifo queue.
19934 : : */
19935 : :
19936 : 10322 : extern "C" void M2Quads_SilentBuildConstructorStart (void)
19937 : : {
19938 : 10322 : unsigned int constValue;
19939 : :
19940 : 10322 : FifoQueue_GetConstructorFromFifoQueue (&constValue);
19941 : 10322 : }
19942 : :
19943 : :
19944 : : /*
19945 : : BuildConstructor - builds a constructor.
19946 : : Stack
19947 : :
19948 : : Entry Exit
19949 : :
19950 : : Ptr ->
19951 : : +------------+
19952 : : | Type | <- Ptr
19953 : : |------------+
19954 : : */
19955 : :
19956 : 19802 : extern "C" void M2Quads_BuildConstructor (unsigned int tokcbrpos)
19957 : : {
19958 : 19802 : unsigned int tok;
19959 : 19802 : unsigned int constValue;
19960 : 19802 : unsigned int type;
19961 : :
19962 : 19802 : M2Quads_PopTtok (&type, &tok);
19963 : 19802 : constValue = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
19964 : 19802 : SymbolTable_PutVar (constValue, type);
19965 : 19802 : SymbolTable_PutConstructor (constValue);
19966 : 19802 : SymbolTable_PushValue (constValue);
19967 : 19802 : if (type == SymbolTable_NulSym)
19968 : : {
19969 : 6 : M2MetaError_MetaErrorT0 (tokcbrpos, (const char *) "{%E}constructor requires a type before the opening %{", 53);
19970 : : }
19971 : : else
19972 : : {
19973 : 19796 : M2ALU_ChangeToConstructor (tok, type);
19974 : 19796 : SymbolTable_PutConstructorFrom (constValue, type);
19975 : 19796 : SymbolTable_PopValue (constValue);
19976 : 19796 : FifoQueue_PutConstructorIntoFifoQueue (constValue);
19977 : : }
19978 : 19802 : PushConstructor (type);
19979 : 19802 : }
19980 : :
19981 : :
19982 : : /*
19983 : : BuildConstructorStart - builds a constructor.
19984 : : Stack
19985 : :
19986 : : Entry Exit
19987 : :
19988 : : Ptr -> <- Ptr
19989 : : +------------+ +----------------+
19990 : : | Type | | ConstructorSym |
19991 : : |------------+ |----------------|
19992 : : */
19993 : :
19994 : 9468 : extern "C" void M2Quads_BuildConstructorStart (unsigned int cbratokpos)
19995 : : {
19996 : 9468 : unsigned int typepos;
19997 : 9468 : unsigned int constValue;
19998 : 9468 : unsigned int type;
19999 : :
20000 : 9468 : M2Quads_PopTtok (&type, &typepos); /* we ignore the type as we already have the constructor symbol from pass C */
20001 : 9468 : FifoQueue_GetConstructorFromFifoQueue (&constValue); /* we ignore the type as we already have the constructor symbol from pass C */
20002 : 9468 : if (type != (SymbolTable_GetSType (constValue)))
20003 : : {
20004 : 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);
20005 : : }
20006 : 9468 : M2Quads_PushTtok (constValue, cbratokpos);
20007 : 9468 : PushConstructor (type);
20008 : 9468 : }
20009 : :
20010 : :
20011 : : /*
20012 : : BuildConstructorEnd - removes the current constructor frame from the
20013 : : constructor stack (it does not effect the quad
20014 : : stack)
20015 : :
20016 : : Entry Exit
20017 : :
20018 : : Ptr -> <- Ptr
20019 : : +------------+ +------------+
20020 : : | const | | const |
20021 : : |------------| |------------|
20022 : :
20023 : : startpos is the start of the constructor, either the typename or '{'
20024 : : cbratokpos is the '}'.
20025 : : */
20026 : :
20027 : 9468 : extern "C" void M2Quads_BuildConstructorEnd (unsigned int startpos, unsigned int cbratokpos)
20028 : : {
20029 : 9468 : unsigned int value;
20030 : 9468 : unsigned int valtok;
20031 : :
20032 : 9468 : if (DebugTokPos)
20033 : : {
20034 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "startpos", 8), startpos);
20035 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "cbratokpos", 10), cbratokpos);
20036 : : }
20037 : 9468 : M2Quads_PopTtok (&value, &valtok);
20038 : 9468 : if (DebugTokPos)
20039 : : {
20040 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "value valtok", 12), valtok);
20041 : : }
20042 : 9468 : valtok = M2LexBuf_MakeVirtual2Tok (startpos, cbratokpos);
20043 : 9468 : SymbolTable_PutDeclared (valtok, value);
20044 : 9468 : M2Quads_PushTtok (value, valtok); /* Use valtok as we now know it was a constructor. */
20045 : 9468 : M2Quads_PopConstructor (); /* Use valtok as we now know it was a constructor. */
20046 : 9468 : if (DebugTokPos)
20047 : : {
20048 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "aggregate constant", 18), valtok);
20049 : : }
20050 : 9468 : }
20051 : :
20052 : :
20053 : : /*
20054 : : NextConstructorField - increments the top of constructor stacks index by one.
20055 : : */
20056 : :
20057 : 32896 : extern "C" void M2Quads_NextConstructorField (void)
20058 : : {
20059 : 32896 : M2Quads_ConstructorFrame c;
20060 : :
20061 : 32896 : c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PeepAddress (ConstructorStack, 1));
20062 : 32896 : c->index += 1;
20063 : 32896 : }
20064 : :
20065 : :
20066 : : /*
20067 : : BuildTypeForConstructor - pushes the type implied by the current constructor.
20068 : : If no constructor is currently being built then
20069 : : it Pushes a Bitset type.
20070 : : */
20071 : :
20072 : 1686 : extern "C" void M2Quads_BuildTypeForConstructor (unsigned int tokpos)
20073 : : {
20074 : 1686 : M2Quads_ConstructorFrame c;
20075 : :
20076 : 1686 : if ((M2StackAddress_NoOfItemsInStackAddress (ConstructorStack)) == 0)
20077 : : {
20078 : 618 : M2Quads_PushTtok (M2Bitset_Bitset, tokpos);
20079 : : }
20080 : : else
20081 : : {
20082 : 1068 : c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PeepAddress (ConstructorStack, 1));
20083 : 1068 : if ((SymbolTable_IsArray (c->type)) || (SymbolTable_IsSet (c->type)))
20084 : : {
20085 : 972 : M2Quads_PushTtok (SymbolTable_GetSType (c->type), tokpos);
20086 : : }
20087 : 96 : else if (SymbolTable_IsRecord (c->type))
20088 : : {
20089 : : /* avoid dangling else. */
20090 : 96 : M2Quads_PushTtok (SymbolTable_GetSType (SymbolTable_GetNth (c->type, c->index)), tokpos);
20091 : : }
20092 : : else
20093 : : {
20094 : : /* avoid dangling else. */
20095 : 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);
20096 : : }
20097 : : }
20098 : 1686 : }
20099 : :
20100 : :
20101 : : /*
20102 : : BuildComponentValue - builds a component value.
20103 : :
20104 : : Entry Exit
20105 : :
20106 : : Ptr -> <- Ptr
20107 : :
20108 : :
20109 : : +------------+ +------------+
20110 : : | const | | const |
20111 : : |------------| |------------|
20112 : : */
20113 : :
20114 : 23734 : extern "C" void M2Quads_BuildComponentValue (void)
20115 : : {
20116 : 23734 : unsigned int const_;
20117 : 23734 : unsigned int e1;
20118 : 23734 : unsigned int e2;
20119 : 23734 : NameKey_Name nuldotdot;
20120 : 23734 : NameKey_Name nulby;
20121 : :
20122 : 23734 : M2Quads_PopT (&nulby);
20123 : 23734 : if (nulby == M2Reserved_NulTok)
20124 : : {
20125 : 23704 : M2Quads_PopT (&nuldotdot);
20126 : 23704 : if (nuldotdot == M2Reserved_NulTok)
20127 : : {
20128 : 23462 : M2Quads_PopT (&e1);
20129 : 23462 : M2Quads_PopT (&const_);
20130 : 23462 : M2Quads_PushT (AddFieldTo (const_, e1));
20131 : : }
20132 : : else
20133 : : {
20134 : 242 : M2Quads_PopT (&e2);
20135 : 242 : M2Quads_PopT (&e1);
20136 : 242 : M2Quads_PopT (&const_);
20137 : 242 : SymbolTable_PushValue (const_);
20138 : 242 : M2ALU_AddBitRange (M2LexBuf_GetTokenNo (), e1, e2);
20139 : 242 : SymbolTable_PopValue (const_);
20140 : 242 : M2Quads_PushT (const_);
20141 : : }
20142 : : }
20143 : : else
20144 : : {
20145 : 30 : M2Quads_PopT (&e1);
20146 : 30 : M2Quads_PopT (&nuldotdot);
20147 : 30 : if (nuldotdot == M2Reserved_NulTok)
20148 : : {
20149 : 30 : M2Quads_PopT (&e2);
20150 : 30 : M2Quads_PopT (&const_);
20151 : 30 : SymbolTable_PushValue (const_);
20152 : 30 : M2ALU_AddElements (M2LexBuf_GetTokenNo (), e2, e1);
20153 : 30 : SymbolTable_PopValue (const_);
20154 : 30 : M2Quads_PushT (const_);
20155 : : }
20156 : : else
20157 : : {
20158 : 0 : M2Quads_PopT (&e2);
20159 : 0 : M2Quads_PopT (&e1);
20160 : 0 : M2Quads_PopT (&const_);
20161 : 0 : M2Error_WriteFormat0 ((const char *) "the constant must be an array constructor or a set constructor but not both", 75);
20162 : 0 : M2Quads_PushT (const_);
20163 : : }
20164 : : }
20165 : 23734 : }
20166 : :
20167 : :
20168 : : /*
20169 : : PopConstructor - removes the top constructor from the top of stack.
20170 : : */
20171 : :
20172 : 29270 : extern "C" void M2Quads_PopConstructor (void)
20173 : : {
20174 : 29270 : M2Quads_ConstructorFrame c;
20175 : :
20176 : 29270 : c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PopAddress (ConstructorStack));
20177 : 29270 : Storage_DEALLOCATE ((void **) &c, sizeof (M2Quads__T1));
20178 : 29270 : }
20179 : :
20180 : :
20181 : : /*
20182 : : BuildNot - Builds a NOT operation from the quad stack.
20183 : : The Stack is expected to contain:
20184 : :
20185 : :
20186 : : Entry Exit
20187 : : ===== ====
20188 : :
20189 : : Ptr -> <- Ptr
20190 : : +------------+ +------------+
20191 : : | t | f | | f | t |
20192 : : |------------| |------------|
20193 : : */
20194 : :
20195 : 3726 : extern "C" void M2Quads_BuildNot (unsigned int notTokPos)
20196 : : {
20197 : 3726 : unsigned int combinedTok;
20198 : 3726 : unsigned int exprTokPos;
20199 : 3726 : unsigned int t;
20200 : 3726 : unsigned int f;
20201 : :
20202 : 3726 : CheckBooleanId ();
20203 : 3726 : PopBooltok (&t, &f, &exprTokPos);
20204 : 3726 : combinedTok = M2LexBuf_MakeVirtualTok (notTokPos, notTokPos, exprTokPos);
20205 : 3726 : PushBooltok (f, t, combinedTok);
20206 : 3726 : }
20207 : :
20208 : :
20209 : : /*
20210 : : RecordOp - Records the operator passed on the stack.
20211 : : Checks for AND operator or OR operator
20212 : : if either of these operators are found then BackPatching
20213 : : takes place.
20214 : : The Expected Stack:
20215 : :
20216 : : Entry Exit
20217 : :
20218 : : Ptr -> <- Ptr
20219 : : +-------------+ +-------------+
20220 : : | OperatorTok | | OperatorTok |
20221 : : |-------------| |-------------|
20222 : : | t | f | | t | f |
20223 : : |-------------| |-------------|
20224 : :
20225 : :
20226 : : If OperatorTok=AndTok
20227 : : Then
20228 : : BackPatch(f, NextQuad)
20229 : : Elsif OperatorTok=OrTok
20230 : : Then
20231 : : BackPatch(t, NextQuad)
20232 : : End
20233 : : */
20234 : :
20235 : 44942 : extern "C" void M2Quads_RecordOp (void)
20236 : : {
20237 : 44942 : NameKey_Name Op;
20238 : 44942 : unsigned int tokno;
20239 : 44942 : unsigned int t;
20240 : 44942 : unsigned int f;
20241 : :
20242 : 44942 : M2Quads_PopTtok (&Op, &tokno);
20243 : 44942 : if ((Op == M2Reserved_AndTok) || (Op == M2Reserved_AmbersandTok))
20244 : : {
20245 : 7174 : CheckBooleanId ();
20246 : 7174 : PopBool (&t, &f);
20247 : 7174 : BackPatch (t, NextQuad);
20248 : 7174 : PushBool (0, f);
20249 : : }
20250 : 37768 : else if (Op == M2Reserved_OrTok)
20251 : : {
20252 : : /* avoid dangling else. */
20253 : 2924 : CheckBooleanId ();
20254 : 2924 : PopBool (&t, &f);
20255 : 2924 : BackPatch (f, NextQuad);
20256 : 2924 : PushBool (t, 0);
20257 : : }
20258 : 44942 : M2Quads_PushTtok (Op, tokno);
20259 : 44942 : }
20260 : :
20261 : :
20262 : : /*
20263 : : BuildRelOp - Builds a relative operation from the quad stack.
20264 : : The Stack is expected to contain:
20265 : :
20266 : :
20267 : : Entry Exit
20268 : : ===== ====
20269 : :
20270 : : Ptr ->
20271 : : +------------+
20272 : : | e1 |
20273 : : |------------| <- Ptr
20274 : : | Operator |
20275 : : |------------| +------------+
20276 : : | e2 | | t | f |
20277 : : |------------| |------------|
20278 : :
20279 : :
20280 : : Quadruples Produced
20281 : :
20282 : : q IFOperator e2 e1 TrueExit ; e2 e1 since
20283 : : q+1 GotoOp FalseExit ; relation > etc
20284 : : ; requires order.
20285 : : */
20286 : :
20287 : 67934 : extern "C" void M2Quads_BuildRelOp (unsigned int optokpos)
20288 : : {
20289 : 67934 : unsigned int combinedTok;
20290 : 67934 : unsigned int rightpos;
20291 : 67934 : unsigned int leftpos;
20292 : 67934 : NameKey_Name Op;
20293 : 67934 : unsigned int t;
20294 : 67934 : unsigned int rightType;
20295 : 67934 : unsigned int leftType;
20296 : 67934 : unsigned int right;
20297 : 67934 : unsigned int left;
20298 : 67934 : DynamicStrings_String s;
20299 : :
20300 : 67934 : if (M2Options_CompilerDebugging)
20301 : : {
20302 : 0 : M2Quads_DisplayStack (); /* Debugging info */
20303 : : }
20304 : 67934 : if ((IsBoolean (1)) && (IsBoolean (3)))
20305 : : {
20306 : : /*
20307 : : we allow # and = to be used with Boolean expressions.
20308 : : we do not allow > < >= <= though
20309 : : */
20310 : 0 : BuildRelOpFromBoolean (optokpos);
20311 : : }
20312 : : else
20313 : : {
20314 : 67934 : if (IsBoolean (1))
20315 : : {
20316 : 12 : ConvertBooleanToVariable (OperandTtok (1), 1);
20317 : : }
20318 : 67934 : if (IsBoolean (3))
20319 : : {
20320 : 0 : ConvertBooleanToVariable (OperandTtok (3), 3);
20321 : : }
20322 : 67934 : M2Quads_PopTFtok (&right, &rightType, &rightpos);
20323 : 67934 : M2Quads_PopT (&Op);
20324 : 67934 : M2Quads_PopTFtok (&left, &leftType, &leftpos);
20325 : 67934 : CheckVariableOrConstantOrProcedure (rightpos, right);
20326 : 67934 : CheckVariableOrConstantOrProcedure (leftpos, left);
20327 : 67934 : combinedTok = M2LexBuf_MakeVirtualTok (optokpos, leftpos, rightpos);
20328 : 67934 : if ((left != SymbolTable_NulSym) && (right != SymbolTable_NulSym))
20329 : : {
20330 : : /* BuildRange will check the expression later on once gcc knows about all data types. */
20331 : 67934 : BuildRange (M2Range_InitTypesExpressionCheck (combinedTok, left, right, true, Op == M2Reserved_InTok));
20332 : : }
20333 : : /* Must dereference LeftValue operands. */
20334 : 67934 : if ((SymbolTable_GetMode (right)) == SymbolTable_LeftValue)
20335 : : {
20336 : 1302 : t = SymbolTable_MakeTemporary (rightpos, SymbolTable_RightValue);
20337 : 1302 : SymbolTable_PutVar (t, SymbolTable_GetSType (right));
20338 : 1302 : CheckPointerThroughNil (rightpos, right);
20339 : 1302 : doIndrX (rightpos, t, right);
20340 : 1302 : right = t;
20341 : : }
20342 : 67934 : if ((SymbolTable_GetMode (left)) == SymbolTable_LeftValue)
20343 : : {
20344 : 5420 : t = SymbolTable_MakeTemporary (leftpos, SymbolTable_RightValue);
20345 : 5420 : SymbolTable_PutVar (t, SymbolTable_GetSType (left));
20346 : 5420 : CheckPointerThroughNil (leftpos, left);
20347 : 5420 : doIndrX (leftpos, t, left);
20348 : 5420 : left = t;
20349 : : }
20350 : 67934 : if (DebugTokPos)
20351 : : {
20352 : : s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (M2LexBuf_GetTokenName (Op)));
20353 : : M2Error_WarnStringAt (s, optokpos);
20354 : : s = DynamicStrings_InitString ((const char *) "left", 4);
20355 : : M2Error_WarnStringAt (s, leftpos);
20356 : : s = DynamicStrings_InitString ((const char *) "right", 5);
20357 : : M2Error_WarnStringAt (s, rightpos);
20358 : : s = DynamicStrings_InitString ((const char *) "caret", 5);
20359 : : M2Error_WarnStringAt (s, optokpos);
20360 : : s = DynamicStrings_InitString ((const char *) "combined", 8);
20361 : : M2Error_WarnStringAt (s, combinedTok);
20362 : : }
20363 : 67934 : GenQuadOtok (combinedTok, MakeOp (Op), left, right, 0, false, leftpos, rightpos, M2LexBuf_UnknownTokenNo); /* True Exit */
20364 : 67934 : GenQuadO (combinedTok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false); /* False Exit */
20365 : 67934 : PushBooltok (NextQuad-2, NextQuad-1, combinedTok); /* False Exit */
20366 : : }
20367 : 67934 : }
20368 : :
20369 : :
20370 : : /*
20371 : : BuildBinaryOp - Builds a binary operation from the quad stack.
20372 : : Be aware that this procedure will check for
20373 : : the overloading of the bitset operators + - \ *.
20374 : : So do NOT call this procedure if you are building
20375 : : a reference to an array which has a bitset type or
20376 : : the address arithmetic will be wrongly coersed into
20377 : : logical ORs.
20378 : :
20379 : : The Stack is expected to contain:
20380 : :
20381 : :
20382 : : Entry Exit
20383 : : ===== ====
20384 : :
20385 : : Ptr ->
20386 : : +------------+
20387 : : | Sym1 |
20388 : : |------------|
20389 : : | Operator | <- Ptr
20390 : : |------------| +------------+
20391 : : | Sym2 | | Temporary |
20392 : : |------------| |------------|
20393 : :
20394 : :
20395 : : Quadruples Produced
20396 : :
20397 : : q Operator Temporary Sym1 Sym2
20398 : :
20399 : :
20400 : : OR
20401 : :
20402 : :
20403 : : Entry Exit
20404 : : ===== ====
20405 : :
20406 : : Ptr ->
20407 : : +------------+
20408 : : | T1 | F1 |
20409 : : |------------|
20410 : : | OrTok | <- Ptr
20411 : : |------------| +------------+
20412 : : | T2 | F2 | | T1+T2| F1 |
20413 : : |------------| |------------|
20414 : :
20415 : :
20416 : : Quadruples Produced
20417 : :
20418 : : */
20419 : :
20420 : 47226 : extern "C" void M2Quads_BuildBinaryOp (void)
20421 : : {
20422 : 47226 : doBuildBinaryOp (true, true);
20423 : 47154 : }
20424 : :
20425 : :
20426 : : /*
20427 : : BuildUnaryOp - Builds a unary operation from the quad stack.
20428 : : The Stack is expected to contain:
20429 : :
20430 : :
20431 : : Entry Exit
20432 : : ===== ====
20433 : :
20434 : : Ptr ->
20435 : : +------------+
20436 : : | Sym |
20437 : : |------------| +------------+
20438 : : | Operator | | Temporary | <- Ptr
20439 : : |------------| |------------|
20440 : :
20441 : :
20442 : : Quadruples Produced
20443 : :
20444 : : q Operator Temporary _ Sym
20445 : :
20446 : : */
20447 : :
20448 : 18216 : extern "C" void M2Quads_BuildUnaryOp (void)
20449 : : {
20450 : 18216 : unsigned int sympos;
20451 : 18216 : unsigned int tokpos;
20452 : 18216 : NameKey_Name Tok;
20453 : 18216 : unsigned int type;
20454 : 18216 : unsigned int Sym;
20455 : 18216 : unsigned int SymT;
20456 : 18216 : unsigned int r;
20457 : 18216 : unsigned int t;
20458 : :
20459 : 18216 : PopTrwtok (&Sym, &r, &sympos);
20460 : 18216 : M2Quads_PopTtok (&Tok, &tokpos);
20461 : 18216 : if (Tok == M2Reserved_MinusTok)
20462 : : {
20463 : 18072 : MarkAsRead (r);
20464 : 18072 : type = M2Base_NegateType (SymbolTable_GetSType (Sym)); /* , sympos */
20465 : 18072 : tokpos = M2LexBuf_MakeVirtualTok (tokpos, tokpos, sympos);
20466 : 36144 : t = SymbolTable_MakeTemporary (tokpos, AreConstant (SymbolTable_IsConst (Sym)));
20467 : 18072 : SymbolTable_PutVar (t, type);
20468 : : /*
20469 : : variables must have a type and REAL/LONGREAL constants must
20470 : : be typed
20471 : : */
20472 : 18072 : if (! (SymbolTable_IsConst (Sym)))
20473 : : {
20474 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
20475 : 834 : if ((type != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_SkipType (type))))
20476 : : {} /* empty. */
20477 : : /* do not dereference set variables */
20478 : 812 : else if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
20479 : : {
20480 : : /* avoid dangling else. */
20481 : : /* dereference symbols which are not sets and which are variables */
20482 : 0 : SymT = SymbolTable_MakeTemporary (sympos, SymbolTable_RightValue);
20483 : 0 : SymbolTable_PutVar (SymT, SymbolTable_GetSType (Sym));
20484 : 0 : CheckPointerThroughNil (sympos, Sym);
20485 : 0 : doIndrX (sympos, SymT, Sym);
20486 : 0 : Sym = SymT;
20487 : : }
20488 : : }
20489 : 18072 : GenQuadO (tokpos, M2Quads_NegateOp, t, SymbolTable_NulSym, Sym, true);
20490 : 18072 : M2Quads_PushTtok (t, tokpos);
20491 : : }
20492 : 144 : else if (Tok == M2Reserved_PlusTok)
20493 : : {
20494 : : /* avoid dangling else. */
20495 : 144 : tokpos = M2LexBuf_MakeVirtualTok (tokpos, tokpos, sympos);
20496 : 144 : PushTrwtok (Sym, r, tokpos);
20497 : : }
20498 : : else
20499 : : {
20500 : : /* avoid dangling else. */
20501 : 0 : M2MetaError_MetaErrorNT1 (tokpos, (const char *) "expecting an unary operator, seen {%Ek%a}", 41, Tok);
20502 : : }
20503 : 18216 : }
20504 : :
20505 : :
20506 : : /*
20507 : : OperandT - returns the ident operand stored in the true position on the boolean stack.
20508 : : */
20509 : :
20510 : 58772322 : extern "C" unsigned int M2Quads_OperandT (unsigned int pos)
20511 : : {
20512 : 58772322 : M2Debug_Assert (! (IsBoolean (pos)));
20513 : 58772322 : return OperandTno (pos);
20514 : : /* static analysis guarentees a RETURN statement will be used before here. */
20515 : : __builtin_unreachable ();
20516 : : }
20517 : :
20518 : :
20519 : : /*
20520 : : OperandF - returns the ident operand stored in the false position on the boolean stack.
20521 : : */
20522 : :
20523 : 139777 : extern "C" unsigned int M2Quads_OperandF (unsigned int pos)
20524 : : {
20525 : 139777 : M2Debug_Assert (! (IsBoolean (pos)));
20526 : 139777 : return OperandFno (pos);
20527 : : /* static analysis guarentees a RETURN statement will be used before here. */
20528 : : __builtin_unreachable ();
20529 : : }
20530 : :
20531 : :
20532 : : /*
20533 : : PushTF - Push a True and False numbers onto the True/False stack.
20534 : : True and False are assumed to contain Symbols or Ident etc.
20535 : : */
20536 : :
20537 : 6589529 : extern "C" void M2Quads_PushTF (unsigned int True, unsigned int False)
20538 : : {
20539 : 6589529 : M2Quads_BoolFrame f;
20540 : :
20541 : 6589529 : f = newBoolFrame ();
20542 : 6589529 : f->TrueExit = static_cast<unsigned int> (True);
20543 : 6589529 : f->FalseExit = static_cast<unsigned int> (False);
20544 : 6589529 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
20545 : 6589529 : }
20546 : :
20547 : :
20548 : : /*
20549 : : PopTF - Pop a True and False number from the True/False stack.
20550 : : True and False are assumed to contain Symbols or Ident etc.
20551 : : */
20552 : :
20553 : 9333320 : extern "C" void M2Quads_PopTF (unsigned int *True, unsigned int *False)
20554 : : {
20555 : 9333320 : M2Quads_BoolFrame f;
20556 : :
20557 : 9333320 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
20558 : 9333320 : (*True) = static_cast<unsigned int> (f->TrueExit);
20559 : 9333320 : (*False) = static_cast<unsigned int> (f->FalseExit);
20560 : 9333320 : M2Debug_Assert (! f->BooleanOp);
20561 : 9333320 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
20562 : 9333320 : }
20563 : :
20564 : :
20565 : : /*
20566 : : PushT - Push an item onto the stack in the T (true) position.
20567 : : */
20568 : :
20569 : 48452581 : extern "C" void M2Quads_PushT (unsigned int True)
20570 : : {
20571 : 48452581 : M2Quads_BoolFrame f;
20572 : :
20573 : 48452581 : f = newBoolFrame ();
20574 : 48452581 : f->TrueExit = static_cast<unsigned int> (True);
20575 : 48452581 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
20576 : 48452581 : }
20577 : :
20578 : :
20579 : : /*
20580 : : PopT - Pops the T value from the stack.
20581 : : */
20582 : :
20583 : 69023068 : extern "C" void M2Quads_PopT (unsigned int *True)
20584 : : {
20585 : 69023068 : M2Quads_BoolFrame f;
20586 : :
20587 : 69023068 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
20588 : 69023068 : (*True) = static_cast<unsigned int> (f->TrueExit);
20589 : 69023068 : M2Debug_Assert (! f->BooleanOp);
20590 : 69023068 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
20591 : 69023068 : }
20592 : :
20593 : :
20594 : : /*
20595 : : PushTtok - Push an item onto the stack in the T (true) position,
20596 : : it is assummed to be a token and its token location is recorded.
20597 : : */
20598 : :
20599 : 24294072 : extern "C" void M2Quads_PushTtok (unsigned int True, unsigned int tokno)
20600 : : {
20601 : 24294072 : M2Quads_BoolFrame f;
20602 : :
20603 : : /* PrintTokenNo (tokno) ; */
20604 : 24294072 : f = newBoolFrame ();
20605 : 24294072 : f->TrueExit = static_cast<unsigned int> (True);
20606 : 24294072 : f->tokenno = tokno;
20607 : 24294072 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
20608 : 24294072 : }
20609 : :
20610 : :
20611 : : /*
20612 : : PushTFtok - Push an item onto the stack in the T (true) position,
20613 : : it is assummed to be a token and its token location is recorded.
20614 : : */
20615 : :
20616 : 70361794 : extern "C" void M2Quads_PushTFtok (unsigned int True, unsigned int False, unsigned int tokno)
20617 : : {
20618 : 70361794 : M2Quads_BoolFrame f;
20619 : :
20620 : 70361794 : f = newBoolFrame ();
20621 : 70361794 : f->TrueExit = static_cast<unsigned int> (True);
20622 : 70361794 : f->FalseExit = static_cast<unsigned int> (False);
20623 : 70361794 : f->tokenno = tokno;
20624 : 70361794 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
20625 : 70361794 : }
20626 : :
20627 : :
20628 : : /*
20629 : : PopTFtok - Pop T/F/tok from the stack.
20630 : : */
20631 : :
20632 : 499188 : extern "C" void M2Quads_PopTFtok (unsigned int *True, unsigned int *False, unsigned int *tokno)
20633 : : {
20634 : 499188 : M2Quads_BoolFrame f;
20635 : :
20636 : 499188 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
20637 : 499188 : (*True) = static_cast<unsigned int> (f->TrueExit);
20638 : 499188 : (*False) = static_cast<unsigned int> (f->FalseExit);
20639 : 499188 : (*tokno) = f->tokenno;
20640 : 499188 : }
20641 : :
20642 : :
20643 : : /*
20644 : : PushTFAtok - Push T/F/A/tok to the stack.
20645 : : */
20646 : :
20647 : 54 : extern "C" void M2Quads_PushTFAtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int tokno)
20648 : : {
20649 : 54 : M2Quads_BoolFrame f;
20650 : :
20651 : 54 : f = newBoolFrame ();
20652 : 54 : f->TrueExit = static_cast<unsigned int> (True);
20653 : 54 : f->FalseExit = static_cast<unsigned int> (False);
20654 : 54 : f->Unbounded = static_cast<unsigned int> (Array);
20655 : 54 : f->tokenno = tokno;
20656 : 54 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
20657 : 54 : }
20658 : :
20659 : :
20660 : : /*
20661 : : PopTtok - Pops the T value from the stack and token position.
20662 : : */
20663 : :
20664 : 38405776 : extern "C" void M2Quads_PopTtok (unsigned int *True, unsigned int *tok)
20665 : : {
20666 : 38405776 : M2Quads_BoolFrame f;
20667 : :
20668 : 38405776 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
20669 : 38405776 : (*True) = static_cast<unsigned int> (f->TrueExit);
20670 : 38405776 : (*tok) = f->tokenno;
20671 : 38405776 : M2Debug_Assert (! f->BooleanOp);
20672 : 38405776 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
20673 : 38405776 : }
20674 : :
20675 : :
20676 : : /*
20677 : : PushTFn - Push a True and False numbers onto the True/False stack.
20678 : : True and False are assumed to contain Symbols or Ident etc.
20679 : : */
20680 : :
20681 : 0 : extern "C" void M2Quads_PushTFn (unsigned int True, unsigned int False, unsigned int n)
20682 : : {
20683 : 0 : M2Quads_BoolFrame f;
20684 : :
20685 : 0 : f = newBoolFrame ();
20686 : 0 : f->TrueExit = static_cast<unsigned int> (True);
20687 : 0 : f->FalseExit = static_cast<unsigned int> (False);
20688 : 0 : f->name = static_cast<unsigned int> (n);
20689 : 0 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
20690 : 0 : }
20691 : :
20692 : :
20693 : : /*
20694 : : PushTFntok - Push a True and False numbers onto the True/False stack.
20695 : : True and False are assumed to contain Symbols or Ident etc.
20696 : : */
20697 : :
20698 : 494824 : extern "C" void M2Quads_PushTFntok (unsigned int True, unsigned int False, unsigned int n, unsigned int tokno)
20699 : : {
20700 : 494824 : M2Quads_BoolFrame f;
20701 : :
20702 : 494824 : f = newBoolFrame ();
20703 : 494824 : f->TrueExit = static_cast<unsigned int> (True);
20704 : 494824 : f->FalseExit = static_cast<unsigned int> (False);
20705 : 494824 : f->name = static_cast<unsigned int> (n);
20706 : 494824 : f->tokenno = tokno;
20707 : 494824 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
20708 : 494824 : }
20709 : :
20710 : :
20711 : : /*
20712 : : PopTFn - Pop a True and False number from the True/False stack.
20713 : : True and False are assumed to contain Symbols or Ident etc.
20714 : : */
20715 : :
20716 : 0 : extern "C" void M2Quads_PopTFn (unsigned int *True, unsigned int *False, unsigned int *n)
20717 : : {
20718 : 0 : M2Quads_BoolFrame f;
20719 : :
20720 : 0 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
20721 : 0 : (*True) = static_cast<unsigned int> (f->TrueExit);
20722 : 0 : (*False) = static_cast<unsigned int> (f->FalseExit);
20723 : 0 : (*n) = static_cast<unsigned int> (f->name);
20724 : 0 : M2Debug_Assert (! f->BooleanOp);
20725 : 0 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
20726 : 0 : }
20727 : :
20728 : :
20729 : : /*
20730 : : PopNothing - pops the top element on the boolean stack.
20731 : : */
20732 : :
20733 : 32120413 : extern "C" void M2Quads_PopNothing (void)
20734 : : {
20735 : 32120413 : M2Quads_BoolFrame f;
20736 : :
20737 : 32120413 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
20738 : 32120413 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
20739 : 32120413 : }
20740 : :
20741 : :
20742 : : /*
20743 : : PopN - pops multiple elements from the BoolStack.
20744 : : */
20745 : :
20746 : 7132852 : extern "C" void M2Quads_PopN (unsigned int n)
20747 : : {
20748 : 27991411 : while (n > 0)
20749 : : {
20750 : 20858559 : M2Quads_PopNothing ();
20751 : 20858559 : n -= 1;
20752 : : }
20753 : 7132852 : }
20754 : :
20755 : :
20756 : : /*
20757 : : PushTFA - Push True, False, Array, numbers onto the
20758 : : True/False stack. True and False are assumed to
20759 : : contain Symbols or Ident etc.
20760 : : */
20761 : :
20762 : 0 : extern "C" void M2Quads_PushTFA (unsigned int True, unsigned int False, unsigned int Array)
20763 : : {
20764 : 0 : M2Quads_BoolFrame f;
20765 : :
20766 : 0 : f = newBoolFrame ();
20767 : 0 : f->TrueExit = static_cast<unsigned int> (True);
20768 : 0 : f->FalseExit = static_cast<unsigned int> (False);
20769 : 0 : f->Unbounded = static_cast<unsigned int> (Array);
20770 : 0 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast<void *> (f));
20771 : 0 : }
20772 : :
20773 : :
20774 : : /*
20775 : : OperandTok - returns the token associated with pos, on the stack.
20776 : : */
20777 : :
20778 : 19940865 : extern "C" unsigned int M2Quads_OperandTok (unsigned int pos)
20779 : : {
20780 : 19940865 : M2Debug_Assert (! (IsBoolean (pos)));
20781 : 19940865 : return static_cast<unsigned int> (OperandTtok (pos));
20782 : : /* static analysis guarentees a RETURN statement will be used before here. */
20783 : : __builtin_unreachable ();
20784 : : }
20785 : :
20786 : :
20787 : : /*
20788 : : OperandA - returns possible array symbol associated with the ident
20789 : : operand stored on the boolean stack.
20790 : : */
20791 : :
20792 : 1286822 : extern "C" unsigned int M2Quads_OperandA (unsigned int pos)
20793 : : {
20794 : 1286822 : M2Quads_BoolFrame f;
20795 : :
20796 : 1286822 : M2Debug_Assert (pos > 0);
20797 : 1286822 : M2Debug_Assert (! (IsBoolean (pos)));
20798 : 1286822 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
20799 : 1286822 : return static_cast<unsigned int> (f->Unbounded);
20800 : : /* static analysis guarentees a RETURN statement will be used before here. */
20801 : : __builtin_unreachable ();
20802 : : }
20803 : :
20804 : :
20805 : : /*
20806 : : OperandAnno - returns the annotation string associated with the
20807 : : position, n, on the stack.
20808 : : */
20809 : :
20810 : 0 : extern "C" DynamicStrings_String M2Quads_OperandAnno (unsigned int n)
20811 : : {
20812 : 0 : M2Quads_BoolFrame f;
20813 : :
20814 : 0 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, n));
20815 : 0 : return f->Annotation;
20816 : : /* static analysis guarentees a RETURN statement will be used before here. */
20817 : : __builtin_unreachable ();
20818 : : }
20819 : :
20820 : :
20821 : : /*
20822 : : Annotate - annotate the top of stack.
20823 : : */
20824 : :
20825 : 35046934 : extern "C" void M2Quads_Annotate (const char *a_, unsigned int _a_high)
20826 : : {
20827 : 35046934 : M2Quads_BoolFrame f;
20828 : 35046934 : char a[_a_high+1];
20829 : :
20830 : : /* make a local copy of each unbounded array. */
20831 : 35046934 : memcpy (a, a_, _a_high+1);
20832 : :
20833 : 0 : if ((DebugStackOn && M2Options_CompilerDebugging) && ((M2StackAddress_NoOfItemsInStackAddress (BoolStack)) > 0))
20834 : : {
20835 : 0 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, 1)); /* top of stack */
20836 : 0 : if (f->Annotation != NULL) /* top of stack */
20837 : : {
20838 : 0 : f->Annotation = DynamicStrings_KillString (f->Annotation);
20839 : : }
20840 : 0 : f->Annotation = DynamicStrings_InitString ((const char *) a, _a_high);
20841 : : }
20842 : 35046934 : }
20843 : :
20844 : :
20845 : : /*
20846 : : DisplayStack - displays the compile time symbol stack.
20847 : : */
20848 : :
20849 : 4474778 : extern "C" void M2Quads_DisplayStack (void)
20850 : : {
20851 : 4474778 : if (DebugStackOn && M2Options_CompilerDebugging)
20852 : : {
20853 : 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});
20854 : : }
20855 : 4474778 : }
20856 : :
20857 : :
20858 : : /*
20859 : : Top - returns the no of items held in the stack.
20860 : : */
20861 : :
20862 : 26762899 : extern "C" unsigned int M2Quads_Top (void)
20863 : : {
20864 : 26762899 : return M2StackAddress_NoOfItemsInStackAddress (BoolStack);
20865 : : /* static analysis guarentees a RETURN statement will be used before here. */
20866 : : __builtin_unreachable ();
20867 : : }
20868 : :
20869 : :
20870 : : /*
20871 : : WriteOperand - displays the operands name, symbol id and mode of addressing.
20872 : : */
20873 : :
20874 : 0 : extern "C" void M2Quads_WriteOperand (unsigned int Sym)
20875 : : {
20876 : 0 : NameKey_Name n;
20877 : :
20878 : 0 : if (Sym == SymbolTable_NulSym)
20879 : : {
20880 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "<nulsym>", 8);
20881 : : }
20882 : : else
20883 : : {
20884 : 0 : n = SymbolTable_GetSymName (Sym);
20885 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%a", 2, (const unsigned char *) &n, (sizeof (n)-1));
20886 : 0 : if ((SymbolTable_IsVar (Sym)) || (SymbolTable_IsConst (Sym)))
20887 : : {
20888 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "[", 1);
20889 : 0 : WriteMode (SymbolTable_GetMode (Sym));
20890 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "]", 1);
20891 : : }
20892 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "(%d)", 4, (const unsigned char *) &Sym, (sizeof (Sym)-1));
20893 : : }
20894 : 0 : }
20895 : :
20896 : :
20897 : : /*
20898 : : BeginVarient - begin a varient record.
20899 : : */
20900 : :
20901 : 276 : extern "C" void M2Quads_BeginVarient (void)
20902 : : {
20903 : 276 : unsigned int r;
20904 : 276 : unsigned int v;
20905 : :
20906 : 276 : r = GetRecordOrField ();
20907 : 552 : M2Debug_Assert ((SymbolTable_IsRecord (r)) || (SymbolTable_IsFieldVarient (r)));
20908 : 276 : v = GetRecordOrField ();
20909 : 276 : M2Debug_Assert (SymbolTable_IsVarient (v));
20910 : 276 : BuildRange (M2Range_InitCaseBounds (M2CaseList_PushCase (r, v, SymbolTable_NulSym)));
20911 : 276 : }
20912 : :
20913 : :
20914 : : /*
20915 : : EndVarient - end a varient record.
20916 : : */
20917 : :
20918 : 276 : extern "C" void M2Quads_EndVarient (void)
20919 : : {
20920 : 276 : M2CaseList_PopCase ();
20921 : 276 : }
20922 : :
20923 : :
20924 : : /*
20925 : : ElseVarient - associate an ELSE clause with a varient record.
20926 : : */
20927 : :
20928 : 114 : extern "C" void M2Quads_ElseVarient (void)
20929 : : {
20930 : 114 : unsigned int f;
20931 : :
20932 : 114 : f = GetRecordOrField ();
20933 : 114 : M2Debug_Assert (SymbolTable_IsFieldVarient (f));
20934 : 114 : M2CaseList_ElseCase (f);
20935 : 114 : }
20936 : :
20937 : :
20938 : : /*
20939 : : BeginVarientList - begin an ident list containing ranges belonging to a
20940 : : varient list.
20941 : : */
20942 : :
20943 : 552 : extern "C" void M2Quads_BeginVarientList (void)
20944 : : {
20945 : 552 : unsigned int f;
20946 : :
20947 : 552 : f = GetRecordOrField ();
20948 : 552 : M2Debug_Assert (SymbolTable_IsFieldVarient (f));
20949 : 552 : M2CaseList_BeginCaseList (f);
20950 : 552 : }
20951 : :
20952 : :
20953 : : /*
20954 : : EndVarientList - end a range list for a varient field.
20955 : : */
20956 : :
20957 : 552 : extern "C" void M2Quads_EndVarientList (void)
20958 : : {
20959 : 552 : M2CaseList_EndCaseList ();
20960 : 552 : }
20961 : :
20962 : :
20963 : : /*
20964 : : AddRecordToList - adds the record held on the top of stack to the
20965 : : list of records and varient fields.
20966 : : */
20967 : :
20968 : 276 : extern "C" void M2Quads_AddRecordToList (void)
20969 : : {
20970 : 276 : unsigned int r;
20971 : 276 : unsigned int n;
20972 : :
20973 : 276 : r = static_cast<unsigned int> (M2Quads_OperandT (1));
20974 : 552 : M2Debug_Assert ((SymbolTable_IsRecord (r)) || (SymbolTable_IsFieldVarient (r)));
20975 : : /*
20976 : : r might be a field varient if the declaration consists of nested
20977 : : varients. However ISO TSIZE can only utilise record types, we store
20978 : : a varient field anyway as the next pass would not know whether to
20979 : : ignore a varient field.
20980 : : */
20981 : 276 : Lists_PutItemIntoList (VarientFields, r);
20982 : 276 : if (DebugVarients)
20983 : : {
20984 : : n = Lists_NoOfItemsInList (VarientFields);
20985 : : if (SymbolTable_IsRecord (r))
20986 : : {
20987 : : 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));
20988 : : }
20989 : : else
20990 : : {
20991 : : 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));
20992 : : }
20993 : : }
20994 : 276 : }
20995 : :
20996 : :
20997 : : /*
20998 : : AddVarientToList - adds varient held on the top of stack to the list.
20999 : : */
21000 : :
21001 : 276 : extern "C" void M2Quads_AddVarientToList (void)
21002 : : {
21003 : 276 : unsigned int v;
21004 : 276 : unsigned int n;
21005 : :
21006 : 276 : v = static_cast<unsigned int> (M2Quads_OperandT (1));
21007 : 276 : M2Debug_Assert (SymbolTable_IsVarient (v));
21008 : 276 : Lists_PutItemIntoList (VarientFields, v);
21009 : 276 : if (DebugVarients)
21010 : : {
21011 : : n = Lists_NoOfItemsInList (VarientFields);
21012 : : 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));
21013 : : }
21014 : 276 : }
21015 : :
21016 : :
21017 : : /*
21018 : : AddVarientFieldToList - adds varient field, f, to the list of all varient
21019 : : fields created.
21020 : : */
21021 : :
21022 : 666 : extern "C" void M2Quads_AddVarientFieldToList (unsigned int f)
21023 : : {
21024 : 666 : unsigned int n;
21025 : :
21026 : 666 : M2Debug_Assert (SymbolTable_IsFieldVarient (f));
21027 : 666 : Lists_PutItemIntoList (VarientFields, f);
21028 : 666 : if (DebugVarients)
21029 : : {
21030 : : n = Lists_NoOfItemsInList (VarientFields);
21031 : : 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));
21032 : : }
21033 : 666 : }
21034 : :
21035 : :
21036 : : /*
21037 : : AddVarientRange - creates a range from the top two contant expressions
21038 : : on the stack which are recorded with the current
21039 : : varient field. The stack is unaltered.
21040 : : */
21041 : :
21042 : 0 : extern "C" void M2Quads_AddVarientRange (void)
21043 : : {
21044 : 0 : unsigned int r1;
21045 : 0 : unsigned int r2;
21046 : :
21047 : 0 : M2Quads_PopT (&r2);
21048 : 0 : M2Quads_PopT (&r1);
21049 : 0 : M2CaseList_AddRange (r1, r2, M2LexBuf_GetTokenNo ());
21050 : 0 : }
21051 : :
21052 : :
21053 : : /*
21054 : : AddVarientEquality - adds the contant expression on the top of the stack
21055 : : to the current varient field being recorded.
21056 : : The stack is unaltered.
21057 : : */
21058 : :
21059 : 594 : extern "C" void M2Quads_AddVarientEquality (void)
21060 : : {
21061 : 594 : unsigned int r1;
21062 : :
21063 : 594 : M2Quads_PopT (&r1);
21064 : 594 : M2CaseList_AddRange (r1, SymbolTable_NulSym, M2LexBuf_GetTokenNo ());
21065 : 594 : }
21066 : :
21067 : :
21068 : : /*
21069 : : BuildCodeOn - generates a quadruple declaring that code should be
21070 : : emmitted from henceforth.
21071 : :
21072 : : The Stack is unnaffected.
21073 : : */
21074 : :
21075 : 0 : extern "C" void M2Quads_BuildCodeOn (void)
21076 : : {
21077 : 0 : GenQuad (M2Quads_CodeOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21078 : 0 : }
21079 : :
21080 : :
21081 : : /*
21082 : : BuildCodeOff - generates a quadruple declaring that code should not be
21083 : : emmitted from henceforth.
21084 : :
21085 : : The Stack is unnaffected.
21086 : : */
21087 : :
21088 : 0 : extern "C" void M2Quads_BuildCodeOff (void)
21089 : : {
21090 : 0 : GenQuad (M2Quads_CodeOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21091 : 0 : }
21092 : :
21093 : :
21094 : : /*
21095 : : BuildProfileOn - generates a quadruple declaring that profile timings
21096 : : should be emmitted from henceforth.
21097 : :
21098 : : The Stack is unnaffected.
21099 : : */
21100 : :
21101 : 0 : extern "C" void M2Quads_BuildProfileOn (void)
21102 : : {
21103 : 0 : GenQuad (M2Quads_ProfileOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21104 : 0 : }
21105 : :
21106 : 0 : extern "C" void M2Quads_BuildProfileOff (void)
21107 : : {
21108 : : /*
21109 : : BuildProfileOn - generates a quadruple declaring that profile timings
21110 : : should be emmitted from henceforth.
21111 : :
21112 : : The Stack is unnaffected.
21113 : : */
21114 : 0 : GenQuad (M2Quads_ProfileOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21115 : 0 : }
21116 : :
21117 : :
21118 : : /*
21119 : : BuildOptimizeOn - generates a quadruple declaring that optimization
21120 : : should occur from henceforth.
21121 : :
21122 : : The Stack is unnaffected.
21123 : : */
21124 : :
21125 : 0 : extern "C" void M2Quads_BuildOptimizeOn (void)
21126 : : {
21127 : 0 : GenQuad (M2Quads_OptimizeOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21128 : 0 : }
21129 : :
21130 : :
21131 : : /*
21132 : : BuildOptimizeOff - generates a quadruple declaring that optimization
21133 : : should not occur from henceforth.
21134 : :
21135 : : The Stack is unnaffected.
21136 : : */
21137 : :
21138 : 0 : extern "C" void M2Quads_BuildOptimizeOff (void)
21139 : : {
21140 : 0 : GenQuad (M2Quads_OptimizeOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21141 : 0 : }
21142 : :
21143 : :
21144 : : /*
21145 : : BuildAsm - builds an Inline pseudo quadruple operator.
21146 : : The inline interface, Sym, is stored as the operand
21147 : : to the operator InlineOp.
21148 : :
21149 : : The stack is expected to contain:
21150 : :
21151 : :
21152 : : Entry Exit
21153 : : ===== ====
21154 : :
21155 : : Ptr ->
21156 : : +--------------+
21157 : : | Sym | Empty
21158 : : |--------------|
21159 : : */
21160 : :
21161 : 18 : extern "C" void M2Quads_BuildAsm (unsigned int tok)
21162 : : {
21163 : 18 : unsigned int Sym;
21164 : :
21165 : 18 : M2Quads_PopT (&Sym);
21166 : 18 : GenQuadO (tok, M2Quads_InlineOp, SymbolTable_NulSym, SymbolTable_NulSym, Sym, false);
21167 : 18 : }
21168 : :
21169 : :
21170 : : /*
21171 : : BuildLineNo - builds a LineNumberOp pseudo quadruple operator.
21172 : : This quadruple indicates which source line has been
21173 : : processed, these quadruples are only generated if we
21174 : : are producing runtime debugging information.
21175 : :
21176 : : The stack is not affected, read or altered in any way.
21177 : :
21178 : :
21179 : : Entry Exit
21180 : : ===== ====
21181 : :
21182 : : Ptr -> <- Ptr
21183 : : */
21184 : :
21185 : 0 : extern "C" void M2Quads_BuildLineNo (void)
21186 : : {
21187 : 0 : NameKey_Name filename;
21188 : 0 : M2Quads_QuadFrame f;
21189 : :
21190 : 0 : if (((NextQuad != Head) && (M2Options_GenerateLineDebug || M2Options_GenerateDebugging)) && false)
21191 : : {
21192 : : filename = NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()));
21193 : : f = GetQF (NextQuad-1);
21194 : : if (! ((f->Operator == M2Quads_LineNumberOp) && (f->Operand1 == ((unsigned int ) (filename)))))
21195 : : {
21196 : : GenQuad (M2Quads_LineNumberOp, (unsigned int ) (filename), SymbolTable_NulSym, (unsigned int ) (M2LexBuf_GetLineNo ()));
21197 : : }
21198 : : }
21199 : 0 : }
21200 : :
21201 : :
21202 : : /*
21203 : : PushLineNo - pushes the current file and line number to the stack.
21204 : : */
21205 : :
21206 : 3704 : extern "C" void M2Quads_PushLineNo (void)
21207 : : {
21208 : 3704 : PushLineNote (InitLineNote (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ())), M2LexBuf_GetLineNo ()));
21209 : 3704 : }
21210 : :
21211 : :
21212 : : /*
21213 : : BuildStmtNote - builds a StatementNoteOp pseudo quadruple operator.
21214 : : This quadruple indicates which source line has been
21215 : : processed and it represents the start of a statement
21216 : : sequence.
21217 : : It differs from LineNumberOp in that multiple successive
21218 : : LineNumberOps will be removed and the final one is attached to
21219 : : the next real GCC tree. Whereas a StatementNoteOp is always left
21220 : : alone. Depending upon the debugging level it will issue a nop
21221 : : instruction to ensure that the gdb single step will step into
21222 : : this line. Practically it allows pedalogical debugging to
21223 : : occur when there is syntax sugar such as:
21224 : :
21225 : :
21226 : : END step
21227 : : END step
21228 : : END ; step
21229 : : a := 1 ; step
21230 : :
21231 : : REPEAT step
21232 : : i := 1 step
21233 : :
21234 : : The stack is not affected, read or altered in any way.
21235 : :
21236 : :
21237 : : Entry Exit
21238 : : ===== ====
21239 : :
21240 : : Ptr -> <- Ptr
21241 : : */
21242 : :
21243 : 406224 : extern "C" void M2Quads_BuildStmtNote (int offset)
21244 : : {
21245 : 406224 : int tokenno;
21246 : :
21247 : 406224 : if (NextQuad != Head)
21248 : : {
21249 : 406224 : tokenno = offset;
21250 : 406224 : tokenno += M2LexBuf_GetTokenNo ();
21251 : 406224 : BuildStmtNoteTok ((unsigned int ) (tokenno));
21252 : : }
21253 : 406224 : }
21254 : :
21255 : :
21256 : : /*
21257 : : LoopAnalysis - checks whether an infinite loop exists.
21258 : : */
21259 : :
21260 : 286717 : extern "C" void M2Quads_LoopAnalysis (unsigned int Scope, unsigned int Current, unsigned int End)
21261 : : {
21262 : 286717 : M2Quads_QuadOperator op;
21263 : 286717 : unsigned int op1;
21264 : 286717 : unsigned int op2;
21265 : 286717 : unsigned int op3;
21266 : :
21267 : 286717 : if (M2Options_Pedantic)
21268 : : {
21269 : 4104 : while ((Current <= End) && (Current != 0))
21270 : : {
21271 : 3408 : M2Quads_GetQuad (Current, &op, &op1, &op2, &op3);
21272 : 3408 : if ((op == M2Quads_GotoOp) || (M2Quads_IsConditional (Current)))
21273 : : {
21274 : 6 : if (op3 <= Current)
21275 : : {
21276 : : /* found a loop - ie a branch which goes back in quadruple numbers */
21277 : 0 : if (IsInfiniteLoop (Current))
21278 : : {
21279 : 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);
21280 : 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);
21281 : : }
21282 : : /*
21283 : : WarnStringAt(InitString('it is very likely (although not absolutely certain) that the top of an infinite loop is here'),
21284 : : QuadToTokenNo(op3)) ;
21285 : : WarnStringAt(InitString('and the bottom of the infinite loop is ends here or alternatively a component of this loop is never executed'),
21286 : : QuadToTokenNo(Current))
21287 : : */
21288 : : }
21289 : : }
21290 : 3408 : Current = M2Quads_GetNextQuad (Current);
21291 : : }
21292 : : }
21293 : 286717 : }
21294 : :
21295 : :
21296 : : /*
21297 : : ForLoopAnalysis - checks all the FOR loops for index variable manipulation
21298 : : and dangerous usage outside the loop.
21299 : : */
21300 : :
21301 : 12454 : extern "C" void M2Quads_ForLoopAnalysis (void)
21302 : : {
21303 : 12454 : unsigned int i;
21304 : 12454 : unsigned int n;
21305 : 12454 : M2Quads_ForLoopInfo forDesc;
21306 : :
21307 : 12454 : if (M2Options_Pedantic)
21308 : : {
21309 : 12 : n = Indexing_HighIndice (ForInfo);
21310 : 12 : i = 1;
21311 : 24 : while (i <= n)
21312 : : {
21313 : 0 : forDesc = static_cast<M2Quads_ForLoopInfo> (Indexing_GetIndice (ForInfo, i));
21314 : 0 : CheckForIndex (forDesc);
21315 : 0 : i += 1;
21316 : : }
21317 : : }
21318 : 12454 : }
21319 : :
21320 : :
21321 : : /*
21322 : : BuildSizeCheckStart - switches off all quadruple generation if the function SIZE or HIGH
21323 : : is being "called". This should be done as SIZE only requires the
21324 : : actual type of the expression, not its value. Consider the problem of
21325 : : SIZE(UninitializedPointer^) which is quite legal and it must
21326 : : also be safe!
21327 : : ISO Modula-2 also allows HIGH(a[0]) for a two dimensional array
21328 : : and there is no need to compute a[0], we just need to follow the
21329 : : type and count dimensions. However if SIZE(a) or HIGH(a) occurs
21330 : : and, a, is an unbounded array then we turn on quadruple generation.
21331 : :
21332 : : The Stack is expected to contain:
21333 : :
21334 : :
21335 : : Entry Exit
21336 : : ===== ====
21337 : :
21338 : : Ptr -> <- Ptr
21339 : : +----------------------+ +----------------------+
21340 : : | ProcSym | Type | tok | | ProcSym | Type | tok |
21341 : : |----------------------| |----------------------|
21342 : : */
21343 : :
21344 : 139739 : extern "C" void M2Quads_BuildSizeCheckStart (void)
21345 : : {
21346 : 139739 : unsigned int ProcSym;
21347 : 139739 : unsigned int Type;
21348 : 139739 : unsigned int tok;
21349 : :
21350 : 139739 : M2Quads_PopTFtok (&ProcSym, &Type, &tok);
21351 : 139739 : if (((ProcSym == M2Size_Size) || (ProcSym == M2System_TSize)) || (ProcSym == M2System_TBitSize))
21352 : : {
21353 : 2728 : QuadrupleGeneration = false;
21354 : 2728 : BuildingSize = true;
21355 : : }
21356 : 137011 : else if (ProcSym == M2Base_High)
21357 : : {
21358 : : /* avoid dangling else. */
21359 : 2286 : QuadrupleGeneration = false;
21360 : 2286 : BuildingHigh = true;
21361 : : }
21362 : 139739 : M2Quads_PushTFtok (ProcSym, Type, tok);
21363 : 139739 : }
21364 : :
21365 : :
21366 : : /*
21367 : : BackPatchSubrangesAndOptParam - runs through all the quadruples and finds SubrangeLow or SubrangeHigh
21368 : : quadruples and replaces it by an assignment to the Low or High component
21369 : : of the subrange type.
21370 : :
21371 : : Input:
21372 : : SubrangeLow op1 op3 op3 is a subrange
21373 : :
21374 : : Output:
21375 : : Becomes op1 low
21376 : :
21377 : : Input:
21378 : : SubrangeHigh op1 op3 op3 is a subrange
21379 : :
21380 : : Output:
21381 : : Becomes op1 high
21382 : :
21383 : : Input:
21384 : : OptParam op1 op2 op3
21385 : :
21386 : : Output:
21387 : : Param op1 op2 GetOptArgInit(op3)
21388 : : */
21389 : :
21390 : 12454 : extern "C" void M2Quads_BackPatchSubrangesAndOptParam (void)
21391 : : {
21392 : 12454 : M2Quads_QuadFrame f;
21393 : 12454 : unsigned int q;
21394 : :
21395 : 12454 : q = M2Quads_GetFirstQuad ();
21396 : 12454 : if (q != 0)
21397 : : {
21398 : 4354135 : do {
21399 : 4354135 : f = GetQF (q);
21400 : 4354135 : switch (f->Operator)
21401 : : {
21402 : 234 : case M2Quads_SubrangeLowOp:
21403 : 234 : f->Operand3 = CollectLow (f->Operand3);
21404 : 234 : f->Operator = M2Quads_BecomesOp;
21405 : 234 : f->ConstExpr = false;
21406 : 234 : break;
21407 : :
21408 : 2882 : case M2Quads_SubrangeHighOp:
21409 : 2882 : f->Operand3 = CollectHigh (f->Operand3);
21410 : 2882 : f->Operator = M2Quads_BecomesOp;
21411 : 2882 : f->ConstExpr = false;
21412 : 2882 : break;
21413 : :
21414 : 2396 : case M2Quads_OptParamOp:
21415 : 2396 : f->Operand3 = SymbolTable_GetOptArgInit (f->Operand3);
21416 : 2396 : f->Operator = M2Quads_ParamOp;
21417 : 2396 : break;
21418 : :
21419 : :
21420 : : default:
21421 : : break;
21422 : : }
21423 : 4354135 : q = f->Next;
21424 : 4354135 : } while (! (q == 0));
21425 : : }
21426 : 12454 : }
21427 : :
21428 : :
21429 : : /*
21430 : : WriteOperator - writes the name of the quadruple operator.
21431 : : */
21432 : :
21433 : 0 : extern "C" void M2Quads_WriteOperator (M2Quads_QuadOperator Operator)
21434 : : {
21435 : 0 : switch (Operator)
21436 : : {
21437 : 0 : case M2Quads_ArithAddOp:
21438 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Arith + ", 18);
21439 : 0 : break;
21440 : :
21441 : 0 : case M2Quads_InitAddressOp:
21442 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitAddress ", 18);
21443 : 0 : break;
21444 : :
21445 : 0 : case M2Quads_LogicalOrOp:
21446 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Or ", 18);
21447 : 0 : break;
21448 : :
21449 : 0 : case M2Quads_LogicalAndOp:
21450 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "And ", 18);
21451 : 0 : break;
21452 : :
21453 : 0 : case M2Quads_LogicalXorOp:
21454 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Xor ", 18);
21455 : 0 : break;
21456 : :
21457 : 0 : case M2Quads_LogicalDiffOp:
21458 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Ldiff ", 18);
21459 : 0 : break;
21460 : :
21461 : 0 : case M2Quads_LogicalShiftOp:
21462 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Shift ", 18);
21463 : 0 : break;
21464 : :
21465 : 0 : case M2Quads_LogicalRotateOp:
21466 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Rotate ", 18);
21467 : 0 : break;
21468 : :
21469 : 0 : case M2Quads_BecomesOp:
21470 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Becomes ", 18);
21471 : 0 : break;
21472 : :
21473 : 0 : case M2Quads_IndrXOp:
21474 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "IndrX ", 18);
21475 : 0 : break;
21476 : :
21477 : 0 : case M2Quads_XIndrOp:
21478 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "XIndr ", 18);
21479 : 0 : break;
21480 : :
21481 : 0 : case M2Quads_ArrayOp:
21482 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Array ", 18);
21483 : 0 : break;
21484 : :
21485 : 0 : case M2Quads_ElementSizeOp:
21486 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ElementSize ", 18);
21487 : 0 : break;
21488 : :
21489 : 0 : case M2Quads_RecordFieldOp:
21490 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RecordField ", 18);
21491 : 0 : break;
21492 : :
21493 : 0 : case M2Quads_AddrOp:
21494 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Addr ", 18);
21495 : 0 : break;
21496 : :
21497 : 0 : case M2Quads_SizeOp:
21498 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Size ", 18);
21499 : 0 : break;
21500 : :
21501 : 0 : case M2Quads_IfInOp:
21502 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If IN ", 18);
21503 : 0 : break;
21504 : :
21505 : 0 : case M2Quads_IfNotInOp:
21506 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If NOT IN ", 18);
21507 : 0 : break;
21508 : :
21509 : 0 : case M2Quads_IfNotEquOp:
21510 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If <> ", 18);
21511 : 0 : break;
21512 : :
21513 : 0 : case M2Quads_IfEquOp:
21514 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If = ", 18);
21515 : 0 : break;
21516 : :
21517 : 0 : case M2Quads_IfLessEquOp:
21518 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If <= ", 18);
21519 : 0 : break;
21520 : :
21521 : 0 : case M2Quads_IfGreEquOp:
21522 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If >= ", 18);
21523 : 0 : break;
21524 : :
21525 : 0 : case M2Quads_IfGreOp:
21526 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If > ", 18);
21527 : 0 : break;
21528 : :
21529 : 0 : case M2Quads_IfLessOp:
21530 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If < ", 18);
21531 : 0 : break;
21532 : :
21533 : 0 : case M2Quads_GotoOp:
21534 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Goto ", 18);
21535 : 0 : break;
21536 : :
21537 : 0 : case M2Quads_DummyOp:
21538 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Dummy ", 18);
21539 : 0 : break;
21540 : :
21541 : 0 : case M2Quads_ModuleScopeOp:
21542 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ModuleScopeOp ", 18);
21543 : 0 : break;
21544 : :
21545 : 0 : case M2Quads_StartDefFileOp:
21546 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StartDefFile ", 18);
21547 : 0 : break;
21548 : :
21549 : 0 : case M2Quads_StartModFileOp:
21550 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StartModFile ", 18);
21551 : 0 : break;
21552 : :
21553 : 0 : case M2Quads_EndFileOp:
21554 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "EndFileOp ", 18);
21555 : 0 : break;
21556 : :
21557 : 0 : case M2Quads_InitStartOp:
21558 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitStart ", 18);
21559 : 0 : break;
21560 : :
21561 : 0 : case M2Quads_InitEndOp:
21562 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitEnd ", 18);
21563 : 0 : break;
21564 : :
21565 : 0 : case M2Quads_FinallyStartOp:
21566 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FinallyStart ", 18);
21567 : 0 : break;
21568 : :
21569 : 0 : case M2Quads_FinallyEndOp:
21570 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FinallyEnd ", 18);
21571 : 0 : break;
21572 : :
21573 : 0 : case M2Quads_RetryOp:
21574 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Retry ", 18);
21575 : 0 : break;
21576 : :
21577 : 0 : case M2Quads_TryOp:
21578 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Try ", 18);
21579 : 0 : break;
21580 : :
21581 : 0 : case M2Quads_ThrowOp:
21582 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Throw ", 18);
21583 : 0 : break;
21584 : :
21585 : 0 : case M2Quads_CatchBeginOp:
21586 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CatchBegin ", 18);
21587 : 0 : break;
21588 : :
21589 : 0 : case M2Quads_CatchEndOp:
21590 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CatchEnd ", 18);
21591 : 0 : break;
21592 : :
21593 : 0 : case M2Quads_AddOp:
21594 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "+ ", 18);
21595 : 0 : break;
21596 : :
21597 : 0 : case M2Quads_SubOp:
21598 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "- ", 18);
21599 : 0 : break;
21600 : :
21601 : 0 : case M2Quads_DivM2Op:
21602 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV M2 ", 18);
21603 : 0 : break;
21604 : :
21605 : 0 : case M2Quads_ModM2Op:
21606 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD M2 ", 18);
21607 : 0 : break;
21608 : :
21609 : 0 : case M2Quads_DivCeilOp:
21610 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV ceil ", 18);
21611 : 0 : break;
21612 : :
21613 : 0 : case M2Quads_ModCeilOp:
21614 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD ceil ", 18);
21615 : 0 : break;
21616 : :
21617 : 0 : case M2Quads_DivFloorOp:
21618 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV floor ", 18);
21619 : 0 : break;
21620 : :
21621 : 0 : case M2Quads_ModFloorOp:
21622 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD floor ", 18);
21623 : 0 : break;
21624 : :
21625 : 0 : case M2Quads_DivTruncOp:
21626 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV trunc ", 18);
21627 : 0 : break;
21628 : :
21629 : 0 : case M2Quads_ModTruncOp:
21630 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD trunc ", 18);
21631 : 0 : break;
21632 : :
21633 : 0 : case M2Quads_MultOp:
21634 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "* ", 18);
21635 : 0 : break;
21636 : :
21637 : 0 : case M2Quads_NegateOp:
21638 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Negate ", 18);
21639 : 0 : break;
21640 : :
21641 : 0 : case M2Quads_InclOp:
21642 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Incl ", 18);
21643 : 0 : break;
21644 : :
21645 : 0 : case M2Quads_ExclOp:
21646 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Excl ", 18);
21647 : 0 : break;
21648 : :
21649 : 0 : case M2Quads_ReturnOp:
21650 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Return ", 18);
21651 : 0 : break;
21652 : :
21653 : 0 : case M2Quads_ReturnValueOp:
21654 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ReturnValue ", 18);
21655 : 0 : break;
21656 : :
21657 : 0 : case M2Quads_FunctValueOp:
21658 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FunctValue ", 18);
21659 : 0 : break;
21660 : :
21661 : 0 : case M2Quads_CallOp:
21662 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Call ", 18);
21663 : 0 : break;
21664 : :
21665 : 0 : case M2Quads_ParamOp:
21666 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Param ", 18);
21667 : 0 : break;
21668 : :
21669 : 0 : case M2Quads_OptParamOp:
21670 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptParam ", 18);
21671 : 0 : break;
21672 : :
21673 : 0 : case M2Quads_NewLocalVarOp:
21674 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "NewLocalVar ", 18);
21675 : 0 : break;
21676 : :
21677 : 0 : case M2Quads_KillLocalVarOp:
21678 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "KillLocalVar ", 18);
21679 : 0 : break;
21680 : :
21681 : 0 : case M2Quads_ProcedureScopeOp:
21682 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProcedureScope ", 18);
21683 : 0 : break;
21684 : :
21685 : 0 : case M2Quads_UnboundedOp:
21686 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Unbounded ", 18);
21687 : 0 : break;
21688 : :
21689 : 0 : case M2Quads_CoerceOp:
21690 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Coerce ", 18);
21691 : 0 : break;
21692 : :
21693 : 0 : case M2Quads_ConvertOp:
21694 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Convert ", 18);
21695 : 0 : break;
21696 : :
21697 : 0 : case M2Quads_CastOp:
21698 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Cast ", 18);
21699 : 0 : break;
21700 : :
21701 : 0 : case M2Quads_HighOp:
21702 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "High ", 18);
21703 : 0 : break;
21704 : :
21705 : 0 : case M2Quads_CodeOnOp:
21706 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CodeOn ", 18);
21707 : 0 : break;
21708 : :
21709 : 0 : case M2Quads_CodeOffOp:
21710 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CodeOff ", 18);
21711 : 0 : break;
21712 : :
21713 : 0 : case M2Quads_ProfileOnOp:
21714 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProfileOn ", 18);
21715 : 0 : break;
21716 : :
21717 : 0 : case M2Quads_ProfileOffOp:
21718 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProfileOff ", 18);
21719 : 0 : break;
21720 : :
21721 : 0 : case M2Quads_OptimizeOnOp:
21722 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptimizeOn ", 18);
21723 : 0 : break;
21724 : :
21725 : 0 : case M2Quads_OptimizeOffOp:
21726 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptimizeOff ", 18);
21727 : 0 : break;
21728 : :
21729 : 0 : case M2Quads_InlineOp:
21730 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Inline ", 18);
21731 : 0 : break;
21732 : :
21733 : 0 : case M2Quads_StatementNoteOp:
21734 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StatementNote ", 18);
21735 : 0 : break;
21736 : :
21737 : 0 : case M2Quads_LineNumberOp:
21738 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "LineNumber ", 18);
21739 : 0 : break;
21740 : :
21741 : 0 : case M2Quads_BuiltinConstOp:
21742 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "BuiltinConst ", 18);
21743 : 0 : break;
21744 : :
21745 : 0 : case M2Quads_BuiltinTypeInfoOp:
21746 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "BuiltinTypeInfo ", 18);
21747 : 0 : break;
21748 : :
21749 : 0 : case M2Quads_StandardFunctionOp:
21750 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StandardFunction ", 18);
21751 : 0 : break;
21752 : :
21753 : 0 : case M2Quads_SavePriorityOp:
21754 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SavePriority ", 18);
21755 : 0 : break;
21756 : :
21757 : 0 : case M2Quads_RestorePriorityOp:
21758 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RestorePriority ", 18);
21759 : 0 : break;
21760 : :
21761 : 0 : case M2Quads_RangeCheckOp:
21762 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RangeCheck ", 18);
21763 : 0 : break;
21764 : :
21765 : 0 : case M2Quads_ErrorOp:
21766 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Error ", 18);
21767 : 0 : break;
21768 : :
21769 : 0 : case M2Quads_SaveExceptionOp:
21770 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SaveException ", 18);
21771 : 0 : break;
21772 : :
21773 : 0 : case M2Quads_RestoreExceptionOp:
21774 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RestoreException ", 18);
21775 : 0 : break;
21776 : :
21777 : 0 : case M2Quads_StringConvertCnulOp:
21778 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringConvertCnul ", 18);
21779 : 0 : break;
21780 : :
21781 : 0 : case M2Quads_StringConvertM2nulOp:
21782 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringConvertM2nul", 18);
21783 : 0 : break;
21784 : :
21785 : 0 : case M2Quads_StringLengthOp:
21786 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringLength ", 18);
21787 : 0 : break;
21788 : :
21789 : 0 : case M2Quads_SubrangeHighOp:
21790 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SubrangeHigh ", 18);
21791 : 0 : break;
21792 : :
21793 : 0 : case M2Quads_SubrangeLowOp:
21794 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SubrangeLow ", 18);
21795 : 0 : break;
21796 : :
21797 : :
21798 : 0 : default:
21799 : 0 : M2Error_InternalError ((const char *) "operator not expected", 21);
21800 : 0 : break;
21801 : : }
21802 : 0 : }
21803 : :
21804 : :
21805 : : /*
21806 : : PushAutoOn - push the auto flag and then set it to TRUE.
21807 : : Any call to ident in the parser will result in the token being pushed.
21808 : : */
21809 : :
21810 : 28644937 : extern "C" void M2Quads_PushAutoOn (void)
21811 : : {
21812 : 28644937 : M2StackWord_PushWord (AutoStack, static_cast<unsigned int> (IsAutoOn));
21813 : 28644937 : IsAutoOn = true;
21814 : 28644937 : }
21815 : :
21816 : :
21817 : : /*
21818 : : PushAutoOff - push the auto flag and then set it to FALSE.
21819 : : */
21820 : :
21821 : 60757227 : extern "C" void M2Quads_PushAutoOff (void)
21822 : : {
21823 : 60757227 : M2StackWord_PushWord (AutoStack, static_cast<unsigned int> (IsAutoOn));
21824 : 60757227 : IsAutoOn = false;
21825 : 60757227 : }
21826 : :
21827 : :
21828 : : /*
21829 : : IsAutoPushOn - returns the value of the current Auto ident push flag.
21830 : : */
21831 : :
21832 : 287992848 : extern "C" bool M2Quads_IsAutoPushOn (void)
21833 : : {
21834 : 287992848 : return IsAutoOn;
21835 : : /* static analysis guarentees a RETURN statement will be used before here. */
21836 : : __builtin_unreachable ();
21837 : : }
21838 : :
21839 : :
21840 : : /*
21841 : : PopAuto - restores the previous value of the Auto flag.
21842 : : */
21843 : :
21844 : 89380898 : extern "C" void M2Quads_PopAuto (void)
21845 : : {
21846 : 89380898 : IsAutoOn = static_cast<bool> (M2StackWord_PopWord (AutoStack));
21847 : 89380898 : }
21848 : :
21849 : :
21850 : : /*
21851 : : MustCheckOverflow - returns TRUE if the quadruple should test for overflow.
21852 : : */
21853 : :
21854 : 422325 : extern "C" bool M2Quads_MustCheckOverflow (unsigned int q)
21855 : : {
21856 : 422325 : M2Quads_QuadFrame f;
21857 : :
21858 : 422325 : f = GetQF (q);
21859 : 422325 : return f->CheckOverflow;
21860 : : /* static analysis guarentees a RETURN statement will be used before here. */
21861 : : __builtin_unreachable ();
21862 : : }
21863 : :
21864 : :
21865 : : /*
21866 : : PushInConstExpression - push the InConstExpression flag and then set it to TRUE.
21867 : : */
21868 : :
21869 : 861453 : extern "C" void M2Quads_PushInConstExpression (void)
21870 : : {
21871 : 861453 : M2StackWord_PushWord (ConstExprStack, static_cast<unsigned int> (InConstExpression));
21872 : 861453 : InConstExpression = true;
21873 : 861453 : }
21874 : :
21875 : :
21876 : : /*
21877 : : PopInConstExpression - restores the previous value of the InConstExpression.
21878 : : */
21879 : :
21880 : 861441 : extern "C" void M2Quads_PopInConstExpression (void)
21881 : : {
21882 : 861441 : InConstExpression = static_cast<bool> (M2StackWord_PopWord (ConstExprStack));
21883 : 861441 : }
21884 : :
21885 : :
21886 : : /*
21887 : : IsInConstExpression - returns the value of the InConstExpression.
21888 : : */
21889 : :
21890 : 4397956 : extern "C" bool M2Quads_IsInConstExpression (void)
21891 : : {
21892 : 4397956 : return InConstExpression;
21893 : : /* static analysis guarentees a RETURN statement will be used before here. */
21894 : : __builtin_unreachable ();
21895 : : }
21896 : :
21897 : :
21898 : : /*
21899 : : PushInConstParameters - push the InConstParameters flag and then set it to TRUE.
21900 : : */
21901 : :
21902 : 1507 : extern "C" void M2Quads_PushInConstParameters (void)
21903 : : {
21904 : 1507 : M2StackWord_PushWord (ConstParamStack, static_cast<unsigned int> (InConstParameters));
21905 : 1507 : InConstParameters = true;
21906 : 1507 : }
21907 : :
21908 : :
21909 : : /*
21910 : : PopInConstParameters - restores the previous value of the InConstParameters.
21911 : : */
21912 : :
21913 : 1507 : extern "C" void M2Quads_PopInConstParameters (void)
21914 : : {
21915 : 1507 : InConstParameters = static_cast<bool> (M2StackWord_PopWord (ConstParamStack));
21916 : 1507 : }
21917 : :
21918 : :
21919 : : /*
21920 : : IsInConstParameters - returns the value of the InConstParameters.
21921 : : */
21922 : :
21923 : 61322 : extern "C" bool M2Quads_IsInConstParameters (void)
21924 : : {
21925 : 61322 : return InConstParameters;
21926 : : /* static analysis guarentees a RETURN statement will be used before here. */
21927 : : __builtin_unreachable ();
21928 : : }
21929 : :
21930 : :
21931 : : /*
21932 : : BuildAsmElement - the stack is expected to contain:
21933 : :
21934 : :
21935 : : Entry Exit
21936 : : ===== ====
21937 : :
21938 : : Ptr ->
21939 : : +------------------+
21940 : : | expr | tokpos |
21941 : : |------------------|
21942 : : | str |
21943 : : |------------------|
21944 : : | name |
21945 : : |------------------| +------------------+
21946 : : | CurrentInterface | | CurrentInterface |
21947 : : |------------------| |------------------|
21948 : : | CurrentAsm | | CurrentAsm |
21949 : : |------------------| |------------------|
21950 : : | n | | n |
21951 : : |------------------| |------------------|
21952 : : */
21953 : :
21954 : 24 : extern "C" void M2Quads_BuildAsmElement (bool input, bool output)
21955 : : {
21956 : 24 : DynamicStrings_String s;
21957 : 24 : unsigned int n;
21958 : 24 : unsigned int str;
21959 : 24 : unsigned int expr;
21960 : 24 : unsigned int tokpos;
21961 : 24 : unsigned int CurrentInterface;
21962 : 24 : unsigned int CurrentAsm;
21963 : 24 : unsigned int name;
21964 : :
21965 : 24 : M2Quads_PopTtok (&expr, &tokpos);
21966 : 24 : M2Quads_PopT (&str);
21967 : 24 : M2Quads_PopT (&name);
21968 : 24 : M2Quads_PopT (&CurrentInterface);
21969 : 24 : M2Quads_PopT (&CurrentAsm);
21970 : 48 : M2Debug_Assert ((SymbolTable_IsGnuAsm (CurrentAsm)) || (SymbolTable_IsGnuAsmVolatile (CurrentAsm)));
21971 : 24 : M2Quads_PopT (&n);
21972 : 24 : n += 1;
21973 : 24 : if (CurrentInterface == SymbolTable_NulSym)
21974 : : {
21975 : 24 : CurrentInterface = SymbolTable_MakeRegInterface ();
21976 : : }
21977 : 24 : if (input)
21978 : : {
21979 : 12 : SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, name, str, expr, NextQuad, 0);
21980 : 12 : if (DebugAsmTokPos)
21981 : : {
21982 : : s = DynamicStrings_InitString ((const char *) "input expression", 16);
21983 : : M2Error_WarnStringAt (s, tokpos);
21984 : : }
21985 : : }
21986 : 24 : if (output)
21987 : : {
21988 : 12 : SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, name, str, expr, 0, NextQuad);
21989 : 12 : if (DebugAsmTokPos)
21990 : : {
21991 : : s = DynamicStrings_InitString ((const char *) "output expression", 17);
21992 : : M2Error_WarnStringAt (s, tokpos);
21993 : : }
21994 : : }
21995 : 24 : M2Quads_PushT (n);
21996 : 24 : M2Quads_PushT (CurrentAsm);
21997 : 24 : M2Quads_PushT (CurrentInterface);
21998 : 24 : }
21999 : :
22000 : :
22001 : : /*
22002 : : BuildAsmTrash - the stack is expected to contain:
22003 : :
22004 : :
22005 : : Entry Exit
22006 : : ===== ====
22007 : :
22008 : : Ptr ->
22009 : : +------------------+
22010 : : | expr | tokpos |
22011 : : |------------------| +------------------+
22012 : : | CurrentInterface | | CurrentInterface |
22013 : : |------------------| |------------------|
22014 : : | CurrentAsm | | CurrentAsm |
22015 : : |------------------| |------------------|
22016 : : | n | | n |
22017 : : |------------------| |------------------|
22018 : : */
22019 : :
22020 : 0 : extern "C" void M2Quads_BuildAsmTrash (void)
22021 : : {
22022 : 0 : unsigned int n;
22023 : 0 : unsigned int expr;
22024 : 0 : unsigned int tokpos;
22025 : 0 : unsigned int CurrentInterface;
22026 : 0 : unsigned int CurrentAsm;
22027 : :
22028 : 0 : M2Quads_PopTtok (&expr, &tokpos);
22029 : 0 : M2Quads_PopT (&CurrentInterface);
22030 : 0 : M2Quads_PopT (&CurrentAsm);
22031 : 0 : M2Debug_Assert ((SymbolTable_IsGnuAsm (CurrentAsm)) || (SymbolTable_IsGnuAsmVolatile (CurrentAsm)));
22032 : 0 : M2Quads_PopT (&n);
22033 : 0 : n += 1;
22034 : 0 : if (CurrentInterface == SymbolTable_NulSym)
22035 : : {
22036 : 0 : CurrentInterface = SymbolTable_MakeRegInterface ();
22037 : : }
22038 : 0 : SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, NameKey_NulName, SymbolTable_NulSym, expr, 0, NextQuad);
22039 : 0 : M2Quads_PushT (n);
22040 : 0 : M2Quads_PushT (CurrentAsm);
22041 : 0 : M2Quads_PushT (CurrentInterface);
22042 : 0 : }
22043 : :
22044 : :
22045 : : /*
22046 : : GetQuadTrash - return the symbol associated with the trashed operand.
22047 : : */
22048 : :
22049 : 120 : extern "C" unsigned int M2Quads_GetQuadTrash (unsigned int quad)
22050 : : {
22051 : 120 : M2Quads_QuadFrame f;
22052 : :
22053 : 120 : f = GetQF (quad);
22054 : 120 : LastQuadNo = quad;
22055 : 120 : return f->Trash;
22056 : : /* static analysis guarentees a RETURN statement will be used before here. */
22057 : : __builtin_unreachable ();
22058 : : }
22059 : :
22060 : 12963 : extern "C" void _M2_M2Quads_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
22061 : : {
22062 : 12963 : Init ();
22063 : 12963 : }
22064 : :
22065 : 0 : extern "C" void _M2_M2Quads_fini (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
22066 : : {
22067 : 0 : }
|