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-2025 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 : : #define INCLUDE_MEMORY
24 : : #include "config.h"
25 : : #include "system.h"
26 : : #include "gcc-consolidation.h"
27 : :
28 : : #include <stdbool.h>
29 : : # if !defined (PROC_D)
30 : : # define PROC_D
31 : : typedef void (*PROC_t) (void);
32 : : typedef struct { PROC_t proc; } PROC;
33 : : # endif
34 : :
35 : : # if !defined (TRUE)
36 : : # define TRUE (1==1)
37 : : # endif
38 : :
39 : : # if !defined (FALSE)
40 : : # define FALSE (1==0)
41 : : # endif
42 : :
43 : : # include "GStorage.h"
44 : : # include "Gmcrts.h"
45 : : #if defined(__cplusplus)
46 : : # undef NULL
47 : : # define NULL 0
48 : : #endif
49 : : #define _M2Quads_C
50 : :
51 : : #include "GM2Quads.h"
52 : : # include "GStorage.h"
53 : : # include "GM2Debug.h"
54 : : # include "GNameKey.h"
55 : : # include "GFormatStrings.h"
56 : : # include "GM2DebugStack.h"
57 : : # include "GStrLib.h"
58 : : # include "GM2Scaffold.h"
59 : : # include "GM2MetaError.h"
60 : : # include "GDynamicStrings.h"
61 : : # include "GSymbolTable.h"
62 : : # include "GM2Batch.h"
63 : : # include "GM2GCCDeclare.h"
64 : : # include "GFifoQueue.h"
65 : : # include "GM2Comp.h"
66 : : # include "GM2LexBuf.h"
67 : : # include "GM2Error.h"
68 : : # include "GM2Printf.h"
69 : : # include "GM2Reserved.h"
70 : : # include "GM2Base.h"
71 : : # include "GM2System.h"
72 : : # include "GM2Size.h"
73 : : # include "GM2Bitset.h"
74 : : # include "GM2ALU.h"
75 : : # include "GLists.h"
76 : : # include "GM2Options.h"
77 : : # include "GM2LangDump.h"
78 : : # include "GM2Pass.h"
79 : : # include "GM2StackAddress.h"
80 : : # include "GM2StackWord.h"
81 : : # include "GIndexing.h"
82 : : # include "GM2Range.h"
83 : : # include "GM2CaseList.h"
84 : : # include "GPCSymBuild.h"
85 : : # include "Gm2builtins.h"
86 : : # include "GFIO.h"
87 : : # include "GSFIO.h"
88 : : # include "GStdIO.h"
89 : :
90 : : # define DebugStackOn true
91 : : # define DebugVarients false
92 : : # define BreakAtQuad 758
93 : : # define DebugTokPos false
94 : : typedef struct M2Quads__T1_r M2Quads__T1;
95 : :
96 : : typedef M2Quads__T1 *M2Quads_ConstructorFrame;
97 : :
98 : : typedef struct M2Quads__T2_r M2Quads__T2;
99 : :
100 : : typedef M2Quads__T2 *M2Quads_BoolFrame;
101 : :
102 : : typedef struct M2Quads__T3_r M2Quads__T3;
103 : :
104 : : typedef M2Quads__T3 *M2Quads_QuadFrame;
105 : :
106 : : typedef struct M2Quads__T4_r M2Quads__T4;
107 : :
108 : : typedef M2Quads__T4 *M2Quads_WithFrame;
109 : :
110 : : typedef struct M2Quads__T5_r M2Quads__T5;
111 : :
112 : : typedef M2Quads__T5 *M2Quads_ForLoopInfo;
113 : :
114 : : typedef struct M2Quads__T6_r M2Quads__T6;
115 : :
116 : : typedef M2Quads__T6 *M2Quads_LineNote;
117 : :
118 : : # define DebugAsmTokPos false
119 : : struct M2Quads__T1_r {
120 : : unsigned int type;
121 : : unsigned int index;
122 : : };
123 : :
124 : : struct M2Quads__T2_r {
125 : : unsigned int TrueExit;
126 : : unsigned int FalseExit;
127 : : unsigned int Unbounded;
128 : : bool BooleanOp;
129 : : unsigned int Dimension;
130 : : unsigned int ReadWrite;
131 : : unsigned int name;
132 : : DynamicStrings_String Annotation;
133 : : unsigned int tokenno;
134 : : };
135 : :
136 : : struct M2Quads__T3_r {
137 : : M2Quads_QuadOperator Operator;
138 : : unsigned int Operand1;
139 : : unsigned int Operand2;
140 : : unsigned int Operand3;
141 : : unsigned int Trash;
142 : : unsigned int Next;
143 : : unsigned int LineNo;
144 : : unsigned int TokenNo;
145 : : unsigned int NoOfTimesReferenced;
146 : : bool ConstExpr;
147 : : bool CheckType;
148 : : bool CheckOverflow;
149 : : unsigned int op1pos;
150 : : unsigned int op2pos;
151 : : unsigned int op3pos;
152 : : };
153 : :
154 : : struct M2Quads__T4_r {
155 : : unsigned int RecordSym;
156 : : unsigned int RecordType;
157 : : unsigned int RecordRef;
158 : : unsigned int rw;
159 : : unsigned int RecordTokPos;
160 : : };
161 : :
162 : : struct M2Quads__T5_r {
163 : : unsigned int IncrementQuad;
164 : : unsigned int StartOfForLoop;
165 : : unsigned int EndOfForLoop;
166 : : unsigned int ForLoopIndex;
167 : : unsigned int IndexTok;
168 : : };
169 : :
170 : : struct M2Quads__T6_r {
171 : : unsigned int Line;
172 : : NameKey_Name File;
173 : : M2Quads_LineNote Next;
174 : : };
175 : :
176 : : static M2StackAddress_StackOfAddress ConstructorStack;
177 : : static M2StackAddress_StackOfAddress LineStack;
178 : : static M2StackAddress_StackOfAddress BoolStack;
179 : : static M2StackAddress_StackOfAddress WithStack;
180 : : static M2StackWord_StackOfWord TryStack;
181 : : static M2StackWord_StackOfWord CatchStack;
182 : : static M2StackWord_StackOfWord ExceptStack;
183 : : static M2StackWord_StackOfWord ConstExprStack;
184 : : static M2StackWord_StackOfWord ConstParamStack;
185 : : static M2StackWord_StackOfWord AutoStack;
186 : : static M2StackWord_StackOfWord RepeatStack;
187 : : static M2StackWord_StackOfWord WhileStack;
188 : : static M2StackWord_StackOfWord ForStack;
189 : : static M2StackWord_StackOfWord ExitStack;
190 : : static M2StackWord_StackOfWord ReturnStack;
191 : : static M2StackWord_StackOfWord PriorityStack;
192 : : static bool SuppressWith;
193 : : static Indexing_Index QuadArray;
194 : : static unsigned int NextQuad;
195 : : static unsigned int FreeList;
196 : : static unsigned int CurrentProc;
197 : : static unsigned int InitQuad;
198 : : static unsigned int LastQuadNo;
199 : : static NameKey_Name ArithPlusTok;
200 : : static NameKey_Name LogicalOrTok;
201 : : static NameKey_Name LogicalAndTok;
202 : : static NameKey_Name LogicalXorTok;
203 : : static NameKey_Name LogicalDifferenceTok;
204 : : static bool InConstExpression;
205 : : static bool InConstParameters;
206 : : static bool IsAutoOn;
207 : : static bool MustNotCheckBounds;
208 : : static Indexing_Index ForInfo;
209 : : static unsigned int GrowInitialization;
210 : : static bool BuildingHigh;
211 : : static bool BuildingSize;
212 : : static bool QuadrupleGeneration;
213 : : static M2Quads_LineNote FreeLineList;
214 : : static Lists_List VarientFields;
215 : : static unsigned int VarientFieldNo;
216 : : static unsigned int NoOfQuads;
217 : : static unsigned int Head;
218 : :
219 : : /*
220 : : SetOptionCoding - builds a code quadruple if the profiling
221 : : option was given to the compiler.
222 : : */
223 : :
224 : : extern "C" void M2Quads_SetOptionCoding (bool b);
225 : :
226 : : /*
227 : : SetOptionProfiling - builds a profile quadruple if the profiling
228 : : option was given to the compiler.
229 : : */
230 : :
231 : : extern "C" void M2Quads_SetOptionProfiling (bool b);
232 : :
233 : : /*
234 : : SetOptionOptimizing - builds a quadruple to say that the optimization option
235 : : has been found in a comment.
236 : : */
237 : :
238 : : extern "C" void M2Quads_SetOptionOptimizing (bool b);
239 : :
240 : : /*
241 : : Opposite - returns the opposite comparison operator.
242 : : */
243 : :
244 : : extern "C" M2Quads_QuadOperator M2Quads_Opposite (M2Quads_QuadOperator Operator);
245 : :
246 : : /*
247 : : IsReferenced - returns true if QuadNo is referenced by another quadruple.
248 : : */
249 : :
250 : : extern "C" bool M2Quads_IsReferenced (unsigned int QuadNo);
251 : :
252 : : /*
253 : : IsBackReference - returns TRUE if quadruple, q, is referenced from a quad further on.
254 : : */
255 : :
256 : : extern "C" bool M2Quads_IsBackReference (unsigned int q);
257 : :
258 : : /*
259 : : IsUnConditional - returns true if QuadNo is an unconditional jump.
260 : : */
261 : :
262 : : extern "C" bool M2Quads_IsUnConditional (unsigned int QuadNo);
263 : :
264 : : /*
265 : : IsConditional - returns true if QuadNo is a conditional jump.
266 : : */
267 : :
268 : : extern "C" bool M2Quads_IsConditional (unsigned int QuadNo);
269 : :
270 : : /*
271 : : IsBackReferenceConditional - returns TRUE if quadruple, q, is referenced from
272 : : a conditional quad further on.
273 : : */
274 : :
275 : : extern "C" bool M2Quads_IsBackReferenceConditional (unsigned int q);
276 : :
277 : : /*
278 : : IsGoto - returns true if QuadNo is a goto operation.
279 : : */
280 : :
281 : : extern "C" bool M2Quads_IsGoto (unsigned int QuadNo);
282 : :
283 : : /*
284 : : IsCall - returns true if QuadNo is a call operation.
285 : : */
286 : :
287 : : extern "C" bool M2Quads_IsCall (unsigned int QuadNo);
288 : :
289 : : /*
290 : : IsReturn - returns true if QuadNo is a return operation.
291 : : */
292 : :
293 : : extern "C" bool M2Quads_IsReturn (unsigned int QuadNo);
294 : :
295 : : /*
296 : : IsProcedureScope - returns true if QuadNo is a ProcedureScope operation.
297 : : */
298 : :
299 : : extern "C" bool M2Quads_IsProcedureScope (unsigned int QuadNo);
300 : :
301 : : /*
302 : : IsNewLocalVar - returns true if QuadNo is a NewLocalVar operation.
303 : : */
304 : :
305 : : extern "C" bool M2Quads_IsNewLocalVar (unsigned int QuadNo);
306 : :
307 : : /*
308 : : IsKillLocalVar - returns true if QuadNo is a KillLocalVar operation.
309 : : */
310 : :
311 : : extern "C" bool M2Quads_IsKillLocalVar (unsigned int QuadNo);
312 : :
313 : : /*
314 : : IsCatchBegin - returns true if QuadNo is a catch begin quad.
315 : : */
316 : :
317 : : extern "C" bool M2Quads_IsCatchBegin (unsigned int QuadNo);
318 : :
319 : : /*
320 : : IsCatchEnd - returns true if QuadNo is a catch end quad.
321 : : */
322 : :
323 : : extern "C" bool M2Quads_IsCatchEnd (unsigned int QuadNo);
324 : :
325 : : /*
326 : : IsInitStart - returns true if QuadNo is a init start quad.
327 : : */
328 : :
329 : : extern "C" bool M2Quads_IsInitStart (unsigned int QuadNo);
330 : :
331 : : /*
332 : : IsInitEnd - returns true if QuadNo is a init end quad.
333 : : */
334 : :
335 : : extern "C" bool M2Quads_IsInitEnd (unsigned int QuadNo);
336 : :
337 : : /*
338 : : IsFinallyStart - returns true if QuadNo is a finally start quad.
339 : : */
340 : :
341 : : extern "C" bool M2Quads_IsFinallyStart (unsigned int QuadNo);
342 : :
343 : : /*
344 : : IsFinallyEnd - returns true if QuadNo is a finally end quad.
345 : : */
346 : :
347 : : extern "C" bool M2Quads_IsFinallyEnd (unsigned int QuadNo);
348 : :
349 : : /*
350 : : IsBecomes - return TRUE if QuadNo is a BecomesOp.
351 : : */
352 : :
353 : : extern "C" bool M2Quads_IsBecomes (unsigned int QuadNo);
354 : :
355 : : /*
356 : : IsDummy - return TRUE if QuadNo is a DummyOp.
357 : : */
358 : :
359 : : extern "C" bool M2Quads_IsDummy (unsigned int QuadNo);
360 : :
361 : : /*
362 : : IsQuadConstExpr - returns TRUE if QuadNo is part of a constant expression.
363 : : */
364 : :
365 : : extern "C" bool M2Quads_IsQuadConstExpr (unsigned int QuadNo);
366 : :
367 : : /*
368 : : SetQuadConstExpr - sets the constexpr field to value.
369 : : */
370 : :
371 : : extern "C" void M2Quads_SetQuadConstExpr (unsigned int QuadNo, bool value);
372 : :
373 : : /*
374 : : GetQuadDest - returns the jump destination associated with quad.
375 : : */
376 : :
377 : : extern "C" unsigned int M2Quads_GetQuadDest (unsigned int QuadNo);
378 : :
379 : : /*
380 : : GetQuadOp1 - returns the 1st operand associated with quad.
381 : : */
382 : :
383 : : extern "C" unsigned int M2Quads_GetQuadOp1 (unsigned int QuadNo);
384 : :
385 : : /*
386 : : GetQuadOp2 - returns the 2nd operand associated with quad.
387 : : */
388 : :
389 : : extern "C" unsigned int M2Quads_GetQuadOp2 (unsigned int QuadNo);
390 : :
391 : : /*
392 : : GetQuadOp3 - returns the 3rd operand associated with quad.
393 : : */
394 : :
395 : : extern "C" unsigned int M2Quads_GetQuadOp3 (unsigned int QuadNo);
396 : :
397 : : /*
398 : : IsInitialisingConst - returns TRUE if the quadruple is setting
399 : : a const (op1) with a value.
400 : : */
401 : :
402 : : extern "C" bool M2Quads_IsInitialisingConst (unsigned int QuadNo);
403 : :
404 : : /*
405 : : IsConstQuad - return TRUE if the quadruple is marked as a constexpr.
406 : : */
407 : :
408 : : extern "C" bool M2Quads_IsConstQuad (unsigned int quad);
409 : :
410 : : /*
411 : : IsConditionalBooleanQuad - return TRUE if operand 1 is a boolean result.
412 : : */
413 : :
414 : : extern "C" bool M2Quads_IsConditionalBooleanQuad (unsigned int quad);
415 : :
416 : : /*
417 : : IsOptimizeOn - returns true if the Optimize flag was true at QuadNo.
418 : : */
419 : :
420 : : extern "C" bool M2Quads_IsOptimizeOn (unsigned int QuadNo);
421 : :
422 : : /*
423 : : IsProfileOn - returns true if the Profile flag was true at QuadNo.
424 : : */
425 : :
426 : : extern "C" bool M2Quads_IsProfileOn (unsigned int QuadNo);
427 : :
428 : : /*
429 : : IsCodeOn - returns true if the Code flag was true at QuadNo.
430 : : */
431 : :
432 : : extern "C" bool M2Quads_IsCodeOn (unsigned int QuadNo);
433 : :
434 : : /*
435 : : IsPseudoQuad - returns true if QuadNo is a compiler directive.
436 : : ie code, profile and optimize.
437 : : StartFile, EndFile,
438 : : */
439 : :
440 : : extern "C" bool M2Quads_IsPseudoQuad (unsigned int QuadNo);
441 : :
442 : : /*
443 : : IsDefOrModFile - returns TRUE if QuadNo is a start of Module or Def file
444 : : directive.
445 : : */
446 : :
447 : : extern "C" bool M2Quads_IsDefOrModFile (unsigned int QuadNo);
448 : :
449 : : /*
450 : : DumpQuadruples - dump all quadruples providing the -fq, -fdump-lang-quad,
451 : : -fdump-lang-quad= or -fdump-lang-all were issued to the
452 : : command line.
453 : : */
454 : :
455 : : extern "C" void M2Quads_DumpQuadruples (const char *title_, unsigned int _title_high);
456 : :
457 : : /*
458 : : DisplayQuadRange - displays all quads in list range, start..end.
459 : : */
460 : :
461 : : extern "C" void M2Quads_DisplayQuadRange (unsigned int scope, unsigned int start, unsigned int end);
462 : :
463 : : /*
464 : : DisplayQuad - displays a quadruple, QuadNo.
465 : : */
466 : :
467 : : extern "C" void M2Quads_DisplayQuad (unsigned int QuadNo);
468 : :
469 : : /*
470 : : GetLastFileQuad - returns the Quadruple number of the last StartDefFile or
471 : : StartModFile quadruple.
472 : : */
473 : :
474 : : extern "C" unsigned int M2Quads_GetLastFileQuad (unsigned int QuadNo);
475 : :
476 : : /*
477 : : GetLastQuadNo - returns the last quadruple number referenced
478 : : by a GetQuad.
479 : : */
480 : :
481 : : extern "C" unsigned int M2Quads_GetLastQuadNo (void);
482 : :
483 : : /*
484 : : QuadToTokenNo - Converts a QuadNo into the approprate token number of the
485 : : source file, the line number is returned.
486 : :
487 : : This may be used to yield an idea where abouts in the
488 : : source file the code generetion is
489 : : processing.
490 : : */
491 : :
492 : : extern "C" unsigned int M2Quads_QuadToTokenNo (unsigned int QuadNo);
493 : :
494 : : /*
495 : : QuadToLineNo - Converts a QuadNo into the approprate line number of the
496 : : source file, the line number is returned.
497 : :
498 : : This may be used to yield an idea where abouts in the
499 : : source file the code generetion is
500 : : processing.
501 : : */
502 : :
503 : : extern "C" unsigned int M2Quads_QuadToLineNo (unsigned int QuadNo);
504 : :
505 : : /*
506 : : GetQuad - returns the Quadruple QuadNo.
507 : : */
508 : :
509 : : extern "C" void M2Quads_GetQuad (unsigned int QuadNo, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3);
510 : :
511 : : /*
512 : : GetQuadOp - returns the operator for quad.
513 : : */
514 : :
515 : : extern "C" M2Quads_QuadOperator M2Quads_GetQuadOp (unsigned int quad);
516 : :
517 : : /*
518 : : GetM2OperatorDesc - returns the Modula-2 string associated with the quad operator
519 : : (if possible). It returns NIL if no there is not an obvious match
520 : : in Modula-2. It is assummed that the string will be used during
521 : : construction of error messages and therefore keywords are
522 : : wrapped with a format specifier.
523 : : */
524 : :
525 : : extern "C" DynamicStrings_String M2Quads_GetM2OperatorDesc (M2Quads_QuadOperator op);
526 : :
527 : : /*
528 : : GetQuadtok - returns the Quadruple QuadNo.
529 : : */
530 : :
531 : : 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);
532 : :
533 : : /*
534 : : GetQuadOtok - returns the Quadruple QuadNo.
535 : : */
536 : :
537 : : 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);
538 : :
539 : : /*
540 : : GetQuadOTypetok - returns the fields associated with quadruple QuadNo.
541 : : */
542 : :
543 : : 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);
544 : :
545 : : /*
546 : : PutQuadOtok - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
547 : : sets a boolean to determinine whether overflow should be checked.
548 : : */
549 : :
550 : : 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);
551 : :
552 : : /*
553 : : PutQuad - overwrites a quadruple QuadNo with Op, Oper1, Oper2, Oper3
554 : : */
555 : :
556 : : extern "C" void M2Quads_PutQuad (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3);
557 : :
558 : : /*
559 : : GetFirstQuad - returns the first quadruple.
560 : : */
561 : :
562 : : extern "C" unsigned int M2Quads_GetFirstQuad (void);
563 : :
564 : : /*
565 : : GetNextQuad - returns the Quadruple number following QuadNo.
566 : : */
567 : :
568 : : extern "C" unsigned int M2Quads_GetNextQuad (unsigned int QuadNo);
569 : :
570 : : /*
571 : : GetRealQuad - returns the Quadruple number of the real quadruple
572 : : at QuadNo or beyond.
573 : : */
574 : :
575 : : extern "C" unsigned int M2Quads_GetRealQuad (unsigned int QuadNo);
576 : :
577 : : /*
578 : : SubQuad - subtracts a quadruple QuadNo from a list Head.
579 : : */
580 : :
581 : : extern "C" void M2Quads_SubQuad (unsigned int QuadNo);
582 : :
583 : : /*
584 : : EraseQuad - erases a quadruple QuadNo, the quadruple is still in the list
585 : : but wiped clean.
586 : : */
587 : :
588 : : extern "C" void M2Quads_EraseQuad (unsigned int QuadNo);
589 : :
590 : : /*
591 : : CountQuads - returns the number of quadruples.
592 : : */
593 : :
594 : : extern "C" unsigned int M2Quads_CountQuads (void);
595 : :
596 : : /*
597 : : BuildScaffold - generate the main, init, finish functions if
598 : : no -c and this is the application module.
599 : : */
600 : :
601 : : extern "C" void M2Quads_BuildScaffold (unsigned int tok, unsigned int moduleSym);
602 : :
603 : : /*
604 : : StartBuildDefFile - generates a StartFileDefOp quadruple indicating the file
605 : : that has produced the subsequent quadruples.
606 : : The code generator uses the StartDefFileOp quadruples
607 : : to relate any error to the appropriate file.
608 : :
609 : :
610 : : Entry Exit
611 : : ===== ====
612 : :
613 : :
614 : : Ptr -> <- Ptr
615 : : +------------+ +------------+
616 : : | ModuleName | | ModuleName |
617 : : |------------| |------------|
618 : :
619 : :
620 : : Quadruples Produced
621 : :
622 : : q StartDefFileOp _ _ ModuleSym
623 : : */
624 : :
625 : : extern "C" void M2Quads_StartBuildDefFile (unsigned int tok);
626 : :
627 : : /*
628 : : StartBuildModFile - generates a StartModFileOp quadruple indicating the file
629 : : that has produced the subsequent quadruples.
630 : : The code generator uses the StartModFileOp quadruples
631 : : to relate any error to the appropriate file.
632 : :
633 : :
634 : : Entry Exit
635 : : ===== ====
636 : :
637 : :
638 : : Ptr -> <- Ptr
639 : : +------------+ +------------+
640 : : | ModuleName | | ModuleName |
641 : : |------------| |------------|
642 : :
643 : :
644 : : Quadruples Produced
645 : :
646 : : q StartModFileOp lineno filename ModuleSym
647 : : */
648 : :
649 : : extern "C" void M2Quads_StartBuildModFile (unsigned int tok);
650 : :
651 : : /*
652 : : EndBuildFile - generates an EndFileOp quadruple indicating the file
653 : : that has produced the previous quadruples has ended.
654 : :
655 : : Entry Exit
656 : : ===== ====
657 : :
658 : :
659 : : Ptr -> <- Ptr
660 : : +------------+ +------------+
661 : : | ModuleName | | ModuleName |
662 : : |------------| |------------|
663 : :
664 : :
665 : : Quadruples Produced
666 : :
667 : : q EndFileOp _ _ ModuleSym
668 : : */
669 : :
670 : : extern "C" void M2Quads_EndBuildFile (unsigned int tok);
671 : :
672 : : /*
673 : : StartBuildInit - Sets the start of initialization code of the
674 : : current module to the next quadruple.
675 : : */
676 : :
677 : : extern "C" void M2Quads_StartBuildInit (unsigned int tok);
678 : :
679 : : /*
680 : : EndBuildInit - Sets the end initialization code of a module.
681 : : */
682 : :
683 : : extern "C" void M2Quads_EndBuildInit (unsigned int tok);
684 : :
685 : : /*
686 : : StartBuildFinally - Sets the start of finalization code of the
687 : : current module to the next quadruple.
688 : : */
689 : :
690 : : extern "C" void M2Quads_StartBuildFinally (unsigned int tok);
691 : :
692 : : /*
693 : : EndBuildFinally - Sets the end finalization code of a module.
694 : : */
695 : :
696 : : extern "C" void M2Quads_EndBuildFinally (unsigned int tok);
697 : :
698 : : /*
699 : : BuildExceptInitial - adds an CatchBeginOp, CatchEndOp quadruple
700 : : in the current block.
701 : : */
702 : :
703 : : extern "C" void M2Quads_BuildExceptInitial (unsigned int tok);
704 : :
705 : : /*
706 : : BuildExceptFinally - adds an ExceptOp quadruple in a modules
707 : : finally block.
708 : : */
709 : :
710 : : extern "C" void M2Quads_BuildExceptFinally (unsigned int tok);
711 : :
712 : : /*
713 : : BuildExceptProcedure - adds an ExceptOp quadruple in a procedure
714 : : block.
715 : : */
716 : :
717 : : extern "C" void M2Quads_BuildExceptProcedure (unsigned int tok);
718 : :
719 : : /*
720 : : BuildRetry - adds an RetryOp quadruple.
721 : : */
722 : :
723 : : extern "C" void M2Quads_BuildRetry (unsigned int tok);
724 : :
725 : : /*
726 : : BuildReThrow - creates a ThrowOp _ _ NulSym, indicating that
727 : : the exception needs to be rethrown. The stack
728 : : is unaltered.
729 : : */
730 : :
731 : : extern "C" void M2Quads_BuildReThrow (unsigned int tokenno);
732 : :
733 : : /*
734 : : StartBuildInnerInit - Sets the start of initialization code of the
735 : : inner module to the next quadruple.
736 : : */
737 : :
738 : : extern "C" void M2Quads_StartBuildInnerInit (unsigned int tok);
739 : :
740 : : /*
741 : : EndBuildInnerInit - Sets the end initialization code of a module.
742 : : */
743 : :
744 : : extern "C" void M2Quads_EndBuildInnerInit (unsigned int tok);
745 : :
746 : : /*
747 : : BuildBuiltinConst - makes reference to a builtin constant within gm2.
748 : :
749 : : Entry Exit
750 : :
751 : : Ptr ->
752 : : +------------+ +------------+
753 : : | Ident | | Sym |
754 : : |------------| |------------|
755 : :
756 : : Quadruple produced:
757 : :
758 : : q Sym BuiltinConstOp Ident
759 : : */
760 : :
761 : : extern "C" void M2Quads_BuildBuiltinConst (void);
762 : :
763 : : /*
764 : : BuildBuiltinTypeInfo - make reference to a builtin typeinfo function
765 : : within gm2.
766 : :
767 : : Entry Exit
768 : :
769 : : Ptr ->
770 : : +-------------+
771 : : | Type |
772 : : |-------------| +------------+
773 : : | Ident | | Sym |
774 : : |-------------| |------------|
775 : :
776 : : Quadruple produced:
777 : :
778 : : q Sym BuiltinTypeInfoOp Type Ident
779 : : */
780 : :
781 : : extern "C" void M2Quads_BuildBuiltinTypeInfo (void);
782 : :
783 : : /*
784 : : BuildAssignment - Builds an assignment from the values given on the
785 : : quad stack. Either an assignment to an
786 : : arithmetic expression or an assignment to a
787 : : boolean expression. This procedure should not
788 : : be called in CONST declarations.
789 : : The Stack is expected to contain:
790 : :
791 : :
792 : : Either
793 : :
794 : : Entry Exit
795 : : ===== ====
796 : :
797 : : Ptr ->
798 : : +------------+
799 : : | Expression |
800 : : |------------|
801 : : | Designator |
802 : : |------------| +------------+
803 : : | | | | <- Ptr
804 : : |------------| |------------|
805 : :
806 : :
807 : : Quadruples Produced
808 : :
809 : : q BecomesOp Designator _ Expression
810 : :
811 : : OR
812 : :
813 : : Entry Exit
814 : : ===== ====
815 : :
816 : : Ptr ->
817 : : +------------+
818 : : | True |False|
819 : : |------------|
820 : : | Designator |
821 : : |------------| +------------+
822 : : | | | | <- Ptr
823 : : |------------| |------------|
824 : :
825 : :
826 : : Quadruples Produced
827 : :
828 : : q BecomesOp Designator _ TRUE
829 : : q+1 GotoOp q+3
830 : : q+2 BecomesOp Designator _ FALSE
831 : :
832 : : */
833 : :
834 : : extern "C" void M2Quads_BuildAssignment (unsigned int becomesTokNo);
835 : :
836 : : /*
837 : : BuildAssignConstant - used to create constant in the CONST declaration.
838 : : The stack is expected to contain:
839 : :
840 : : Either
841 : :
842 : : Entry Exit
843 : : ===== ====
844 : :
845 : : Ptr ->
846 : : +------------+
847 : : | Expression |
848 : : |------------|
849 : : | Designator |
850 : : |------------| +------------+
851 : : | | | | <- Ptr
852 : : |------------| |------------|
853 : :
854 : :
855 : : Quadruples Produced
856 : :
857 : : q BecomesOp Designator _ Expression
858 : :
859 : : OR
860 : :
861 : : Entry Exit
862 : : ===== ====
863 : :
864 : : Ptr ->
865 : : +------------+
866 : : | True |False|
867 : : |------------|
868 : : | Designator |
869 : : |------------| +------------+
870 : : | | | | <- Ptr
871 : : |------------| |------------|
872 : :
873 : :
874 : : Quadruples Produced
875 : :
876 : : q BecomesOp Designator _ TRUE
877 : : q+1 GotoOp q+3
878 : : q+2 BecomesOp Designator _ FALSE
879 : : */
880 : :
881 : : extern "C" void M2Quads_BuildAssignConstant (unsigned int equalsTokNo);
882 : :
883 : : /*
884 : : BuildAlignment - builds an assignment to an alignment constant.
885 : :
886 : : The Stack is expected to contain:
887 : :
888 : :
889 : : Entry Exit
890 : : ===== ====
891 : :
892 : : Ptr ->
893 : : +---------------+
894 : : | Expression |
895 : : |---------------|
896 : : | bytealignment |
897 : : |---------------| empty
898 : : */
899 : :
900 : : extern "C" void M2Quads_BuildAlignment (unsigned int tokno);
901 : :
902 : : /*
903 : : BuildBitLength - builds an assignment to a bit length constant.
904 : :
905 : : The Stack is expected to contain:
906 : :
907 : :
908 : : Entry Exit
909 : : ===== ====
910 : :
911 : : Ptr ->
912 : : +------------+
913 : : | Expression |
914 : : |------------| empty
915 : : */
916 : :
917 : : extern "C" void M2Quads_BuildBitLength (unsigned int tokno);
918 : :
919 : : /*
920 : : BuildPragmaField - builds an assignment to an alignment constant.
921 : :
922 : : The Stack is expected to contain:
923 : :
924 : :
925 : : Entry Exit
926 : : ===== ====
927 : :
928 : : Ptr ->
929 : : +------------+
930 : : | Expression |
931 : : |------------| empty
932 : : */
933 : :
934 : : extern "C" void M2Quads_BuildPragmaField (void);
935 : :
936 : : /*
937 : : BuildDefaultFieldAlignment - builds an assignment to an alignment constant.
938 : :
939 : : The Stack is expected to contain:
940 : :
941 : :
942 : : Entry Exit
943 : : ===== ====
944 : :
945 : : Ptr ->
946 : : +------------+
947 : : | Expression |
948 : : |------------| empty
949 : : */
950 : :
951 : : extern "C" void M2Quads_BuildDefaultFieldAlignment (void);
952 : :
953 : : /*
954 : : BuildRepeat - Builds the repeat statement from the quad stack.
955 : : The Stack is expected to contain:
956 : :
957 : :
958 : : Entry Exit
959 : : ===== ====
960 : :
961 : :
962 : : Empty
963 : : <- Ptr
964 : : +------------+
965 : : | RepeatQuad |
966 : : |------------|
967 : :
968 : : */
969 : :
970 : : extern "C" void M2Quads_BuildRepeat (void);
971 : :
972 : : /*
973 : : BuildUntil - Builds the until part of the repeat statement
974 : : from the quad stack.
975 : : The Stack is expected to contain:
976 : :
977 : :
978 : : Entry Exit
979 : : ===== ====
980 : :
981 : : Ptr ->
982 : : +------------+
983 : : | t | f |
984 : : |------------|
985 : : | RepeatQuad | Empty
986 : : |------------|
987 : : */
988 : :
989 : : extern "C" void M2Quads_BuildUntil (void);
990 : :
991 : : /*
992 : : BuildWhile - Builds the While part of the While statement
993 : : from the quad stack.
994 : : The Stack is expected to contain:
995 : :
996 : :
997 : : Entry Exit
998 : : ===== ====
999 : :
1000 : : <- Ptr
1001 : : |------------|
1002 : : Empty | WhileQuad |
1003 : : |------------|
1004 : : */
1005 : :
1006 : : extern "C" void M2Quads_BuildWhile (void);
1007 : :
1008 : : /*
1009 : : BuildDoWhile - Builds the Do part of the while statement
1010 : : from the quad stack.
1011 : : The Stack is expected to contain:
1012 : :
1013 : :
1014 : : Entry Exit
1015 : : ===== ====
1016 : :
1017 : : Ptr ->
1018 : : +------------+ +------------+
1019 : : | t | f | | 0 | f |
1020 : : |------------| |------------|
1021 : : | WhileQuad | | WhileQuad |
1022 : : |------------| |------------|
1023 : :
1024 : : Quadruples
1025 : :
1026 : : BackPatch t exit to the NextQuad
1027 : : */
1028 : :
1029 : : extern "C" void M2Quads_BuildDoWhile (void);
1030 : :
1031 : : /*
1032 : : BuildEndWhile - Builds the end part of the while statement
1033 : : from the quad stack.
1034 : : The Stack is expected to contain:
1035 : :
1036 : :
1037 : : Entry Exit
1038 : : ===== ====
1039 : :
1040 : : Ptr ->
1041 : : +------------+
1042 : : | t | f |
1043 : : |------------|
1044 : : | WhileQuad | Empty
1045 : : |------------|
1046 : :
1047 : : Quadruples
1048 : :
1049 : : q GotoOp WhileQuad
1050 : : False exit is backpatched with q+1
1051 : : */
1052 : :
1053 : : extern "C" void M2Quads_BuildEndWhile (void);
1054 : :
1055 : : /*
1056 : : BuildLoop - Builds the Loop part of the Loop statement
1057 : : from the quad stack.
1058 : : The Stack is expected to contain:
1059 : :
1060 : :
1061 : : Entry Exit
1062 : : ===== ====
1063 : :
1064 : : <- Ptr
1065 : : Empty +------------+
1066 : : | LoopQuad |
1067 : : |------------|
1068 : : */
1069 : :
1070 : : extern "C" void M2Quads_BuildLoop (void);
1071 : :
1072 : : /*
1073 : : BuildExit - Builds the Exit part of the Loop statement.
1074 : : */
1075 : :
1076 : : extern "C" void M2Quads_BuildExit (void);
1077 : :
1078 : : /*
1079 : : BuildEndLoop - Builds the End part of the Loop statement
1080 : : from the quad stack.
1081 : : The Stack is expected to contain:
1082 : :
1083 : :
1084 : : Entry Exit
1085 : : ===== ====
1086 : :
1087 : : Ptr ->
1088 : : +------------+
1089 : : | LoopQuad | Empty
1090 : : |------------|
1091 : :
1092 : : Quadruples
1093 : :
1094 : : Goto _ _ LoopQuad
1095 : : */
1096 : :
1097 : : extern "C" void M2Quads_BuildEndLoop (void);
1098 : :
1099 : : /*
1100 : : BuildThenIf - Builds the Then part of the If statement
1101 : : from the quad stack.
1102 : : The Stack is expected to contain:
1103 : :
1104 : :
1105 : : Entry Exit
1106 : : ===== ====
1107 : :
1108 : : Ptr -> <- Ptr
1109 : : +------------+ +------------+
1110 : : | t | f | | 0 | f |
1111 : : |------------| |------------|
1112 : :
1113 : : Quadruples
1114 : :
1115 : : The true exit is BackPatched to point to
1116 : : the NextQuad.
1117 : : */
1118 : :
1119 : : extern "C" void M2Quads_BuildThenIf (void);
1120 : :
1121 : : /*
1122 : : BuildElse - Builds the Else part of the If statement
1123 : : from the quad stack.
1124 : : The Stack is expected to contain:
1125 : :
1126 : :
1127 : : Entry Exit
1128 : : ===== ====
1129 : :
1130 : : Ptr ->
1131 : : +------------+ +------------+
1132 : : | t | f | | t+q | 0 |
1133 : : |------------| |------------|
1134 : :
1135 : : Quadruples
1136 : :
1137 : : q GotoOp _ _ 0
1138 : : q+1 <- BackPatched from f
1139 : : */
1140 : :
1141 : : extern "C" void M2Quads_BuildElse (void);
1142 : :
1143 : : /*
1144 : : BuildEndIf - Builds the End part of the If statement
1145 : : from the quad stack.
1146 : : The Stack is expected to contain:
1147 : :
1148 : :
1149 : : Entry Exit
1150 : : ===== ====
1151 : :
1152 : : Ptr ->
1153 : : +------------+
1154 : : | t | f | Empty
1155 : : |------------|
1156 : :
1157 : : Quadruples
1158 : :
1159 : : Both t and f are backpatched to point to the NextQuad
1160 : : */
1161 : :
1162 : : extern "C" void M2Quads_BuildEndIf (void);
1163 : :
1164 : : /*
1165 : : BuildElsif1 - Builds the Elsif part of the If statement
1166 : : from the quad stack.
1167 : : The Stack is expected to contain:
1168 : :
1169 : :
1170 : : Entry Exit
1171 : : ===== ====
1172 : :
1173 : : Ptr ->
1174 : : +------------+ +------------+
1175 : : | t | f | | t+q | 0 |
1176 : : |------------| |------------|
1177 : :
1178 : : Quadruples
1179 : :
1180 : : q GotoOp _ _ 0
1181 : : q+1 <- BackPatched from f
1182 : : */
1183 : :
1184 : : extern "C" void M2Quads_BuildElsif1 (void);
1185 : :
1186 : : /*
1187 : : BuildElsif2 - Builds the Elsif until part of the If statement
1188 : : from the quad stack.
1189 : : The Stack is expected to contain:
1190 : :
1191 : :
1192 : : Entry Exit
1193 : : ===== ====
1194 : :
1195 : : Ptr ->
1196 : : +--------------+
1197 : : | 0 | f1 | <- Ptr
1198 : : |--------------| +---------------+
1199 : : | t2 | f2 | | t2 | f1+f2 |
1200 : : |--------------| |---------------|
1201 : : */
1202 : :
1203 : : extern "C" void M2Quads_BuildElsif2 (void);
1204 : :
1205 : : /*
1206 : : BuildForToByDo - Builds the For To By Do part of the For statement
1207 : : from the quad stack.
1208 : : The Stack is expected to contain:
1209 : :
1210 : :
1211 : : Entry Exit
1212 : : ===== ====
1213 : :
1214 : : <- Ptr
1215 : : +----------------+
1216 : : Ptr -> | RangeId |
1217 : : +----------------+ |----------------|
1218 : : | BySym | ByType | | ForQuad |
1219 : : |----------------| |----------------|
1220 : : | e2 | | LastValue |
1221 : : |----------------| |----------------|
1222 : : | e1 | | BySym | ByType |
1223 : : |----------------| |----------------|
1224 : : | Ident | | IdentSym |
1225 : : |----------------| |----------------|
1226 : :
1227 : :
1228 : : x := e1 ;
1229 : : Note that LASTVALUE is calculated during M2GenGCC
1230 : : after all the types have been resolved.
1231 : : LASTVALUE := ((e2-e1) DIV BySym) * BySym + e1
1232 : : IF BySym<0
1233 : : THEN
1234 : : IF e1<e2
1235 : : THEN
1236 : : goto exit
1237 : : END
1238 : : ELSE
1239 : : IF e1>e2
1240 : : THEN
1241 : : goto exit
1242 : : END
1243 : : END ;
1244 : : LOOP
1245 : : body
1246 : : IF x=LASTVALUE
1247 : : THEN
1248 : : goto exit
1249 : : END ;
1250 : : INC(x, BySym)
1251 : : END
1252 : :
1253 : : Quadruples:
1254 : :
1255 : : q BecomesOp IdentSym _ e1
1256 : : q+ LastForIteratorOp LastValue := ((e1-e2) DIV by) * by + e1
1257 : : q+1 if >= by 0 q+..2
1258 : : q+2 GotoOp q+3
1259 : : q+3 If >= e1 e2 q+5
1260 : : q+4 GotoOp exit
1261 : : q+5 ..
1262 : : q+..1 Goto q+..5
1263 : : q+..2 If >= e2 e1 q+..4
1264 : : q+..3 GotoOp exit
1265 : : q+..4 ..
1266 : :
1267 : : The For Loop is regarded:
1268 : :
1269 : : For ident := e1 To e2 By by Do
1270 : :
1271 : : End
1272 : : */
1273 : :
1274 : : extern "C" void M2Quads_BuildForToByDo (void);
1275 : :
1276 : : /*
1277 : : BuildPseudoBy - Builds the Non existant part of the By
1278 : : clause of the For statement
1279 : : from the quad stack.
1280 : : The Stack is expected to contain:
1281 : :
1282 : :
1283 : : Entry Exit
1284 : : ===== ====
1285 : :
1286 : : <- Ptr
1287 : : +------------+
1288 : : Ptr -> | BySym | t |
1289 : : +------------+ |------------|
1290 : : | e | t | | e | t |
1291 : : |------------| |------------|
1292 : : */
1293 : :
1294 : : extern "C" void M2Quads_BuildPseudoBy (void);
1295 : :
1296 : : /*
1297 : : BuildEndFor - Builds the End part of the For statement
1298 : : from the quad stack.
1299 : : The Stack is expected to contain:
1300 : :
1301 : :
1302 : : Entry Exit
1303 : : ===== ====
1304 : :
1305 : : Ptr ->
1306 : : +----------------+
1307 : : | RangeId |
1308 : : |----------------|
1309 : : | ForQuad |
1310 : : |----------------|
1311 : : | LastValue |
1312 : : |----------------|
1313 : : | BySym | ByType |
1314 : : |----------------|
1315 : : | IdSym | Empty
1316 : : |----------------|
1317 : : */
1318 : :
1319 : : extern "C" void M2Quads_BuildEndFor (unsigned int endpostok);
1320 : :
1321 : : /*
1322 : : BuildCaseStart - starts the case statement.
1323 : : It initializes a backpatch list on the compile
1324 : : time stack, the list is used to contain all
1325 : : case break points. The list is later backpatched
1326 : : and contains all positions of the case statement
1327 : : which jump to the end of the case statement.
1328 : : The stack also contains room for a boolean
1329 : : expression, this is needed to allow , operator
1330 : : in the CaseField alternatives.
1331 : :
1332 : : The Stack is expected to contain:
1333 : :
1334 : :
1335 : : Entry Exit
1336 : : ===== ====
1337 : :
1338 : : <- Ptr
1339 : : +------------+
1340 : : | 0 | 0 |
1341 : : |------------|
1342 : : | 0 | 0 |
1343 : : +-------------+ |------------|
1344 : : | Expr | | | Expr | |
1345 : : |-------------| |------------|
1346 : : */
1347 : :
1348 : : extern "C" void M2Quads_BuildCaseStart (void);
1349 : :
1350 : : /*
1351 : : BuildCaseStartStatementSequence - starts the statement sequence
1352 : : inside a case clause.
1353 : : BackPatches the true exit to the
1354 : : NextQuad.
1355 : : The Stack:
1356 : :
1357 : : Entry Exit
1358 : :
1359 : : Ptr -> <- Ptr
1360 : : +-----------+ +------------+
1361 : : | t | f | | 0 | f |
1362 : : |-----------| |------------|
1363 : : */
1364 : :
1365 : : extern "C" void M2Quads_BuildCaseStartStatementSequence (void);
1366 : :
1367 : : /*
1368 : : BuildCaseEndStatementSequence - ends the statement sequence
1369 : : inside a case clause.
1370 : : BackPatches the false exit f1 to the
1371 : : NextQuad.
1372 : : Asserts that t1 and f2 is 0
1373 : : Pushes t2+q and 0
1374 : :
1375 : : Quadruples:
1376 : :
1377 : : q GotoOp _ _ 0
1378 : :
1379 : : The Stack:
1380 : :
1381 : : Entry Exit
1382 : :
1383 : : Ptr -> <- Ptr
1384 : : +-----------+ +------------+
1385 : : | t1 | f1 | | 0 | 0 |
1386 : : |-----------| |------------|
1387 : : | t2 | f2 | | t2+q | 0 |
1388 : : |-----------| |------------|
1389 : : */
1390 : :
1391 : : extern "C" void M2Quads_BuildCaseEndStatementSequence (void);
1392 : :
1393 : : /*
1394 : : BuildCaseRange - builds the range testing quaruples for
1395 : : a case clause.
1396 : :
1397 : : IF (e1>=ce1) AND (e1<=ce2)
1398 : : THEN
1399 : :
1400 : : ELS..
1401 : :
1402 : : The Stack:
1403 : :
1404 : : Entry Exit
1405 : :
1406 : : Ptr ->
1407 : : +-----------+
1408 : : | ce2 | <- Ptr
1409 : : |-----------| +-----------+
1410 : : | ce1 | | t | f |
1411 : : |-----------| |-----------|
1412 : : | t1 | f1 | | t1 | f1 |
1413 : : |-----------| |-----------|
1414 : : | t2 | f2 | | t2 | f2 |
1415 : : |-----------| |-----------|
1416 : : | e1 | | e1 |
1417 : : |-----------| |-----------|
1418 : : */
1419 : :
1420 : : extern "C" void M2Quads_BuildCaseRange (void);
1421 : :
1422 : : /*
1423 : : BuildCaseEquality - builds the range testing quadruples for
1424 : : a case clause.
1425 : :
1426 : : IF e1=ce1
1427 : : THEN
1428 : :
1429 : : ELS..
1430 : :
1431 : : The Stack:
1432 : :
1433 : : Entry Exit
1434 : :
1435 : : Ptr ->
1436 : : +-----------+ +-----------+
1437 : : | ce1 | | t | f |
1438 : : |-----------| |-----------|
1439 : : | t1 | f1 | | t1 | f1 |
1440 : : |-----------| |-----------|
1441 : : | t2 | f2 | | t2 | f2 |
1442 : : |-----------| |-----------|
1443 : : | e1 | | e1 |
1444 : : |-----------| |-----------|
1445 : : */
1446 : :
1447 : : extern "C" void M2Quads_BuildCaseEquality (void);
1448 : :
1449 : : /*
1450 : : BuildCaseList - merges two case tests into one
1451 : :
1452 : : The Stack:
1453 : :
1454 : : Entry Exit
1455 : :
1456 : : Ptr ->
1457 : : +-----------+
1458 : : | t2 | f2 |
1459 : : |-----------| +-------------+
1460 : : | t1 | f1 | | t1+t2| f1+f2|
1461 : : |-----------| |-------------|
1462 : : */
1463 : :
1464 : : extern "C" void M2Quads_BuildCaseList (void);
1465 : :
1466 : : /*
1467 : : BuildCaseOr - builds the , in the 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_BuildCaseOr (void);
1480 : :
1481 : : /*
1482 : : BuildCaseElse - builds the else of case clause.
1483 : :
1484 : : The Stack:
1485 : :
1486 : : Entry Exit
1487 : :
1488 : : Ptr -> <- Ptr
1489 : : +-----------+ +------------+
1490 : : | t | f | | t | 0 |
1491 : : |-----------| |------------|
1492 : : */
1493 : :
1494 : : extern "C" void M2Quads_BuildCaseElse (void);
1495 : :
1496 : : /*
1497 : : BuildCaseEnd - builds the end of case clause.
1498 : :
1499 : : The Stack:
1500 : :
1501 : : Entry Exit
1502 : :
1503 : : Ptr ->
1504 : : +-----------+
1505 : : | t1 | f1 |
1506 : : |-----------|
1507 : : | t2 | f2 |
1508 : : |-----------|
1509 : : | e1 |
1510 : : |-----------| Empty
1511 : : */
1512 : :
1513 : : extern "C" void M2Quads_BuildCaseEnd (void);
1514 : :
1515 : : /*
1516 : : BuildCaseCheck - builds the case checking code to ensure that
1517 : : the program does not need an else clause at runtime.
1518 : : The stack is unaltered.
1519 : : */
1520 : :
1521 : : extern "C" void M2Quads_BuildCaseCheck (void);
1522 : :
1523 : : /*
1524 : : BuildNulParam - Builds a nul parameter on the stack.
1525 : : The Stack:
1526 : :
1527 : : Entry Exit
1528 : :
1529 : : <- Ptr
1530 : : Empty +------------+
1531 : : | 0 |
1532 : : |------------|
1533 : : */
1534 : :
1535 : : extern "C" void M2Quads_BuildNulParam (void);
1536 : :
1537 : : /*
1538 : : BuildProcedureCall - builds a procedure call.
1539 : : Although this procedure does not directly
1540 : : destroy the procedure parameters, it calls
1541 : : routine which will manipulate the stack and
1542 : : so the entry and exit states of the stack are shown.
1543 : :
1544 : : The Stack:
1545 : :
1546 : :
1547 : : Entry Exit
1548 : :
1549 : : Ptr ->
1550 : : +----------------+
1551 : : | NoOfParam |
1552 : : |----------------|
1553 : : | Param 1 |
1554 : : |----------------|
1555 : : | Param 2 |
1556 : : |----------------|
1557 : : . .
1558 : : . .
1559 : : . .
1560 : : |----------------|
1561 : : | Param # |
1562 : : |----------------|
1563 : : | ProcSym | Type | Empty
1564 : : |----------------|
1565 : : */
1566 : :
1567 : : extern "C" void M2Quads_BuildProcedureCall (unsigned int tokno);
1568 : :
1569 : : /*
1570 : : CheckBuildFunction - checks to see whether ProcSym is a function
1571 : : and if so it adds a TempSym value which will
1572 : : hold the return value once the function finishes.
1573 : : This procedure also generates an error message
1574 : : if the user is calling a function and ignoring
1575 : : the return result. The additional TempSym
1576 : : is not created if ProcSym is a procedure
1577 : : and the stack is unaltered.
1578 : :
1579 : : The Stack:
1580 : :
1581 : :
1582 : : Entry Exit
1583 : :
1584 : : Ptr ->
1585 : :
1586 : : +----------------+
1587 : : | ProcSym | Type |
1588 : : +----------------+ |----------------|
1589 : : | ProcSym | Type | | TempSym | Type |
1590 : : |----------------| |----------------|
1591 : : */
1592 : :
1593 : : extern "C" bool M2Quads_CheckBuildFunction (void);
1594 : :
1595 : : /*
1596 : : BuildFunctionCall - builds a function call.
1597 : : The Stack:
1598 : :
1599 : :
1600 : : Entry Exit
1601 : :
1602 : : Ptr ->
1603 : : +----------------+
1604 : : | NoOfParam |
1605 : : |----------------|
1606 : : | Param 1 |
1607 : : |----------------|
1608 : : | Param 2 |
1609 : : |----------------|
1610 : : . .
1611 : : . .
1612 : : . .
1613 : : |----------------|
1614 : : | Param # | <- Ptr
1615 : : |----------------| +------------+
1616 : : | ProcSym | Type | | ReturnVar |
1617 : : |----------------| |------------|
1618 : : */
1619 : :
1620 : : extern "C" void M2Quads_BuildFunctionCall (bool ConstExpr);
1621 : :
1622 : : /*
1623 : : BuildConstFunctionCall - builds a function call and checks that this function can be
1624 : : called inside a ConstExpression.
1625 : :
1626 : : The Stack:
1627 : :
1628 : :
1629 : : Entry Exit
1630 : :
1631 : : Ptr ->
1632 : : +----------------+
1633 : : | NoOfParam |
1634 : : |----------------|
1635 : : | Param 1 |
1636 : : |----------------|
1637 : : | Param 2 |
1638 : : |----------------|
1639 : : . .
1640 : : . .
1641 : : . .
1642 : : |----------------|
1643 : : | Param # | <- Ptr
1644 : : |----------------| +------------+
1645 : : | ProcSym | Type | | ReturnVar |
1646 : : |----------------| |------------|
1647 : :
1648 : : */
1649 : :
1650 : : extern "C" void M2Quads_BuildConstFunctionCall (void);
1651 : :
1652 : : /*
1653 : : BuildBooleanVariable - tests to see whether top of stack is a boolean
1654 : : conditional and if so it converts it into a boolean
1655 : : variable.
1656 : : */
1657 : :
1658 : : extern "C" void M2Quads_BuildBooleanVariable (void);
1659 : :
1660 : : /*
1661 : : BuildModuleStart - starts current module scope.
1662 : : */
1663 : :
1664 : : extern "C" void M2Quads_BuildModuleStart (unsigned int tok);
1665 : :
1666 : : /*
1667 : : BuildProcedureStart - Builds start of the procedure. Generates a
1668 : : quadruple which indicated the start of
1669 : : this procedure declarations scope.
1670 : : The Stack is expected to contain:
1671 : :
1672 : :
1673 : : Entry Exit
1674 : : ===== ====
1675 : :
1676 : : Ptr -> <- Ptr
1677 : : +------------+ +-----------+
1678 : : | ProcSym | | ProcSym |
1679 : : |------------| |-----------|
1680 : : | Name | | Name |
1681 : : |------------| |-----------|
1682 : :
1683 : :
1684 : : Quadruples:
1685 : :
1686 : : q ProcedureScopeOp Line# Scope ProcSym
1687 : : */
1688 : :
1689 : : extern "C" void M2Quads_BuildProcedureStart (void);
1690 : :
1691 : : /*
1692 : : BuildProcedureBegin - determines the start of the BEGIN END block of
1693 : : the procedure.
1694 : : The Stack is expected to contain:
1695 : :
1696 : :
1697 : : Entry Exit
1698 : : ===== ====
1699 : :
1700 : : Ptr -> <- Ptr
1701 : : +------------+ +-----------+
1702 : : | ProcSym | | ProcSym |
1703 : : |------------| |-----------|
1704 : : | Name | | Name |
1705 : : |------------| |-----------|
1706 : :
1707 : :
1708 : : Quadruples:
1709 : :
1710 : : q NewLocalVarOp TokenNo(BEGIN) _ ProcSym
1711 : : */
1712 : :
1713 : : extern "C" void M2Quads_BuildProcedureBegin (void);
1714 : :
1715 : : /*
1716 : : BuildProcedureEnd - Builds end of the procedure. Destroys space for
1717 : : the local variables.
1718 : : The Stack is expected to contain:
1719 : :
1720 : :
1721 : : Entry Exit
1722 : : ===== ====
1723 : :
1724 : : Ptr -> <- Ptr
1725 : : +------------+ +-----------+
1726 : : | ProcSym | | ProcSym |
1727 : : |------------| |-----------|
1728 : : | Name | | Name |
1729 : : |------------| |-----------|
1730 : :
1731 : :
1732 : : Quadruples:
1733 : :
1734 : : q KillLocalVarOp TokenNo(END) _ ProcSym
1735 : : */
1736 : :
1737 : : extern "C" void M2Quads_BuildProcedureEnd (void);
1738 : :
1739 : : /*
1740 : : BuildReturn - Builds the Return part of the procedure.
1741 : : tokreturn is the location of the RETURN keyword.
1742 : : The Stack is expected to contain:
1743 : :
1744 : :
1745 : : Entry Exit
1746 : : ===== ====
1747 : :
1748 : : Ptr ->
1749 : : +------------+
1750 : : | e1 | Empty
1751 : : |------------|
1752 : : */
1753 : :
1754 : : extern "C" void M2Quads_BuildReturn (unsigned int tokreturn);
1755 : :
1756 : : /*
1757 : : BuildModulePriority - assigns the current module with a priority
1758 : : from the top of stack.
1759 : :
1760 : : Entry Exit
1761 : : ===== ====
1762 : :
1763 : :
1764 : : Ptr -> Empty
1765 : : +------------+
1766 : : | Priority |
1767 : : |------------|
1768 : : */
1769 : :
1770 : : extern "C" void M2Quads_BuildModulePriority (void);
1771 : :
1772 : : /*
1773 : : StartBuildWith - performs the with statement.
1774 : : The Stack:
1775 : :
1776 : : Entry Exit
1777 : :
1778 : : +------------+
1779 : : | Sym | Type | Empty
1780 : : |------------|
1781 : : */
1782 : :
1783 : : extern "C" void M2Quads_StartBuildWith (unsigned int withTok);
1784 : :
1785 : : /*
1786 : : EndBuildWith - terminates the innermost with scope.
1787 : : */
1788 : :
1789 : : extern "C" void M2Quads_EndBuildWith (void);
1790 : :
1791 : : /*
1792 : : CheckWithReference - performs the with statement.
1793 : : The Stack:
1794 : :
1795 : : Entry Exit
1796 : :
1797 : : +------------+ +------------+
1798 : : | Sym | Type | | Sym | Type |
1799 : : |------------| |------------|
1800 : : */
1801 : :
1802 : : extern "C" void M2Quads_CheckWithReference (void);
1803 : :
1804 : : /*
1805 : : BuildDesignatorRecord - Builds the record referencing.
1806 : : The Stack is expected to contain:
1807 : :
1808 : :
1809 : : Entry Exit
1810 : : ===== ====
1811 : :
1812 : : Ptr ->
1813 : : +--------------+
1814 : : | n |
1815 : : |--------------|
1816 : : | fld1 | type1 |
1817 : : |--------------|
1818 : : . .
1819 : : . .
1820 : : . .
1821 : : |--------------|
1822 : : | fldn | typen | <- Ptr
1823 : : |--------------| +-------------+
1824 : : | Sym | Type | | S | type1|
1825 : : |--------------| |-------------|
1826 : : */
1827 : :
1828 : : extern "C" void M2Quads_BuildDesignatorRecord (unsigned int dottok);
1829 : :
1830 : : /*
1831 : : BuildDesignatorArray - Builds the array referencing.
1832 : : The purpose of this procedure is to work out
1833 : : whether the DesignatorArray is a static or
1834 : : dynamic array and to call the appropriate
1835 : : BuildRoutine.
1836 : :
1837 : : The Stack is expected to contain:
1838 : :
1839 : :
1840 : : Entry Exit
1841 : : ===== ====
1842 : :
1843 : : Ptr ->
1844 : : +--------------+
1845 : : | e | <- Ptr
1846 : : |--------------| +------------+
1847 : : | Sym | Type | | S | T |
1848 : : |--------------| |------------|
1849 : : */
1850 : :
1851 : : extern "C" void M2Quads_BuildDesignatorArray (void);
1852 : :
1853 : : /*
1854 : : BuildDesignatorPointer - Builds a pointer reference.
1855 : : The Stack is expected to contain:
1856 : :
1857 : :
1858 : : Entry Exit
1859 : : ===== ====
1860 : :
1861 : : Ptr -> <- Ptr
1862 : : +--------------+ +--------------+
1863 : : | Sym1 | Type1| | Sym2 | Type2|
1864 : : |--------------| |--------------|
1865 : : */
1866 : :
1867 : : extern "C" void M2Quads_BuildDesignatorPointer (unsigned int ptrtok);
1868 : :
1869 : : /*
1870 : : BuildNulExpression - Builds a nul expression on the stack.
1871 : : The Stack:
1872 : :
1873 : : Entry Exit
1874 : :
1875 : : <- Ptr
1876 : : Empty +------------+
1877 : : | NulSym |
1878 : : |------------|
1879 : : tokpos is the position of the RETURN token.
1880 : : */
1881 : :
1882 : : extern "C" void M2Quads_BuildNulExpression (unsigned int tokpos);
1883 : :
1884 : : /*
1885 : : BuildSetStart - Pushes a Bitset type on the stack.
1886 : :
1887 : : The Stack:
1888 : :
1889 : : Entry Exit
1890 : :
1891 : : Ptr -> <- Ptr
1892 : :
1893 : : Empty +--------------+
1894 : : | Bitset |
1895 : : |--------------|
1896 : : */
1897 : :
1898 : : extern "C" void M2Quads_BuildSetStart (unsigned int tokpos);
1899 : :
1900 : : /*
1901 : : BuildSetEnd - pops the set value and type from the stack
1902 : : and pushes the value,type pair.
1903 : :
1904 : : Entry Exit
1905 : :
1906 : : Ptr ->
1907 : : +--------------+
1908 : : | Set Value | <- Ptr
1909 : : |--------------| +--------------+
1910 : : | Set Type | | Value | Type |
1911 : : |--------------| |--------------|
1912 : : */
1913 : :
1914 : : extern "C" void M2Quads_BuildSetEnd (void);
1915 : :
1916 : : /*
1917 : : BuildEmptySet - Builds an empty set on the stack.
1918 : : The Stack:
1919 : :
1920 : : Entry Exit
1921 : :
1922 : : <- Ptr
1923 : : +-------------+
1924 : : Ptr -> | Value |
1925 : : +-----------+ |-------------|
1926 : : | SetType | | SetType |
1927 : : |-----------| |-------------|
1928 : :
1929 : : tokpos points to the opening '{'.
1930 : : */
1931 : :
1932 : : extern "C" void M2Quads_BuildEmptySet (unsigned int tokpos);
1933 : :
1934 : : /*
1935 : : BuildInclRange - includes a set range with a set.
1936 : :
1937 : :
1938 : : Entry Exit
1939 : : ===== ====
1940 : :
1941 : :
1942 : : Ptr ->
1943 : : +------------+
1944 : : | El2 |
1945 : : |------------|
1946 : : | El1 | <- Ptr
1947 : : |------------| +-------------------+
1948 : : | Set Value | | Value + {El1..El2}|
1949 : : |------------| |-------------------|
1950 : :
1951 : : No quadruples produced as the range info is contained within
1952 : : the set value.
1953 : : */
1954 : :
1955 : : extern "C" void M2Quads_BuildInclRange (void);
1956 : :
1957 : : /*
1958 : : BuildInclBit - includes a bit into the set.
1959 : :
1960 : : Entry Exit
1961 : : ===== ====
1962 : :
1963 : :
1964 : : Ptr ->
1965 : : +------------+
1966 : : | Element | <- Ptr
1967 : : |------------| +------------+
1968 : : | Value | | Value |
1969 : : |------------| |------------|
1970 : :
1971 : : */
1972 : :
1973 : : extern "C" void M2Quads_BuildInclBit (void);
1974 : :
1975 : : /*
1976 : : SilentBuildConstructor - places NulSym into the constructor fifo queue.
1977 : : */
1978 : :
1979 : : extern "C" void M2Quads_SilentBuildConstructor (void);
1980 : :
1981 : : /*
1982 : : SilentBuildConstructorStart - removes an entry from the constructor fifo queue.
1983 : : */
1984 : :
1985 : : extern "C" void M2Quads_SilentBuildConstructorStart (void);
1986 : :
1987 : : /*
1988 : : BuildConstructor - builds a constructor.
1989 : : Stack
1990 : :
1991 : : Entry Exit
1992 : :
1993 : : Ptr ->
1994 : : +------------+
1995 : : | Type | <- Ptr
1996 : : |------------+
1997 : : */
1998 : :
1999 : : extern "C" void M2Quads_BuildConstructor (unsigned int tokcbrpos);
2000 : :
2001 : : /*
2002 : : BuildConstructorStart - builds a constructor.
2003 : : Stack
2004 : :
2005 : : Entry Exit
2006 : :
2007 : : Ptr -> <- Ptr
2008 : : +------------+ +----------------+
2009 : : | Type | | ConstructorSym |
2010 : : |------------+ |----------------|
2011 : : */
2012 : :
2013 : : extern "C" void M2Quads_BuildConstructorStart (unsigned int cbratokpos);
2014 : :
2015 : : /*
2016 : : BuildConstructorEnd - removes the current constructor frame from the
2017 : : constructor stack (it does not effect the quad
2018 : : stack)
2019 : :
2020 : : Entry Exit
2021 : :
2022 : : Ptr -> <- Ptr
2023 : : +------------+ +------------+
2024 : : | const | | const |
2025 : : |------------| |------------|
2026 : :
2027 : : startpos is the start of the constructor, either the typename or '{'
2028 : : cbratokpos is the '}'.
2029 : : */
2030 : :
2031 : : extern "C" void M2Quads_BuildConstructorEnd (unsigned int startpos, unsigned int cbratokpos);
2032 : :
2033 : : /*
2034 : : NextConstructorField - increments the top of constructor stacks index by one.
2035 : : */
2036 : :
2037 : : extern "C" void M2Quads_NextConstructorField (void);
2038 : :
2039 : : /*
2040 : : BuildTypeForConstructor - pushes the type implied by the current constructor.
2041 : : If no constructor is currently being built then
2042 : : it Pushes a Bitset type.
2043 : : */
2044 : :
2045 : : extern "C" void M2Quads_BuildTypeForConstructor (unsigned int tokpos);
2046 : :
2047 : : /*
2048 : : BuildComponentValue - builds a component value.
2049 : :
2050 : : Entry Exit
2051 : :
2052 : : Ptr -> <- Ptr
2053 : :
2054 : :
2055 : : +------------+ +------------+
2056 : : | const | | const |
2057 : : |------------| |------------|
2058 : : */
2059 : :
2060 : : extern "C" void M2Quads_BuildComponentValue (void);
2061 : :
2062 : : /*
2063 : : PopConstructor - removes the top constructor from the top of stack.
2064 : : */
2065 : :
2066 : : extern "C" void M2Quads_PopConstructor (void);
2067 : :
2068 : : /*
2069 : : BuildNot - Builds a NOT operation from the quad stack.
2070 : : The Stack is expected to contain:
2071 : :
2072 : :
2073 : : Entry Exit
2074 : : ===== ====
2075 : :
2076 : : Ptr -> <- Ptr
2077 : : +------------+ +------------+
2078 : : | t | f | | f | t |
2079 : : |------------| |------------|
2080 : : */
2081 : :
2082 : : extern "C" void M2Quads_BuildNot (unsigned int notTokPos);
2083 : :
2084 : : /*
2085 : : RecordOp - Records the operator passed on the stack.
2086 : : This is called when a boolean operator is found in an
2087 : : expression. It is called just after the lhs has been built
2088 : : and pushed to the quad stack and prior to the rhs build.
2089 : : It checks to see if AND OR or equality tests are required.
2090 : : It will short circuit AND and OR expressions. It also
2091 : : converts a lhs to a boolean variable if an xor comparison
2092 : : is about to be performed.
2093 : :
2094 : : Checks for AND operator or OR operator
2095 : : if either of these operators are found then BackPatching
2096 : : takes place.
2097 : : The Expected Stack:
2098 : :
2099 : : Entry Exit
2100 : :
2101 : : Ptr -> <- Ptr
2102 : : +-------------+ +-------------+
2103 : : | OperatorTok | | OperatorTok |
2104 : : |-------------| |-------------|
2105 : : | t | f | | t | f |
2106 : : |-------------| |-------------|
2107 : :
2108 : :
2109 : : If OperatorTok=AndTok
2110 : : Then
2111 : : BackPatch(f, NextQuad)
2112 : : Elsif OperatorTok=OrTok
2113 : : Then
2114 : : BackPatch(t, NextQuad)
2115 : : End
2116 : : */
2117 : :
2118 : : extern "C" void M2Quads_RecordOp (void);
2119 : :
2120 : : /*
2121 : : BuildRelOp - Builds a relative operation from the quad stack.
2122 : : The Stack is expected to contain:
2123 : :
2124 : :
2125 : : Entry Exit
2126 : : ===== ====
2127 : :
2128 : : Ptr ->
2129 : : +------------+
2130 : : | e1 |
2131 : : |------------| <- Ptr
2132 : : | Operator |
2133 : : |------------| +------------+
2134 : : | e2 | | t | f |
2135 : : |------------| |------------|
2136 : :
2137 : :
2138 : : Quadruples Produced
2139 : :
2140 : : q IFOperator e2 e1 TrueExit ; e2 e1 since
2141 : : q+1 GotoOp FalseExit ; relation > etc
2142 : : ; requires order.
2143 : : */
2144 : :
2145 : : extern "C" void M2Quads_BuildRelOp (unsigned int optokpos);
2146 : :
2147 : : /*
2148 : : BuildBinaryOp - Builds a binary operation from the quad stack.
2149 : : Be aware that this procedure will check for
2150 : : the overloading of the bitset operators + - \ *.
2151 : : So do NOT call this procedure if you are building
2152 : : a reference to an array which has a bitset type or
2153 : : the address arithmetic will be wrongly coersed into
2154 : : logical ORs.
2155 : :
2156 : : The Stack is expected to contain:
2157 : :
2158 : :
2159 : : Entry Exit
2160 : : ===== ====
2161 : :
2162 : : Ptr ->
2163 : : +------------+
2164 : : | Sym1 |
2165 : : |------------|
2166 : : | Operator | <- Ptr
2167 : : |------------| +------------+
2168 : : | Sym2 | | Temporary |
2169 : : |------------| |------------|
2170 : :
2171 : :
2172 : : Quadruples Produced
2173 : :
2174 : : q Operator Temporary Sym1 Sym2
2175 : :
2176 : :
2177 : : OR
2178 : :
2179 : :
2180 : : Entry Exit
2181 : : ===== ====
2182 : :
2183 : : Ptr ->
2184 : : +------------+
2185 : : | T1 | F1 |
2186 : : |------------|
2187 : : | OrTok | <- Ptr
2188 : : |------------| +------------+
2189 : : | T2 | F2 | | T1+T2| F1 |
2190 : : |------------| |------------|
2191 : :
2192 : :
2193 : : Quadruples Produced
2194 : :
2195 : : */
2196 : :
2197 : : extern "C" void M2Quads_BuildBinaryOp (void);
2198 : :
2199 : : /*
2200 : : BuildUnaryOp - Builds a unary operation from the quad stack.
2201 : : The Stack is expected to contain:
2202 : :
2203 : :
2204 : : Entry Exit
2205 : : ===== ====
2206 : :
2207 : : Ptr ->
2208 : : +------------+
2209 : : | Sym |
2210 : : |------------| +------------+
2211 : : | Operator | | Temporary | <- Ptr
2212 : : |------------| |------------|
2213 : :
2214 : :
2215 : : Quadruples Produced
2216 : :
2217 : : q Operator Temporary _ Sym
2218 : :
2219 : : */
2220 : :
2221 : : extern "C" void M2Quads_BuildUnaryOp (void);
2222 : :
2223 : : /*
2224 : : OperandT - returns the ident operand stored in the true position on the boolean stack.
2225 : : */
2226 : :
2227 : : extern "C" unsigned int M2Quads_OperandT (unsigned int pos);
2228 : :
2229 : : /*
2230 : : OperandF - returns the ident operand stored in the false position on the boolean stack.
2231 : : */
2232 : :
2233 : : extern "C" unsigned int M2Quads_OperandF (unsigned int pos);
2234 : :
2235 : : /*
2236 : : PushTF - Push a True and False numbers onto the True/False stack.
2237 : : True and False are assumed to contain Symbols or Ident etc.
2238 : : */
2239 : :
2240 : : extern "C" void M2Quads_PushTF (unsigned int True, unsigned int False);
2241 : :
2242 : : /*
2243 : : PopTF - Pop a True and False number from the True/False stack.
2244 : : True and False are assumed to contain Symbols or Ident etc.
2245 : : */
2246 : :
2247 : : extern "C" void M2Quads_PopTF (unsigned int *True, unsigned int *False);
2248 : :
2249 : : /*
2250 : : PushT - Push an item onto the stack in the T (true) position.
2251 : : */
2252 : :
2253 : : extern "C" void M2Quads_PushT (unsigned int True);
2254 : :
2255 : : /*
2256 : : PopT - Pops the T value from the stack.
2257 : : */
2258 : :
2259 : : extern "C" void M2Quads_PopT (unsigned int *True);
2260 : :
2261 : : /*
2262 : : PushTtok - Push an item onto the stack in the T (true) position,
2263 : : it is assummed to be a token and its token location is recorded.
2264 : : */
2265 : :
2266 : : extern "C" void M2Quads_PushTtok (unsigned int True, unsigned int tokno);
2267 : :
2268 : : /*
2269 : : PushTFtok - Push an item onto the stack in the T (true) position,
2270 : : it is assummed to be a token and its token location is recorded.
2271 : : */
2272 : :
2273 : : extern "C" void M2Quads_PushTFtok (unsigned int True, unsigned int False, unsigned int tokno);
2274 : :
2275 : : /*
2276 : : PopTFtok - Pop T/F/tok from the stack.
2277 : : */
2278 : :
2279 : : extern "C" void M2Quads_PopTFtok (unsigned int *True, unsigned int *False, unsigned int *tokno);
2280 : :
2281 : : /*
2282 : : PushTFAtok - Push T/F/A/tok to the stack.
2283 : : */
2284 : :
2285 : : extern "C" void M2Quads_PushTFAtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int tokno);
2286 : :
2287 : : /*
2288 : : PopTtok - Pops the T value from the stack and token position.
2289 : : */
2290 : :
2291 : : extern "C" void M2Quads_PopTtok (unsigned int *True, unsigned int *tok);
2292 : :
2293 : : /*
2294 : : PushTFn - Push a True and False numbers onto the True/False stack.
2295 : : True and False are assumed to contain Symbols or Ident etc.
2296 : : */
2297 : :
2298 : : extern "C" void M2Quads_PushTFn (unsigned int True, unsigned int False, unsigned int n);
2299 : :
2300 : : /*
2301 : : PushTFntok - Push a True and False numbers onto the True/False stack.
2302 : : True and False are assumed to contain Symbols or Ident etc.
2303 : : */
2304 : :
2305 : : extern "C" void M2Quads_PushTFntok (unsigned int True, unsigned int False, unsigned int n, unsigned int tokno);
2306 : :
2307 : : /*
2308 : : PopTFn - Pop a True and False number from the True/False stack.
2309 : : True and False are assumed to contain Symbols or Ident etc.
2310 : : */
2311 : :
2312 : : extern "C" void M2Quads_PopTFn (unsigned int *True, unsigned int *False, unsigned int *n);
2313 : :
2314 : : /*
2315 : : PopNothing - pops the top element on the boolean stack.
2316 : : */
2317 : :
2318 : : extern "C" void M2Quads_PopNothing (void);
2319 : :
2320 : : /*
2321 : : PopN - pops multiple elements from the BoolStack.
2322 : : */
2323 : :
2324 : : extern "C" void M2Quads_PopN (unsigned int n);
2325 : :
2326 : : /*
2327 : : PushTFA - Push True, False, Array, numbers onto the
2328 : : True/False stack. True and False are assumed to
2329 : : contain Symbols or Ident etc.
2330 : : */
2331 : :
2332 : : extern "C" void M2Quads_PushTFA (unsigned int True, unsigned int False, unsigned int Array);
2333 : :
2334 : : /*
2335 : : OperandTok - returns the token associated with pos, on the stack.
2336 : : */
2337 : :
2338 : : extern "C" unsigned int M2Quads_OperandTok (unsigned int pos);
2339 : :
2340 : : /*
2341 : : OperandA - returns possible array symbol associated with the ident
2342 : : operand stored on the boolean stack.
2343 : : */
2344 : :
2345 : : extern "C" unsigned int M2Quads_OperandA (unsigned int pos);
2346 : :
2347 : : /*
2348 : : OperandAnno - returns the annotation string associated with the
2349 : : position, n, on the stack.
2350 : : */
2351 : :
2352 : : extern "C" DynamicStrings_String M2Quads_OperandAnno (unsigned int n);
2353 : :
2354 : : /*
2355 : : Annotate - annotate the top of stack.
2356 : : */
2357 : :
2358 : : extern "C" void M2Quads_Annotate (const char *a_, unsigned int _a_high);
2359 : :
2360 : : /*
2361 : : DisplayStack - displays the compile time symbol stack.
2362 : : */
2363 : :
2364 : : extern "C" void M2Quads_DisplayStack (void);
2365 : :
2366 : : /*
2367 : : Top - returns the no of items held in the stack.
2368 : : */
2369 : :
2370 : : extern "C" unsigned int M2Quads_Top (void);
2371 : :
2372 : : /*
2373 : : DupFrame - duplicate the top of stack and push the new frame.
2374 : : */
2375 : :
2376 : : extern "C" void M2Quads_DupFrame (void);
2377 : :
2378 : : /*
2379 : : WriteOperand - displays the operands name, symbol id and mode of addressing.
2380 : : */
2381 : :
2382 : : extern "C" void M2Quads_WriteOperand (unsigned int Sym);
2383 : :
2384 : : /*
2385 : : BeginVarient - begin a varient record.
2386 : : */
2387 : :
2388 : : extern "C" void M2Quads_BeginVarient (void);
2389 : :
2390 : : /*
2391 : : EndVarient - end a varient record.
2392 : : */
2393 : :
2394 : : extern "C" void M2Quads_EndVarient (void);
2395 : :
2396 : : /*
2397 : : ElseVarient - associate an ELSE clause with a varient record.
2398 : : */
2399 : :
2400 : : extern "C" void M2Quads_ElseVarient (void);
2401 : :
2402 : : /*
2403 : : BeginVarientList - begin an ident list containing ranges belonging to a
2404 : : varient list.
2405 : : */
2406 : :
2407 : : extern "C" void M2Quads_BeginVarientList (void);
2408 : :
2409 : : /*
2410 : : EndVarientList - end a range list for a varient field.
2411 : : */
2412 : :
2413 : : extern "C" void M2Quads_EndVarientList (void);
2414 : :
2415 : : /*
2416 : : AddRecordToList - adds the record held on the top of stack to the
2417 : : list of records and varient fields.
2418 : : */
2419 : :
2420 : : extern "C" void M2Quads_AddRecordToList (void);
2421 : :
2422 : : /*
2423 : : AddVarientToList - adds varient held on the top of stack to the list.
2424 : : */
2425 : :
2426 : : extern "C" void M2Quads_AddVarientToList (void);
2427 : :
2428 : : /*
2429 : : AddVarientFieldToList - adds varient field, f, to the list of all varient
2430 : : fields created.
2431 : : */
2432 : :
2433 : : extern "C" void M2Quads_AddVarientFieldToList (unsigned int f);
2434 : :
2435 : : /*
2436 : : AddVarientRange - creates a range from the top two contant expressions
2437 : : on the stack which are recorded with the current
2438 : : varient field. The stack is unaltered.
2439 : : */
2440 : :
2441 : : extern "C" void M2Quads_AddVarientRange (void);
2442 : :
2443 : : /*
2444 : : AddVarientEquality - adds the contant expression on the top of the stack
2445 : : to the current varient field being recorded.
2446 : : The stack is unaltered.
2447 : : */
2448 : :
2449 : : extern "C" void M2Quads_AddVarientEquality (void);
2450 : :
2451 : : /*
2452 : : BuildCodeOn - generates a quadruple declaring that code should be
2453 : : emmitted from henceforth.
2454 : :
2455 : : The Stack is unnaffected.
2456 : : */
2457 : :
2458 : : extern "C" void M2Quads_BuildCodeOn (void);
2459 : :
2460 : : /*
2461 : : BuildCodeOff - generates a quadruple declaring that code should not be
2462 : : emmitted from henceforth.
2463 : :
2464 : : The Stack is unnaffected.
2465 : : */
2466 : :
2467 : : extern "C" void M2Quads_BuildCodeOff (void);
2468 : :
2469 : : /*
2470 : : BuildProfileOn - generates a quadruple declaring that profile timings
2471 : : should be emmitted from henceforth.
2472 : :
2473 : : The Stack is unnaffected.
2474 : : */
2475 : :
2476 : : extern "C" void M2Quads_BuildProfileOn (void);
2477 : : extern "C" void M2Quads_BuildProfileOff (void);
2478 : :
2479 : : /*
2480 : : BuildOptimizeOn - generates a quadruple declaring that optimization
2481 : : should occur from henceforth.
2482 : :
2483 : : The Stack is unnaffected.
2484 : : */
2485 : :
2486 : : extern "C" void M2Quads_BuildOptimizeOn (void);
2487 : :
2488 : : /*
2489 : : BuildOptimizeOff - generates a quadruple declaring that optimization
2490 : : should not occur from henceforth.
2491 : :
2492 : : The Stack is unnaffected.
2493 : : */
2494 : :
2495 : : extern "C" void M2Quads_BuildOptimizeOff (void);
2496 : :
2497 : : /*
2498 : : BuildAsm - builds an Inline pseudo quadruple operator.
2499 : : The inline interface, Sym, is stored as the operand
2500 : : to the operator InlineOp.
2501 : :
2502 : : The stack is expected to contain:
2503 : :
2504 : :
2505 : : Entry Exit
2506 : : ===== ====
2507 : :
2508 : : Ptr ->
2509 : : +--------------+
2510 : : | Sym | Empty
2511 : : |--------------|
2512 : : */
2513 : :
2514 : : extern "C" void M2Quads_BuildAsm (unsigned int tok);
2515 : :
2516 : : /*
2517 : : BuildLineNo - builds a LineNumberOp pseudo quadruple operator.
2518 : : This quadruple indicates which source line has been
2519 : : processed, these quadruples are only generated if we
2520 : : are producing runtime debugging information.
2521 : :
2522 : : The stack is not affected, read or altered in any way.
2523 : :
2524 : :
2525 : : Entry Exit
2526 : : ===== ====
2527 : :
2528 : : Ptr -> <- Ptr
2529 : : */
2530 : :
2531 : : extern "C" void M2Quads_BuildLineNo (void);
2532 : :
2533 : : /*
2534 : : PushLineNo - pushes the current file and line number to the stack.
2535 : : */
2536 : :
2537 : : extern "C" void M2Quads_PushLineNo (void);
2538 : :
2539 : : /*
2540 : : BuildStmtNote - builds a StatementNoteOp pseudo quadruple operator.
2541 : : This quadruple indicates which source line has been
2542 : : processed and it represents the start of a statement
2543 : : sequence.
2544 : : It differs from LineNumberOp in that multiple successive
2545 : : LineNumberOps will be removed and the final one is attached to
2546 : : the next real GCC tree. Whereas a StatementNoteOp is always left
2547 : : alone. Depending upon the debugging level it will issue a nop
2548 : : instruction to ensure that the gdb single step will step into
2549 : : this line. Practically it allows pedalogical debugging to
2550 : : occur when there is syntax sugar such as:
2551 : :
2552 : :
2553 : : END step
2554 : : END step
2555 : : END ; step
2556 : : a := 1 ; step
2557 : :
2558 : : REPEAT step
2559 : : i := 1 step
2560 : :
2561 : : The stack is not affected, read or altered in any way.
2562 : :
2563 : :
2564 : : Entry Exit
2565 : : ===== ====
2566 : :
2567 : : Ptr -> <- Ptr
2568 : : */
2569 : :
2570 : : extern "C" void M2Quads_BuildStmtNote (int offset);
2571 : :
2572 : : /*
2573 : : LoopAnalysis - checks whether an infinite loop exists.
2574 : : */
2575 : :
2576 : : extern "C" void M2Quads_LoopAnalysis (unsigned int Scope, unsigned int Current, unsigned int End);
2577 : :
2578 : : /*
2579 : : ForLoopAnalysis - checks all the FOR loops for index variable manipulation
2580 : : and dangerous usage outside the loop.
2581 : : */
2582 : :
2583 : : extern "C" void M2Quads_ForLoopAnalysis (void);
2584 : :
2585 : : /*
2586 : : BuildSizeCheckStart - switches off all quadruple generation if the function SIZE or HIGH
2587 : : is being "called". This should be done as SIZE only requires the
2588 : : actual type of the expression, not its value. Consider the problem of
2589 : : SIZE(UninitializedPointer^) which is quite legal and it must
2590 : : also be safe!
2591 : : ISO Modula-2 also allows HIGH(a[0]) for a two dimensional array
2592 : : and there is no need to compute a[0], we just need to follow the
2593 : : type and count dimensions. However if SIZE(a) or HIGH(a) occurs
2594 : : and, a, is an unbounded array then we turn on quadruple generation.
2595 : :
2596 : : The Stack is expected to contain:
2597 : :
2598 : :
2599 : : Entry Exit
2600 : : ===== ====
2601 : :
2602 : : Ptr -> <- Ptr
2603 : : +----------------------+ +----------------------+
2604 : : | ProcSym | Type | tok | | ProcSym | Type | tok |
2605 : : |----------------------| |----------------------|
2606 : : */
2607 : :
2608 : : extern "C" void M2Quads_BuildSizeCheckStart (void);
2609 : :
2610 : : /*
2611 : : BackPatchSubrangesAndOptParam - runs through all the quadruples and finds SubrangeLow or SubrangeHigh
2612 : : quadruples and replaces it by an assignment to the Low or High component
2613 : : of the subrange type.
2614 : :
2615 : : Input:
2616 : : SubrangeLow op1 op3 op3 is a subrange
2617 : :
2618 : : Output:
2619 : : Becomes op1 low
2620 : :
2621 : : Input:
2622 : : SubrangeHigh op1 op3 op3 is a subrange
2623 : :
2624 : : Output:
2625 : : Becomes op1 high
2626 : :
2627 : : Input:
2628 : : OptParam op1 op2 op3
2629 : :
2630 : : Output:
2631 : : Param op1 op2 GetOptArgInit(op3)
2632 : : */
2633 : :
2634 : : extern "C" void M2Quads_BackPatchSubrangesAndOptParam (void);
2635 : :
2636 : : /*
2637 : : WriteOperator - writes the name of the quadruple operator.
2638 : : */
2639 : :
2640 : : extern "C" void M2Quads_WriteOperator (M2Quads_QuadOperator Operator);
2641 : :
2642 : : /*
2643 : : PushAutoOn - push the auto flag and then set it to TRUE.
2644 : : Any call to ident in the parser will result in the token being pushed.
2645 : : */
2646 : :
2647 : : extern "C" void M2Quads_PushAutoOn (void);
2648 : :
2649 : : /*
2650 : : PushAutoOff - push the auto flag and then set it to FALSE.
2651 : : */
2652 : :
2653 : : extern "C" void M2Quads_PushAutoOff (void);
2654 : :
2655 : : /*
2656 : : IsAutoPushOn - returns the value of the current Auto ident push flag.
2657 : : */
2658 : :
2659 : : extern "C" bool M2Quads_IsAutoPushOn (void);
2660 : :
2661 : : /*
2662 : : PopAuto - restores the previous value of the Auto flag.
2663 : : */
2664 : :
2665 : : extern "C" void M2Quads_PopAuto (void);
2666 : :
2667 : : /*
2668 : : MustCheckOverflow - returns TRUE if the quadruple should test for overflow.
2669 : : */
2670 : :
2671 : : extern "C" bool M2Quads_MustCheckOverflow (unsigned int q);
2672 : :
2673 : : /*
2674 : : PushInConstExpression - push the InConstExpression flag and then set it to TRUE.
2675 : : */
2676 : :
2677 : : extern "C" void M2Quads_PushInConstExpression (void);
2678 : :
2679 : : /*
2680 : : PopInConstExpression - restores the previous value of the InConstExpression.
2681 : : */
2682 : :
2683 : : extern "C" void M2Quads_PopInConstExpression (void);
2684 : :
2685 : : /*
2686 : : IsInConstExpression - returns the value of the InConstExpression.
2687 : : */
2688 : :
2689 : : extern "C" bool M2Quads_IsInConstExpression (void);
2690 : :
2691 : : /*
2692 : : PushInConstParameters - push the InConstParameters flag and then set it to TRUE.
2693 : : */
2694 : :
2695 : : extern "C" void M2Quads_PushInConstParameters (void);
2696 : :
2697 : : /*
2698 : : PopInConstParameters - restores the previous value of the InConstParameters.
2699 : : */
2700 : :
2701 : : extern "C" void M2Quads_PopInConstParameters (void);
2702 : :
2703 : : /*
2704 : : IsInConstParameters - returns the value of the InConstParameters.
2705 : : */
2706 : :
2707 : : extern "C" bool M2Quads_IsInConstParameters (void);
2708 : :
2709 : : /*
2710 : : BuildAsmElement - the stack is expected to contain:
2711 : :
2712 : :
2713 : : Entry Exit
2714 : : ===== ====
2715 : :
2716 : : Ptr ->
2717 : : +------------------+
2718 : : | expr | tokpos |
2719 : : |------------------|
2720 : : | str |
2721 : : |------------------|
2722 : : | name |
2723 : : |------------------| +------------------+
2724 : : | CurrentInterface | | CurrentInterface |
2725 : : |------------------| |------------------|
2726 : : | CurrentAsm | | CurrentAsm |
2727 : : |------------------| |------------------|
2728 : : | n | | n |
2729 : : |------------------| |------------------|
2730 : : */
2731 : :
2732 : : extern "C" void M2Quads_BuildAsmElement (bool input, bool output);
2733 : :
2734 : : /*
2735 : : BuildAsmTrash - the stack is expected to contain:
2736 : :
2737 : :
2738 : : Entry Exit
2739 : : ===== ====
2740 : :
2741 : : Ptr ->
2742 : : +------------------+
2743 : : | expr | tokpos |
2744 : : |------------------| +------------------+
2745 : : | CurrentInterface | | CurrentInterface |
2746 : : |------------------| |------------------|
2747 : : | CurrentAsm | | CurrentAsm |
2748 : : |------------------| |------------------|
2749 : : | n | | n |
2750 : : |------------------| |------------------|
2751 : : */
2752 : :
2753 : : extern "C" void M2Quads_BuildAsmTrash (void);
2754 : :
2755 : : /*
2756 : : GetQuadTrash - return the symbol associated with the trashed operand.
2757 : : */
2758 : :
2759 : : extern "C" unsigned int M2Quads_GetQuadTrash (unsigned int quad);
2760 : :
2761 : : /*
2762 : : DSdbEnter -
2763 : : */
2764 : :
2765 : : static void DSdbEnter (void);
2766 : :
2767 : : /*
2768 : : DSdbExit -
2769 : : */
2770 : :
2771 : : static void DSdbExit (void);
2772 : :
2773 : : /*
2774 : : GetQF - returns the QuadFrame associated with, q.
2775 : : */
2776 : :
2777 : : static M2Quads_QuadFrame GetQF (unsigned int q);
2778 : :
2779 : : /*
2780 : : IsQuadA - returns true if QuadNo is a op.
2781 : : */
2782 : :
2783 : : static bool IsQuadA (unsigned int QuadNo, M2Quads_QuadOperator op);
2784 : :
2785 : : /*
2786 : : OpUsesOp1 - return TRUE if op allows op1.
2787 : : */
2788 : :
2789 : : static bool OpUsesOp1 (M2Quads_QuadOperator op);
2790 : :
2791 : : /*
2792 : : AddQuadInformation - adds variable analysis and jump analysis to the new quadruple.
2793 : : */
2794 : :
2795 : : static void AddQuadInformation (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3);
2796 : : static void stop (void);
2797 : :
2798 : : /*
2799 : : CheckBreak - check whether QuadNo = BreakAtQuad and if so call stop.
2800 : : */
2801 : :
2802 : : static void CheckBreak (unsigned int QuadNo);
2803 : :
2804 : : /*
2805 : : PutQuadO - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
2806 : : sets a boolean to determinine whether overflow should be checked.
2807 : : */
2808 : :
2809 : : static void PutQuadO (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow);
2810 : :
2811 : : /*
2812 : : PutQuadOType -
2813 : : */
2814 : :
2815 : : static void PutQuadOType (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow, bool checktype);
2816 : :
2817 : : /*
2818 : : UndoReadWriteInfo -
2819 : : */
2820 : :
2821 : : static void UndoReadWriteInfo (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3);
2822 : :
2823 : : /*
2824 : : CheckAddTuple2Read - checks to see whether symbol tuple contains variables or
2825 : : parameters and if so it then adds them to the quadruple
2826 : : variable list.
2827 : : */
2828 : :
2829 : : static void CheckAddTuple2Read (unsigned int tuple, bool canDereference, unsigned int Quad);
2830 : :
2831 : : /*
2832 : : CheckAddVariableRead - checks to see whether symbol, Sym, is a variable or
2833 : : a parameter and if so it then adds this quadruple
2834 : : to the variable list.
2835 : : */
2836 : :
2837 : : static void CheckAddVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad);
2838 : :
2839 : : /*
2840 : : CheckRemoveVariableRead - checks to see whether, Sym, is a variable or
2841 : : a parameter and if so then it removes the
2842 : : quadruple from the variable list.
2843 : : */
2844 : :
2845 : : static void CheckRemoveVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad);
2846 : :
2847 : : /*
2848 : : CheckAddVariableWrite - checks to see whether symbol, Sym, is a variable and
2849 : : if so it then adds this quadruple to the variable list.
2850 : : */
2851 : :
2852 : : static void CheckAddVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad);
2853 : :
2854 : : /*
2855 : : CheckRemoveVariableWrite - checks to see whether, Sym, is a variable and
2856 : : if so then it removes the quadruple from the
2857 : : variable list.
2858 : : */
2859 : :
2860 : : static void CheckRemoveVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad);
2861 : :
2862 : : /*
2863 : : CheckConst -
2864 : : */
2865 : :
2866 : : static void CheckConst (unsigned int sym);
2867 : :
2868 : : /*
2869 : : AlterReference - alters all references from OldQuad, to NewQuad in a
2870 : : quadruple list Head.
2871 : : */
2872 : :
2873 : : static void AlterReference (unsigned int Head, unsigned int OldQuad, unsigned int NewQuad);
2874 : :
2875 : : /*
2876 : : GrowQuads - grows the list of quadruples to the quadruple, to.
2877 : : */
2878 : :
2879 : : static void GrowQuads (unsigned int to);
2880 : :
2881 : : /*
2882 : : ManipulateReference - manipulates the quadruple, q, so that it now points to quad, to.
2883 : : */
2884 : :
2885 : : static void ManipulateReference (unsigned int q, unsigned int to);
2886 : :
2887 : : /*
2888 : : RemoveReference - remove the reference by quadruple q to wherever
2889 : : it was pointing.
2890 : : */
2891 : :
2892 : : static void RemoveReference (unsigned int q);
2893 : :
2894 : : /*
2895 : : NewQuad - sets QuadNo to a new quadruple.
2896 : : */
2897 : :
2898 : : static void NewQuad (unsigned int *QuadNo);
2899 : :
2900 : : /*
2901 : : CheckVariableAt - checks to see whether, sym, was declared at a particular address.
2902 : : */
2903 : :
2904 : : static void CheckVariableAt (unsigned int sym);
2905 : :
2906 : : /*
2907 : : CheckVariablesAt - checks to see whether we need to initialize any pointers
2908 : : which point to variable declared at addresses.
2909 : : */
2910 : :
2911 : : static void CheckVariablesAt (unsigned int scope);
2912 : :
2913 : : /*
2914 : : GetTurnInterrupts - returns the TurnInterrupts procedure function.
2915 : : */
2916 : :
2917 : : static unsigned int GetTurnInterrupts (unsigned int tok);
2918 : :
2919 : : /*
2920 : : GetProtection - returns the PROTECTION data type.
2921 : : */
2922 : :
2923 : : static unsigned int GetProtection (unsigned int tok);
2924 : :
2925 : : /*
2926 : : CheckNeedPriorityBegin - checks to see whether we need to save the old
2927 : : module priority and change to another module
2928 : : priority.
2929 : : The current module initialization or procedure
2930 : : being built is defined by, scope. The module whose
2931 : : priority will be used is defined by, module.
2932 : : */
2933 : :
2934 : : static void CheckNeedPriorityBegin (unsigned int tok, unsigned int scope, unsigned int module);
2935 : :
2936 : : /*
2937 : : CheckNeedPriorityEnd - checks to see whether we need to restore the old
2938 : : module priority.
2939 : : The current module initialization or procedure
2940 : : being built is defined by, scope.
2941 : : */
2942 : :
2943 : : static void CheckNeedPriorityEnd (unsigned int tok, unsigned int scope, unsigned int module);
2944 : :
2945 : : /*
2946 : : BuildRTExceptEnter - informs RTExceptions that we are about to enter the except state.
2947 : : */
2948 : :
2949 : : static void BuildRTExceptEnter (unsigned int tok);
2950 : :
2951 : : /*
2952 : : BuildRTExceptLeave - informs RTExceptions that we are about to leave the except state.
2953 : : If, destroy, is TRUE then pop the ExceptStack.
2954 : : */
2955 : :
2956 : : static void BuildRTExceptLeave (unsigned int tok, bool destroy);
2957 : :
2958 : : /*
2959 : : SafeRequestSym - only used during scaffold to get argc, argv, envp.
2960 : : It attempts to get symbol name from the current scope(s) and if
2961 : : it fails then it falls back onto default constants.
2962 : : */
2963 : :
2964 : : static unsigned int SafeRequestSym (unsigned int tok, NameKey_Name name);
2965 : :
2966 : : /*
2967 : : callRequestDependant - create a call:
2968 : : RequestDependant (GetSymName (modulesym), GetLibName (modulesym),
2969 : : GetSymName (depModuleSym), GetLibName (depModuleSym));
2970 : : */
2971 : :
2972 : : static void callRequestDependant (unsigned int tokno, unsigned int moduleSym, unsigned int depModuleSym, unsigned int requestDep);
2973 : :
2974 : : /*
2975 : : ForeachImportInDepDo -
2976 : : */
2977 : :
2978 : : static void ForeachImportInDepDo (Lists_List importStatements, unsigned int moduleSym, unsigned int requestDep);
2979 : :
2980 : : /*
2981 : : ForeachImportedModuleDo -
2982 : : */
2983 : :
2984 : : static void ForeachImportedModuleDo (unsigned int moduleSym, unsigned int requestDep);
2985 : :
2986 : : /*
2987 : : BuildM2DepFunction - creates the dependency graph procedure using IR:
2988 : : static void
2989 : : dependencies (void)
2990 : : {
2991 : : M2RTS_RequestDependant (module_name, libname, "b", "b libname");
2992 : : M2RTS_RequestDependant (module_name, libname, NULL, NULL);
2993 : : }
2994 : : */
2995 : :
2996 : : static void BuildM2DepFunction (unsigned int tokno, unsigned int moduleSym);
2997 : :
2998 : : /*
2999 : : BuildM2LinkFunction - creates the _M2_link procedure which will
3000 : : cause the linker to pull in all the module ctors.
3001 : : */
3002 : :
3003 : : static void BuildM2LinkFunction (unsigned int tokno);
3004 : :
3005 : : /*
3006 : : BuildTry - build the try statement for main.
3007 : : */
3008 : :
3009 : : static void BuildTry (unsigned int tokno);
3010 : :
3011 : : /*
3012 : : BuildExcept - build the except block for main.
3013 : : */
3014 : :
3015 : : static void BuildExcept (unsigned int tokno);
3016 : :
3017 : : /*
3018 : : BuildM2MainFunction - creates the main function with appropriate calls to the scaffold.
3019 : : */
3020 : :
3021 : : static void BuildM2MainFunction (unsigned int tokno);
3022 : :
3023 : : /*
3024 : : DeferMakeConstStringCnul - return a C const string which will be nul terminated.
3025 : : */
3026 : :
3027 : : static unsigned int DeferMakeConstStringCnul (unsigned int tok, unsigned int sym);
3028 : :
3029 : : /*
3030 : : DeferMakeConstStringM2nul - return a const string which will be nul terminated.
3031 : : */
3032 : :
3033 : : static unsigned int DeferMakeConstStringM2nul (unsigned int tok, unsigned int sym);
3034 : :
3035 : : /*
3036 : : BuildStringAdrParam - push the address of a nul terminated string onto the quad stack.
3037 : : */
3038 : :
3039 : : static void BuildStringAdrParam (unsigned int tok, NameKey_Name name);
3040 : :
3041 : : /*
3042 : : BuildM2InitFunction -
3043 : : */
3044 : :
3045 : : static void BuildM2InitFunction (unsigned int tok, unsigned int moduleSym);
3046 : :
3047 : : /*
3048 : : BuildM2FiniFunction -
3049 : : */
3050 : :
3051 : : static void BuildM2FiniFunction (unsigned int tok, unsigned int moduleSym);
3052 : :
3053 : : /*
3054 : : BuildM2CtorFunction - create a constructor function associated with moduleSym.
3055 : :
3056 : : void
3057 : : ctorFunction ()
3058 : : {
3059 : : M2RTS_RegisterModule (GetSymName (moduleSym), GetLibName (moduleSym),
3060 : : init, fini, dependencies);
3061 : : }
3062 : : */
3063 : :
3064 : : static void BuildM2CtorFunction (unsigned int tok, unsigned int moduleSym);
3065 : :
3066 : : /*
3067 : : AddForInfo - adds the description of the FOR loop into the record list.
3068 : : This is used if -pedantic is turned on to check index variable
3069 : : usage.
3070 : : */
3071 : :
3072 : : static void AddForInfo (unsigned int Start, unsigned int End, unsigned int IncQuad, unsigned int Sym, unsigned int idtok);
3073 : :
3074 : : /*
3075 : : CheckForIndex - checks the quadruples: Start..End to see whether a
3076 : : for loop index is manipulated by the programmer.
3077 : : It generates a warning if this is the case.
3078 : : It also checks to see whether the IndexSym is read
3079 : : immediately outside the loop in which case a warning
3080 : : is issued.
3081 : : */
3082 : :
3083 : : static void CheckForIndex (M2Quads_ForLoopInfo forDesc);
3084 : :
3085 : : /*
3086 : : BuildRange - generates a RangeCheckOp quad with, r, as its operand.
3087 : : */
3088 : :
3089 : : static void BuildRange (unsigned int r);
3090 : :
3091 : : /*
3092 : : BuildError - generates a ErrorOp quad, indicating that if this
3093 : : quadruple is reachable, then a runtime error would
3094 : : occur.
3095 : : */
3096 : :
3097 : : static void BuildError (unsigned int r);
3098 : :
3099 : : /*
3100 : : CheckPointerThroughNil - builds a range quadruple, providing, sym, is
3101 : : a candidate for checking against NIL.
3102 : : This range quadruple is only expanded into
3103 : : code during the code generation phase
3104 : : thus allowing limited compile time checking.
3105 : : */
3106 : :
3107 : : static void CheckPointerThroughNil (unsigned int tokpos, unsigned int sym);
3108 : :
3109 : : /*
3110 : : CollectLow - returns the low of the subrange value.
3111 : : */
3112 : :
3113 : : static unsigned int CollectLow (unsigned int sym);
3114 : :
3115 : : /*
3116 : : CollectHigh - returns the high of the subrange value, sym.
3117 : : */
3118 : :
3119 : : static unsigned int CollectHigh (unsigned int sym);
3120 : :
3121 : : /*
3122 : : CheckCompatibleWithBecomes - checks to see that symbol, sym, is
3123 : : compatible with the := operator.
3124 : : */
3125 : :
3126 : : static void CheckCompatibleWithBecomes (unsigned int des, unsigned int expr, unsigned int destok, unsigned int exprtok);
3127 : :
3128 : : /*
3129 : : BuildAssignmentWithoutBounds - calls BuildAssignment but makes sure we do not
3130 : : check bounds.
3131 : : */
3132 : :
3133 : : static void BuildAssignmentWithoutBounds (unsigned int tok, bool checkTypes, bool checkOverflow);
3134 : :
3135 : : /*
3136 : : MarkArrayWritten - marks, Array, as being written.
3137 : : */
3138 : :
3139 : : static void MarkArrayWritten (unsigned int Array);
3140 : :
3141 : : /*
3142 : : MarkAsReadWrite - marks the variable or parameter as being
3143 : : read/write.
3144 : : */
3145 : :
3146 : : static void MarkAsReadWrite (unsigned int sym);
3147 : :
3148 : : /*
3149 : : MarkAsRead - marks the variable or parameter as being read.
3150 : : */
3151 : :
3152 : : static void MarkAsRead (unsigned int sym);
3153 : :
3154 : : /*
3155 : : MarkAsWrite - marks the variable or parameter as being written.
3156 : : */
3157 : :
3158 : : static void MarkAsWrite (unsigned int sym);
3159 : :
3160 : : /*
3161 : : doVal - return an expression which is VAL(type, expr). If
3162 : : expr is a constant then return expr.
3163 : : */
3164 : :
3165 : : static unsigned int doVal (unsigned int type, unsigned int expr);
3166 : :
3167 : : /*
3168 : : MoveWithMode -
3169 : : */
3170 : :
3171 : : static void MoveWithMode (unsigned int tokno, unsigned int Des, unsigned int Exp, unsigned int Array, unsigned int destok, unsigned int exptok, bool checkOverflow);
3172 : :
3173 : : /*
3174 : : CheckBecomesMeta - checks to make sure that we are not
3175 : : assigning a variable to a constant.
3176 : : Also check we are not assigning to an
3177 : : unbounded array.
3178 : : */
3179 : :
3180 : : static void CheckBecomesMeta (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok);
3181 : :
3182 : : /*
3183 : : doBuildAssignment - subsiduary procedure of BuildAssignment.
3184 : : It builds the assignment and optionally
3185 : : checks the types are compatible.
3186 : : */
3187 : :
3188 : : static void doBuildAssignment (unsigned int becomesTokNo, bool checkTypes, bool checkOverflow);
3189 : :
3190 : : /*
3191 : : CheckAssignCompatible - checks to see that an assignment is compatible.
3192 : : It performs limited checking - thorough checking
3193 : : is done in pass 3. But we do what we can here
3194 : : given knowledge so far.
3195 : : */
3196 : :
3197 : : static void CheckAssignCompatible (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok);
3198 : :
3199 : : /*
3200 : : CheckBooleanId - Checks to see if the top operand is a boolean.
3201 : : If the operand is not a boolean then it is tested
3202 : : with true and a boolean is generated.
3203 : : The Stack:
3204 : :
3205 : :
3206 : : Entry Exit
3207 : : Ptr -> <- Ptr
3208 : : +------------+ +------------+
3209 : : | Sym | | t | f |
3210 : : |------------| |------------|
3211 : :
3212 : : Quadruples
3213 : :
3214 : : q If= Sym True _
3215 : : q+1 GotoOp _ _ _
3216 : : */
3217 : :
3218 : : static void CheckBooleanId (void);
3219 : :
3220 : : /*
3221 : : PushOne - pushes the value one to the stack.
3222 : : The Stack is changed:
3223 : :
3224 : :
3225 : : Entry Exit
3226 : : ===== ====
3227 : :
3228 : : <- Ptr
3229 : : +------------+
3230 : : Ptr -> | 1 | type |
3231 : : |------------|
3232 : : */
3233 : :
3234 : : static void PushOne (unsigned int tok, unsigned int type, const char *message_, unsigned int _message_high);
3235 : :
3236 : : /*
3237 : : PushZero - pushes the value zero to the stack.
3238 : : The Stack is changed:
3239 : :
3240 : :
3241 : : Entry Exit
3242 : : ===== ====
3243 : :
3244 : : <- Ptr
3245 : : +------------+
3246 : : Ptr -> | 0 | type |
3247 : : |------------|
3248 : : */
3249 : :
3250 : : static void PushZero (unsigned int tok, unsigned int type);
3251 : :
3252 : : /*
3253 : : ForLoopLastIterator - calculate the last iterator value but avoid setting
3254 : : LastIterator twice if it is a constant (in the quads).
3255 : : In the ForLoopLastIteratorVariable case only one
3256 : : path will be chosen but at the time of quadruple
3257 : : generation we do not know the value of BySym.
3258 : : */
3259 : :
3260 : : static void ForLoopLastIterator (unsigned int LastIterator, unsigned int e1, unsigned int e2, unsigned int BySym, unsigned int e1tok, unsigned int e2tok, unsigned int bytok);
3261 : :
3262 : : /*
3263 : : BuildSizeCheckEnd - checks to see whether the function "called" was in fact SIZE.
3264 : : If so then we restore quadruple generation.
3265 : : */
3266 : :
3267 : : static void BuildSizeCheckEnd (unsigned int ProcSym);
3268 : :
3269 : : /*
3270 : : BuildRealProcedureCall - builds a real procedure call.
3271 : : The Stack:
3272 : :
3273 : :
3274 : : Entry Exit
3275 : :
3276 : : Ptr ->
3277 : : +----------------+
3278 : : | NoOfParam |
3279 : : |----------------|
3280 : : | Param 1 |
3281 : : |----------------|
3282 : : | Param 2 |
3283 : : |----------------|
3284 : : . .
3285 : : . .
3286 : : . .
3287 : : |----------------|
3288 : : | Param # |
3289 : : |----------------|
3290 : : | ProcSym | Type | Empty
3291 : : |----------------|
3292 : : */
3293 : :
3294 : : static void BuildRealProcedureCall (unsigned int tokno);
3295 : :
3296 : : /*
3297 : : BuildRealFuncProcCall - builds a real procedure or function call.
3298 : : The Stack:
3299 : :
3300 : :
3301 : : Entry Exit
3302 : :
3303 : : Ptr ->
3304 : : +----------------+
3305 : : | NoOfParam |
3306 : : |----------------|
3307 : : | Param 1 |
3308 : : |----------------|
3309 : : | Param 2 |
3310 : : |----------------|
3311 : : . .
3312 : : . .
3313 : : . .
3314 : : |----------------|
3315 : : | Param # |
3316 : : |----------------|
3317 : : | ProcSym | Type | Empty
3318 : : |----------------|
3319 : : */
3320 : :
3321 : : static void BuildRealFuncProcCall (unsigned int tokno, bool IsFunc, bool IsForC, bool ConstExpr);
3322 : :
3323 : : /*
3324 : : CheckProcedureParameters - Checks the parameters which are being passed to
3325 : : procedure ProcSym.
3326 : :
3327 : : The Stack:
3328 : :
3329 : :
3330 : : Entry Exit
3331 : :
3332 : : Ptr -> <- Ptr
3333 : : +----------------+ +----------------+
3334 : : | NoOfParam | | NoOfParam |
3335 : : |----------------| |----------------|
3336 : : | Param 1 | | Param 1 |
3337 : : |----------------| |----------------|
3338 : : | Param 2 | | Param 2 |
3339 : : |----------------| |----------------|
3340 : : . . . .
3341 : : . . . .
3342 : : . . . .
3343 : : |----------------| |----------------|
3344 : : | Param # | | Param # |
3345 : : |----------------| |----------------|
3346 : : | ProcSym | Type | | ProcSym | Type |
3347 : : |----------------| |----------------|
3348 : :
3349 : : */
3350 : :
3351 : : static void CheckProcedureParameters (bool IsForC);
3352 : :
3353 : : /*
3354 : : CheckProcTypeAndProcedure - checks the ProcType with the call.
3355 : : */
3356 : :
3357 : : static void CheckProcTypeAndProcedure (unsigned int tokno, unsigned int ProcType, unsigned int call);
3358 : :
3359 : : /*
3360 : : IsReallyPointer - returns TRUE is sym is a pointer, address or a type declared
3361 : : as a pointer or address.
3362 : : */
3363 : :
3364 : : static bool IsReallyPointer (unsigned int Sym);
3365 : :
3366 : : /*
3367 : : LegalUnboundedParam - returns TRUE if the parameter, Actual, can legitimately be
3368 : : passed to ProcSym, i, the, Formal, parameter.
3369 : : */
3370 : :
3371 : : static bool LegalUnboundedParam (unsigned int tokpos, unsigned int ProcSym, unsigned int i, unsigned int ActualType, unsigned int Actual, unsigned int Dimension, unsigned int Formal);
3372 : :
3373 : : /*
3374 : : CheckParameter - checks that types ActualType and FormalType are compatible for parameter
3375 : : passing. ProcSym is the procedure and i is the parameter number.
3376 : :
3377 : : We obey the following rules:
3378 : :
3379 : : (1) we allow WORD, BYTE, LOC to be compitable with any like sized
3380 : : type.
3381 : : (2) we allow ADDRESS to be compatible with any pointer type.
3382 : : (3) we relax INTEGER and CARDINAL checking for Temporary variables.
3383 : :
3384 : : Note that type sizes are checked during the code generation pass.
3385 : : */
3386 : :
3387 : : static void CheckParameter (unsigned int tokpos, unsigned int Actual, unsigned int Dimension, unsigned int Formal, unsigned int ProcSym, unsigned int i, Lists_List TypeList);
3388 : :
3389 : : /*
3390 : : DescribeType - returns a String describing a symbol, Sym, name and its type.
3391 : : */
3392 : :
3393 : : static DynamicStrings_String DescribeType (unsigned int Sym);
3394 : :
3395 : : /*
3396 : : FailParameter - generates an error message indicating that a parameter
3397 : : declaration has failed.
3398 : :
3399 : : The parameters are:
3400 : :
3401 : : CurrentState - string describing the current failing state.
3402 : : Actual - actual parameter.
3403 : : ParameterNo - parameter number that has failed.
3404 : : ProcedureSym - procedure symbol where parameter has failed.
3405 : :
3406 : : If any parameter is Nul then it is ignored.
3407 : : */
3408 : :
3409 : : static void FailParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo);
3410 : :
3411 : : /*
3412 : : WarnParameter - generates a warning message indicating that a parameter
3413 : : use might cause problems on another target.
3414 : :
3415 : : CurrentState - string describing the current failing state.
3416 : : Actual - actual parameter.
3417 : : ParameterNo - parameter number that has failed.
3418 : : ProcedureSym - procedure symbol where parameter has failed.
3419 : :
3420 : : If any parameter is Nul then it is ignored.
3421 : : */
3422 : :
3423 : : static void WarnParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo);
3424 : :
3425 : : /*
3426 : : doIndrX - perform des = *exp with a conversion if necessary.
3427 : : */
3428 : :
3429 : : static void doIndrX (unsigned int tok, unsigned int des, unsigned int exp);
3430 : :
3431 : : /*
3432 : : MakeRightValue - returns a temporary which will have the RightValue of symbol, Sym.
3433 : : If Sym is a right value and has type, type, then no quadruples are
3434 : : generated and Sym is returned. Otherwise a new temporary is created
3435 : : and an IndrX quadruple is generated.
3436 : : */
3437 : :
3438 : : static unsigned int MakeRightValue (unsigned int tok, unsigned int Sym, unsigned int type);
3439 : :
3440 : : /*
3441 : : MakeLeftValue - returns a temporary coresponding to the LeftValue of
3442 : : symbol, Sym. No quadruple is generated if Sym is already
3443 : : a LeftValue and has the same type.
3444 : : */
3445 : :
3446 : : static unsigned int MakeLeftValue (unsigned int tok, unsigned int Sym, SymbolTable_ModeOfAddr with, unsigned int type);
3447 : :
3448 : : /*
3449 : : ManipulatePseudoCallParameters - manipulates the parameters to a pseudo function or
3450 : : procedure. It dereferences all LeftValue parameters
3451 : : and Boolean parameters.
3452 : : The Stack:
3453 : :
3454 : :
3455 : : Entry Exit
3456 : :
3457 : : Ptr -> exactly the same
3458 : : +----------------+
3459 : : | NoOfParameters |
3460 : : |----------------|
3461 : : | Param 1 |
3462 : : |----------------|
3463 : : | Param 2 |
3464 : : |----------------|
3465 : : . .
3466 : : . .
3467 : : . .
3468 : : |----------------|
3469 : : | Param # |
3470 : : |----------------|
3471 : : | ProcSym | Type |
3472 : : |----------------|
3473 : :
3474 : : */
3475 : :
3476 : : static void ManipulatePseudoCallParameters (void);
3477 : :
3478 : : /*
3479 : : ManipulateParameters - manipulates the procedure parameters in
3480 : : preparation for a procedure call.
3481 : : Prepares Boolean, Unbounded and VAR parameters.
3482 : : The Stack:
3483 : :
3484 : :
3485 : : Entry Exit
3486 : :
3487 : : Ptr -> exactly the same
3488 : : +----------------+
3489 : : | NoOfParameters |
3490 : : |----------------|
3491 : : | Param 1 |
3492 : : |----------------|
3493 : : | Param 2 |
3494 : : |----------------|
3495 : : . .
3496 : : . .
3497 : : . .
3498 : : |----------------|
3499 : : | Param # |
3500 : : |----------------|
3501 : : | ProcSym | Type |
3502 : : |----------------|
3503 : : */
3504 : :
3505 : : static void ManipulateParameters (bool IsForC);
3506 : :
3507 : : /*
3508 : : CheckParameterOrdinals - check that ordinal values are within type range.
3509 : : */
3510 : :
3511 : : static void CheckParameterOrdinals (void);
3512 : :
3513 : : /*
3514 : : IsSameUnbounded - returns TRUE if unbounded types, t1, and, t2,
3515 : : are compatible.
3516 : : */
3517 : :
3518 : : static bool IsSameUnbounded (unsigned int t1, unsigned int t2);
3519 : :
3520 : : /*
3521 : : AssignUnboundedVar - assigns an Unbounded symbol fields,
3522 : : ArrayAddress and ArrayHigh, from an array symbol.
3523 : : UnboundedSym is not a VAR parameter and therefore
3524 : : this procedure can complete both of the fields.
3525 : : Sym can be a Variable with type Unbounded.
3526 : : Sym can be a Variable with type Array.
3527 : : Sym can be a String Constant.
3528 : :
3529 : : ParamType is the TYPE of the parameter
3530 : : */
3531 : :
3532 : : static void AssignUnboundedVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3533 : :
3534 : : /*
3535 : : AssignUnboundedNonVar - assigns an Unbounded symbol fields,
3536 : : The difference between this procedure and
3537 : : AssignUnboundedVar is that this procedure cannot
3538 : : set the Unbounded.Address since the data from
3539 : : Sym will be copied because parameter is NOT a VAR
3540 : : parameter.
3541 : : UnboundedSym is not a VAR parameter and therefore
3542 : : this procedure can only complete the HIGH field
3543 : : and not the ADDRESS field.
3544 : : Sym can be a Variable with type Unbounded.
3545 : : Sym can be a Variable with type Array.
3546 : : Sym can be a String Constant.
3547 : :
3548 : : ParamType is the TYPE of the paramater
3549 : : */
3550 : :
3551 : : static void AssignUnboundedNonVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3552 : :
3553 : : /*
3554 : : GenHigh - generates a HighOp but it checks if op3 is a
3555 : : L value and if so it dereferences it. This
3556 : : is inefficient, however it is clean and we let the gcc
3557 : : backend detect these as common subexpressions.
3558 : : It will also detect that a R value -> L value -> R value
3559 : : via indirection and eleminate these.
3560 : : */
3561 : :
3562 : : static void GenHigh (unsigned int tok, unsigned int op1, unsigned int op2, unsigned int op3);
3563 : :
3564 : : /*
3565 : : AssignHighField -
3566 : : */
3567 : :
3568 : : static void AssignHighField (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int actuali, unsigned int formali);
3569 : :
3570 : : /*
3571 : : AssignHighFields -
3572 : : */
3573 : :
3574 : : static void AssignHighFields (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3575 : :
3576 : : /*
3577 : : UnboundedNonVarLinkToArray - links an array, ArraySym, to an unbounded
3578 : : array, UnboundedSym. The parameter is a
3579 : : NON VAR variety.
3580 : : */
3581 : :
3582 : : static void UnboundedNonVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3583 : :
3584 : : /*
3585 : : UnboundedVarLinkToArray - links an array, ArraySym, to an unbounded array,
3586 : : UnboundedSym. The parameter is a VAR variety.
3587 : : */
3588 : :
3589 : : static void UnboundedVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3590 : :
3591 : : /*
3592 : : BuildPseudoProcedureCall - builds a pseudo procedure call.
3593 : : This procedure does not directly alter the
3594 : : stack, but by calling routines the stack
3595 : : will change in the following way when this
3596 : : procedure returns.
3597 : :
3598 : : The Stack:
3599 : :
3600 : :
3601 : : Entry Exit
3602 : :
3603 : : Ptr ->
3604 : : +----------------+
3605 : : | NoOfParam |
3606 : : |----------------|
3607 : : | Param 1 |
3608 : : |----------------|
3609 : : | Param 2 |
3610 : : |----------------|
3611 : : . .
3612 : : . .
3613 : : . .
3614 : : |----------------|
3615 : : | Param # |
3616 : : |----------------|
3617 : : | ProcSym | Type | Empty
3618 : : |----------------|
3619 : : */
3620 : :
3621 : : static void BuildPseudoProcedureCall (unsigned int tokno);
3622 : :
3623 : : /*
3624 : : GetItemPointedTo - returns the symbol type that is being pointed to
3625 : : by Sym.
3626 : : */
3627 : :
3628 : : static unsigned int GetItemPointedTo (unsigned int Sym);
3629 : :
3630 : : /*
3631 : : BuildThrowProcedure - builds the pseudo procedure call M2RTS.Throw.
3632 : : The Stack:
3633 : :
3634 : :
3635 : : Entry Exit
3636 : :
3637 : : Ptr ->
3638 : : +----------------+
3639 : : | NoOfParam |
3640 : : |----------------|
3641 : : | Param 1 |
3642 : : |----------------|
3643 : : | Param 2 |
3644 : : |----------------|
3645 : : . .
3646 : : . .
3647 : : . .
3648 : : |----------------|
3649 : : | Param # |
3650 : : |----------------|
3651 : : | ProcSym | Type | Empty
3652 : : |----------------|
3653 : : */
3654 : :
3655 : : static void BuildThrowProcedure (void);
3656 : :
3657 : : /*
3658 : : BuildNewProcedure - builds the pseudo procedure call NEW.
3659 : : This procedure is traditionally a "macro" for
3660 : : NEW(x, ...) --> ALLOCATE(x, TSIZE(x^, ...))
3661 : : One method of implementation is to emulate a "macro"
3662 : : processor by pushing the relevant input tokens
3663 : : back onto the input stack.
3664 : : However this causes two problems:
3665 : :
3666 : : (i) Unnecessary code is produced for x^
3667 : : (ii) SIZE must be imported from SYSTEM
3668 : : Therefore we chose an alternative method of
3669 : : implementation;
3670 : : generate quadruples for ALLOCATE(x, TSIZE(x^, ...))
3671 : : this, although slightly more efficient,
3672 : : is more complex and circumvents problems (i) and (ii).
3673 : :
3674 : : The Stack:
3675 : :
3676 : :
3677 : : Entry Exit
3678 : :
3679 : : Ptr ->
3680 : : +----------------+
3681 : : | NoOfParam |
3682 : : |----------------|
3683 : : | Param 1 |
3684 : : |----------------|
3685 : : | Param 2 |
3686 : : |----------------|
3687 : : . .
3688 : : . .
3689 : : . .
3690 : : |----------------|
3691 : : | Param # |
3692 : : |----------------|
3693 : : | ProcSym | Type | Empty
3694 : : |----------------|
3695 : : */
3696 : :
3697 : : static void BuildNewProcedure (unsigned int functok);
3698 : :
3699 : : /*
3700 : : BuildDisposeProcedure - builds the pseudo procedure call DISPOSE.
3701 : : This procedure is traditionally a "macro" for
3702 : : DISPOSE(x) --> DEALLOCATE(x, TSIZE(x^))
3703 : : One method of implementation is to emulate a "macro"
3704 : : processor by pushing the relevant input tokens
3705 : : back onto the input stack.
3706 : : However this causes two problems:
3707 : :
3708 : : (i) Unnecessary code is produced for x^
3709 : : (ii) TSIZE must be imported from SYSTEM
3710 : : Therefore we chose an alternative method of
3711 : : implementation;
3712 : : generate quadruples for DEALLOCATE(x, TSIZE(x^))
3713 : : this, although slightly more efficient,
3714 : : is more complex and circumvents problems (i)
3715 : : and (ii).
3716 : :
3717 : : The Stack:
3718 : :
3719 : :
3720 : : Entry Exit
3721 : :
3722 : : Ptr ->
3723 : : +----------------+
3724 : : | NoOfParam |
3725 : : |----------------|
3726 : : | Param 1 |
3727 : : |----------------|
3728 : : | Param 2 |
3729 : : |----------------|
3730 : : . .
3731 : : . .
3732 : : . .
3733 : : |----------------|
3734 : : | Param # |
3735 : : |----------------|
3736 : : | ProcSym | Type | Empty
3737 : : |----------------|
3738 : : */
3739 : :
3740 : : static void BuildDisposeProcedure (unsigned int functok);
3741 : :
3742 : : /*
3743 : : CheckRangeIncDec - performs des := des <tok> expr
3744 : : with range checking (if enabled).
3745 : :
3746 : : Stack
3747 : : Entry Exit
3748 : :
3749 : : +------------+
3750 : : empty | des + expr |
3751 : : |------------|
3752 : : */
3753 : :
3754 : : static void CheckRangeIncDec (unsigned int tokenpos, unsigned int des, unsigned int expr, NameKey_Name tok);
3755 : :
3756 : : /*
3757 : : BuildIncProcedure - builds the pseudo procedure call INC.
3758 : : INC is a procedure which increments a variable.
3759 : : It takes one or two parameters:
3760 : : INC(a, b) or INC(a)
3761 : : a := a+b or a := a+1
3762 : :
3763 : : The Stack:
3764 : :
3765 : :
3766 : : Entry Exit
3767 : :
3768 : : Ptr ->
3769 : : +----------------+
3770 : : | NoOfParam |
3771 : : |----------------|
3772 : : | Param 1 |
3773 : : |----------------|
3774 : : | Param 2 |
3775 : : |----------------|
3776 : : . .
3777 : : . .
3778 : : . .
3779 : : |----------------|
3780 : : | Param # |
3781 : : |----------------|
3782 : : | ProcSym | Type | Empty
3783 : : |----------------|
3784 : : */
3785 : :
3786 : : static void BuildIncProcedure (void);
3787 : :
3788 : : /*
3789 : : BuildDecProcedure - builds the pseudo procedure call DEC.
3790 : : DEC is a procedure which decrements a variable.
3791 : : It takes one or two parameters:
3792 : : DEC(a, b) or DEC(a)
3793 : : a := a-b or a := a-1
3794 : :
3795 : : The Stack:
3796 : :
3797 : :
3798 : : Entry Exit
3799 : :
3800 : : Ptr ->
3801 : : +----------------+
3802 : : | NoOfParam |
3803 : : |----------------|
3804 : : | Param 1 |
3805 : : |----------------|
3806 : : | Param 2 |
3807 : : |----------------|
3808 : : . .
3809 : : . .
3810 : : . .
3811 : : |----------------|
3812 : : | Param # |
3813 : : |----------------|
3814 : : | ProcSym | Type | Empty
3815 : : |----------------|
3816 : : */
3817 : :
3818 : : static void BuildDecProcedure (void);
3819 : :
3820 : : /*
3821 : : DereferenceLValue - checks to see whether, operand, is declare as an LValue
3822 : : and if so it dereferences it.
3823 : : */
3824 : :
3825 : : static unsigned int DereferenceLValue (unsigned int tok, unsigned int operand);
3826 : :
3827 : : /*
3828 : : BuildInclProcedure - builds the pseudo procedure call INCL.
3829 : : INCL is a procedure which adds bit b into a BITSET a.
3830 : : It takes two parameters:
3831 : : INCL(a, b)
3832 : :
3833 : : a := a + {b}
3834 : :
3835 : : The Stack:
3836 : :
3837 : :
3838 : : Entry Exit
3839 : :
3840 : : Ptr ->
3841 : : +----------------+
3842 : : | NoOfParam |
3843 : : |----------------|
3844 : : | Param 1 |
3845 : : |----------------|
3846 : : | Param 2 |
3847 : : |----------------|
3848 : : | ProcSym | Type | Empty
3849 : : |----------------|
3850 : : */
3851 : :
3852 : : static void BuildInclProcedure (void);
3853 : :
3854 : : /*
3855 : : BuildExclProcedure - builds the pseudo procedure call EXCL.
3856 : : INCL is a procedure which removes bit b from SET a.
3857 : : It takes two parameters:
3858 : : EXCL(a, b)
3859 : :
3860 : : a := a - {b}
3861 : :
3862 : : The Stack:
3863 : :
3864 : :
3865 : : Entry Exit
3866 : :
3867 : : Ptr ->
3868 : : +----------------+
3869 : : | NoOfParam |
3870 : : |----------------|
3871 : : | Param 1 |
3872 : : |----------------|
3873 : : | Param 2 |
3874 : : |----------------|
3875 : : | ProcSym | Type | Empty
3876 : : |----------------|
3877 : : */
3878 : :
3879 : : static void BuildExclProcedure (void);
3880 : :
3881 : : /*
3882 : : BuildTypeCoercion - builds the type coersion.
3883 : : Modula-2 allows types to be coersed with no runtime
3884 : : penility.
3885 : : It insists that the TSIZE(t1)=TSIZE(t2) where
3886 : : t2 variable := t2(variable of type t1).
3887 : : The ReturnVar on the stack is of type t2.
3888 : :
3889 : : The Stack:
3890 : :
3891 : :
3892 : : Entry Exit
3893 : :
3894 : : Ptr ->
3895 : : +----------------+
3896 : : | NoOfParam |
3897 : : |----------------|
3898 : : | Param 1 |
3899 : : |----------------|
3900 : : | Param 2 |
3901 : : |----------------|
3902 : : . .
3903 : : . .
3904 : : . .
3905 : : |----------------|
3906 : : | Param # | <- Ptr
3907 : : |----------------| +------------+
3908 : : | ProcSym | Type | | ReturnVar |
3909 : : |----------------| |------------|
3910 : :
3911 : : Quadruples:
3912 : :
3913 : : CoerceOp ReturnVar Type Param1
3914 : :
3915 : : A type coercion will only be legal if the different
3916 : : types have exactly the same size.
3917 : : Since we can only decide this after M2Eval has processed
3918 : : the symbol table then we create a quadruple explaining
3919 : : the coercion taking place, the code generator can test
3920 : : this assertion and report an error if the type sizes
3921 : : differ.
3922 : : */
3923 : :
3924 : : static void BuildTypeCoercion (bool ConstExpr);
3925 : :
3926 : : /*
3927 : : BuildRealFunctionCall - builds a function call.
3928 : : The Stack:
3929 : :
3930 : :
3931 : : Entry Exit
3932 : :
3933 : : Ptr ->
3934 : : +----------------+
3935 : : | NoOfParam |
3936 : : |----------------|
3937 : : | Param 1 |
3938 : : |----------------|
3939 : : | Param 2 |
3940 : : |----------------|
3941 : : . .
3942 : : . .
3943 : : . .
3944 : : |----------------|
3945 : : | Param # | <- Ptr
3946 : : |----------------| +------------+
3947 : : | ProcSym | Type | | ReturnVar |
3948 : : |----------------| |------------|
3949 : : */
3950 : :
3951 : : static void BuildRealFunctionCall (unsigned int tokno, bool ConstExpr);
3952 : :
3953 : : /*
3954 : : BuildPseudoFunctionCall - builds the pseudo function
3955 : : The Stack:
3956 : :
3957 : :
3958 : : Entry Exit
3959 : :
3960 : : Ptr ->
3961 : : +----------------+
3962 : : | NoOfParam |
3963 : : |----------------|
3964 : : | Param 1 |
3965 : : |----------------|
3966 : : | Param 2 |
3967 : : |----------------|
3968 : : . .
3969 : : . .
3970 : : . .
3971 : : |----------------|
3972 : : | Param # | <- Ptr
3973 : : |----------------| +------------+
3974 : : | ProcSym | Type | | ReturnVar |
3975 : : |----------------| |------------|
3976 : :
3977 : : */
3978 : :
3979 : : static void BuildPseudoFunctionCall (bool ConstExpr);
3980 : :
3981 : : /*
3982 : : BuildAddAdrFunction - builds the pseudo procedure call ADDADR.
3983 : :
3984 : : PROCEDURE ADDADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
3985 : :
3986 : : Which returns address given by (addr + offset),
3987 : : [ the standard says that it _may_
3988 : : "raise an exception if this address is not valid."
3989 : : currently we do not generate any exception code ]
3990 : :
3991 : : The Stack:
3992 : :
3993 : : Entry Exit
3994 : :
3995 : : Ptr ->
3996 : : +----------------+
3997 : : | NoOfParam |
3998 : : |----------------|
3999 : : | Param 1 |
4000 : : |----------------|
4001 : : | Param 2 | <- Ptr
4002 : : |----------------| +------------+
4003 : : | ProcSym | Type | | ReturnVar |
4004 : : |----------------| |------------|
4005 : : */
4006 : :
4007 : : static void BuildAddAdrFunction (unsigned int ProcSym, bool ConstExpr);
4008 : :
4009 : : /*
4010 : : BuildSubAdrFunction - builds the pseudo procedure call ADDADR.
4011 : :
4012 : : PROCEDURE SUBADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
4013 : :
4014 : : Which returns address given by (addr - offset),
4015 : : [ the standard says that it _may_
4016 : : "raise an exception if this address is not valid."
4017 : : currently we do not generate any exception code ]
4018 : :
4019 : : The Stack:
4020 : :
4021 : : Entry Exit
4022 : :
4023 : : Ptr ->
4024 : : +----------------+
4025 : : | NoOfParam |
4026 : : |----------------|
4027 : : | Param 1 |
4028 : : |----------------|
4029 : : | Param 2 | <- Ptr
4030 : : |----------------| +------------+
4031 : : | ProcSym | Type | | ReturnVar |
4032 : : |----------------| |------------|
4033 : : */
4034 : :
4035 : : static void BuildSubAdrFunction (unsigned int ProcSym, bool ConstExpr);
4036 : :
4037 : : /*
4038 : : BuildDifAdrFunction - builds the pseudo procedure call DIFADR.
4039 : :
4040 : : PROCEDURE DIFADR (addr1, addr2: ADDRESS): INTEGER ;
4041 : :
4042 : : Which returns address given by (addr1 - addr2),
4043 : : [ the standard says that it _may_
4044 : : "raise an exception if this address is invalid or
4045 : : address space is non-contiguous."
4046 : : currently we do not generate any exception code ]
4047 : :
4048 : : The Stack:
4049 : :
4050 : : Entry Exit
4051 : :
4052 : : Ptr ->
4053 : : +----------------+
4054 : : | NoOfParam |
4055 : : |----------------|
4056 : : | Param 1 |
4057 : : |----------------|
4058 : : | Param 2 | <- Ptr
4059 : : |----------------| +------------+
4060 : : | ProcSym | Type | | ReturnVar |
4061 : : |----------------| |------------|
4062 : : */
4063 : :
4064 : : static void BuildDifAdrFunction (unsigned int ProcSym, bool ConstExpr);
4065 : :
4066 : : /*
4067 : : BuildHighFunction - checks the stack in preparation for generating
4068 : : quadruples which perform HIGH.
4069 : : This procedure does not alter the stack but
4070 : : determines whether, a, in HIGH(a) is an ArraySym
4071 : : or UnboundedSym.
4072 : : Both cases are different and appropriate quadruple
4073 : : generating routines are called.
4074 : :
4075 : : The Stack:
4076 : :
4077 : :
4078 : : Entry Exit
4079 : :
4080 : : Ptr ->
4081 : : +----------------+
4082 : : | NoOfParam |
4083 : : |----------------|
4084 : : | Param 1 |
4085 : : |----------------|
4086 : : | Param 2 |
4087 : : |----------------|
4088 : : . .
4089 : : . .
4090 : : . .
4091 : : |----------------|
4092 : : | Param # | <- Ptr
4093 : : |----------------| +------------+
4094 : : | ProcSym | Type | | ReturnVar |
4095 : : |----------------| |------------|
4096 : :
4097 : : */
4098 : :
4099 : : static void BuildHighFunction (void);
4100 : :
4101 : : /*
4102 : : BuildConstHighFromSym - builds the pseudo function HIGH from an Sym.
4103 : : Sym is a constant or an array which has constant bounds
4104 : : and therefore it can be calculated at compile time.
4105 : :
4106 : : The Stack:
4107 : :
4108 : :
4109 : : Entry Exit
4110 : :
4111 : : Ptr ->
4112 : : +----------------+
4113 : : | NoOfParam |
4114 : : |----------------|
4115 : : | Param 1 |
4116 : : |----------------|
4117 : : | Param 2 |
4118 : : |----------------|
4119 : : . .
4120 : : . .
4121 : : . .
4122 : : |----------------|
4123 : : | Param # | <- Ptr
4124 : : |----------------| +------------+
4125 : : | ProcSym | Type | | ReturnVar |
4126 : : |----------------| |------------|
4127 : : */
4128 : :
4129 : : static void BuildConstHighFromSym (unsigned int tok);
4130 : :
4131 : : /*
4132 : : BuildHighFromUnbounded - builds the pseudo function HIGH from an
4133 : : UnboundedSym.
4134 : :
4135 : : The Stack:
4136 : :
4137 : :
4138 : : Entry Exit
4139 : :
4140 : : Ptr ->
4141 : : +----------------+
4142 : : | NoOfParam |
4143 : : |----------------|
4144 : : | Param # | <- Ptr
4145 : : |----------------| +------------+
4146 : : | ProcSym | Type | | ReturnVar |
4147 : : |----------------| |------------|
4148 : :
4149 : : */
4150 : :
4151 : : static void BuildHighFromUnbounded (unsigned int tok);
4152 : :
4153 : : /*
4154 : : GetQualidentImport - returns the symbol as if it were qualified from, module.n.
4155 : : This is used to reference runtime support procedures and an
4156 : : error is generated if the symbol cannot be obtained.
4157 : : */
4158 : :
4159 : : static unsigned int GetQualidentImport (unsigned int tokno, NameKey_Name n, NameKey_Name module);
4160 : :
4161 : : /*
4162 : : ConstExprError - return TRUE if a constant expression is being built and Var is a variable.
4163 : : */
4164 : :
4165 : : static bool ConstExprError (unsigned int Func, unsigned int Var, unsigned int optok, bool ConstExpr);
4166 : :
4167 : : /*
4168 : : DeferMakeLengthConst - creates a constant which contains the length of string, sym.
4169 : : */
4170 : :
4171 : : static unsigned int DeferMakeLengthConst (unsigned int tok, unsigned int sym);
4172 : :
4173 : : /*
4174 : : BuildLengthFunction - builds the inline standard function LENGTH.
4175 : :
4176 : : The Stack:
4177 : :
4178 : :
4179 : : Entry Exit
4180 : :
4181 : : Ptr ->
4182 : : +----------------+
4183 : : | NoOfParam |
4184 : : |----------------|
4185 : : | Param 1 | <- Ptr
4186 : : |----------------| +------------+
4187 : : | ProcSym | Type | | ReturnVar |
4188 : : |----------------| |------------|
4189 : :
4190 : : */
4191 : :
4192 : : static void BuildLengthFunction (unsigned int Function, bool ConstExpr);
4193 : :
4194 : : /*
4195 : : BuildOddFunction - builds the pseudo procedure call ODD.
4196 : : This procedure is actually a "macro" for
4197 : : ORD(x) --> VAL(BOOLEAN, x MOD 2)
4198 : : However we cannot push tokens back onto the input stack
4199 : : because the compiler is currently building a function
4200 : : call and expecting a ReturnVar on the stack.
4201 : : Hence we manipulate the stack and call
4202 : : BuildConvertFunction.
4203 : :
4204 : : The Stack:
4205 : :
4206 : :
4207 : : Entry Exit
4208 : :
4209 : : Ptr ->
4210 : : +----------------+
4211 : : | NoOfParam |
4212 : : |----------------|
4213 : : | Param 1 |
4214 : : |----------------|
4215 : : | Param 2 |
4216 : : |----------------|
4217 : : . .
4218 : : . .
4219 : : . .
4220 : : |----------------|
4221 : : | Param # |
4222 : : |----------------|
4223 : : | ProcSym | Type | Empty
4224 : : |----------------|
4225 : : */
4226 : :
4227 : : static void BuildOddFunction (unsigned int ProcSym, bool ConstExpr);
4228 : :
4229 : : /*
4230 : : BuildAbsFunction - builds a call to the standard function ABS.
4231 : :
4232 : : We cannot implement it as a macro or inline an
4233 : : IF THEN statement as the IF THEN ELSE requires
4234 : : we write the value to the same variable (or constant)
4235 : : twice. The macro implementation will fail as
4236 : : the compiler maybe building a function
4237 : : call and expecting a ReturnVar on the stack.
4238 : : The only method to implement this is to pass it to the
4239 : : gcc backend.
4240 : :
4241 : : The Stack:
4242 : :
4243 : :
4244 : : Entry Exit
4245 : :
4246 : : Ptr ->
4247 : : +----------------+
4248 : : | NoOfParam |
4249 : : |----------------|
4250 : : | Param 1 |
4251 : : |----------------|
4252 : : | Param 2 |
4253 : : |----------------|
4254 : : . .
4255 : : . .
4256 : : . .
4257 : : |----------------|
4258 : : | Param # |
4259 : : |----------------|
4260 : : | ProcSym | Type | Empty
4261 : : |----------------|
4262 : : */
4263 : :
4264 : : static void BuildAbsFunction (unsigned int ProcSym, bool ConstExpr);
4265 : :
4266 : : /*
4267 : : BuildCapFunction - builds the pseudo procedure call CAP.
4268 : : We generate a the following quad:
4269 : :
4270 : :
4271 : : StandardFunctionOp ReturnVal Cap Param1
4272 : :
4273 : : The Stack:
4274 : :
4275 : :
4276 : : Entry Exit
4277 : :
4278 : : Ptr ->
4279 : : +----------------+
4280 : : | NoOfParam = 1 |
4281 : : |----------------|
4282 : : | Param 1 |
4283 : : |----------------| +-------------+
4284 : : | ProcSym | Type | | ReturnVal |
4285 : : |----------------| |-------------|
4286 : : */
4287 : :
4288 : : static void BuildCapFunction (unsigned int ProcSym, bool ConstExpr);
4289 : :
4290 : : /*
4291 : : BuildChrFunction - builds the pseudo procedure call CHR.
4292 : : This procedure is actually a "macro" for
4293 : : CHR(x) --> CONVERT(CHAR, x)
4294 : : However we cannot push tokens back onto the input stack
4295 : : because the compiler is currently building a function
4296 : : call and expecting a ReturnVar on the stack.
4297 : : Hence we manipulate the stack and call
4298 : : BuildConvertFunction.
4299 : :
4300 : : The Stack:
4301 : :
4302 : :
4303 : : Entry Exit
4304 : :
4305 : : Ptr ->
4306 : : +----------------+
4307 : : | NoOfParam |
4308 : : |----------------|
4309 : : | Param 1 |
4310 : : |----------------|
4311 : : | Param 2 |
4312 : : |----------------|
4313 : : . .
4314 : : . .
4315 : : . .
4316 : : |----------------|
4317 : : | Param # |
4318 : : |----------------|
4319 : : | ProcSym | Type | Empty
4320 : : |----------------|
4321 : : */
4322 : :
4323 : : static void BuildChrFunction (unsigned int ProcSym, bool ConstExpr);
4324 : :
4325 : : /*
4326 : : BuildOrdFunction - builds the pseudo procedure call ORD.
4327 : : This procedure is actually a "macro" for
4328 : : ORD(x) --> CONVERT(GetSType(sym), x)
4329 : : However we cannot push tokens back onto the input stack
4330 : : because the compiler is currently building a function
4331 : : call and expecting a ReturnVar on the stack.
4332 : : Hence we manipulate the stack and call
4333 : : BuildConvertFunction.
4334 : :
4335 : : The Stack:
4336 : :
4337 : :
4338 : : Entry Exit
4339 : :
4340 : : Ptr ->
4341 : : +----------------+
4342 : : | NoOfParam |
4343 : : |----------------|
4344 : : | Param 1 |
4345 : : |----------------|
4346 : : | Param 2 |
4347 : : |----------------|
4348 : : . .
4349 : : . .
4350 : : . .
4351 : : |----------------|
4352 : : | Param # |
4353 : : |----------------|
4354 : : | ProcSym | Type | Empty
4355 : : |----------------|
4356 : : */
4357 : :
4358 : : static void BuildOrdFunction (unsigned int Sym, bool ConstExpr);
4359 : :
4360 : : /*
4361 : : BuildIntFunction - builds the pseudo procedure call INT.
4362 : : This procedure is actually a "macro" for
4363 : : INT(x) --> CONVERT(INTEGER, x)
4364 : : However we cannot push tokens back onto the input stack
4365 : : because the compiler is currently building a function
4366 : : call and expecting a ReturnVar on the stack.
4367 : : Hence we manipulate the stack and call
4368 : : BuildConvertFunction.
4369 : :
4370 : : The Stack:
4371 : :
4372 : :
4373 : : Entry Exit
4374 : :
4375 : : Ptr ->
4376 : : +----------------+
4377 : : | NoOfParam |
4378 : : |----------------|
4379 : : | Param 1 |
4380 : : |----------------|
4381 : : | Param 2 |
4382 : : |----------------|
4383 : : . .
4384 : : . .
4385 : : . .
4386 : : |----------------|
4387 : : | Param # |
4388 : : |----------------|
4389 : : | ProcSym | Type | Empty
4390 : : |----------------|
4391 : : */
4392 : :
4393 : : static void BuildIntFunction (unsigned int Sym, bool ConstExpr);
4394 : :
4395 : : /*
4396 : : BuildMakeAdrFunction - builds the pseudo procedure call MAKEADR.
4397 : :
4398 : : The Stack:
4399 : :
4400 : :
4401 : : Entry Exit
4402 : :
4403 : : Ptr ->
4404 : : +----------------+
4405 : : | NoOfParam |
4406 : : |----------------|
4407 : : | Param 1 |
4408 : : |----------------|
4409 : : | Param 2 |
4410 : : |----------------|
4411 : : . .
4412 : : . .
4413 : : . .
4414 : : |----------------|
4415 : : | Param # |
4416 : : |----------------|
4417 : : | ProcSym | Type | Empty
4418 : : |----------------|
4419 : : */
4420 : :
4421 : : static void BuildMakeAdrFunction (void);
4422 : :
4423 : : /*
4424 : : BuildShiftFunction - builds the pseudo procedure call SHIFT.
4425 : :
4426 : : PROCEDURE SHIFT (val: <any type>;
4427 : : num: INTEGER): <any type> ;
4428 : :
4429 : : "Returns a bit sequence obtained from val by
4430 : : shifting up or down (left or right) by the
4431 : : absolute value of num, introducing
4432 : : zeros as necessary. The direction is down if
4433 : : the sign of num is negative, otherwise the
4434 : : direction is up."
4435 : :
4436 : : The Stack:
4437 : :
4438 : : Entry Exit
4439 : :
4440 : : Ptr ->
4441 : : +----------------+
4442 : : | NoOfParam |
4443 : : |----------------|
4444 : : | Param 1 |
4445 : : |----------------|
4446 : : | Param 2 | <- Ptr
4447 : : |----------------| +------------+
4448 : : | ProcSym | Type | | ReturnVar |
4449 : : |----------------| |------------|
4450 : : */
4451 : :
4452 : : static void BuildShiftFunction (void);
4453 : :
4454 : : /*
4455 : : BuildRotateFunction - builds the pseudo procedure call ROTATE.
4456 : :
4457 : : PROCEDURE ROTATE (val: <any type>;
4458 : : num: INTEGER): <any type> ;
4459 : :
4460 : : "Returns a bit sequence obtained from val
4461 : : by rotating up or down (left or right) by
4462 : : the absolute value of num. The direction is
4463 : : down if the sign of num is negative, otherwise
4464 : : the direction is up."
4465 : :
4466 : : The Stack:
4467 : :
4468 : : Entry Exit
4469 : :
4470 : : Ptr ->
4471 : : +----------------+
4472 : : | NoOfParam |
4473 : : |----------------|
4474 : : | Param 1 |
4475 : : |----------------|
4476 : : | Param 2 | <- Ptr
4477 : : |----------------| +------------+
4478 : : | ProcSym | Type | | ReturnVar |
4479 : : |----------------| |------------|
4480 : : */
4481 : :
4482 : : static void BuildRotateFunction (void);
4483 : :
4484 : : /*
4485 : : BuildValFunction - builds the pseudo procedure call VAL.
4486 : : This procedure is actually a "macro" for
4487 : : VAL(Type, x) --> CONVERT(Type, x)
4488 : : However we cannot push tokens back onto the input stack
4489 : : because the compiler is currently building a function
4490 : : call and expecting a ReturnVar on the stack.
4491 : : Hence we manipulate the stack and call
4492 : : BuildConvertFunction.
4493 : :
4494 : : The Stack:
4495 : :
4496 : :
4497 : : Entry Exit
4498 : :
4499 : : Ptr ->
4500 : : +----------------+
4501 : : | NoOfParam |
4502 : : |----------------|
4503 : : | Param 1 |
4504 : : |----------------|
4505 : : | Param 2 |
4506 : : |----------------|
4507 : : . .
4508 : : . .
4509 : : . .
4510 : : |----------------|
4511 : : | Param # |
4512 : : |----------------|
4513 : : | ProcSym | Type | Empty
4514 : : |----------------|
4515 : : */
4516 : :
4517 : : static void BuildValFunction (unsigned int ProcSym, bool ConstExpr);
4518 : :
4519 : : /*
4520 : : BuildCastFunction - builds the pseudo procedure call CAST.
4521 : : This procedure is actually a "macro" for
4522 : : CAST(Type, x) --> Type(x)
4523 : : However we cannot push tokens back onto the input stack
4524 : : because the compiler is currently building a function
4525 : : call and expecting a ReturnVar on the stack.
4526 : : Hence we manipulate the stack and call
4527 : : BuildConvertFunction.
4528 : :
4529 : : The Stack:
4530 : :
4531 : :
4532 : : Entry Exit
4533 : :
4534 : : Ptr ->
4535 : : +----------------+
4536 : : | NoOfParam |
4537 : : |----------------|
4538 : : | Param 1 |
4539 : : |----------------|
4540 : : | Param 2 |
4541 : : |----------------|
4542 : : . .
4543 : : . .
4544 : : . .
4545 : : |----------------|
4546 : : | Param # |
4547 : : |----------------|
4548 : : | ProcSym | Type | Empty
4549 : : |----------------|
4550 : : */
4551 : :
4552 : : static void BuildCastFunction (unsigned int ProcSym, bool ConstExpr);
4553 : :
4554 : : /*
4555 : : BuildConvertFunction - builds the pseudo function CONVERT.
4556 : : CONVERT( Type, Variable ) ;
4557 : :
4558 : : The Stack:
4559 : :
4560 : :
4561 : : Entry Exit
4562 : :
4563 : : Ptr ->
4564 : : +----------------+
4565 : : | NoOfParam |
4566 : : |----------------|
4567 : : | Param 1 |
4568 : : |----------------|
4569 : : | Param 2 |
4570 : : |----------------|
4571 : : . .
4572 : : . .
4573 : : . .
4574 : : |----------------|
4575 : : | Param # | <- Ptr
4576 : : |----------------| +---------------------+
4577 : : | ProcSym | Type | | ReturnVar | Param1 |
4578 : : |----------------| |---------------------|
4579 : :
4580 : : Quadruples:
4581 : :
4582 : : ConvertOp ReturnVar Param1 Param2
4583 : :
4584 : : Converts variable Param2 into a variable Param1
4585 : : with a type Param1.
4586 : : */
4587 : :
4588 : : static void BuildConvertFunction (unsigned int ProcSym, bool ConstExpr);
4589 : :
4590 : : /*
4591 : : CheckBaseTypeValue - checks to see whether the value, min, really exists.
4592 : : */
4593 : :
4594 : : static unsigned int CheckBaseTypeValue (unsigned int tok, unsigned int type, unsigned int min, unsigned int func);
4595 : :
4596 : : /*
4597 : : GetTypeMin - returns the minimium value of type.
4598 : : */
4599 : :
4600 : : static unsigned int GetTypeMin (unsigned int tok, unsigned int func, unsigned int type);
4601 : :
4602 : : /*
4603 : : GetTypeMax - returns the maximum value of type.
4604 : : */
4605 : :
4606 : : static unsigned int GetTypeMax (unsigned int tok, unsigned int func, unsigned int type);
4607 : :
4608 : : /*
4609 : : BuildMinFunction - builds the pseudo function call Min.
4610 : :
4611 : : The Stack:
4612 : :
4613 : : Entry Exit
4614 : :
4615 : : Ptr ->
4616 : : +----------------+
4617 : : | NoOfParam=1 |
4618 : : |----------------|
4619 : : | Param 1 |
4620 : : |----------------|
4621 : : | ProcSym | Type | Empty
4622 : : |----------------|
4623 : : */
4624 : :
4625 : : static void BuildMinFunction (void);
4626 : :
4627 : : /*
4628 : : BuildMaxFunction - builds the pseudo function call Max.
4629 : :
4630 : : The Stack:
4631 : :
4632 : : Entry Exit
4633 : :
4634 : : Ptr ->
4635 : : +----------------+
4636 : : | NoOfParam=1 |
4637 : : |----------------|
4638 : : | Param 1 |
4639 : : |----------------|
4640 : : | ProcSym | Type | Empty
4641 : : |----------------|
4642 : : */
4643 : :
4644 : : static void BuildMaxFunction (void);
4645 : :
4646 : : /*
4647 : : BuildTruncFunction - builds the pseudo procedure call TRUNC.
4648 : : This procedure is actually a "macro" for
4649 : : TRUNC(x) --> CONVERT(INTEGER, x)
4650 : : However we cannot push tokens back onto the input stack
4651 : : because the compiler is currently building a function
4652 : : call and expecting a ReturnVar on the stack.
4653 : : Hence we manipulate the stack and call
4654 : : BuildConvertFunction.
4655 : :
4656 : : The Stack:
4657 : :
4658 : :
4659 : : Entry Exit
4660 : :
4661 : : Ptr ->
4662 : : +----------------+
4663 : : | NoOfParam |
4664 : : |----------------|
4665 : : | Param 1 |
4666 : : |----------------|
4667 : : | Param 2 |
4668 : : |----------------|
4669 : : . .
4670 : : . .
4671 : : . .
4672 : : |----------------|
4673 : : | Param # |
4674 : : |----------------|
4675 : : | ProcSym | Type | Empty
4676 : : |----------------|
4677 : : */
4678 : :
4679 : : static void BuildTruncFunction (unsigned int Sym, bool ConstExpr);
4680 : :
4681 : : /*
4682 : : BuildFloatFunction - builds the pseudo procedure call FLOAT.
4683 : : This procedure is actually a "macro" for
4684 : : FLOAT(x) --> CONVERT(REAL, x)
4685 : : However we cannot push tokens back onto the input stack
4686 : : because the compiler is currently building a function
4687 : : call and expecting a ReturnVar on the stack.
4688 : : Hence we manipulate the stack and call
4689 : : BuildConvertFunction.
4690 : :
4691 : : The Stack:
4692 : :
4693 : :
4694 : : Entry Exit
4695 : :
4696 : : Ptr ->
4697 : : +----------------+
4698 : : | NoOfParam |
4699 : : |----------------|
4700 : : | Param 1 |
4701 : : |----------------|
4702 : : | Param 2 |
4703 : : |----------------|
4704 : : . .
4705 : : . .
4706 : : . .
4707 : : |----------------|
4708 : : | Param # |
4709 : : |----------------|
4710 : : | ProcSym | Type | Empty
4711 : : |----------------|
4712 : : */
4713 : :
4714 : : static void BuildFloatFunction (unsigned int Sym, bool ConstExpr);
4715 : :
4716 : : /*
4717 : : BuildReFunction - builds the pseudo procedure call RE.
4718 : :
4719 : : The Stack:
4720 : :
4721 : :
4722 : : Entry Exit
4723 : :
4724 : : Ptr ->
4725 : : +----------------+
4726 : : | NoOfParam |
4727 : : |----------------|
4728 : : | Param 1 |
4729 : : |----------------|
4730 : : | Param 2 |
4731 : : |----------------|
4732 : : . .
4733 : : . .
4734 : : . .
4735 : : |----------------|
4736 : : | Param # |
4737 : : |----------------|
4738 : : | ProcSym | Type | Empty
4739 : : |----------------|
4740 : : */
4741 : :
4742 : : static void BuildReFunction (unsigned int Sym, bool ConstExpr);
4743 : :
4744 : : /*
4745 : : BuildImFunction - builds the pseudo procedure call IM.
4746 : :
4747 : : The Stack:
4748 : :
4749 : :
4750 : : Entry Exit
4751 : :
4752 : : Ptr ->
4753 : : +----------------+
4754 : : | NoOfParam |
4755 : : |----------------|
4756 : : | Param 1 |
4757 : : |----------------|
4758 : : | Param 2 |
4759 : : |----------------|
4760 : : . .
4761 : : . .
4762 : : . .
4763 : : |----------------|
4764 : : | Param # |
4765 : : |----------------|
4766 : : | ProcSym | Type | Empty
4767 : : |----------------|
4768 : : */
4769 : :
4770 : : static void BuildImFunction (unsigned int Sym, bool ConstExpr);
4771 : :
4772 : : /*
4773 : : BuildCmplxFunction - builds the pseudo procedure call CMPLX.
4774 : :
4775 : : The Stack:
4776 : :
4777 : :
4778 : : Entry Exit
4779 : :
4780 : : Ptr ->
4781 : : +----------------+
4782 : : | NoOfParam |
4783 : : |----------------|
4784 : : | Param 1 |
4785 : : |----------------|
4786 : : | Param 2 |
4787 : : |----------------|
4788 : : . .
4789 : : . .
4790 : : . .
4791 : : |----------------|
4792 : : | Param # |
4793 : : |----------------|
4794 : : | ProcSym | Type | Empty
4795 : : |----------------|
4796 : : */
4797 : :
4798 : : static void BuildCmplxFunction (unsigned int func, bool ConstExpr);
4799 : :
4800 : : /*
4801 : : BuildAdrFunction - builds the pseudo function ADR
4802 : : The Stack:
4803 : :
4804 : :
4805 : : Entry Exit
4806 : :
4807 : : Ptr ->
4808 : : +----------------+
4809 : : | NoOfParam |
4810 : : |----------------|
4811 : : | Param 1 |
4812 : : |----------------|
4813 : : | Param 2 |
4814 : : |----------------|
4815 : : . .
4816 : : . .
4817 : : . .
4818 : : |----------------|
4819 : : | Param # | <- Ptr
4820 : : |----------------| +------------+
4821 : : | ProcSym | Type | | ReturnVar |
4822 : : |----------------| |------------|
4823 : :
4824 : : */
4825 : :
4826 : : static void BuildAdrFunction (void);
4827 : :
4828 : : /*
4829 : : BuildSizeFunction - builds the pseudo function SIZE
4830 : : The Stack:
4831 : :
4832 : :
4833 : : Entry Exit
4834 : :
4835 : : Ptr ->
4836 : : +----------------+
4837 : : | NoOfParam |
4838 : : |----------------|
4839 : : | Param 1 |
4840 : : |----------------|
4841 : : | Param 2 |
4842 : : |----------------|
4843 : : . .
4844 : : . .
4845 : : . .
4846 : : |----------------|
4847 : : | Param # | <- Ptr
4848 : : |----------------| +------------+
4849 : : | ProcSym | Type | | ReturnVar |
4850 : : |----------------| |------------|
4851 : : */
4852 : :
4853 : : static void BuildSizeFunction (void);
4854 : :
4855 : : /*
4856 : : BuildTSizeFunction - builds the pseudo function TSIZE
4857 : : The Stack:
4858 : :
4859 : :
4860 : : Entry Exit
4861 : :
4862 : : Ptr ->
4863 : : +----------------+
4864 : : | NoOfParam |
4865 : : |----------------|
4866 : : | Param 1 |
4867 : : |----------------|
4868 : : | Param 2 |
4869 : : |----------------|
4870 : : . .
4871 : : . .
4872 : : . .
4873 : : |----------------|
4874 : : | Param # | <- Ptr
4875 : : |----------------| +------------+
4876 : : | ProcSym | Type | | ReturnVar |
4877 : : |----------------| |------------|
4878 : :
4879 : : */
4880 : :
4881 : : static void BuildTSizeFunction (void);
4882 : :
4883 : : /*
4884 : : BuildTBitSizeFunction - builds the pseudo function TBITSIZE
4885 : : The Stack:
4886 : :
4887 : :
4888 : : Entry Exit
4889 : :
4890 : : Ptr ->
4891 : : +----------------+
4892 : : | NoOfParam |
4893 : : |----------------|
4894 : : | Param 1 |
4895 : : |----------------|
4896 : : | Param 2 |
4897 : : |----------------|
4898 : : . .
4899 : : . .
4900 : : . .
4901 : : |----------------|
4902 : : | Param # | <- Ptr
4903 : : |----------------| +------------+
4904 : : | ProcSym | Type | | ReturnVar |
4905 : : |----------------| |------------|
4906 : :
4907 : : */
4908 : :
4909 : : static void BuildTBitSizeFunction (void);
4910 : :
4911 : : /*
4912 : : ExpectingParameterType -
4913 : : */
4914 : :
4915 : : static void ExpectingParameterType (unsigned int BlockSym, unsigned int Type);
4916 : :
4917 : : /*
4918 : : ExpectingVariableType -
4919 : : */
4920 : :
4921 : : static void ExpectingVariableType (unsigned int BlockSym, unsigned int Type);
4922 : :
4923 : : /*
4924 : : CheckVariablesAndParameterTypesInBlock - checks to make sure that block, BlockSym, has
4925 : : parameters types and variable types which are legal.
4926 : : */
4927 : :
4928 : : static void CheckVariablesAndParameterTypesInBlock (unsigned int BlockSym);
4929 : :
4930 : : /*
4931 : : IsNeverAltered - returns TRUE if variable, sym, is never altered
4932 : : between quadruples: Start..End
4933 : : */
4934 : :
4935 : : static bool IsNeverAltered (unsigned int sym, unsigned int Start, unsigned int End);
4936 : :
4937 : : /*
4938 : : IsConditionVariable - returns TRUE if the condition at quadruple, q, is variable.
4939 : : */
4940 : :
4941 : : static bool IsConditionVariable (unsigned int q, unsigned int Start, unsigned int End);
4942 : :
4943 : : /*
4944 : : IsInfiniteLoop - returns TRUE if an infinite loop is found.
4945 : : Given a backwards jump at, End, it returns a BOOLEAN which depends on
4946 : : whether a jump is found to jump beyond, End. If a conditonal jump is found
4947 : : to pass over, End, the condition is tested for global variables, procedure variables and
4948 : : constants.
4949 : :
4950 : : constant - ignored
4951 : : variables - tested to see whether they are altered inside the loop
4952 : : global variable - the procedure tests to see whether it is altered as above
4953 : : but will also test to see whether this loop calls a procedure
4954 : : in which case it believes the loop NOT to be infinite
4955 : : (as this procedure call might alter the global variable)
4956 : :
4957 : : Note that this procedure can easily be fooled by the user altering variables
4958 : : with pointers.
4959 : : */
4960 : :
4961 : : static bool IsInfiniteLoop (unsigned int End);
4962 : :
4963 : : /*
4964 : : CheckVariablesInBlock - given a block, BlockSym, check whether all variables are used.
4965 : : */
4966 : :
4967 : : static void CheckVariablesInBlock (unsigned int BlockSym);
4968 : :
4969 : : /*
4970 : : CheckFunctionReturn - checks to see that a RETURN statement was present in a function.
4971 : : */
4972 : :
4973 : : static void CheckFunctionReturn (unsigned int ProcSym);
4974 : :
4975 : : /*
4976 : : CheckReturnType - checks to see that the return type from currentProc is
4977 : : assignment compatible with actualType.
4978 : : */
4979 : :
4980 : : static void CheckReturnType (unsigned int tokno, unsigned int currentProc, unsigned int actualVal, unsigned int actualType);
4981 : :
4982 : : /*
4983 : : IsReadOnly - a helper procedure function to detect constants.
4984 : : */
4985 : :
4986 : : static bool IsReadOnly (unsigned int sym);
4987 : :
4988 : : /*
4989 : : BuildDesignatorError - removes the designator from the stack and replaces
4990 : : it with an error symbol.
4991 : : */
4992 : :
4993 : : static void BuildDesignatorError (const char *message_, unsigned int _message_high);
4994 : :
4995 : : /*
4996 : : BuildStaticArray - Builds the array referencing for static arrays.
4997 : : The Stack is expected to contain:
4998 : :
4999 : :
5000 : : Entry Exit
5001 : : ===== ====
5002 : :
5003 : : Ptr ->
5004 : : +--------------+
5005 : : | e | <- Ptr
5006 : : |--------------| +------------+
5007 : : | Sym | Type | | S | T |
5008 : : |--------------| |------------|
5009 : : */
5010 : :
5011 : : static void BuildStaticArray (void);
5012 : :
5013 : : /*
5014 : : calculateMultipicand - generates quadruples which calculate the
5015 : : multiplicand for the array at dimension, dim.
5016 : : */
5017 : :
5018 : : static unsigned int calculateMultipicand (unsigned int tok, unsigned int arraySym, unsigned int arrayType, unsigned int dim);
5019 : :
5020 : : /*
5021 : : ConvertToAddress - convert sym to an address.
5022 : : */
5023 : :
5024 : : static unsigned int ConvertToAddress (unsigned int tokpos, unsigned int sym);
5025 : :
5026 : : /*
5027 : : BuildDynamicArray - Builds the array referencing for dynamic arrays.
5028 : : The Stack is expected to contain:
5029 : :
5030 : :
5031 : : Entry Exit
5032 : : ===== ====
5033 : :
5034 : : Ptr ->
5035 : : +-----------------------+
5036 : : | Index | <- Ptr
5037 : : |-----------------------| +---------------------------+
5038 : : | ArraySym | Type | Dim | | S | T | ArraySym | Dim+1 |
5039 : : |-----------------------| |---------------------------|
5040 : :
5041 : :
5042 : : if Dim=1
5043 : : then
5044 : : S := base of ArraySym + TSIZE(Type)*Index
5045 : : else
5046 : : S := S + TSIZE(Type)*Index
5047 : : fi
5048 : : */
5049 : :
5050 : : static void BuildDynamicArray (void);
5051 : :
5052 : : /*
5053 : : DebugLocation -
5054 : : */
5055 : :
5056 : : static void DebugLocation (unsigned int tok, const char *message_, unsigned int _message_high);
5057 : :
5058 : : /*
5059 : : PushWith - pushes sym and type onto the with stack. It checks for
5060 : : previous declaration of this record type.
5061 : : */
5062 : :
5063 : : static void PushWith (unsigned int Sym, unsigned int Type, unsigned int Ref, unsigned int Tok);
5064 : : static void PopWith (void);
5065 : :
5066 : : /*
5067 : : BuildAccessWithField - similar to BuildDesignatorRecord except it
5068 : : does not perform the address operation.
5069 : : The address will have been computed at the
5070 : : beginning of the WITH statement.
5071 : : It also stops the GenQuad procedure from examining the
5072 : : with stack.
5073 : :
5074 : : The Stack
5075 : :
5076 : : Entry
5077 : :
5078 : : Ptr ->
5079 : : +--------------+
5080 : : | Field | Type1| <- Ptr
5081 : : |-------|------| +-------------+
5082 : : | Adr | Type2| | Sym | Type1|
5083 : : |--------------| |-------------|
5084 : : */
5085 : :
5086 : : static void BuildAccessWithField (void);
5087 : :
5088 : : /*
5089 : : PushConstructor -
5090 : : */
5091 : :
5092 : : static void PushConstructor (unsigned int sym);
5093 : :
5094 : : /*
5095 : : AddFieldTo - adds field, e, to, value.
5096 : : */
5097 : :
5098 : : static unsigned int AddFieldTo (unsigned int value, unsigned int e);
5099 : :
5100 : : /*
5101 : : CheckLogicalOperator - returns a logical operator if the operands imply
5102 : : a logical operation should be performed.
5103 : : */
5104 : :
5105 : : static NameKey_Name CheckLogicalOperator (NameKey_Name Tok, unsigned int left, unsigned int lefttype);
5106 : :
5107 : : /*
5108 : : CheckDivModRem - initiates calls to check the divisor for DIV, MOD, REM
5109 : : expressions.
5110 : : */
5111 : :
5112 : : static void CheckDivModRem (unsigned int TokPos, NameKey_Name tok, unsigned int d, unsigned int e);
5113 : :
5114 : : /*
5115 : : doConvert - convert, sym, to a new symbol with, type.
5116 : : Return the new symbol.
5117 : : */
5118 : :
5119 : : static unsigned int doConvert (unsigned int type, unsigned int sym);
5120 : :
5121 : : /*
5122 : : doBuildBinaryOp - build the binary op, with or without type
5123 : : checking.
5124 : : */
5125 : :
5126 : : static void doBuildBinaryOp (bool checkTypes, bool checkOverflow);
5127 : :
5128 : : /*
5129 : : AreConstant - returns immediate addressing mode if b is true else
5130 : : offset mode is returned. b determines whether the
5131 : : operands are all constant - in which case we can use
5132 : : a constant temporary variable.
5133 : : */
5134 : :
5135 : : static SymbolTable_ModeOfAddr AreConstant (bool b);
5136 : :
5137 : : /*
5138 : : ConvertBooleanToVariable - converts a BoolStack(i) from a Boolean True|False
5139 : : exit pair into a variable containing the value TRUE or
5140 : : FALSE. The parameter i is relative to the top
5141 : : of the stack.
5142 : : */
5143 : :
5144 : : static void ConvertBooleanToVariable (unsigned int tok, unsigned int i);
5145 : :
5146 : : /*
5147 : : DumpQuadSummary -
5148 : : */
5149 : :
5150 : : static void DumpQuadSummary (unsigned int quad);
5151 : :
5152 : : /*
5153 : : BuildRelOpFromBoolean - builds a relational operator sequence of quadruples
5154 : : instead of using a temporary boolean variable.
5155 : : This function can only be used when we perform
5156 : : the following translation:
5157 : :
5158 : : (a=b) # (c=d) alternatively (a=b) = (c=d)
5159 : : ^ ^
5160 : :
5161 : : it only allows # = to be used as >= <= > < all
5162 : : assume a particular value for TRUE and FALSE.
5163 : : (In which case the user should specify ORD)
5164 : :
5165 : :
5166 : : before
5167 : :
5168 : : q if r1 op1 op2 t2
5169 : : q+1 Goto f2
5170 : : ...
5171 : : q+n if r2 op3 op4 t1
5172 : : q+n+1 Goto f1
5173 : :
5174 : : after (in case of =)
5175 : :
5176 : : q if r1 op1 op2 q+2
5177 : : q+1 Goto q+4
5178 : : q+2 if r2 op3 op4 t
5179 : : q+3 Goto f
5180 : : q+4 if r2 op3 op4 f
5181 : : q+5 Goto t
5182 : :
5183 : : after (in case of #)
5184 : :
5185 : : q if r1 op1 op2 q+2
5186 : : q+1 Goto q+n+2
5187 : : q+2 ...
5188 : : ... ...
5189 : : q+n if r2 op3 op4 f
5190 : : q+n+1 Goto t
5191 : : q+n+2 if r2 op3 op4 t
5192 : : q+n+3 Goto f
5193 : :
5194 : : The Stack is expected to contain:
5195 : :
5196 : :
5197 : : Entry Exit
5198 : : ===== ====
5199 : :
5200 : : Ptr ->
5201 : : +------------+
5202 : : | t1 | f1 |
5203 : : |------------|
5204 : : | Operator | <- Ptr
5205 : : |------------| +------------+
5206 : : | t2 | f2 | | t | f |
5207 : : |------------| |------------|
5208 : :
5209 : :
5210 : : */
5211 : :
5212 : : static void BuildRelOpFromBoolean (unsigned int tokpos);
5213 : :
5214 : : /*
5215 : : CheckVariableOrConstantOrProcedure - checks to make sure sym is a variable, constant or procedure.
5216 : : */
5217 : :
5218 : : static void CheckVariableOrConstantOrProcedure (unsigned int tokpos, unsigned int sym);
5219 : :
5220 : : /*
5221 : : MakeOp - returns the equalent quadruple operator to a token, t.
5222 : : */
5223 : :
5224 : : static M2Quads_QuadOperator MakeOp (NameKey_Name t);
5225 : :
5226 : : /*
5227 : : GenQuadO - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
5228 : : */
5229 : :
5230 : : static void GenQuadO (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow);
5231 : :
5232 : : /*
5233 : : GenQuadOTrash - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
5234 : : */
5235 : :
5236 : : static void GenQuadOTrash (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow, unsigned int trash);
5237 : :
5238 : : /*
5239 : : GenQuad - Generate a quadruple with Operation, Op1, Op2, Op3.
5240 : : */
5241 : :
5242 : : static void GenQuad (M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3);
5243 : :
5244 : : /*
5245 : : GenQuadOtok - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
5246 : : */
5247 : :
5248 : : 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);
5249 : :
5250 : : /*
5251 : : GenQuadOTypetok - assigns the fields of the quadruple with
5252 : : the parameters.
5253 : : */
5254 : :
5255 : : 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);
5256 : :
5257 : : /*
5258 : : DumpUntil - dump all quadruples until we seen the ending quadruple
5259 : : with procsym in the third operand.
5260 : : Return the quad number containing the match.
5261 : : */
5262 : :
5263 : : static unsigned int DumpUntil (M2Quads_QuadOperator ending, unsigned int procsym, unsigned int quad);
5264 : :
5265 : : /*
5266 : : GetCtorInit - return the init procedure for the module.
5267 : : */
5268 : :
5269 : : static unsigned int GetCtorInit (unsigned int sym);
5270 : :
5271 : : /*
5272 : : GetCtorFini - return the fini procedure for the module.
5273 : : */
5274 : :
5275 : : static unsigned int GetCtorFini (unsigned int sym);
5276 : :
5277 : : /*
5278 : : DumpQuadrupleFilter -
5279 : : */
5280 : :
5281 : : static void DumpQuadrupleFilter (void);
5282 : :
5283 : : /*
5284 : : DumpQuadrupleAll - dump all quadruples.
5285 : : */
5286 : :
5287 : : static void DumpQuadrupleAll (void);
5288 : :
5289 : : /*
5290 : : BackPatch - Makes each of the quadruples on the list pointed to by
5291 : : QuadNo take quadruple Value as a target.
5292 : : */
5293 : :
5294 : : static void BackPatch (unsigned int QuadNo, unsigned int Value);
5295 : :
5296 : : /*
5297 : : Merge - joins two quad lists, QuadList2 to the end of QuadList1.
5298 : : A QuadList of value zero is a nul list.
5299 : : */
5300 : :
5301 : : static unsigned int Merge (unsigned int QuadList1, unsigned int QuadList2);
5302 : :
5303 : : /*
5304 : : DisplayProcedureAttributes -
5305 : : */
5306 : :
5307 : : static void DisplayProcedureAttributes (unsigned int proc);
5308 : :
5309 : : /*
5310 : : WriteQuad - Writes out the Quad BufferQuad.
5311 : : */
5312 : :
5313 : : static void WriteQuad (unsigned int BufferQuad);
5314 : :
5315 : : /*
5316 : : WriteOperand - displays the operands name, symbol id and mode of addressing.
5317 : : */
5318 : :
5319 : : static void WriteMode (SymbolTable_ModeOfAddr Mode);
5320 : :
5321 : : /*
5322 : : PushExit - pushes the exit value onto the EXIT stack.
5323 : : */
5324 : :
5325 : : static void PushExit (unsigned int Exit);
5326 : :
5327 : : /*
5328 : : PopExit - pops the exit value from the EXIT stack.
5329 : : */
5330 : :
5331 : : static unsigned int PopExit (void);
5332 : :
5333 : : /*
5334 : : PushFor - pushes the exit value onto the FOR stack.
5335 : : */
5336 : :
5337 : : static void PushFor (unsigned int Exit);
5338 : :
5339 : : /*
5340 : : PopFor - pops the exit value from the FOR stack.
5341 : : */
5342 : :
5343 : : static unsigned int PopFor (void);
5344 : :
5345 : : /*
5346 : : OperandTno - returns the ident operand stored in the true position
5347 : : on the boolean stack. This is exactly the same as
5348 : : OperandT but it has no IsBoolean checking.
5349 : : */
5350 : :
5351 : : static unsigned int OperandTno (unsigned int pos);
5352 : :
5353 : : /*
5354 : : OperandFno - returns the ident operand stored in the false position
5355 : : on the boolean stack. This is exactly the same as
5356 : : OperandF but it has no IsBoolean checking.
5357 : : */
5358 : :
5359 : : static unsigned int OperandFno (unsigned int pos);
5360 : :
5361 : : /*
5362 : : OperandTtok - returns the token associated with the position, pos
5363 : : on the boolean stack.
5364 : : */
5365 : :
5366 : : static unsigned int OperandTtok (unsigned int pos);
5367 : :
5368 : : /*
5369 : : PopBooltok - Pops a True and a False exit quad number from the True/False
5370 : : stack.
5371 : : */
5372 : :
5373 : : static void PopBooltok (unsigned int *True, unsigned int *False, unsigned int *tokno);
5374 : :
5375 : : /*
5376 : : PushBooltok - Push a True and a False exit quad numbers onto the
5377 : : True/False stack.
5378 : : */
5379 : :
5380 : : static void PushBooltok (unsigned int True, unsigned int False, unsigned int tokno);
5381 : :
5382 : : /*
5383 : : PopBool - Pops a True and a False exit quad number from the True/False
5384 : : stack.
5385 : : */
5386 : :
5387 : : static void PopBool (unsigned int *True, unsigned int *False);
5388 : :
5389 : : /*
5390 : : PushBool - Push a True and a False exit quad numbers onto the
5391 : : True/False stack.
5392 : : */
5393 : :
5394 : : static void PushBool (unsigned int True, unsigned int False);
5395 : :
5396 : : /*
5397 : : IsBoolean - returns true is the Stack position pos contains a Boolean
5398 : : Exit. False is returned if an Ident is stored.
5399 : : */
5400 : :
5401 : : static bool IsBoolean (unsigned int pos);
5402 : :
5403 : : /*
5404 : : OperandD - returns possible array dimension associated with the ident
5405 : : operand stored on the boolean stack.
5406 : : */
5407 : :
5408 : : static unsigned int OperandD (unsigned int pos);
5409 : :
5410 : : /*
5411 : : OperandRW - returns the rw operand stored on the boolean stack.
5412 : : */
5413 : :
5414 : : static unsigned int OperandRW (unsigned int pos);
5415 : :
5416 : : /*
5417 : : OperandMergeRW - returns the rw operand if not NulSym else it
5418 : : returns True.
5419 : : */
5420 : :
5421 : : static unsigned int OperandMergeRW (unsigned int pos);
5422 : :
5423 : : /*
5424 : : UseLineNote - uses the line note and returns it to the free list.
5425 : : */
5426 : :
5427 : : static void UseLineNote (M2Quads_LineNote l);
5428 : :
5429 : : /*
5430 : : PopLineNo - pops a line note from the line stack.
5431 : : */
5432 : :
5433 : : static M2Quads_LineNote PopLineNo (void);
5434 : :
5435 : : /*
5436 : : InitLineNote - creates a line note and initializes it to
5437 : : contain, file, line.
5438 : : */
5439 : :
5440 : : static M2Quads_LineNote InitLineNote (NameKey_Name file, unsigned int line);
5441 : :
5442 : : /*
5443 : : PushLineNote -
5444 : : */
5445 : :
5446 : : static void PushLineNote (M2Quads_LineNote l);
5447 : :
5448 : : /*
5449 : : BuildStmtNoteTok - adds a nop (with an assigned tokenno location) to the code.
5450 : : */
5451 : :
5452 : : static void BuildStmtNoteTok (unsigned int tokenno);
5453 : :
5454 : : /*
5455 : : GetRecordOrField -
5456 : : */
5457 : :
5458 : : static unsigned int GetRecordOrField (void);
5459 : :
5460 : : /*
5461 : : PushTFAD - Push True, False, Array, Dim, numbers onto the
5462 : : True/False stack. True and False are assumed to
5463 : : contain Symbols or Ident etc.
5464 : : */
5465 : :
5466 : : static void PushTFAD (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim);
5467 : :
5468 : : /*
5469 : : PushTFADtok - Push True, False, Array, Dim, numbers onto the
5470 : : True/False stack. True and False are assumed to
5471 : : contain Symbols or Ident etc.
5472 : : */
5473 : :
5474 : : static void PushTFADtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int tokno);
5475 : :
5476 : : /*
5477 : : PushTFADrwtok - Push True, False, Array, Dim, rw, numbers onto the
5478 : : True/False stack. True and False are assumed to
5479 : : contain Symbols or Ident etc.
5480 : : */
5481 : :
5482 : : static void PushTFADrwtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int rw, unsigned int Tok);
5483 : :
5484 : : /*
5485 : : PopTFrwtok - Pop a True and False number from the True/False stack.
5486 : : True and False are assumed to contain Symbols or Ident etc.
5487 : : */
5488 : :
5489 : : static void PopTFrwtok (unsigned int *True, unsigned int *False, unsigned int *rw, unsigned int *tokno);
5490 : :
5491 : : /*
5492 : : PushTFrwtok - Push an item onto the stack in the T (true) position,
5493 : : it is assummed to be a token and its token location is recorded.
5494 : : */
5495 : :
5496 : : static void PushTFrwtok (unsigned int True, unsigned int False, unsigned int rw, unsigned int tokno);
5497 : :
5498 : : /*
5499 : : PushTFDtok - Push True, False, Dim, numbers onto the
5500 : : True/False stack. True and False are assumed to
5501 : : contain Symbols or Ident etc.
5502 : : */
5503 : :
5504 : : static void PushTFDtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int Tok);
5505 : :
5506 : : /*
5507 : : PopTFDtok - Pop a True, False, Dim number from the True/False stack.
5508 : : True and False are assumed to contain Symbols or Ident etc.
5509 : : */
5510 : :
5511 : : static void PopTFDtok (unsigned int *True, unsigned int *False, unsigned int *Dim, unsigned int *Tok);
5512 : :
5513 : : /*
5514 : : PushTFDrwtok - Push True, False, Dim, numbers onto the
5515 : : True/False stack. True and False are assumed to
5516 : : contain Symbols or Ident etc.
5517 : : */
5518 : :
5519 : : static void PushTFDrwtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int rw, unsigned int Tok);
5520 : :
5521 : : /*
5522 : : PushTFrw - Push a True and False numbers onto the True/False stack.
5523 : : True and False are assumed to contain Symbols or Ident etc.
5524 : : It also pushes the higher level symbol which is associated
5525 : : with the True symbol. Eg record variable or array variable.
5526 : : */
5527 : :
5528 : : static void PushTFrw (unsigned int True, unsigned int False, unsigned int rw);
5529 : :
5530 : : /*
5531 : : PopTFrw - Pop a True and False number from the True/False stack.
5532 : : True and False are assumed to contain Symbols or Ident etc.
5533 : : */
5534 : :
5535 : : static void PopTFrw (unsigned int *True, unsigned int *False, unsigned int *rw);
5536 : :
5537 : : /*
5538 : : newBoolFrame - creates a new BoolFrame with all fields initialised to their defaults.
5539 : : */
5540 : :
5541 : : static M2Quads_BoolFrame newBoolFrame (void);
5542 : :
5543 : : /*
5544 : : PushTrwtok - Push an item onto the True/False stack. The False value will be zero.
5545 : : */
5546 : :
5547 : : static void PushTrwtok (unsigned int True, unsigned int rw, unsigned int tok);
5548 : :
5549 : : /*
5550 : : PopTrw - Pop a True field and rw symbol from the stack.
5551 : : */
5552 : :
5553 : : static void PopTrw (unsigned int *True, unsigned int *rw);
5554 : :
5555 : : /*
5556 : : PopTrwtok - Pop a True field and rw symbol from the stack.
5557 : : */
5558 : :
5559 : : static void PopTrwtok (unsigned int *True, unsigned int *rw, unsigned int *tok);
5560 : :
5561 : : /*
5562 : : Init - initialize the M2Quads module, all the stacks, all the lists
5563 : : and the quads list.
5564 : : */
5565 : :
5566 : : static void Init (void);
5567 : :
5568 : :
5569 : : /*
5570 : : DSdbEnter -
5571 : : */
5572 : :
5573 : 0 : static void DSdbEnter (void)
5574 : : {
5575 : 0 : }
5576 : :
5577 : :
5578 : : /*
5579 : : DSdbExit -
5580 : : */
5581 : :
5582 : 0 : static void DSdbExit (void)
5583 : : {
5584 : 0 : }
5585 : :
5586 : :
5587 : : /*
5588 : : GetQF - returns the QuadFrame associated with, q.
5589 : : */
5590 : :
5591 : 5558812567 : static M2Quads_QuadFrame GetQF (unsigned int q)
5592 : : {
5593 : 0 : return (M2Quads_QuadFrame) (Indexing_GetIndice (QuadArray, q));
5594 : : /* static analysis guarentees a RETURN statement will be used before here. */
5595 : : __builtin_unreachable ();
5596 : : }
5597 : :
5598 : :
5599 : : /*
5600 : : IsQuadA - returns true if QuadNo is a op.
5601 : : */
5602 : :
5603 : 627593982 : static bool IsQuadA (unsigned int QuadNo, M2Quads_QuadOperator op)
5604 : : {
5605 : 627593982 : M2Quads_QuadFrame f;
5606 : :
5607 : 0 : f = GetQF (QuadNo);
5608 : 627593982 : return f->Operator == op;
5609 : : /* static analysis guarentees a RETURN statement will be used before here. */
5610 : : __builtin_unreachable ();
5611 : : }
5612 : :
5613 : :
5614 : : /*
5615 : : OpUsesOp1 - return TRUE if op allows op1.
5616 : : */
5617 : :
5618 : 315619 : static bool OpUsesOp1 (M2Quads_QuadOperator op)
5619 : : {
5620 : 315619 : switch (op)
5621 : : {
5622 : : case M2Quads_StringConvertCnulOp:
5623 : : case M2Quads_StringConvertM2nulOp:
5624 : : case M2Quads_StringLengthOp:
5625 : : case M2Quads_InclOp:
5626 : : case M2Quads_ExclOp:
5627 : : case M2Quads_UnboundedOp:
5628 : : case M2Quads_FunctValueOp:
5629 : : case M2Quads_NegateOp:
5630 : : case M2Quads_BecomesOp:
5631 : : case M2Quads_HighOp:
5632 : : case M2Quads_SizeOp:
5633 : : case M2Quads_AddrOp:
5634 : : case M2Quads_RecordFieldOp:
5635 : : case M2Quads_ArrayOp:
5636 : : case M2Quads_LogicalShiftOp:
5637 : : case M2Quads_LogicalRotateOp:
5638 : : case M2Quads_LogicalOrOp:
5639 : : case M2Quads_LogicalAndOp:
5640 : : case M2Quads_LogicalXorOp:
5641 : : case M2Quads_CoerceOp:
5642 : : case M2Quads_ConvertOp:
5643 : : case M2Quads_CastOp:
5644 : : case M2Quads_AddOp:
5645 : : case M2Quads_SubOp:
5646 : : case M2Quads_MultOp:
5647 : : case M2Quads_ModFloorOp:
5648 : : case M2Quads_DivCeilOp:
5649 : : case M2Quads_ModCeilOp:
5650 : : case M2Quads_DivFloorOp:
5651 : : case M2Quads_ModTruncOp:
5652 : : case M2Quads_DivTruncOp:
5653 : : case M2Quads_DivM2Op:
5654 : : case M2Quads_ModM2Op:
5655 : : case M2Quads_XIndrOp:
5656 : : case M2Quads_IndrXOp:
5657 : : case M2Quads_SaveExceptionOp:
5658 : : case M2Quads_RestoreExceptionOp:
5659 : : return true;
5660 : 58918 : break;
5661 : :
5662 : :
5663 : 58918 : default:
5664 : 58918 : return false;
5665 : : break;
5666 : : }
5667 : : /* static analysis guarentees a RETURN statement will be used before here. */
5668 : : __builtin_unreachable ();
5669 : : }
5670 : :
5671 : :
5672 : : /*
5673 : : AddQuadInformation - adds variable analysis and jump analysis to the new quadruple.
5674 : : */
5675 : :
5676 : 4946579 : static void AddQuadInformation (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
5677 : : {
5678 : 4946579 : switch (Op)
5679 : : {
5680 : 148589 : case M2Quads_IfInOp:
5681 : 148589 : case M2Quads_IfNotInOp:
5682 : 148589 : case M2Quads_IfEquOp:
5683 : 148589 : case M2Quads_IfNotEquOp:
5684 : 148589 : case M2Quads_IfLessOp:
5685 : 148589 : case M2Quads_IfLessEquOp:
5686 : 148589 : case M2Quads_IfGreOp:
5687 : 148589 : case M2Quads_IfGreEquOp:
5688 : 148589 : ManipulateReference (QuadNo, Oper3);
5689 : 148589 : CheckAddVariableRead (Oper1, false, QuadNo);
5690 : 148589 : CheckAddVariableRead (Oper2, false, QuadNo);
5691 : 148589 : break;
5692 : :
5693 : 2130 : case M2Quads_LastForIteratorOp:
5694 : 2130 : CheckAddVariableWrite (Oper1, false, QuadNo);
5695 : 2130 : CheckAddTuple2Read (Oper2, false, QuadNo);
5696 : 2130 : CheckAddVariableRead (Oper3, false, QuadNo);
5697 : 2130 : break;
5698 : :
5699 : 151451 : case M2Quads_TryOp:
5700 : 151451 : case M2Quads_RetryOp:
5701 : 151451 : case M2Quads_GotoOp:
5702 : 151451 : ManipulateReference (QuadNo, Oper3);
5703 : 151451 : break;
5704 : :
5705 : 1290 : case M2Quads_InclOp:
5706 : 1290 : case M2Quads_ExclOp:
5707 : : /* variable references */
5708 : 1290 : CheckConst (Oper1);
5709 : 1290 : CheckAddVariableRead (Oper3, false, QuadNo);
5710 : 1290 : CheckAddVariableWrite (Oper1, true, QuadNo);
5711 : 1290 : break;
5712 : :
5713 : 561235 : case M2Quads_UnboundedOp:
5714 : 561235 : case M2Quads_FunctValueOp:
5715 : 561235 : case M2Quads_NegateOp:
5716 : 561235 : case M2Quads_BecomesOp:
5717 : 561235 : case M2Quads_HighOp:
5718 : 561235 : case M2Quads_SizeOp:
5719 : 561235 : CheckConst (Oper1);
5720 : 561235 : CheckAddVariableWrite (Oper1, false, QuadNo);
5721 : 561235 : CheckAddVariableRead (Oper3, false, QuadNo);
5722 : 561235 : break;
5723 : :
5724 : 186514 : case M2Quads_AddrOp:
5725 : 186514 : CheckConst (Oper1);
5726 : 186514 : CheckAddVariableWrite (Oper1, false, QuadNo);
5727 : : /* the next line is a kludge and assumes we _will_
5728 : : write to the variable as we have taken its address */
5729 : 186514 : CheckRemoveVariableWrite (Oper1, true, QuadNo);
5730 : 186514 : break;
5731 : :
5732 : 19044 : case M2Quads_ReturnValueOp:
5733 : 19044 : CheckAddVariableRead (Oper1, false, QuadNo);
5734 : 19044 : break;
5735 : :
5736 : : case M2Quads_ReturnOp:
5737 : : case M2Quads_NewLocalVarOp:
5738 : : case M2Quads_KillLocalVarOp:
5739 : : break;
5740 : :
5741 : 190437 : case M2Quads_CallOp:
5742 : 190437 : CheckAddVariableRead (Oper3, true, QuadNo);
5743 : 190437 : break;
5744 : :
5745 : 538605 : case M2Quads_ParamOp:
5746 : 538605 : CheckAddVariableRead (Oper2, false, QuadNo);
5747 : 538605 : CheckAddVariableRead (Oper3, false, QuadNo);
5748 : 538605 : if (((Oper1 > 0) && (Oper1 <= (SymbolTable_NoOfParamAny (Oper2)))) && (SymbolTable_IsVarParamAny (Oper2, Oper1)))
5749 : : {
5750 : : /* _may_ also write to a var parameter, although we dont know */
5751 : 18890 : CheckAddVariableWrite (Oper3, true, QuadNo);
5752 : : }
5753 : : break;
5754 : :
5755 : 295821 : case M2Quads_RecordFieldOp:
5756 : 295821 : case M2Quads_ArrayOp:
5757 : 295821 : case M2Quads_LogicalShiftOp:
5758 : 295821 : case M2Quads_LogicalRotateOp:
5759 : 295821 : case M2Quads_LogicalOrOp:
5760 : 295821 : case M2Quads_LogicalAndOp:
5761 : 295821 : case M2Quads_LogicalXorOp:
5762 : 295821 : case M2Quads_CoerceOp:
5763 : 295821 : case M2Quads_ConvertOp:
5764 : 295821 : case M2Quads_CastOp:
5765 : 295821 : case M2Quads_AddOp:
5766 : 295821 : case M2Quads_SubOp:
5767 : 295821 : case M2Quads_MultOp:
5768 : 295821 : case M2Quads_DivM2Op:
5769 : 295821 : case M2Quads_ModM2Op:
5770 : 295821 : case M2Quads_ModFloorOp:
5771 : 295821 : case M2Quads_DivCeilOp:
5772 : 295821 : case M2Quads_ModCeilOp:
5773 : 295821 : case M2Quads_DivFloorOp:
5774 : 295821 : case M2Quads_ModTruncOp:
5775 : 295821 : case M2Quads_DivTruncOp:
5776 : 295821 : CheckConst (Oper1);
5777 : 295821 : CheckAddVariableWrite (Oper1, false, QuadNo);
5778 : 295821 : CheckAddVariableRead (Oper2, false, QuadNo);
5779 : 295821 : CheckAddVariableRead (Oper3, false, QuadNo);
5780 : 295821 : break;
5781 : :
5782 : 35770 : case M2Quads_XIndrOp:
5783 : 35770 : CheckConst (Oper1);
5784 : 35770 : CheckAddVariableWrite (Oper1, true, QuadNo);
5785 : 35770 : CheckAddVariableRead (Oper3, false, QuadNo);
5786 : 35770 : break;
5787 : :
5788 : 15299 : case M2Quads_IndrXOp:
5789 : 15299 : CheckConst (Oper1);
5790 : 15299 : CheckAddVariableWrite (Oper1, false, QuadNo);
5791 : 15299 : CheckAddVariableRead (Oper3, true, QuadNo);
5792 : 15299 : break;
5793 : :
5794 : 2690 : case M2Quads_SaveExceptionOp:
5795 : : /* RangeCheckOp : CheckRangeAddVariableRead(Oper3, QuadNo) | */
5796 : 2690 : CheckConst (Oper1);
5797 : 2690 : CheckAddVariableWrite (Oper1, false, QuadNo);
5798 : 2690 : break;
5799 : :
5800 : 2804 : case M2Quads_RestoreExceptionOp:
5801 : 2804 : CheckAddVariableRead (Oper1, false, QuadNo);
5802 : 2804 : break;
5803 : :
5804 : :
5805 : : default:
5806 : : break;
5807 : : }
5808 : 4946579 : }
5809 : :
5810 : 0 : static void stop (void)
5811 : : {
5812 : 0 : }
5813 : :
5814 : :
5815 : : /*
5816 : : CheckBreak - check whether QuadNo = BreakAtQuad and if so call stop.
5817 : : */
5818 : :
5819 : 0 : static void CheckBreak (unsigned int QuadNo)
5820 : : {
5821 : 0 : if (QuadNo == BreakAtQuad)
5822 : : {
5823 : 0 : stop ();
5824 : : }
5825 : 0 : }
5826 : :
5827 : :
5828 : : /*
5829 : : PutQuadO - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
5830 : : sets a boolean to determinine whether overflow should be checked.
5831 : : */
5832 : :
5833 : 4136139 : static void PutQuadO (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow)
5834 : : {
5835 : 0 : PutQuadOType (QuadNo, Op, Oper1, Oper2, Oper3, overflow, true);
5836 : 0 : }
5837 : :
5838 : :
5839 : : /*
5840 : : PutQuadOType -
5841 : : */
5842 : :
5843 : 4878391 : static void PutQuadOType (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow, bool checktype)
5844 : : {
5845 : 4878391 : M2Quads_QuadFrame f;
5846 : :
5847 : 4878391 : if (QuadrupleGeneration)
5848 : : {
5849 : 4878391 : M2Quads_EraseQuad (QuadNo);
5850 : 4878391 : AddQuadInformation (QuadNo, Op, Oper1, Oper2, Oper3);
5851 : 4878391 : f = GetQF (QuadNo);
5852 : 4878391 : f->Operator = Op;
5853 : 4878391 : f->Operand1 = Oper1;
5854 : 4878391 : f->Operand2 = Oper2;
5855 : 4878391 : f->Operand3 = Oper3;
5856 : 4878391 : f->CheckOverflow = overflow;
5857 : 4878391 : f->CheckType = checktype;
5858 : 4878391 : f->ConstExpr = false; /* IsInConstExpression () */
5859 : : }
5860 : : /* IsInConstExpression () */
5861 : 4878391 : }
5862 : :
5863 : :
5864 : : /*
5865 : : UndoReadWriteInfo -
5866 : : */
5867 : :
5868 : 6247101 : static void UndoReadWriteInfo (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
5869 : : {
5870 : 6247101 : switch (Op)
5871 : : {
5872 : 79895 : case M2Quads_IfInOp:
5873 : 79895 : case M2Quads_IfNotInOp:
5874 : 79895 : case M2Quads_IfEquOp:
5875 : 79895 : case M2Quads_IfNotEquOp:
5876 : 79895 : case M2Quads_IfLessOp:
5877 : 79895 : case M2Quads_IfLessEquOp:
5878 : 79895 : case M2Quads_IfGreOp:
5879 : 79895 : case M2Quads_IfGreEquOp:
5880 : : /* jumps, calls and branches */
5881 : 79895 : RemoveReference (QuadNo);
5882 : 79895 : CheckRemoveVariableRead (Oper1, false, QuadNo);
5883 : 79895 : CheckRemoveVariableRead (Oper2, false, QuadNo);
5884 : 79895 : break;
5885 : :
5886 : 109539 : case M2Quads_TryOp:
5887 : 109539 : case M2Quads_RetryOp:
5888 : 109539 : case M2Quads_GotoOp:
5889 : 109539 : RemoveReference (QuadNo);
5890 : 109539 : break;
5891 : :
5892 : 0 : case M2Quads_InclOp:
5893 : 0 : case M2Quads_ExclOp:
5894 : : /* variable references */
5895 : 0 : CheckRemoveVariableRead (Oper1, false, QuadNo);
5896 : 0 : CheckRemoveVariableWrite (Oper1, true, QuadNo);
5897 : 0 : break;
5898 : :
5899 : 273984 : case M2Quads_UnboundedOp:
5900 : 273984 : case M2Quads_FunctValueOp:
5901 : 273984 : case M2Quads_NegateOp:
5902 : 273984 : case M2Quads_BecomesOp:
5903 : 273984 : case M2Quads_HighOp:
5904 : 273984 : case M2Quads_SizeOp:
5905 : 273984 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
5906 : 273984 : CheckRemoveVariableRead (Oper3, false, QuadNo);
5907 : 273984 : break;
5908 : :
5909 : 842 : case M2Quads_AddrOp:
5910 : 842 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
5911 : : /* the next line is a kludge and assumes we _will_
5912 : : write to the variable as we have taken its address */
5913 : 842 : CheckRemoveVariableWrite (Oper1, true, QuadNo);
5914 : 842 : break;
5915 : :
5916 : 72 : case M2Quads_ReturnValueOp:
5917 : 72 : CheckRemoveVariableRead (Oper1, false, QuadNo);
5918 : 72 : break;
5919 : :
5920 : : case M2Quads_ReturnOp:
5921 : : case M2Quads_CallOp:
5922 : : case M2Quads_NewLocalVarOp:
5923 : : case M2Quads_KillLocalVarOp:
5924 : : break;
5925 : :
5926 : 4870 : case M2Quads_ParamOp:
5927 : 4870 : CheckRemoveVariableRead (Oper2, false, QuadNo);
5928 : 4870 : CheckRemoveVariableRead (Oper3, false, QuadNo);
5929 : 4870 : if (((Oper1 > 0) && (Oper1 <= (SymbolTable_NoOfParamAny (Oper2)))) && (SymbolTable_IsVarParamAny (Oper2, Oper1)))
5930 : : {
5931 : : /* _may_ also write to a var parameter, although we dont know */
5932 : 88 : CheckRemoveVariableWrite (Oper3, true, QuadNo);
5933 : : }
5934 : : break;
5935 : :
5936 : 28739 : case M2Quads_RecordFieldOp:
5937 : 28739 : case M2Quads_ArrayOp:
5938 : 28739 : case M2Quads_LogicalShiftOp:
5939 : 28739 : case M2Quads_LogicalRotateOp:
5940 : 28739 : case M2Quads_LogicalOrOp:
5941 : 28739 : case M2Quads_LogicalAndOp:
5942 : 28739 : case M2Quads_LogicalXorOp:
5943 : 28739 : case M2Quads_CoerceOp:
5944 : 28739 : case M2Quads_ConvertOp:
5945 : 28739 : case M2Quads_CastOp:
5946 : 28739 : case M2Quads_AddOp:
5947 : 28739 : case M2Quads_SubOp:
5948 : 28739 : case M2Quads_MultOp:
5949 : 28739 : case M2Quads_DivM2Op:
5950 : 28739 : case M2Quads_ModM2Op:
5951 : 28739 : case M2Quads_ModFloorOp:
5952 : 28739 : case M2Quads_DivCeilOp:
5953 : 28739 : case M2Quads_ModCeilOp:
5954 : 28739 : case M2Quads_DivFloorOp:
5955 : 28739 : case M2Quads_ModTruncOp:
5956 : 28739 : case M2Quads_DivTruncOp:
5957 : 28739 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
5958 : 28739 : CheckRemoveVariableRead (Oper2, false, QuadNo);
5959 : 28739 : CheckRemoveVariableRead (Oper3, false, QuadNo);
5960 : 28739 : break;
5961 : :
5962 : 4 : case M2Quads_XIndrOp:
5963 : 4 : CheckRemoveVariableWrite (Oper1, true, QuadNo);
5964 : 4 : CheckRemoveVariableRead (Oper3, false, QuadNo);
5965 : 4 : break;
5966 : :
5967 : 360 : case M2Quads_IndrXOp:
5968 : 360 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
5969 : 360 : CheckRemoveVariableRead (Oper3, true, QuadNo);
5970 : 360 : break;
5971 : :
5972 : 0 : case M2Quads_SaveExceptionOp:
5973 : : /* RangeCheckOp : CheckRangeRemoveVariableRead(Oper3, QuadNo) | */
5974 : 0 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
5975 : 0 : break;
5976 : :
5977 : 174 : case M2Quads_RestoreExceptionOp:
5978 : 174 : CheckRemoveVariableRead (Oper1, false, QuadNo);
5979 : 174 : break;
5980 : :
5981 : :
5982 : : default:
5983 : : break;
5984 : : }
5985 : 6247101 : }
5986 : :
5987 : :
5988 : : /*
5989 : : CheckAddTuple2Read - checks to see whether symbol tuple contains variables or
5990 : : parameters and if so it then adds them to the quadruple
5991 : : variable list.
5992 : : */
5993 : :
5994 : 2130 : static void CheckAddTuple2Read (unsigned int tuple, bool canDereference, unsigned int Quad)
5995 : : {
5996 : 2130 : if (SymbolTable_IsTuple (tuple))
5997 : : {
5998 : 2130 : CheckAddVariableRead (SymbolTable_GetNth (tuple, 1), canDereference, Quad);
5999 : 2130 : CheckAddVariableRead (SymbolTable_GetNth (tuple, 2), canDereference, Quad);
6000 : : }
6001 : 2130 : }
6002 : :
6003 : :
6004 : : /*
6005 : : CheckAddVariableRead - checks to see whether symbol, Sym, is a variable or
6006 : : a parameter and if so it then adds this quadruple
6007 : : to the variable list.
6008 : : */
6009 : :
6010 : 2798299 : static void CheckAddVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad)
6011 : : {
6012 : 2798299 : if (SymbolTable_IsVar (Sym))
6013 : : {
6014 : 1015113 : SymbolTable_PutReadQuad (Sym, SymbolTable_GetMode (Sym), Quad);
6015 : 1015113 : if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
6016 : : {
6017 : 15367 : SymbolTable_PutReadQuad (Sym, SymbolTable_RightValue, Quad);
6018 : : }
6019 : : }
6020 : 2798299 : }
6021 : :
6022 : :
6023 : : /*
6024 : : CheckRemoveVariableRead - checks to see whether, Sym, is a variable or
6025 : : a parameter and if so then it removes the
6026 : : quadruple from the variable list.
6027 : : */
6028 : :
6029 : 501602 : static void CheckRemoveVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad)
6030 : : {
6031 : 501602 : if (SymbolTable_IsVar (Sym))
6032 : : {
6033 : 94573 : SymbolTable_RemoveReadQuad (Sym, SymbolTable_GetMode (Sym), Quad);
6034 : 94573 : if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
6035 : : {
6036 : 360 : SymbolTable_RemoveReadQuad (Sym, SymbolTable_RightValue, Quad);
6037 : : }
6038 : : }
6039 : 501602 : }
6040 : :
6041 : :
6042 : : /*
6043 : : CheckAddVariableWrite - checks to see whether symbol, Sym, is a variable and
6044 : : if so it then adds this quadruple to the variable list.
6045 : : */
6046 : :
6047 : 1119639 : static void CheckAddVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad)
6048 : : {
6049 : 1119639 : if (SymbolTable_IsVar (Sym))
6050 : : {
6051 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
6052 : 820856 : if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
6053 : : {
6054 : 50580 : SymbolTable_PutReadQuad (Sym, SymbolTable_LeftValue, Quad);
6055 : 50580 : SymbolTable_PutWriteQuad (Sym, SymbolTable_RightValue, Quad);
6056 : : }
6057 : : else
6058 : : {
6059 : 770276 : SymbolTable_PutWriteQuad (Sym, SymbolTable_GetMode (Sym), Quad);
6060 : : }
6061 : : }
6062 : 1119639 : }
6063 : :
6064 : :
6065 : : /*
6066 : : CheckRemoveVariableWrite - checks to see whether, Sym, is a variable and
6067 : : if so then it removes the quadruple from the
6068 : : variable list.
6069 : : */
6070 : :
6071 : 491373 : static void CheckRemoveVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad)
6072 : : {
6073 : 491373 : if (SymbolTable_IsVar (Sym))
6074 : : {
6075 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
6076 : 193640 : if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
6077 : : {
6078 : 9926 : SymbolTable_RemoveReadQuad (Sym, SymbolTable_LeftValue, Quad);
6079 : 9926 : SymbolTable_RemoveWriteQuad (Sym, SymbolTable_RightValue, Quad);
6080 : : }
6081 : : else
6082 : : {
6083 : 183714 : SymbolTable_RemoveWriteQuad (Sym, SymbolTable_GetMode (Sym), Quad);
6084 : : }
6085 : : }
6086 : 491373 : }
6087 : :
6088 : :
6089 : : /*
6090 : : CheckConst -
6091 : : */
6092 : :
6093 : 1098619 : static void CheckConst (unsigned int sym)
6094 : : {
6095 : 1098619 : if (SymbolTable_IsConst (sym))
6096 : : {
6097 : 297213 : M2GCCDeclare_PutToBeSolvedByQuads (sym);
6098 : : }
6099 : 1098619 : }
6100 : :
6101 : :
6102 : : /*
6103 : : AlterReference - alters all references from OldQuad, to NewQuad in a
6104 : : quadruple list Head.
6105 : : */
6106 : :
6107 : 1300522 : static void AlterReference (unsigned int Head, unsigned int OldQuad, unsigned int NewQuad)
6108 : : {
6109 : 1300522 : M2Quads_QuadFrame f;
6110 : 1300522 : M2Quads_QuadFrame g;
6111 : 1300522 : unsigned int i;
6112 : :
6113 : 1300522 : f = GetQF (OldQuad);
6114 : 9206896 : while ((f->NoOfTimesReferenced > 0) && (Head != 0))
6115 : : {
6116 : 6605852 : g = GetQF (Head);
6117 : 6605852 : switch (g->Operator)
6118 : : {
6119 : 317026 : case M2Quads_IfInOp:
6120 : 317026 : case M2Quads_IfNotInOp:
6121 : 317026 : case M2Quads_IfEquOp:
6122 : 317026 : case M2Quads_IfNotEquOp:
6123 : 317026 : case M2Quads_IfLessOp:
6124 : 317026 : case M2Quads_IfLessEquOp:
6125 : 317026 : case M2Quads_IfGreOp:
6126 : 317026 : case M2Quads_IfGreEquOp:
6127 : 317026 : case M2Quads_TryOp:
6128 : 317026 : case M2Quads_RetryOp:
6129 : 317026 : case M2Quads_GotoOp:
6130 : 317026 : if (g->Operand3 == OldQuad)
6131 : : {
6132 : 8428 : ManipulateReference (Head, NewQuad);
6133 : : }
6134 : : break;
6135 : :
6136 : :
6137 : : default:
6138 : : break;
6139 : : }
6140 : 6605852 : i = g->Next;
6141 : 6605852 : Head = i;
6142 : : }
6143 : 1300522 : }
6144 : :
6145 : :
6146 : : /*
6147 : : GrowQuads - grows the list of quadruples to the quadruple, to.
6148 : : */
6149 : :
6150 : 531439 : static void GrowQuads (unsigned int to)
6151 : : {
6152 : 531439 : unsigned int i;
6153 : 531439 : M2Quads_QuadFrame f;
6154 : :
6155 : 531439 : if ((to != 0) && (to > GrowInitialization))
6156 : : {
6157 : 8778 : i = GrowInitialization+1;
6158 : 17556 : while (i <= to)
6159 : : {
6160 : 8778 : if (Indexing_InBounds (QuadArray, i))
6161 : : {
6162 : 0 : M2Debug_Assert ((Indexing_GetIndice (QuadArray, i)) != NULL);
6163 : : }
6164 : : else
6165 : : {
6166 : 8778 : Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T3));
6167 : 8778 : if (f == NULL)
6168 : : {
6169 : 0 : M2Error_InternalError ((const char *) "out of memory error when trying to allocate a quadruple", 55);
6170 : : }
6171 : 8778 : Indexing_PutIndice (QuadArray, i, reinterpret_cast <void *> (f));
6172 : 8778 : f->NoOfTimesReferenced = 0;
6173 : : }
6174 : 8778 : i += 1;
6175 : : }
6176 : 8778 : GrowInitialization = to;
6177 : : }
6178 : 531439 : }
6179 : :
6180 : :
6181 : : /*
6182 : : ManipulateReference - manipulates the quadruple, q, so that it now points to quad, to.
6183 : : */
6184 : :
6185 : 531439 : static void ManipulateReference (unsigned int q, unsigned int to)
6186 : : {
6187 : 531439 : M2Quads_QuadFrame f;
6188 : :
6189 : 1062878 : M2Debug_Assert ((GrowInitialization >= q) || (to == 0));
6190 : 531439 : GrowQuads (to);
6191 : 531439 : RemoveReference (q);
6192 : 531439 : f = GetQF (q);
6193 : 531439 : f->Operand3 = to;
6194 : 531439 : if (to != 0)
6195 : : {
6196 : 338448 : f = GetQF (to);
6197 : 338448 : f->NoOfTimesReferenced += 1;
6198 : : }
6199 : 531439 : }
6200 : :
6201 : :
6202 : : /*
6203 : : RemoveReference - remove the reference by quadruple q to wherever
6204 : : it was pointing.
6205 : : */
6206 : :
6207 : 720873 : static void RemoveReference (unsigned int q)
6208 : : {
6209 : 720873 : M2Quads_QuadFrame f;
6210 : 720873 : M2Quads_QuadFrame g;
6211 : :
6212 : 720873 : f = GetQF (q);
6213 : 720873 : if ((f->Operand3 != 0) && (f->Operand3 < NextQuad))
6214 : : {
6215 : 227842 : CheckBreak (f->Operand3);
6216 : 227842 : g = GetQF (f->Operand3);
6217 : 227842 : M2Debug_Assert (g->NoOfTimesReferenced != 0);
6218 : 227842 : g->NoOfTimesReferenced -= 1;
6219 : : }
6220 : 720873 : }
6221 : :
6222 : :
6223 : : /*
6224 : : NewQuad - sets QuadNo to a new quadruple.
6225 : : */
6226 : :
6227 : 4882340 : static void NewQuad (unsigned int *QuadNo)
6228 : : {
6229 : 4882340 : M2Quads_QuadFrame f;
6230 : :
6231 : 4882340 : (*QuadNo) = FreeList;
6232 : 4882340 : if ((Indexing_InBounds (QuadArray, (*QuadNo))) && ((Indexing_GetIndice (QuadArray, (*QuadNo))) != NULL))
6233 : : {
6234 : 8778 : f = static_cast<M2Quads_QuadFrame> (Indexing_GetIndice (QuadArray, (*QuadNo)));
6235 : : }
6236 : : else
6237 : : {
6238 : 4873562 : Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T3));
6239 : 4873562 : if (f == NULL)
6240 : : {
6241 : 0 : M2Error_InternalError ((const char *) "out of memory error trying to allocate a quadruple", 50);
6242 : : }
6243 : : else
6244 : : {
6245 : 4873562 : NoOfQuads += 1;
6246 : 4873562 : Indexing_PutIndice (QuadArray, (*QuadNo), reinterpret_cast <void *> (f));
6247 : 4873562 : f->NoOfTimesReferenced = 0;
6248 : : }
6249 : : }
6250 : 4882340 : f->Operator = M2Quads_DummyOp;
6251 : 4882340 : f->Operand3 = 0;
6252 : 4882340 : f->Next = 0;
6253 : 4882340 : FreeList += 1;
6254 : 4882340 : if (GrowInitialization < FreeList)
6255 : : {
6256 : 4873562 : GrowInitialization = FreeList;
6257 : : }
6258 : 4882340 : }
6259 : :
6260 : :
6261 : : /*
6262 : : CheckVariableAt - checks to see whether, sym, was declared at a particular address.
6263 : : */
6264 : :
6265 : 2588850 : static void CheckVariableAt (unsigned int sym)
6266 : : {
6267 : 2588850 : if ((SymbolTable_IsVar (sym)) && (SymbolTable_IsVariableAtAddress (sym)))
6268 : : {
6269 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
6270 : 54 : if ((SymbolTable_GetMode (sym)) == SymbolTable_LeftValue)
6271 : : {
6272 : 54 : GenQuad (M2Quads_InitAddressOp, sym, SymbolTable_NulSym, SymbolTable_GetVariableAtAddress (sym));
6273 : : }
6274 : : else
6275 : : {
6276 : 0 : M2Error_InternalError ((const char *) "expecting lvalue for this variable which is declared at an explicit address", 75);
6277 : : }
6278 : : }
6279 : 2588850 : }
6280 : :
6281 : :
6282 : : /*
6283 : : CheckVariablesAt - checks to see whether we need to initialize any pointers
6284 : : which point to variable declared at addresses.
6285 : : */
6286 : :
6287 : 136384 : static void CheckVariablesAt (unsigned int scope)
6288 : : {
6289 : 0 : SymbolTable_ForeachLocalSymDo (scope, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) CheckVariableAt});
6290 : 0 : }
6291 : :
6292 : :
6293 : : /*
6294 : : GetTurnInterrupts - returns the TurnInterrupts procedure function.
6295 : : */
6296 : :
6297 : 840 : static unsigned int GetTurnInterrupts (unsigned int tok)
6298 : : {
6299 : 840 : if (M2Options_Iso)
6300 : : {
6301 : 0 : return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "TurnInterrupts", 14), NameKey_MakeKey ((const char *) "COROUTINES", 10));
6302 : : }
6303 : : else
6304 : : {
6305 : 840 : return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "TurnInterrupts", 14), NameKey_MakeKey ((const char *) "SYSTEM", 6));
6306 : : }
6307 : : /* static analysis guarentees a RETURN statement will be used before here. */
6308 : : __builtin_unreachable ();
6309 : : }
6310 : :
6311 : :
6312 : : /*
6313 : : GetProtection - returns the PROTECTION data type.
6314 : : */
6315 : :
6316 : 420 : static unsigned int GetProtection (unsigned int tok)
6317 : : {
6318 : 420 : if (M2Options_Iso)
6319 : : {
6320 : 0 : return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "PROTECTION", 10), NameKey_MakeKey ((const char *) "COROUTINES", 10));
6321 : : }
6322 : : else
6323 : : {
6324 : 420 : return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "PROTECTION", 10), NameKey_MakeKey ((const char *) "SYSTEM", 6));
6325 : : }
6326 : : /* static analysis guarentees a RETURN statement will be used before here. */
6327 : : __builtin_unreachable ();
6328 : : }
6329 : :
6330 : :
6331 : : /*
6332 : : CheckNeedPriorityBegin - checks to see whether we need to save the old
6333 : : module priority and change to another module
6334 : : priority.
6335 : : The current module initialization or procedure
6336 : : being built is defined by, scope. The module whose
6337 : : priority will be used is defined by, module.
6338 : : */
6339 : :
6340 : 152029 : static void CheckNeedPriorityBegin (unsigned int tok, unsigned int scope, unsigned int module)
6341 : : {
6342 : 152029 : unsigned int ProcSym;
6343 : 152029 : unsigned int old;
6344 : :
6345 : 152029 : if ((SymbolTable_GetPriority (module)) != SymbolTable_NulSym)
6346 : : {
6347 : : /* module has been given a priority */
6348 : 420 : ProcSym = GetTurnInterrupts (tok);
6349 : 420 : if (ProcSym != SymbolTable_NulSym)
6350 : : {
6351 : 420 : old = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
6352 : 420 : SymbolTable_PutVar (old, GetProtection (tok));
6353 : 840 : GenQuadO (tok, M2Quads_SavePriorityOp, old, scope, ProcSym, false);
6354 : 420 : M2StackWord_PushWord (PriorityStack, old);
6355 : : }
6356 : : }
6357 : 152029 : }
6358 : :
6359 : :
6360 : : /*
6361 : : CheckNeedPriorityEnd - checks to see whether we need to restore the old
6362 : : module priority.
6363 : : The current module initialization or procedure
6364 : : being built is defined by, scope.
6365 : : */
6366 : :
6367 : 151867 : static void CheckNeedPriorityEnd (unsigned int tok, unsigned int scope, unsigned int module)
6368 : : {
6369 : 151867 : unsigned int ProcSym;
6370 : 151867 : unsigned int old;
6371 : :
6372 : 151867 : if ((SymbolTable_GetPriority (module)) != SymbolTable_NulSym)
6373 : : {
6374 : : /* module has been given a priority */
6375 : 420 : ProcSym = GetTurnInterrupts (tok);
6376 : 420 : if (ProcSym != SymbolTable_NulSym)
6377 : : {
6378 : 420 : old = static_cast<unsigned int> (M2StackWord_PopWord (PriorityStack));
6379 : 420 : GenQuad (M2Quads_RestorePriorityOp, old, scope, ProcSym);
6380 : : }
6381 : : }
6382 : 151867 : }
6383 : :
6384 : :
6385 : : /*
6386 : : BuildRTExceptEnter - informs RTExceptions that we are about to enter the except state.
6387 : : */
6388 : :
6389 : 2690 : static void BuildRTExceptEnter (unsigned int tok)
6390 : : {
6391 : 2690 : unsigned int old;
6392 : 2690 : unsigned int ProcSym;
6393 : :
6394 : 2690 : if (M2Options_Exceptions)
6395 : : {
6396 : : /* now inform the Modula-2 runtime we are in the exception state */
6397 : 2690 : ProcSym = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "SetExceptionState", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
6398 : 2690 : if (ProcSym == SymbolTable_NulSym)
6399 : : {
6400 : 0 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%W}no procedure SetExceptionState found in RTExceptions which is needed to implement exception handling", 104);
6401 : : }
6402 : : else
6403 : : {
6404 : 2690 : old = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
6405 : 2690 : SymbolTable_PutVar (old, M2Base_Boolean);
6406 : 5380 : GenQuadO (tok, M2Quads_SaveExceptionOp, old, SymbolTable_NulSym, ProcSym, false);
6407 : 2690 : M2StackWord_PushWord (ExceptStack, old);
6408 : : }
6409 : : }
6410 : : else
6411 : : {
6412 : 0 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}cannot use {%kEXCEPT} blocks with the -fno-exceptions flag", 62);
6413 : : }
6414 : 2690 : }
6415 : :
6416 : :
6417 : : /*
6418 : : BuildRTExceptLeave - informs RTExceptions that we are about to leave the except state.
6419 : : If, destroy, is TRUE then pop the ExceptStack.
6420 : : */
6421 : :
6422 : 2804 : static void BuildRTExceptLeave (unsigned int tok, bool destroy)
6423 : : {
6424 : 2804 : unsigned int old;
6425 : 2804 : unsigned int ProcSym;
6426 : :
6427 : 2804 : if (M2Options_Exceptions)
6428 : : {
6429 : : /* avoid dangling else. */
6430 : : /* now inform the Modula-2 runtime we are in the exception state */
6431 : 2804 : ProcSym = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "SetExceptionState", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
6432 : 2804 : if (ProcSym != SymbolTable_NulSym)
6433 : : {
6434 : 2804 : if (destroy)
6435 : : {
6436 : 2690 : old = static_cast<unsigned int> (M2StackWord_PopWord (ExceptStack));
6437 : : }
6438 : : else
6439 : : {
6440 : 114 : old = static_cast<unsigned int> (M2StackWord_PeepWord (ExceptStack, 1));
6441 : : }
6442 : 2804 : GenQuadO (tok, M2Quads_RestoreExceptionOp, old, SymbolTable_NulSym, ProcSym, false);
6443 : : }
6444 : : }
6445 : : /* no need for an error message here as it will be generated in the Enter procedure above */
6446 : 2804 : }
6447 : :
6448 : :
6449 : : /*
6450 : : SafeRequestSym - only used during scaffold to get argc, argv, envp.
6451 : : It attempts to get symbol name from the current scope(s) and if
6452 : : it fails then it falls back onto default constants.
6453 : : */
6454 : :
6455 : 15060 : static unsigned int SafeRequestSym (unsigned int tok, NameKey_Name name)
6456 : : {
6457 : 15060 : unsigned int sym;
6458 : :
6459 : 15060 : sym = SymbolTable_GetSym (name);
6460 : 15060 : if (sym == SymbolTable_NulSym)
6461 : : {
6462 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
6463 : 0 : if (name == (NameKey_MakeKey ((const char *) "argc", 4)))
6464 : : {
6465 : 0 : return SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType);
6466 : : }
6467 : 0 : else if ((name == (NameKey_MakeKey ((const char *) "argv", 4))) || (name == (NameKey_MakeKey ((const char *) "envp", 4))))
6468 : : {
6469 : : /* avoid dangling else. */
6470 : 0 : return M2Base_Nil;
6471 : : }
6472 : : else
6473 : : {
6474 : : /* avoid dangling else. */
6475 : 0 : M2Error_InternalError ((const char *) "not expecting this parameter name", 33);
6476 : : return M2Base_Nil;
6477 : : }
6478 : : }
6479 : : return sym;
6480 : : /* static analysis guarentees a RETURN statement will be used before here. */
6481 : : __builtin_unreachable ();
6482 : : }
6483 : :
6484 : :
6485 : : /*
6486 : : callRequestDependant - create a call:
6487 : : RequestDependant (GetSymName (modulesym), GetLibName (modulesym),
6488 : : GetSymName (depModuleSym), GetLibName (depModuleSym));
6489 : : */
6490 : :
6491 : 37271 : static void callRequestDependant (unsigned int tokno, unsigned int moduleSym, unsigned int depModuleSym, unsigned int requestDep)
6492 : : {
6493 : 37271 : M2Debug_Assert (requestDep != SymbolTable_NulSym);
6494 : 37271 : M2Quads_PushTtok (requestDep, tokno);
6495 : 37271 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
6496 : 37271 : M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetSymName (moduleSym)), tokno);
6497 : 37271 : M2Quads_PushT (static_cast<unsigned int> (1));
6498 : 37271 : BuildAdrFunction ();
6499 : 37271 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
6500 : 37271 : M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetLibName (moduleSym)), tokno);
6501 : 37271 : M2Quads_PushT (static_cast<unsigned int> (1));
6502 : 37271 : BuildAdrFunction ();
6503 : 37271 : if (depModuleSym == SymbolTable_NulSym)
6504 : : {
6505 : 15387 : M2Quads_PushTF (M2Base_Nil, M2System_Address);
6506 : 15387 : M2Quads_PushTF (M2Base_Nil, M2System_Address);
6507 : : }
6508 : : else
6509 : : {
6510 : 21884 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
6511 : 21884 : M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetSymName (depModuleSym)), tokno);
6512 : 21884 : M2Quads_PushT (static_cast<unsigned int> (1));
6513 : 21884 : BuildAdrFunction ();
6514 : 21884 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
6515 : 21884 : M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetLibName (depModuleSym)), tokno);
6516 : 21884 : M2Quads_PushT (static_cast<unsigned int> (1));
6517 : 21884 : BuildAdrFunction ();
6518 : : }
6519 : 37271 : M2Quads_PushT (static_cast<unsigned int> (4));
6520 : 37271 : M2Quads_BuildProcedureCall (tokno);
6521 : 37271 : }
6522 : :
6523 : :
6524 : : /*
6525 : : ForeachImportInDepDo -
6526 : : */
6527 : :
6528 : 30774 : static void ForeachImportInDepDo (Lists_List importStatements, unsigned int moduleSym, unsigned int requestDep)
6529 : : {
6530 : 30774 : unsigned int i;
6531 : 30774 : unsigned int j;
6532 : 30774 : unsigned int m;
6533 : 30774 : unsigned int n;
6534 : 30774 : unsigned int imported;
6535 : 30774 : unsigned int stmt;
6536 : 30774 : Lists_List l;
6537 : :
6538 : 30774 : if (importStatements != NULL)
6539 : : {
6540 : 19802 : i = 1;
6541 : 19802 : n = Lists_NoOfItemsInList (importStatements);
6542 : 60998 : while (i <= n)
6543 : : {
6544 : 21394 : stmt = static_cast<unsigned int> (Lists_GetItemFromList (importStatements, i));
6545 : 21394 : M2Debug_Assert (SymbolTable_IsImportStatement (stmt));
6546 : 21394 : l = SymbolTable_GetImportStatementList (stmt);
6547 : 21394 : j = 1;
6548 : 21394 : m = Lists_NoOfItemsInList (l);
6549 : 64672 : while (j <= m)
6550 : : {
6551 : 21884 : imported = static_cast<unsigned int> (Lists_GetItemFromList (l, j));
6552 : 21884 : M2Debug_Assert (SymbolTable_IsImport (imported));
6553 : 21884 : callRequestDependant (SymbolTable_GetImportDeclared (imported), moduleSym, SymbolTable_GetImportModule (imported), requestDep);
6554 : 21884 : j += 1;
6555 : : }
6556 : 21394 : i += 1;
6557 : : }
6558 : : }
6559 : 30774 : }
6560 : :
6561 : :
6562 : : /*
6563 : : ForeachImportedModuleDo -
6564 : : */
6565 : :
6566 : 15387 : static void ForeachImportedModuleDo (unsigned int moduleSym, unsigned int requestDep)
6567 : : {
6568 : 15387 : Lists_List importStatements;
6569 : :
6570 : 15387 : importStatements = SymbolTable_GetModuleModImportStatementList (moduleSym);
6571 : 15387 : ForeachImportInDepDo (importStatements, moduleSym, requestDep);
6572 : 15387 : importStatements = SymbolTable_GetModuleDefImportStatementList (moduleSym);
6573 : 15387 : ForeachImportInDepDo (importStatements, moduleSym, requestDep);
6574 : 15387 : }
6575 : :
6576 : :
6577 : : /*
6578 : : BuildM2DepFunction - creates the dependency graph procedure using IR:
6579 : : static void
6580 : : dependencies (void)
6581 : : {
6582 : : M2RTS_RequestDependant (module_name, libname, "b", "b libname");
6583 : : M2RTS_RequestDependant (module_name, libname, NULL, NULL);
6584 : : }
6585 : : */
6586 : :
6587 : 15429 : static void BuildM2DepFunction (unsigned int tokno, unsigned int moduleSym)
6588 : : {
6589 : 15429 : unsigned int requestDep;
6590 : 15429 : unsigned int ctor;
6591 : 15429 : unsigned int init;
6592 : 15429 : unsigned int fini;
6593 : 15429 : unsigned int dep;
6594 : :
6595 : 15429 : if (M2Options_ScaffoldDynamic)
6596 : : {
6597 : : /* Scaffold required and dynamic dependency graph should be produced. */
6598 : 15387 : SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
6599 : 15387 : M2Quads_PushT (dep);
6600 : 15387 : M2Quads_BuildProcedureStart ();
6601 : 15387 : M2Quads_BuildProcedureBegin ();
6602 : 15387 : SymbolTable_StartScope (dep);
6603 : 15387 : requestDep = GetQualidentImport (tokno, NameKey_MakeKey ((const char *) "RequestDependant", 16), NameKey_MakeKey ((const char *) "M2RTS", 5));
6604 : 15387 : if (requestDep != SymbolTable_NulSym)
6605 : : {
6606 : 15387 : ForeachImportedModuleDo (moduleSym, requestDep);
6607 : 15387 : callRequestDependant (tokno, moduleSym, SymbolTable_NulSym, requestDep);
6608 : : }
6609 : 15387 : SymbolTable_EndScope ();
6610 : 15387 : M2Quads_BuildProcedureEnd ();
6611 : 15387 : M2Quads_PopN (1);
6612 : : }
6613 : 15429 : }
6614 : :
6615 : :
6616 : : /*
6617 : : BuildM2LinkFunction - creates the _M2_link procedure which will
6618 : : cause the linker to pull in all the module ctors.
6619 : : */
6620 : :
6621 : 2544 : static void BuildM2LinkFunction (unsigned int tokno)
6622 : : {
6623 : 2544 : if (M2Options_ScaffoldDynamic)
6624 : : {
6625 : 2510 : if (M2Scaffold_linkFunction != SymbolTable_NulSym)
6626 : : {
6627 : : /* void
6628 : : _M2_link (void)
6629 : : {
6630 : : for each module in uselist do
6631 : : PROC foo_%d = _M2_module_ctor
6632 : : done
6633 : : }. */
6634 : 2510 : M2Quads_PushT (M2Scaffold_linkFunction);
6635 : 2510 : M2Quads_BuildProcedureStart ();
6636 : 2510 : M2Quads_BuildProcedureBegin ();
6637 : 2510 : SymbolTable_StartScope (M2Scaffold_linkFunction);
6638 : 2510 : M2Scaffold_PopulateCtorArray (tokno);
6639 : 2510 : SymbolTable_EndScope ();
6640 : 2510 : M2Quads_BuildProcedureEnd ();
6641 : 2510 : M2Quads_PopN (1);
6642 : : }
6643 : : }
6644 : 2544 : }
6645 : :
6646 : :
6647 : : /*
6648 : : BuildTry - build the try statement for main.
6649 : : */
6650 : :
6651 : 2510 : static void BuildTry (unsigned int tokno)
6652 : : {
6653 : 2510 : if (M2Options_Exceptions)
6654 : : {
6655 : 2510 : M2StackWord_PushWord (TryStack, NextQuad);
6656 : 2510 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
6657 : 2510 : GenQuadO (tokno, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
6658 : : }
6659 : 2510 : }
6660 : :
6661 : :
6662 : : /*
6663 : : BuildExcept - build the except block for main.
6664 : : */
6665 : :
6666 : 2510 : static void BuildExcept (unsigned int tokno)
6667 : : {
6668 : 2510 : unsigned int catchProcedure;
6669 : :
6670 : 2510 : if (M2Options_Exceptions)
6671 : : {
6672 : 2510 : M2Quads_BuildExceptInitial (tokno);
6673 : 2510 : catchProcedure = GetQualidentImport (tokno, NameKey_MakeKey ((const char *) "DefaultErrorCatch", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
6674 : 2510 : if (catchProcedure != SymbolTable_NulSym)
6675 : : {
6676 : 2510 : M2Quads_PushTtok (catchProcedure, tokno);
6677 : 2510 : M2Quads_PushT (static_cast<unsigned int> (0));
6678 : 2510 : M2Quads_BuildProcedureCall (tokno);
6679 : : }
6680 : 2510 : BuildRTExceptLeave (tokno, true);
6681 : 2510 : GenQuadO (tokno, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
6682 : : }
6683 : 2510 : }
6684 : :
6685 : :
6686 : : /*
6687 : : BuildM2MainFunction - creates the main function with appropriate calls to the scaffold.
6688 : : */
6689 : :
6690 : 2544 : static void BuildM2MainFunction (unsigned int tokno)
6691 : : {
6692 : 2544 : if ((M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic) && ! M2Options_SharedFlag)
6693 : : {
6694 : : /*
6695 : : int
6696 : : main (int argc, char *argv[], char *envp[])
6697 : : {
6698 : : try {
6699 : : _M2_init (argc, argv, envp);
6700 : : _M2_fini (argc, argv, envp);
6701 : : return 0;
6702 : : }
6703 : : catch (...) {
6704 : : RTExceptions_DefaultErrorCatch ();
6705 : : return 0;
6706 : : }
6707 : : }
6708 : : */
6709 : 2510 : M2Quads_PushT (M2Scaffold_mainFunction);
6710 : 2510 : M2Quads_BuildProcedureStart ();
6711 : 2510 : M2Quads_BuildProcedureBegin ();
6712 : 2510 : SymbolTable_StartScope (M2Scaffold_mainFunction);
6713 : 2510 : BuildTry (tokno);
6714 : : /* _M2_init (argc, argv, envp); */
6715 : 2510 : M2Quads_PushTtok (M2Scaffold_initFunction, tokno);
6716 : 2510 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argc", 4)), tokno);
6717 : 2510 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argv", 4)), tokno);
6718 : 2510 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "envp", 4)), tokno);
6719 : 2510 : M2Quads_PushT (static_cast<unsigned int> (3));
6720 : 2510 : M2Quads_BuildProcedureCall (tokno);
6721 : : /* _M2_fini (argc, argv, envp); */
6722 : 2510 : M2Quads_PushTtok (M2Scaffold_finiFunction, tokno);
6723 : 2510 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argc", 4)), tokno);
6724 : 2510 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argv", 4)), tokno);
6725 : 2510 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "envp", 4)), tokno);
6726 : 2510 : M2Quads_PushT (static_cast<unsigned int> (3));
6727 : 2510 : M2Quads_BuildProcedureCall (tokno);
6728 : 2510 : PushZero (tokno, M2Base_Integer);
6729 : 2510 : M2Quads_BuildReturn (tokno);
6730 : 2510 : BuildExcept (tokno);
6731 : 2510 : PushZero (tokno, M2Base_Integer);
6732 : 2510 : M2Quads_BuildReturn (tokno);
6733 : 2510 : SymbolTable_EndScope ();
6734 : 2510 : M2Quads_BuildProcedureEnd ();
6735 : 2510 : M2Quads_PopN (1);
6736 : : }
6737 : 2544 : }
6738 : :
6739 : :
6740 : : /*
6741 : : DeferMakeConstStringCnul - return a C const string which will be nul terminated.
6742 : : */
6743 : :
6744 : 7642 : static unsigned int DeferMakeConstStringCnul (unsigned int tok, unsigned int sym)
6745 : : {
6746 : 7642 : unsigned int const_;
6747 : :
6748 : 7642 : const_ = SymbolTable_MakeConstStringCnul (tok, NameKey_NulName, false);
6749 : 15284 : GenQuadO (tok, M2Quads_StringConvertCnulOp, const_, 0, sym, false);
6750 : 7642 : return const_;
6751 : : /* static analysis guarentees a RETURN statement will be used before here. */
6752 : : __builtin_unreachable ();
6753 : : }
6754 : :
6755 : :
6756 : : /*
6757 : : DeferMakeConstStringM2nul - return a const string which will be nul terminated.
6758 : : */
6759 : :
6760 : 31650 : static unsigned int DeferMakeConstStringM2nul (unsigned int tok, unsigned int sym)
6761 : : {
6762 : 31650 : unsigned int const_;
6763 : :
6764 : 31650 : const_ = SymbolTable_MakeConstStringM2nul (tok, NameKey_NulName, false);
6765 : 63300 : GenQuadO (tok, M2Quads_StringConvertM2nulOp, const_, 0, sym, false);
6766 : 31650 : return const_;
6767 : : /* static analysis guarentees a RETURN statement will be used before here. */
6768 : : __builtin_unreachable ();
6769 : : }
6770 : :
6771 : :
6772 : : /*
6773 : : BuildStringAdrParam - push the address of a nul terminated string onto the quad stack.
6774 : : */
6775 : :
6776 : 7530 : static void BuildStringAdrParam (unsigned int tok, NameKey_Name name)
6777 : : {
6778 : 7530 : unsigned int str;
6779 : 7530 : unsigned int m2strnul;
6780 : :
6781 : 7530 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6782 : 7530 : str = SymbolTable_MakeConstString (tok, name);
6783 : 7530 : SymbolTable_PutConstStringKnown (tok, str, name, false, true);
6784 : 7530 : m2strnul = DeferMakeConstStringM2nul (tok, str);
6785 : 7530 : M2Quads_PushTtok (m2strnul, tok);
6786 : 7530 : M2Quads_PushT (static_cast<unsigned int> (1));
6787 : 7530 : BuildAdrFunction ();
6788 : 7530 : }
6789 : :
6790 : :
6791 : : /*
6792 : : BuildM2InitFunction -
6793 : : */
6794 : :
6795 : 2544 : static void BuildM2InitFunction (unsigned int tok, unsigned int moduleSym)
6796 : : {
6797 : 2544 : unsigned int constructModules;
6798 : :
6799 : 2544 : if (M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic)
6800 : : {
6801 : : /* int
6802 : : _M2_init (int argc, char *argv[], char *envp[])
6803 : : {
6804 : : M2RTS_ConstructModules (module_name, libname,
6805 : : overrideliborder, argc, argv, envp);
6806 : : } */
6807 : 2510 : M2Quads_PushT (M2Scaffold_initFunction);
6808 : 2510 : M2Quads_BuildProcedureStart ();
6809 : 2510 : M2Quads_BuildProcedureBegin ();
6810 : 2510 : SymbolTable_StartScope (M2Scaffold_initFunction);
6811 : 2510 : if (M2Options_ScaffoldDynamic)
6812 : : {
6813 : : /* avoid dangling else. */
6814 : 2510 : if (M2Scaffold_linkFunction != SymbolTable_NulSym)
6815 : : {
6816 : : /* _M2_link (); */
6817 : 2510 : M2Quads_PushTtok (M2Scaffold_linkFunction, tok);
6818 : 2510 : M2Quads_PushT (static_cast<unsigned int> (0));
6819 : 2510 : M2Quads_BuildProcedureCall (tok);
6820 : : }
6821 : : /* Lookup ConstructModules and call it. */
6822 : 2510 : constructModules = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "ConstructModules", 16), NameKey_MakeKey ((const char *) "M2RTS", 5));
6823 : 2510 : if (constructModules != SymbolTable_NulSym)
6824 : : {
6825 : : /* ConstructModules (module_name, argc, argv, envp); */
6826 : 2510 : M2Quads_PushTtok (constructModules, tok);
6827 : 2510 : BuildStringAdrParam (tok, SymbolTable_GetSymName (moduleSym));
6828 : 2510 : BuildStringAdrParam (tok, SymbolTable_GetLibName (moduleSym));
6829 : 2510 : BuildStringAdrParam (tok, NameKey_makekey (M2Options_GetRuntimeModuleOverride ()));
6830 : 2510 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argc", 4)), tok);
6831 : 2510 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argv", 4)), tok);
6832 : 2510 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "envp", 4)), tok);
6833 : 2510 : M2Quads_PushT (static_cast<unsigned int> (6));
6834 : 2510 : M2Quads_BuildProcedureCall (tok);
6835 : : }
6836 : : }
6837 : 0 : else if (M2Options_ScaffoldStatic)
6838 : : {
6839 : : /* avoid dangling else. */
6840 : 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)));
6841 : : }
6842 : 2510 : SymbolTable_EndScope ();
6843 : 2510 : M2Quads_BuildProcedureEnd ();
6844 : 2510 : M2Quads_PopN (1);
6845 : : }
6846 : 2544 : }
6847 : :
6848 : :
6849 : : /*
6850 : : BuildM2FiniFunction -
6851 : : */
6852 : :
6853 : 2544 : static void BuildM2FiniFunction (unsigned int tok, unsigned int moduleSym)
6854 : : {
6855 : 2544 : unsigned int deconstructModules;
6856 : :
6857 : 2544 : if (M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic)
6858 : : {
6859 : : /* Scaffold required and main should be produced. */
6860 : 2510 : M2Quads_PushT (M2Scaffold_finiFunction);
6861 : 2510 : M2Quads_BuildProcedureStart ();
6862 : 2510 : M2Quads_BuildProcedureBegin ();
6863 : 2510 : SymbolTable_StartScope (M2Scaffold_finiFunction);
6864 : 2510 : if (M2Options_ScaffoldDynamic)
6865 : : {
6866 : : /* avoid dangling else. */
6867 : : /* static void
6868 : : _M2_finish (int argc, char *argv[], char *envp[])
6869 : : {
6870 : : M2RTS_DeconstructModules (module_name, argc, argv, envp);
6871 : : } */
6872 : 2510 : deconstructModules = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "DeconstructModules", 18), NameKey_MakeKey ((const char *) "M2RTS", 5));
6873 : 2510 : if (deconstructModules != SymbolTable_NulSym)
6874 : : {
6875 : : /* DeconstructModules (module_name, argc, argv, envp); */
6876 : 2510 : M2Quads_PushTtok (deconstructModules, tok);
6877 : 2510 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6878 : 2510 : M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetSymName (moduleSym)), tok);
6879 : 2510 : M2Quads_PushT (static_cast<unsigned int> (1));
6880 : 2510 : BuildAdrFunction ();
6881 : 2510 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6882 : 2510 : M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetLibName (moduleSym)), tok);
6883 : 2510 : M2Quads_PushT (static_cast<unsigned int> (1));
6884 : 2510 : BuildAdrFunction ();
6885 : 2510 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argc", 4)), tok);
6886 : 2510 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argv", 4)), tok);
6887 : 2510 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "envp", 4)), tok);
6888 : 2510 : M2Quads_PushT (static_cast<unsigned int> (5));
6889 : 2510 : M2Quads_BuildProcedureCall (tok);
6890 : : }
6891 : : }
6892 : 0 : else if (M2Options_ScaffoldStatic)
6893 : : {
6894 : : /* avoid dangling else. */
6895 : 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)));
6896 : : }
6897 : 2510 : SymbolTable_EndScope ();
6898 : 2510 : M2Quads_BuildProcedureEnd ();
6899 : 2510 : M2Quads_PopN (1);
6900 : : }
6901 : 2544 : }
6902 : :
6903 : :
6904 : : /*
6905 : : BuildM2CtorFunction - create a constructor function associated with moduleSym.
6906 : :
6907 : : void
6908 : : ctorFunction ()
6909 : : {
6910 : : M2RTS_RegisterModule (GetSymName (moduleSym), GetLibName (moduleSym),
6911 : : init, fini, dependencies);
6912 : : }
6913 : : */
6914 : :
6915 : 15429 : static void BuildM2CtorFunction (unsigned int tok, unsigned int moduleSym)
6916 : : {
6917 : 15429 : unsigned int RegisterModule;
6918 : 15429 : unsigned int ctor;
6919 : 15429 : unsigned int init;
6920 : 15429 : unsigned int fini;
6921 : 15429 : unsigned int dep;
6922 : :
6923 : 15429 : if (M2Options_ScaffoldDynamic)
6924 : : {
6925 : 15387 : SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
6926 : 15387 : if (ctor != SymbolTable_NulSym)
6927 : : {
6928 : 15387 : M2Debug_Assert (SymbolTable_IsProcedure (ctor));
6929 : 15387 : M2Quads_PushT (ctor);
6930 : 15387 : M2Quads_BuildProcedureStart ();
6931 : 15387 : M2Quads_BuildProcedureBegin ();
6932 : 15387 : SymbolTable_StartScope (ctor);
6933 : 15387 : RegisterModule = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "RegisterModule", 14), NameKey_MakeKey ((const char *) "M2RTS", 5));
6934 : 15387 : if (RegisterModule != SymbolTable_NulSym)
6935 : : {
6936 : : /* RegisterModule (module_name, init, fini, dependencies); */
6937 : 15387 : M2Quads_PushTtok (RegisterModule, tok);
6938 : 15387 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6939 : 15387 : M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetSymName (moduleSym)), tok);
6940 : 15387 : M2Quads_PushT (static_cast<unsigned int> (1));
6941 : 15387 : BuildAdrFunction ();
6942 : 15387 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6943 : 15387 : M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetLibName (moduleSym)), tok);
6944 : 15387 : M2Quads_PushT (static_cast<unsigned int> (1));
6945 : 15387 : BuildAdrFunction ();
6946 : 15387 : M2Quads_PushTtok (init, tok);
6947 : 15387 : M2Quads_PushTtok (fini, tok);
6948 : 15387 : M2Quads_PushTtok (dep, tok);
6949 : 15387 : M2Quads_PushT (static_cast<unsigned int> (5));
6950 : 15387 : M2Quads_BuildProcedureCall (tok);
6951 : : }
6952 : 15387 : SymbolTable_EndScope ();
6953 : 15387 : M2Quads_BuildProcedureEnd ();
6954 : 15387 : M2Quads_PopN (1);
6955 : : }
6956 : : }
6957 : 15429 : }
6958 : :
6959 : :
6960 : : /*
6961 : : AddForInfo - adds the description of the FOR loop into the record list.
6962 : : This is used if -pedantic is turned on to check index variable
6963 : : usage.
6964 : : */
6965 : :
6966 : 2148 : static void AddForInfo (unsigned int Start, unsigned int End, unsigned int IncQuad, unsigned int Sym, unsigned int idtok)
6967 : : {
6968 : 2148 : M2Quads_ForLoopInfo forDesc;
6969 : :
6970 : 2148 : if (M2Options_Pedantic)
6971 : : {
6972 : 0 : Storage_ALLOCATE ((void **) &forDesc, sizeof (M2Quads__T5));
6973 : 0 : forDesc->IncrementQuad = IncQuad;
6974 : 0 : forDesc->StartOfForLoop = Start;
6975 : 0 : forDesc->EndOfForLoop = End;
6976 : 0 : forDesc->ForLoopIndex = Sym;
6977 : 0 : forDesc->IndexTok = idtok;
6978 : 0 : Indexing_IncludeIndiceIntoIndex (ForInfo, reinterpret_cast <void *> (forDesc));
6979 : : }
6980 : 2148 : }
6981 : :
6982 : :
6983 : : /*
6984 : : CheckForIndex - checks the quadruples: Start..End to see whether a
6985 : : for loop index is manipulated by the programmer.
6986 : : It generates a warning if this is the case.
6987 : : It also checks to see whether the IndexSym is read
6988 : : immediately outside the loop in which case a warning
6989 : : is issued.
6990 : : */
6991 : :
6992 : 0 : static void CheckForIndex (M2Quads_ForLoopInfo forDesc)
6993 : : {
6994 : 0 : unsigned int ReadStart;
6995 : 0 : unsigned int ReadEnd;
6996 : 0 : unsigned int WriteStart;
6997 : 0 : unsigned int WriteEnd;
6998 : :
6999 : 0 : SymbolTable_GetWriteLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->StartOfForLoop, forDesc->EndOfForLoop, &WriteStart, &WriteEnd);
7000 : 0 : if ((WriteStart < forDesc->IncrementQuad) && (WriteStart > forDesc->StartOfForLoop))
7001 : : {
7002 : 0 : M2MetaError_MetaErrorT1 (forDesc->IndexTok, (const char *) "{%kFOR} loop index variable {%1Wad} is being manipulated inside the loop", 72, forDesc->ForLoopIndex);
7003 : 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);
7004 : : }
7005 : 0 : SymbolTable_GetWriteLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->EndOfForLoop, 0, &WriteStart, &WriteEnd);
7006 : 0 : SymbolTable_GetReadLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->EndOfForLoop, 0, &ReadStart, &ReadEnd);
7007 : 0 : if ((ReadStart != 0) && ((ReadStart < WriteStart) || (WriteStart == 0)))
7008 : : {
7009 : 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);
7010 : 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);
7011 : : }
7012 : 0 : }
7013 : :
7014 : :
7015 : : /*
7016 : : BuildRange - generates a RangeCheckOp quad with, r, as its operand.
7017 : : */
7018 : :
7019 : 1352521 : static void BuildRange (unsigned int r)
7020 : : {
7021 : 1352521 : GenQuad (M2Quads_RangeCheckOp, (unsigned int ) (M2LexBuf_GetLineNo ()), SymbolTable_NulSym, r);
7022 : 1352521 : }
7023 : :
7024 : :
7025 : : /*
7026 : : BuildError - generates a ErrorOp quad, indicating that if this
7027 : : quadruple is reachable, then a runtime error would
7028 : : occur.
7029 : : */
7030 : :
7031 : 12650 : static void BuildError (unsigned int r)
7032 : : {
7033 : 12650 : GenQuad (M2Quads_ErrorOp, (unsigned int ) (M2LexBuf_GetLineNo ()), SymbolTable_NulSym, r);
7034 : 12650 : }
7035 : :
7036 : :
7037 : : /*
7038 : : CheckPointerThroughNil - builds a range quadruple, providing, sym, is
7039 : : a candidate for checking against NIL.
7040 : : This range quadruple is only expanded into
7041 : : code during the code generation phase
7042 : : thus allowing limited compile time checking.
7043 : : */
7044 : :
7045 : 64749 : static void CheckPointerThroughNil (unsigned int tokpos, unsigned int sym)
7046 : : {
7047 : 64749 : if ((SymbolTable_IsVar (sym)) && (SymbolTable_GetVarPointerCheck (sym)))
7048 : : {
7049 : : /* PutVarPointerCheck(sym, FALSE) ; so we do not detect this again */
7050 : 17616 : BuildRange (M2Range_InitPointerRangeCheck (tokpos, sym, (SymbolTable_GetMode (sym)) == SymbolTable_LeftValue));
7051 : : }
7052 : 64749 : }
7053 : :
7054 : :
7055 : : /*
7056 : : CollectLow - returns the low of the subrange value.
7057 : : */
7058 : :
7059 : 234 : static unsigned int CollectLow (unsigned int sym)
7060 : : {
7061 : 234 : unsigned int low;
7062 : 234 : unsigned int high;
7063 : :
7064 : 234 : if (SymbolTable_IsSubrange (sym))
7065 : : {
7066 : 234 : SymbolTable_GetSubrange (sym, &high, &low);
7067 : 234 : return low;
7068 : : }
7069 : : else
7070 : : {
7071 : 0 : M2Error_InternalError ((const char *) "expecting Subrange symbol", 25);
7072 : : }
7073 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
7074 : : __builtin_unreachable ();
7075 : : }
7076 : :
7077 : :
7078 : : /*
7079 : : CollectHigh - returns the high of the subrange value, sym.
7080 : : */
7081 : :
7082 : 3034 : static unsigned int CollectHigh (unsigned int sym)
7083 : : {
7084 : 3034 : unsigned int low;
7085 : 3034 : unsigned int high;
7086 : :
7087 : 3034 : if (SymbolTable_IsSubrange (sym))
7088 : : {
7089 : 3034 : SymbolTable_GetSubrange (sym, &high, &low);
7090 : 3034 : return high;
7091 : : }
7092 : : else
7093 : : {
7094 : 0 : M2Error_InternalError ((const char *) "expecting Subrange symbol", 25);
7095 : : }
7096 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
7097 : : __builtin_unreachable ();
7098 : : }
7099 : :
7100 : :
7101 : : /*
7102 : : CheckCompatibleWithBecomes - checks to see that symbol, sym, is
7103 : : compatible with the := operator.
7104 : : */
7105 : :
7106 : 418084 : static void CheckCompatibleWithBecomes (unsigned int des, unsigned int expr, unsigned int destok, unsigned int exprtok)
7107 : : {
7108 : 418084 : if (SymbolTable_IsType (des))
7109 : : {
7110 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to a type {%1a}", 51, des);
7111 : : }
7112 : 418084 : else if (SymbolTable_IsProcedure (des))
7113 : : {
7114 : : /* avoid dangling else. */
7115 : 6 : M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to a procedure {%1a}", 56, des);
7116 : : }
7117 : 418078 : else if (SymbolTable_IsFieldEnumeration (des))
7118 : : {
7119 : : /* avoid dangling else. */
7120 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to an enumeration field {%1a}", 65, des);
7121 : : }
7122 : 418084 : if ((M2Base_IsPseudoBaseProcedure (expr)) || (M2Base_IsPseudoBaseFunction (expr)))
7123 : : {
7124 : 6 : M2MetaError_MetaErrorT1 (exprtok, (const char *) "an assignment cannot assign a {%1d} {%1a}", 41, expr);
7125 : : }
7126 : 418084 : }
7127 : :
7128 : :
7129 : : /*
7130 : : BuildAssignmentWithoutBounds - calls BuildAssignment but makes sure we do not
7131 : : check bounds.
7132 : : */
7133 : :
7134 : 75432 : static void BuildAssignmentWithoutBounds (unsigned int tok, bool checkTypes, bool checkOverflow)
7135 : : {
7136 : 75432 : bool old;
7137 : :
7138 : 75432 : old = MustNotCheckBounds;
7139 : 75432 : MustNotCheckBounds = true;
7140 : 0 : doBuildAssignment (tok, checkTypes, checkOverflow);
7141 : 75432 : MustNotCheckBounds = old;
7142 : 18200 : }
7143 : :
7144 : :
7145 : : /*
7146 : : MarkArrayWritten - marks, Array, as being written.
7147 : : */
7148 : :
7149 : 90370 : static void MarkArrayWritten (unsigned int Array)
7150 : : {
7151 : 90370 : if ((Array != SymbolTable_NulSym) && (SymbolTable_IsVarAParam (Array)))
7152 : : {
7153 : 12046 : SymbolTable_PutVarWritten (Array, true);
7154 : : }
7155 : 90370 : }
7156 : :
7157 : :
7158 : : /*
7159 : : MarkAsReadWrite - marks the variable or parameter as being
7160 : : read/write.
7161 : : */
7162 : :
7163 : 27432 : static void MarkAsReadWrite (unsigned int sym)
7164 : : {
7165 : 27432 : if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
7166 : : {
7167 : 19790 : SymbolTable_PutReadQuad (sym, SymbolTable_RightValue, NextQuad);
7168 : 19790 : SymbolTable_PutWriteQuad (sym, SymbolTable_RightValue, NextQuad);
7169 : : }
7170 : 27432 : }
7171 : :
7172 : :
7173 : : /*
7174 : : MarkAsRead - marks the variable or parameter as being read.
7175 : : */
7176 : :
7177 : 1072570 : static void MarkAsRead (unsigned int sym)
7178 : : {
7179 : 1072570 : if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
7180 : : {
7181 : 317944 : SymbolTable_PutReadQuad (sym, SymbolTable_RightValue, NextQuad);
7182 : : }
7183 : 1072570 : }
7184 : :
7185 : :
7186 : : /*
7187 : : MarkAsWrite - marks the variable or parameter as being written.
7188 : : */
7189 : :
7190 : 418084 : static void MarkAsWrite (unsigned int sym)
7191 : : {
7192 : 418084 : if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
7193 : : {
7194 : 73814 : SymbolTable_PutWriteQuad (sym, SymbolTable_RightValue, NextQuad);
7195 : : }
7196 : 418084 : }
7197 : :
7198 : :
7199 : : /*
7200 : : doVal - return an expression which is VAL(type, expr). If
7201 : : expr is a constant then return expr.
7202 : : */
7203 : :
7204 : 35820 : static unsigned int doVal (unsigned int type, unsigned int expr)
7205 : : {
7206 : 35820 : if ((! (SymbolTable_IsConst (expr))) && ((SymbolTable_SkipType (type)) != (SymbolTable_GetDType (expr))))
7207 : : {
7208 : 25636 : M2Quads_PushTF (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym));
7209 : 25636 : M2Quads_PushT (SymbolTable_SkipType (type));
7210 : 25636 : M2Quads_PushT (expr);
7211 : 25636 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
7212 : 25636 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
7213 : 25636 : M2Quads_PopT (&expr);
7214 : : }
7215 : 35820 : return expr;
7216 : : /* static analysis guarentees a RETURN statement will be used before here. */
7217 : : __builtin_unreachable ();
7218 : : }
7219 : :
7220 : :
7221 : : /*
7222 : : MoveWithMode -
7223 : : */
7224 : :
7225 : 418084 : static void MoveWithMode (unsigned int tokno, unsigned int Des, unsigned int Exp, unsigned int Array, unsigned int destok, unsigned int exptok, bool checkOverflow)
7226 : : {
7227 : 418084 : unsigned int t;
7228 : :
7229 : 418084 : if ((SymbolTable_IsConstString (Exp)) && (SymbolTable_IsConst (Des)))
7230 : : {
7231 : 1598 : GenQuadOtok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, destok, M2LexBuf_UnknownTokenNo, exptok);
7232 : : }
7233 : : else
7234 : : {
7235 : 416486 : if ((SymbolTable_GetMode (Des)) == SymbolTable_RightValue)
7236 : : {
7237 : 138203 : if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
7238 : : {
7239 : 2160 : CheckPointerThroughNil (tokno, Exp); /* Des = *Exp */
7240 : 2160 : doIndrX (tokno, Des, Exp); /* Des = *Exp */
7241 : : }
7242 : : else
7243 : : {
7244 : 136043 : GenQuadOtok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, destok, M2LexBuf_UnknownTokenNo, exptok);
7245 : : }
7246 : : }
7247 : 278283 : else if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
7248 : : {
7249 : : /* avoid dangling else. */
7250 : 35678 : MarkArrayWritten (Array);
7251 : 35678 : if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
7252 : : {
7253 : 928 : t = SymbolTable_MakeTemporary (tokno, SymbolTable_RightValue);
7254 : 928 : SymbolTable_PutVar (t, SymbolTable_GetSType (Exp));
7255 : 928 : CheckPointerThroughNil (tokno, Exp);
7256 : 928 : doIndrX (tokno, t, Exp);
7257 : 928 : CheckPointerThroughNil (tokno, Des); /* *Des = Exp */
7258 : 928 : GenQuadO (tokno, M2Quads_XIndrOp, Des, SymbolTable_GetSType (Des), doVal (SymbolTable_GetSType (Des), t), checkOverflow); /* *Des = Exp */
7259 : : }
7260 : : else
7261 : : {
7262 : 34750 : CheckPointerThroughNil (tokno, Des); /* *Des = Exp */
7263 : 34750 : GenQuadO (tokno, M2Quads_XIndrOp, Des, SymbolTable_GetSType (Des), doVal (SymbolTable_GetSType (Des), Exp), checkOverflow); /* *Des = Exp */
7264 : : }
7265 : : }
7266 : : else
7267 : : {
7268 : : /* avoid dangling else. */
7269 : : /* This might be inside a const expression. */
7270 : 242605 : GenQuadOTypetok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, true, destok, M2LexBuf_UnknownTokenNo, exptok);
7271 : : }
7272 : : }
7273 : 418084 : }
7274 : :
7275 : :
7276 : : /*
7277 : : CheckBecomesMeta - checks to make sure that we are not
7278 : : assigning a variable to a constant.
7279 : : Also check we are not assigning to an
7280 : : unbounded array.
7281 : : */
7282 : :
7283 : 352916 : static void CheckBecomesMeta (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok)
7284 : : {
7285 : 352916 : if ((SymbolTable_IsConst (Des)) && (SymbolTable_IsVar (Exp)))
7286 : : {
7287 : 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);
7288 : : }
7289 : 352916 : if ((((SymbolTable_GetDType (Des)) != SymbolTable_NulSym) && (SymbolTable_IsVar (Des))) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (Des))))
7290 : : {
7291 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "in assignment, cannot assign to an unbounded array {%1ad}", 57, Des);
7292 : : }
7293 : 352916 : if ((((SymbolTable_GetDType (Exp)) != SymbolTable_NulSym) && (SymbolTable_IsVar (Exp))) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (Exp))))
7294 : : {
7295 : 0 : M2MetaError_MetaErrorT1 (exprtok, (const char *) "in assignment, cannot assign from an unbounded array {%1ad}", 59, Exp);
7296 : : }
7297 : 352916 : }
7298 : :
7299 : :
7300 : : /*
7301 : : doBuildAssignment - subsiduary procedure of BuildAssignment.
7302 : : It builds the assignment and optionally
7303 : : checks the types are compatible.
7304 : : */
7305 : :
7306 : 426862 : static void doBuildAssignment (unsigned int becomesTokNo, bool checkTypes, bool checkOverflow)
7307 : : {
7308 : 426862 : unsigned int r;
7309 : 426862 : unsigned int w;
7310 : 426862 : unsigned int t;
7311 : 426862 : unsigned int f;
7312 : 426862 : unsigned int Array;
7313 : 426862 : unsigned int Des;
7314 : 426862 : unsigned int Exp;
7315 : 426862 : unsigned int combinedtok;
7316 : 426862 : unsigned int destok;
7317 : 426862 : unsigned int exptok;
7318 : :
7319 : 426862 : M2Quads_DisplayStack ();
7320 : 426862 : if (IsBoolean (1))
7321 : : {
7322 : 17556 : PopBool (&t, &f);
7323 : 8778 : M2Quads_PopTtok (&Des, &destok);
7324 : 8778 : SymbolTable_PutVarConditional (Des, true); /* Des will contain the result of a boolean relop. */
7325 : : /* Conditional Boolean Assignment. */
7326 : 8778 : BackPatch (t, NextQuad);
7327 : 8778 : if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
7328 : : {
7329 : 46 : CheckPointerThroughNil (destok, Des);
7330 : 92 : GenQuadO (destok, M2Quads_XIndrOp, Des, M2Base_Boolean, M2Base_True, checkOverflow);
7331 : 46 : GenQuadO (destok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, NextQuad+2, false);
7332 : : }
7333 : : else
7334 : : {
7335 : : /* This might be inside a const expression. */
7336 : 17464 : GenQuadO (becomesTokNo, M2Quads_BecomesOp, Des, SymbolTable_NulSym, M2Base_True, checkOverflow);
7337 : 8732 : GenQuadO (destok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, NextQuad+2, false);
7338 : : }
7339 : 8778 : BackPatch (f, NextQuad);
7340 : 8778 : if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
7341 : : {
7342 : 46 : CheckPointerThroughNil (destok, Des);
7343 : 46 : GenQuadO (destok, M2Quads_XIndrOp, Des, M2Base_Boolean, M2Base_False, checkOverflow);
7344 : : }
7345 : : else
7346 : : {
7347 : 8732 : GenQuadO (becomesTokNo, M2Quads_BecomesOp, Des, SymbolTable_NulSym, M2Base_False, checkOverflow);
7348 : : }
7349 : : }
7350 : : else
7351 : : {
7352 : 418084 : PopTrwtok (&Exp, &r, &exptok);
7353 : 418084 : MarkAsRead (r);
7354 : 418084 : if (Exp == SymbolTable_NulSym)
7355 : : {
7356 : 0 : M2MetaError_MetaError0 ((const char *) "{%E}unknown expression found during assignment", 46);
7357 : 0 : M2Error_FlushErrors ();
7358 : : }
7359 : 418084 : Array = static_cast<unsigned int> (M2Quads_OperandA (1));
7360 : 418084 : PopTrwtok (&Des, &w, &destok);
7361 : 418084 : MarkAsWrite (w);
7362 : 418084 : CheckCompatibleWithBecomes (Des, Exp, destok, exptok);
7363 : 418084 : if (DebugTokPos)
7364 : : {
7365 : : M2MetaError_MetaErrorT1 (becomesTokNo, (const char *) "becomestok {%1Oad}", 18, Des);
7366 : : M2MetaError_MetaErrorT1 (destok, (const char *) "destok {%1Oad}", 14, Des);
7367 : : M2MetaError_MetaErrorT1 (exptok, (const char *) "exptok {%1Oad}", 14, Exp);
7368 : : }
7369 : 418084 : combinedtok = M2LexBuf_MakeVirtualTok (becomesTokNo, destok, exptok);
7370 : 418084 : if (DebugTokPos)
7371 : : {
7372 : : M2MetaError_MetaErrorT1 (combinedtok, (const char *) "combined {%1Oad}", 16, Des);
7373 : : }
7374 : 418084 : if (((SymbolTable_GetSType (Des)) != SymbolTable_NulSym) && (! (SymbolTable_IsSet (SymbolTable_GetDType (Des)))))
7375 : : {
7376 : : /* Tell code generator to test runtime values of assignment so ensure we
7377 : : catch overflow and underflow. */
7378 : 409284 : BuildRange (M2Range_InitAssignmentRangeCheck (combinedtok, Des, Exp, destok, exptok));
7379 : : }
7380 : 418084 : if (checkTypes)
7381 : : {
7382 : 352916 : CheckBecomesMeta (Des, Exp, combinedtok, destok, exptok);
7383 : : }
7384 : : /* Simple assignment. */
7385 : 418084 : MoveWithMode (combinedtok, Des, Exp, Array, destok, exptok, checkOverflow);
7386 : 418084 : if (checkTypes)
7387 : : {
7388 : 352916 : CheckAssignCompatible (Des, Exp, combinedtok, destok, exptok);
7389 : : }
7390 : : }
7391 : 426862 : M2Quads_DisplayStack ();
7392 : 426862 : }
7393 : :
7394 : :
7395 : : /*
7396 : : CheckAssignCompatible - checks to see that an assignment is compatible.
7397 : : It performs limited checking - thorough checking
7398 : : is done in pass 3. But we do what we can here
7399 : : given knowledge so far.
7400 : : */
7401 : :
7402 : 352916 : static void CheckAssignCompatible (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok)
7403 : : {
7404 : 352916 : unsigned int DesT;
7405 : 352916 : unsigned int ExpT;
7406 : 352916 : unsigned int DesL;
7407 : :
7408 : 352916 : DesT = SymbolTable_GetSType (Des);
7409 : 352916 : ExpT = SymbolTable_GetSType (Exp);
7410 : 352916 : DesL = SymbolTable_GetLType (Des);
7411 : 352916 : if (((SymbolTable_IsProcedure (Exp)) && ((DesT != SymbolTable_NulSym) && (! (SymbolTable_IsProcType (DesT))))) && ((DesL != SymbolTable_NulSym) && (! (SymbolTable_IsProcType (DesL)))))
7412 : : {
7413 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "incorrectly assigning a procedure to a designator {%1Ead} (designator is not a procedure type, {%1ast})", 103, Des);
7414 : : }
7415 : : /* We ignore checking of these types in pass 3 - but we do check them thoroughly post pass 3 */
7416 : 352916 : else if ((SymbolTable_IsProcedure (Exp)) && (SymbolTable_IsProcedureNested (Exp)))
7417 : : {
7418 : : /* avoid dangling else. */
7419 : 6 : M2MetaError_MetaErrorT1 (exprtok, (const char *) "cannot call nested procedure {%1Ead} indirectly as the outer scope will not be known", 84, Exp);
7420 : : }
7421 : 352910 : else if (SymbolTable_IsConstString (Exp))
7422 : : {
7423 : : /* avoid dangling else. */
7424 : : }
7425 : 349642 : else if ((DesT != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (DesT)))
7426 : : {
7427 : : /* avoid dangling else. */
7428 : : }
7429 : 349642 : else if ((ExpT != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (ExpT)))
7430 : : {
7431 : : /* avoid dangling else. */
7432 : : }
7433 : 349642 : else if ((DesL != SymbolTable_NulSym) && (SymbolTable_IsArray (DesL)))
7434 : : {
7435 : : /* avoid dangling else. */
7436 : : }
7437 : 348854 : else if (SymbolTable_IsConstructor (Exp))
7438 : : {
7439 : : /* avoid dangling else. */
7440 : 6060 : if (ExpT == SymbolTable_NulSym)
7441 : : {} /* empty. */
7442 : 6020 : else if (((DesT == SymbolTable_NulSym) && (SymbolTable_IsConst (Des))) && ((SymbolTable_IsConstructor (Des)) || (SymbolTable_IsConstSet (Des))))
7443 : : {
7444 : : /* avoid dangling else. */
7445 : 0 : SymbolTable_PutConst (Des, ExpT);
7446 : : }
7447 : 6020 : else if (! (M2Base_IsAssignmentCompatible (DesT, ExpT)))
7448 : : {
7449 : : /* avoid dangling else. */
7450 : 0 : M2MetaError_MetaErrorT1 (combinedtok, (const char *) "constructor expression is not compatible during assignment to {%1Ead}", 69, Des);
7451 : : }
7452 : : }
7453 : 342794 : else if (((DesT != SymbolTable_NulSym) && (SymbolTable_IsSet (DesT))) && (SymbolTable_IsConst (Exp)))
7454 : : {
7455 : : /* avoid dangling else. */
7456 : : }
7457 : 342782 : else if ((((((SymbolTable_IsConst (Exp)) && (ExpT != M2System_Address)) && (! (SymbolTable_IsConst (Des)))) && (DesL != SymbolTable_NulSym)) && ((DesL == M2Base_Cardinal) || (! (SymbolTable_IsSubrange (DesL))))) && (! (SymbolTable_IsEnumeration (DesL))))
7458 : : {
7459 : : /* avoid dangling else. */
7460 : 22593 : if ((M2Base_IsBaseType (DesL)) || (M2System_IsSystemType (DesL)))
7461 : : {
7462 : 22593 : M2Base_CheckAssignmentCompatible (combinedtok, ExpT, DesT);
7463 : : }
7464 : : else
7465 : : {
7466 : 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);
7467 : : }
7468 : : }
7469 : : else
7470 : : {
7471 : : /* avoid dangling else. */
7472 : 320189 : if (((DesT != SymbolTable_NulSym) && (SymbolTable_IsProcType (DesT))) && (SymbolTable_IsProcedure (Exp)))
7473 : : {
7474 : 25932 : DesT = SymbolTable_GetSType (DesT); /* we can at least check RETURN values of procedure variables */
7475 : : /* remember that thorough assignment checking is done post pass 3 */
7476 : 25932 : M2Base_CheckAssignmentCompatible (combinedtok, ExpT, DesT);
7477 : : }
7478 : : }
7479 : 352916 : }
7480 : :
7481 : :
7482 : : /*
7483 : : CheckBooleanId - Checks to see if the top operand is a boolean.
7484 : : If the operand is not a boolean then it is tested
7485 : : with true and a boolean is generated.
7486 : : The Stack:
7487 : :
7488 : :
7489 : : Entry Exit
7490 : : Ptr -> <- Ptr
7491 : : +------------+ +------------+
7492 : : | Sym | | t | f |
7493 : : |------------| |------------|
7494 : :
7495 : : Quadruples
7496 : :
7497 : : q If= Sym True _
7498 : : q+1 GotoOp _ _ _
7499 : : */
7500 : :
7501 : 72970 : static void CheckBooleanId (void)
7502 : : {
7503 : 72970 : unsigned int tok;
7504 : :
7505 : 72970 : if (! (IsBoolean (1)))
7506 : : {
7507 : 14677 : tok = static_cast<unsigned int> (M2Quads_OperandTok (1));
7508 : 14677 : if (SymbolTable_IsVar (M2Quads_OperandT (1)))
7509 : : {
7510 : 13351 : if ((SymbolTable_GetSType (M2Quads_OperandT (1))) != M2Base_Boolean)
7511 : : {
7512 : 0 : M2MetaError_MetaError1 ((const char *) "{%1Ua:is not a boolean expression}''{!%1Ua:boolean expression expected}", 71, M2Quads_OperandT (1));
7513 : : }
7514 : : }
7515 : 14677 : M2Quads_PushT (M2Reserved_EqualTok);
7516 : 14677 : M2Quads_PushT (M2Base_True);
7517 : 14677 : M2Quads_BuildRelOp (tok);
7518 : : }
7519 : 72970 : }
7520 : :
7521 : :
7522 : : /*
7523 : : PushOne - pushes the value one to the stack.
7524 : : The Stack is changed:
7525 : :
7526 : :
7527 : : Entry Exit
7528 : : ===== ====
7529 : :
7530 : : <- Ptr
7531 : : +------------+
7532 : : Ptr -> | 1 | type |
7533 : : |------------|
7534 : : */
7535 : :
7536 : 15036 : static void PushOne (unsigned int tok, unsigned int type, const char *message_, unsigned int _message_high)
7537 : : {
7538 : 15036 : unsigned int const_;
7539 : 15036 : char message[_message_high+1];
7540 : :
7541 : : /* make a local copy of each unbounded array. */
7542 : 15036 : memcpy (message, message_, _message_high+1);
7543 : :
7544 : 15036 : if (type == SymbolTable_NulSym)
7545 : : {
7546 : 100 : const_ = SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), SymbolTable_NulSym);
7547 : 100 : SymbolTable_PutConstLitInternal (const_, true);
7548 : 100 : M2Quads_PushTFtok (const_, static_cast<unsigned int> (SymbolTable_NulSym), tok);
7549 : : }
7550 : 14936 : else if (SymbolTable_IsEnumeration (type))
7551 : : {
7552 : : /* avoid dangling else. */
7553 : 238 : if ((SymbolTable_NoOfElements (type)) == 0)
7554 : : {
7555 : 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);
7556 : 0 : PushZero (tok, type);
7557 : : }
7558 : : else
7559 : : {
7560 : 238 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
7561 : 238 : M2Quads_PushT (type);
7562 : 238 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_ZType), M2Base_ZType, tok);
7563 : 238 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
7564 : 238 : BuildConvertFunction (M2Base_Convert, true); /* Two parameters */
7565 : : }
7566 : : }
7567 : : else
7568 : : {
7569 : : /* avoid dangling else. */
7570 : 14698 : const_ = SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), type);
7571 : 14698 : SymbolTable_PutConstLitInternal (const_, true);
7572 : 14698 : M2Quads_PushTFtok (const_, type, tok);
7573 : : }
7574 : 15036 : }
7575 : :
7576 : :
7577 : : /*
7578 : : PushZero - pushes the value zero to the stack.
7579 : : The Stack is changed:
7580 : :
7581 : :
7582 : : Entry Exit
7583 : : ===== ====
7584 : :
7585 : : <- Ptr
7586 : : +------------+
7587 : : Ptr -> | 0 | type |
7588 : : |------------|
7589 : : */
7590 : :
7591 : 7168 : static void PushZero (unsigned int tok, unsigned int type)
7592 : : {
7593 : 7168 : if (type == SymbolTable_NulSym)
7594 : : {
7595 : 304 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym), static_cast<unsigned int> (SymbolTable_NulSym), tok);
7596 : : }
7597 : 6864 : else if (SymbolTable_IsEnumeration (type))
7598 : : {
7599 : : /* avoid dangling else. */
7600 : 196 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
7601 : 196 : M2Quads_PushTtok (type, tok);
7602 : 196 : M2Quads_PushTtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType), tok);
7603 : 196 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
7604 : 196 : BuildConvertFunction (M2Base_Convert, true); /* Two parameters */
7605 : : }
7606 : : else
7607 : : {
7608 : : /* avoid dangling else. */
7609 : 6668 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), type), type, tok);
7610 : : }
7611 : 7168 : }
7612 : :
7613 : :
7614 : : /*
7615 : : ForLoopLastIterator - calculate the last iterator value but avoid setting
7616 : : LastIterator twice if it is a constant (in the quads).
7617 : : In the ForLoopLastIteratorVariable case only one
7618 : : path will be chosen but at the time of quadruple
7619 : : generation we do not know the value of BySym.
7620 : : */
7621 : :
7622 : 2148 : static void ForLoopLastIterator (unsigned int LastIterator, unsigned int e1, unsigned int e2, unsigned int BySym, unsigned int e1tok, unsigned int e2tok, unsigned int bytok)
7623 : : {
7624 : 2148 : if (! (SymbolTable_IsConst (BySym)))
7625 : : {
7626 : 18 : M2MetaError_MetaErrorT1 (bytok, (const char *) "{%E}the {%kFOR} loop {%kBY} expression must be constant, the expression {%1a} is variable", 89, BySym);
7627 : 18 : M2MetaError_MetaErrorDecl (BySym, true);
7628 : : }
7629 : : else
7630 : : {
7631 : 2130 : GenQuadOTypetok (bytok, M2Quads_LastForIteratorOp, LastIterator, SymbolTable_Make2Tuple (e1, e2), BySym, false, false, bytok, M2LexBuf_MakeVirtual2Tok (e1tok, e2tok), bytok);
7632 : : }
7633 : 2148 : }
7634 : :
7635 : :
7636 : : /*
7637 : : BuildSizeCheckEnd - checks to see whether the function "called" was in fact SIZE.
7638 : : If so then we restore quadruple generation.
7639 : : */
7640 : :
7641 : 7926 : static void BuildSizeCheckEnd (unsigned int ProcSym)
7642 : : {
7643 : 7926 : if (((ProcSym == M2Size_Size) || (ProcSym == M2System_TSize)) || (ProcSym == M2System_TBitSize))
7644 : : {
7645 : 5612 : QuadrupleGeneration = true;
7646 : 5612 : BuildingSize = false;
7647 : : }
7648 : 2314 : else if (ProcSym == M2Base_High)
7649 : : {
7650 : : /* avoid dangling else. */
7651 : 2314 : QuadrupleGeneration = true;
7652 : 2314 : BuildingHigh = false;
7653 : : }
7654 : 7926 : }
7655 : :
7656 : :
7657 : : /*
7658 : : BuildRealProcedureCall - builds a real procedure call.
7659 : : The Stack:
7660 : :
7661 : :
7662 : : Entry Exit
7663 : :
7664 : : Ptr ->
7665 : : +----------------+
7666 : : | NoOfParam |
7667 : : |----------------|
7668 : : | Param 1 |
7669 : : |----------------|
7670 : : | Param 2 |
7671 : : |----------------|
7672 : : . .
7673 : : . .
7674 : : . .
7675 : : |----------------|
7676 : : | Param # |
7677 : : |----------------|
7678 : : | ProcSym | Type | Empty
7679 : : |----------------|
7680 : : */
7681 : :
7682 : 148407 : static void BuildRealProcedureCall (unsigned int tokno)
7683 : : {
7684 : 148407 : unsigned int NoOfParam;
7685 : 148407 : unsigned int ProcSym;
7686 : :
7687 : 148407 : M2Quads_PopT (&NoOfParam);
7688 : 148407 : M2Quads_PushT (NoOfParam);
7689 : 148407 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+2));
7690 : 148407 : ProcSym = PCSymBuild_SkipConst (ProcSym);
7691 : : /* --checkme-- */
7692 : 148407 : if (SymbolTable_IsVar (ProcSym))
7693 : : {
7694 : : /* Procedure Variable ? */
7695 : 644 : ProcSym = SymbolTable_SkipType (M2Quads_OperandF (NoOfParam+2));
7696 : : }
7697 : 148407 : if ((SymbolTable_IsDefImp (SymbolTable_GetScope (ProcSym))) && (SymbolTable_IsDefinitionForC (SymbolTable_GetScope (ProcSym))))
7698 : : {
7699 : 12306 : BuildRealFuncProcCall (tokno, false, true, false);
7700 : : }
7701 : : else
7702 : : {
7703 : 136101 : BuildRealFuncProcCall (tokno, false, false, false);
7704 : : }
7705 : 148401 : }
7706 : :
7707 : :
7708 : : /*
7709 : : BuildRealFuncProcCall - builds a real procedure or function call.
7710 : : The Stack:
7711 : :
7712 : :
7713 : : Entry Exit
7714 : :
7715 : : Ptr ->
7716 : : +----------------+
7717 : : | NoOfParam |
7718 : : |----------------|
7719 : : | Param 1 |
7720 : : |----------------|
7721 : : | Param 2 |
7722 : : |----------------|
7723 : : . .
7724 : : . .
7725 : : . .
7726 : : |----------------|
7727 : : | Param # |
7728 : : |----------------|
7729 : : | ProcSym | Type | Empty
7730 : : |----------------|
7731 : : */
7732 : :
7733 : 190449 : static void BuildRealFuncProcCall (unsigned int tokno, bool IsFunc, bool IsForC, bool ConstExpr)
7734 : : {
7735 : 190449 : bool AllocateProc;
7736 : 190449 : bool DeallocateProc;
7737 : 190449 : bool ForcedFunc;
7738 : 190449 : bool ParamConstant;
7739 : 190449 : unsigned int trash;
7740 : 190449 : unsigned int resulttok;
7741 : 190449 : unsigned int paramtok;
7742 : 190449 : unsigned int proctok;
7743 : 190449 : unsigned int NoOfParameters;
7744 : 190449 : unsigned int i;
7745 : 190449 : unsigned int pi;
7746 : 190449 : unsigned int ParamType;
7747 : 190449 : unsigned int Param1;
7748 : 190449 : unsigned int ReturnVar;
7749 : 190449 : unsigned int ProcSym;
7750 : 190449 : unsigned int Proc;
7751 : :
7752 : 190449 : Param1 = SymbolTable_NulSym; /* Used to remember first param for allocate/deallocate. */
7753 : 190449 : ParamType = SymbolTable_NulSym;
7754 : 190449 : CheckProcedureParameters (IsForC);
7755 : 190437 : M2Quads_PopT (&NoOfParameters);
7756 : 190437 : M2Quads_PushT (NoOfParameters); /* Restore stack to original state. */
7757 : 190437 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+2)); /* Restore stack to original state. */
7758 : 190437 : proctok = tokno; /* OperandTtok (NoOfParameters+2) ; */
7759 : 190437 : if (proctok == M2LexBuf_UnknownTokenNo) /* OperandTtok (NoOfParameters+2) ; */
7760 : : {
7761 : 0 : proctok = M2LexBuf_GetTokenNo ();
7762 : : }
7763 : 190437 : paramtok = proctok;
7764 : 190437 : ProcSym = PCSymBuild_SkipConst (ProcSym);
7765 : 190437 : ForcedFunc = false;
7766 : 190437 : AllocateProc = false;
7767 : 190437 : DeallocateProc = false;
7768 : 190437 : if (SymbolTable_IsVar (ProcSym))
7769 : : {
7770 : : /* Procedure Variable ? */
7771 : 720 : Proc = SymbolTable_SkipType (M2Quads_OperandF (NoOfParameters+2));
7772 : 720 : ParamConstant = false;
7773 : : }
7774 : : else
7775 : : {
7776 : 189717 : Proc = ProcSym;
7777 : 189717 : ParamConstant = true;
7778 : 189717 : AllocateProc = (SymbolTable_GetSymName (Proc)) == (NameKey_MakeKey ((const char *) "ALLOCATE", 8));
7779 : 189717 : DeallocateProc = (SymbolTable_GetSymName (Proc)) == (NameKey_MakeKey ((const char *) "DEALLOCATE", 10));
7780 : : }
7781 : 190437 : if (IsFunc)
7782 : : {
7783 : : /* avoid dangling else. */
7784 : 42036 : if ((SymbolTable_GetSType (Proc)) == SymbolTable_NulSym)
7785 : : {
7786 : 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);
7787 : : }
7788 : : }
7789 : : else
7790 : : {
7791 : : /* is being called as a procedure */
7792 : 148401 : if ((SymbolTable_GetSType (Proc)) != SymbolTable_NulSym)
7793 : : {
7794 : : /* however it was declared as a procedure function */
7795 : 6658 : if (! (SymbolTable_IsReturnOptionalAny (Proc)))
7796 : : {
7797 : 6 : M2MetaError_MetaErrors1 ((const char *) "function {%1a} is being called but its return value is ignored", 62, (const char *) "function {%1Da} return a type {%1ta:of {%1ta}}", 46, Proc);
7798 : : }
7799 : : IsFunc = true;
7800 : : ForcedFunc = true;
7801 : : }
7802 : : }
7803 : 190437 : if (AllocateProc || DeallocateProc)
7804 : : {
7805 : 1414 : Param1 = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+1)); /* Remember this before manipulating. */
7806 : : }
7807 : 190437 : ManipulateParameters (IsForC);
7808 : 190437 : CheckParameterOrdinals ();
7809 : 190437 : M2Quads_PopT (&NoOfParameters);
7810 : 190437 : if (IsFunc)
7811 : : {
7812 : 48694 : GenQuad (M2Quads_ParamOp, 0, Proc, ProcSym); /* Space for return value */
7813 : : }
7814 : 190437 : if (((NoOfParameters+1) == (SymbolTable_NoOfParamAny (Proc))) && (SymbolTable_UsesOptArgAny (Proc)))
7815 : : {
7816 : 3146 : GenQuad (M2Quads_OptParamOp, SymbolTable_NoOfParamAny (Proc), Proc, Proc);
7817 : : }
7818 : 190437 : i = NoOfParameters;
7819 : 190437 : pi = 1; /* stack index referencing stacked parameter, i */
7820 : 680324 : while (i > 0) /* stack index referencing stacked parameter, i */
7821 : : {
7822 : 489887 : paramtok = OperandTtok (pi);
7823 : 489887 : if (((AllocateProc || DeallocateProc) && (i == 1)) && (Param1 != SymbolTable_NulSym))
7824 : : {
7825 : 1414 : ParamType = GetItemPointedTo (Param1);
7826 : 1414 : if (ParamType == SymbolTable_NulSym)
7827 : : {
7828 : 0 : GenQuadO (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true);
7829 : : }
7830 : : else
7831 : : {
7832 : 1414 : if (AllocateProc)
7833 : : {
7834 : 942 : trash = SymbolTable_MakeTemporary (paramtok, SymbolTable_RightValue);
7835 : 942 : SymbolTable_PutVar (trash, ParamType);
7836 : 942 : SymbolTable_PutVarHeap (trash, true);
7837 : : }
7838 : : else
7839 : : {
7840 : 472 : M2Debug_Assert (DeallocateProc);
7841 : 472 : trash = M2Base_Nil;
7842 : : }
7843 : 1414 : GenQuadOTrash (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true, trash);
7844 : : }
7845 : : }
7846 : : else
7847 : : {
7848 : 488473 : GenQuadO (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true);
7849 : : }
7850 : 489887 : if (! (SymbolTable_IsConst (M2Quads_OperandT (pi))))
7851 : : {
7852 : 412911 : ParamConstant = false;
7853 : : }
7854 : 489887 : i -= 1;
7855 : 489887 : pi += 1;
7856 : : }
7857 : 380874 : GenQuadO (proctok, M2Quads_CallOp, SymbolTable_NulSym, SymbolTable_NulSym, ProcSym, true);
7858 : 190437 : M2Quads_PopN (NoOfParameters+1); /* Destroy arguments and procedure call */
7859 : 190437 : if (IsFunc)
7860 : : {
7861 : : /* ReturnVar has the type of the procedure. */
7862 : 48694 : resulttok = M2LexBuf_MakeVirtualTok (proctok, proctok, paramtok);
7863 : 48694 : if (ConstExpr && (! (SymbolTable_IsProcedureBuiltinAvailable (Proc))))
7864 : : {
7865 : 0 : M2MetaError_MetaError1 ((const char *) "{%1d} {%1ad} cannot be used in a constant expression", 52, Proc);
7866 : 0 : ParamConstant = false;
7867 : : }
7868 : 48694 : ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (ParamConstant && ConstExpr));
7869 : 48694 : SymbolTable_PutVar (ReturnVar, SymbolTable_GetSType (Proc));
7870 : 97388 : GenQuadO (resulttok, M2Quads_FunctValueOp, ReturnVar, SymbolTable_NulSym, Proc, true);
7871 : 48694 : if (! ForcedFunc)
7872 : : {
7873 : 42036 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (Proc), resulttok);
7874 : : }
7875 : : }
7876 : 190437 : }
7877 : :
7878 : :
7879 : : /*
7880 : : CheckProcedureParameters - Checks the parameters which are being passed to
7881 : : procedure ProcSym.
7882 : :
7883 : : The Stack:
7884 : :
7885 : :
7886 : : Entry Exit
7887 : :
7888 : : Ptr -> <- Ptr
7889 : : +----------------+ +----------------+
7890 : : | NoOfParam | | NoOfParam |
7891 : : |----------------| |----------------|
7892 : : | Param 1 | | Param 1 |
7893 : : |----------------| |----------------|
7894 : : | Param 2 | | Param 2 |
7895 : : |----------------| |----------------|
7896 : : . . . .
7897 : : . . . .
7898 : : . . . .
7899 : : |----------------| |----------------|
7900 : : | Param # | | Param # |
7901 : : |----------------| |----------------|
7902 : : | ProcSym | Type | | ProcSym | Type |
7903 : : |----------------| |----------------|
7904 : :
7905 : : */
7906 : :
7907 : 190449 : static void CheckProcedureParameters (bool IsForC)
7908 : : {
7909 : 190449 : unsigned int proctok;
7910 : 190449 : unsigned int paramtok;
7911 : 190449 : NameKey_Name n1;
7912 : 190449 : NameKey_Name n2;
7913 : 190449 : unsigned int Dim;
7914 : 190449 : unsigned int Actual;
7915 : 190449 : unsigned int FormalI;
7916 : 190449 : unsigned int ParamTotal;
7917 : 190449 : unsigned int pi;
7918 : 190449 : unsigned int Proc;
7919 : 190449 : unsigned int ProcSym;
7920 : 190449 : unsigned int i;
7921 : 190449 : DynamicStrings_String s;
7922 : :
7923 : 190449 : M2Quads_PopT (&ParamTotal);
7924 : 190449 : M2Quads_PushT (ParamTotal); /* Restore stack to origional state */
7925 : 190449 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((ParamTotal+1)+1)); /* Restore stack to origional state */
7926 : 190449 : proctok = OperandTtok ((ParamTotal+1)+1);
7927 : 190449 : if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (SymbolTable_GetDType (ProcSym))))
7928 : : {
7929 : : /* Procedure Variable ? */
7930 : 720 : Proc = SymbolTable_SkipType (M2Quads_OperandF ((ParamTotal+1)+1));
7931 : : }
7932 : : else
7933 : : {
7934 : 189729 : Proc = PCSymBuild_SkipConst (ProcSym);
7935 : : }
7936 : 190449 : if (! ((SymbolTable_IsProcedure (Proc)) || (SymbolTable_IsProcType (Proc))))
7937 : : {
7938 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
7939 : 12 : if (SymbolTable_IsUnknown (Proc))
7940 : : {
7941 : 0 : M2MetaError_MetaError1 ((const char *) "{%1Ua} is not recognised as a procedure, check declaration or import", 68, Proc);
7942 : : }
7943 : : else
7944 : : {
7945 : 12 : 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);
7946 : : }
7947 : : }
7948 : 190449 : if (M2Options_CompilerDebugging)
7949 : : {
7950 : 0 : n1 = SymbolTable_GetSymName (Proc);
7951 : 0 : M2Printf_printf1 ((const char *) " %a ( ", 7, (const unsigned char *) &n1, (sizeof (n1)-1));
7952 : : }
7953 : 190449 : if (DebugTokPos)
7954 : : {
7955 : : s = DynamicStrings_InitString ((const char *) "procedure", 9);
7956 : : M2Error_WarnStringAt (s, proctok);
7957 : : }
7958 : 190449 : i = 1;
7959 : 190449 : pi = ParamTotal+1; /* stack index referencing stacked parameter, i */
7960 : 677618 : while (i <= ParamTotal) /* stack index referencing stacked parameter, i */
7961 : : {
7962 : 487181 : if (i <= (SymbolTable_NoOfParamAny (Proc)))
7963 : : {
7964 : 482843 : FormalI = SymbolTable_GetParam (Proc, i);
7965 : 482843 : if (M2Options_CompilerDebugging)
7966 : : {
7967 : 0 : n1 = SymbolTable_GetSymName (FormalI);
7968 : 0 : n2 = SymbolTable_GetSymName (SymbolTable_GetSType (FormalI));
7969 : 0 : M2Printf_printf2 ((const char *) "%a: %a", 6, (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
7970 : : }
7971 : 482843 : Actual = static_cast<unsigned int> (M2Quads_OperandT (pi));
7972 : 482843 : Dim = static_cast<unsigned int> (OperandD (pi));
7973 : 482843 : paramtok = OperandTtok (pi);
7974 : 482843 : if (DebugTokPos)
7975 : : {
7976 : : s = DynamicStrings_InitString ((const char *) "actual", 6);
7977 : : M2Error_WarnStringAt (s, paramtok);
7978 : : }
7979 : 482843 : BuildRange (M2Range_InitTypesParameterCheck (paramtok, Proc, i, FormalI, Actual));
7980 : 482843 : if (SymbolTable_IsConst (Actual))
7981 : : {
7982 : : /* avoid dangling else. */
7983 : 108004 : if (SymbolTable_IsVarParamAny (Proc, i))
7984 : : {
7985 : 0 : FailParameter (paramtok, (const char *) "trying to pass a constant to a VAR parameter", 44, Actual, Proc, i);
7986 : : }
7987 : 108004 : else if (SymbolTable_IsConstString (Actual))
7988 : : {
7989 : : /* avoid dangling else. */
7990 : 33396 : if (! (SymbolTable_IsConstStringKnown (Actual)))
7991 : : {} /* empty. */
7992 : 33162 : else if ((SymbolTable_IsArray (SymbolTable_GetDType (FormalI))) && ((SymbolTable_GetSType (SymbolTable_GetDType (FormalI))) == M2Base_Char))
7993 : : {
7994 : : /* avoid dangling else. */
7995 : : }
7996 : 33138 : else if ((SymbolTable_GetStringLength (paramtok, Actual)) == 1)
7997 : : {
7998 : : /* avoid dangling else. */
7999 : 3368 : CheckParameter (paramtok, Actual, Dim, FormalI, Proc, i, static_cast<Lists_List> (NULL));
8000 : : }
8001 : 29770 : else if (! (SymbolTable_IsUnboundedParamAny (Proc, i)))
8002 : : {
8003 : : /* avoid dangling else. */
8004 : 0 : if (IsForC && ((SymbolTable_GetSType (FormalI)) == M2System_Address))
8005 : : {
8006 : 0 : FailParameter (paramtok, (const char *) "a string constant can either be passed to an ADDRESS parameter or an ARRAY OF CHAR", 82, Actual, Proc, i);
8007 : : }
8008 : : else
8009 : : {
8010 : 0 : FailParameter (paramtok, (const char *) "cannot pass a string constant to a non unbounded array parameter", 64, Actual, Proc, i);
8011 : : }
8012 : : }
8013 : : }
8014 : : }
8015 : : else
8016 : : {
8017 : 374839 : CheckParameter (paramtok, Actual, Dim, FormalI, Proc, i, static_cast<Lists_List> (NULL));
8018 : : }
8019 : : }
8020 : : else
8021 : : {
8022 : 4326 : if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
8023 : : {
8024 : : /* these are varargs, therefore we don't check them */
8025 : 4326 : i = ParamTotal;
8026 : : }
8027 : : else
8028 : : {
8029 : 0 : M2MetaError_MetaErrorT2 (proctok, (const char *) "too many parameters, {%2n} passed to {%1a} ", 43, Proc, i);
8030 : : }
8031 : : }
8032 : 487169 : i += 1;
8033 : 487169 : pi -= 1;
8034 : 487169 : if (M2Options_CompilerDebugging)
8035 : : {
8036 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
8037 : 0 : if (i <= ParamTotal)
8038 : : {
8039 : 0 : M2Printf_printf0 ((const char *) "; ", 2);
8040 : : }
8041 : : else
8042 : : {
8043 : 0 : M2Printf_printf0 ((const char *) " ) ; \\n", 7);
8044 : : }
8045 : : }
8046 : : }
8047 : 190437 : }
8048 : :
8049 : :
8050 : : /*
8051 : : CheckProcTypeAndProcedure - checks the ProcType with the call.
8052 : : */
8053 : :
8054 : 48015 : static void CheckProcTypeAndProcedure (unsigned int tokno, unsigned int ProcType, unsigned int call)
8055 : : {
8056 : 48015 : NameKey_Name n1;
8057 : 48015 : NameKey_Name n2;
8058 : 48015 : unsigned int i;
8059 : 48015 : unsigned int n;
8060 : 48015 : unsigned int t;
8061 : 48015 : unsigned int CheckedProcedure;
8062 : 48015 : M2Error_Error e;
8063 : :
8064 : 48015 : n = SymbolTable_NoOfParamAny (ProcType);
8065 : 48015 : if (((SymbolTable_IsVar (call)) || (SymbolTable_IsTemporary (call))) || (SymbolTable_IsParameter (call)))
8066 : : {
8067 : 580 : CheckedProcedure = SymbolTable_GetDType (call);
8068 : : }
8069 : : else
8070 : : {
8071 : : CheckedProcedure = call;
8072 : : }
8073 : 48015 : if (n != (SymbolTable_NoOfParamAny (CheckedProcedure)))
8074 : : {
8075 : 0 : e = M2Error_NewError (SymbolTable_GetDeclaredMod (ProcType));
8076 : 0 : n1 = SymbolTable_GetSymName (call);
8077 : 0 : n2 = SymbolTable_GetSymName (ProcType);
8078 : 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));
8079 : 0 : e = M2Error_ChainError (SymbolTable_GetDeclaredMod (call), e);
8080 : 0 : t = SymbolTable_NoOfParamAny (CheckedProcedure);
8081 : 0 : if (n < 2)
8082 : : {
8083 : 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));
8084 : : }
8085 : : else
8086 : : {
8087 : 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));
8088 : : }
8089 : : }
8090 : : else
8091 : : {
8092 : : i = 1;
8093 : 142727 : while (i <= n)
8094 : : {
8095 : 94712 : if ((SymbolTable_IsVarParamAny (ProcType, i)) != (SymbolTable_IsVarParamAny (CheckedProcedure, i)))
8096 : : {
8097 : 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);
8098 : 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);
8099 : : }
8100 : 94712 : BuildRange (M2Range_InitTypesParameterCheck (tokno, CheckedProcedure, i, SymbolTable_GetParam (CheckedProcedure, i), SymbolTable_GetParam (ProcType, i)));
8101 : : /* CheckParameter(tokpos, GetParam(CheckedProcedure, i), 0, GetParam(ProcType, i), call, i, TypeList) ; */
8102 : 94712 : i += 1;
8103 : : }
8104 : : }
8105 : 48015 : }
8106 : :
8107 : :
8108 : : /*
8109 : : IsReallyPointer - returns TRUE is sym is a pointer, address or a type declared
8110 : : as a pointer or address.
8111 : : */
8112 : :
8113 : 956 : static bool IsReallyPointer (unsigned int Sym)
8114 : : {
8115 : 956 : if (SymbolTable_IsVar (Sym))
8116 : : {
8117 : 956 : Sym = SymbolTable_GetSType (Sym);
8118 : : }
8119 : 956 : Sym = SymbolTable_SkipType (Sym);
8120 : 956 : return (SymbolTable_IsPointer (Sym)) || (Sym == M2System_Address);
8121 : : /* static analysis guarentees a RETURN statement will be used before here. */
8122 : : __builtin_unreachable ();
8123 : : }
8124 : :
8125 : :
8126 : : /*
8127 : : LegalUnboundedParam - returns TRUE if the parameter, Actual, can legitimately be
8128 : : passed to ProcSym, i, the, Formal, parameter.
8129 : : */
8130 : :
8131 : 9316 : static bool LegalUnboundedParam (unsigned int tokpos, unsigned int ProcSym, unsigned int i, unsigned int ActualType, unsigned int Actual, unsigned int Dimension, unsigned int Formal)
8132 : : {
8133 : 9316 : unsigned int FormalType;
8134 : 9316 : unsigned int n;
8135 : 9316 : unsigned int m;
8136 : :
8137 : 9316 : ActualType = SymbolTable_SkipType (ActualType);
8138 : 9316 : FormalType = SymbolTable_GetDType (Formal);
8139 : 9316 : FormalType = SymbolTable_GetSType (FormalType); /* type of the unbounded ARRAY */
8140 : 9316 : if (SymbolTable_IsArray (ActualType)) /* type of the unbounded ARRAY */
8141 : : {
8142 : 6894 : m = SymbolTable_GetDimension (Formal);
8143 : 6894 : n = 0;
8144 : 14034 : while (SymbolTable_IsArray (ActualType))
8145 : : {
8146 : 7062 : n += 1;
8147 : 7062 : ActualType = SymbolTable_GetDType (ActualType);
8148 : 7062 : if ((m == n) && (ActualType == FormalType))
8149 : : {
8150 : : return true;
8151 : : }
8152 : : }
8153 : 78 : if (n == m)
8154 : : {} /* empty. */
8155 : : else
8156 : : {
8157 : : /* now we fall though and test ActualType against FormalType */
8158 : 24 : if (M2System_IsGenericSystemType (FormalType))
8159 : : {
8160 : : return true;
8161 : : }
8162 : : else
8163 : : {
8164 : 12 : FailParameter (tokpos, (const char *) "attempting to pass an array with the incorrect number dimenisons to an unbounded formal parameter of different dimensions", 121, Actual, ProcSym, i);
8165 : 12 : return false;
8166 : : }
8167 : : }
8168 : : }
8169 : 2422 : else if (SymbolTable_IsUnbounded (ActualType))
8170 : : {
8171 : : /* avoid dangling else. */
8172 : 36 : if ((Dimension == 0) && ((SymbolTable_GetDimension (Formal)) == (SymbolTable_GetDimension (Actual))))
8173 : : {
8174 : : /* now we fall though and test ActualType against FormalType */
8175 : 0 : ActualType = SymbolTable_GetSType (ActualType);
8176 : : }
8177 : : else
8178 : : {
8179 : 36 : if (M2System_IsGenericSystemType (FormalType))
8180 : : {
8181 : : return true;
8182 : : }
8183 : : else
8184 : : {
8185 : 12 : if (((SymbolTable_GetDimension (Actual))-Dimension) == (SymbolTable_GetDimension (Formal)))
8186 : : {
8187 : 12 : ActualType = SymbolTable_GetSType (ActualType);
8188 : : }
8189 : : else
8190 : : {
8191 : 0 : FailParameter (tokpos, (const char *) "attempting to pass an unbounded array with the incorrect number dimenisons to an unbounded formal parameter of different dimensions", 131, Actual, ProcSym, i);
8192 : 0 : return false;
8193 : : }
8194 : : }
8195 : : }
8196 : : }
8197 : 2452 : if (((M2System_IsGenericSystemType (FormalType)) || (M2System_IsGenericSystemType (ActualType))) || (M2Base_IsAssignmentCompatible (FormalType, ActualType)))
8198 : : {
8199 : : /* we think it is legal, but we ask post pass 3 to check as
8200 : : not all types are known at this point */
8201 : 2446 : return true;
8202 : : }
8203 : : else
8204 : : {
8205 : 6 : FailParameter (tokpos, (const char *) "identifier with an incompatible type is being passed to this procedure", 70, Actual, ProcSym, i);
8206 : 6 : return false;
8207 : : }
8208 : : /* static analysis guarentees a RETURN statement will be used before here. */
8209 : : __builtin_unreachable ();
8210 : : }
8211 : :
8212 : :
8213 : : /*
8214 : : CheckParameter - checks that types ActualType and FormalType are compatible for parameter
8215 : : passing. ProcSym is the procedure and i is the parameter number.
8216 : :
8217 : : We obey the following rules:
8218 : :
8219 : : (1) we allow WORD, BYTE, LOC to be compitable with any like sized
8220 : : type.
8221 : : (2) we allow ADDRESS to be compatible with any pointer type.
8222 : : (3) we relax INTEGER and CARDINAL checking for Temporary variables.
8223 : :
8224 : : Note that type sizes are checked during the code generation pass.
8225 : : */
8226 : :
8227 : 378207 : static void CheckParameter (unsigned int tokpos, unsigned int Actual, unsigned int Dimension, unsigned int Formal, unsigned int ProcSym, unsigned int i, Lists_List TypeList)
8228 : : {
8229 : 378207 : bool NewList;
8230 : 378207 : unsigned int ActualType;
8231 : 378207 : unsigned int FormalType;
8232 : :
8233 : 378207 : if ((SymbolTable_IsConstString (Actual)) && (! (SymbolTable_IsConstStringKnown (Actual))))
8234 : : {
8235 : : /* Cannot check if the string content is not yet known. */
8236 : : return;
8237 : : }
8238 : 378207 : FormalType = SymbolTable_GetDType (Formal);
8239 : 378207 : if ((SymbolTable_IsConstString (Actual)) && ((SymbolTable_GetStringLength (tokpos, Actual)) == 1)) /* if = 1 then it maybe treated as a char */
8240 : : {
8241 : 3368 : ActualType = M2Base_Char;
8242 : : }
8243 : 374839 : else if (Actual == M2Base_Boolean)
8244 : : {
8245 : : /* avoid dangling else. */
8246 : : ActualType = Actual;
8247 : : }
8248 : : else
8249 : : {
8250 : : /* avoid dangling else. */
8251 : 374839 : ActualType = SymbolTable_GetDType (Actual);
8252 : : }
8253 : 378207 : if (TypeList == NULL)
8254 : : {
8255 : 378207 : NewList = true;
8256 : 378207 : Lists_InitList (&TypeList);
8257 : : }
8258 : : else
8259 : : {
8260 : : NewList = false;
8261 : : }
8262 : 378207 : if (Lists_IsItemInList (TypeList, ActualType))
8263 : : {
8264 : : /* no need to check */
8265 : : return;
8266 : : }
8267 : 378207 : Lists_IncludeItemIntoList (TypeList, ActualType);
8268 : 378207 : if (SymbolTable_IsProcType (FormalType))
8269 : : {
8270 : 48015 : if ((! (SymbolTable_IsProcedure (Actual))) && ((ActualType == SymbolTable_NulSym) || (! (SymbolTable_IsProcType (SymbolTable_SkipType (ActualType))))))
8271 : : {
8272 : 0 : FailParameter (tokpos, (const char *) "expecting a procedure or procedure variable as a parameter", 58, Actual, ProcSym, i);
8273 : 0 : return;
8274 : : }
8275 : 48015 : if ((SymbolTable_IsProcedure (Actual)) && (SymbolTable_IsProcedureNested (Actual)))
8276 : : {
8277 : 6 : M2MetaError_MetaError2 ((const char *) "cannot pass a nested procedure {%1Ea} seen in the {%2N} parameter as the outer scope will be unknown at runtime", 111, Actual, i);
8278 : : }
8279 : : /* we can check the return type of both proc types */
8280 : 48015 : if ((ActualType != SymbolTable_NulSym) && (SymbolTable_IsProcType (ActualType)))
8281 : : {
8282 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
8283 : 580 : if (((SymbolTable_GetSType (ActualType)) != SymbolTable_NulSym) && ((SymbolTable_GetSType (FormalType)) == SymbolTable_NulSym))
8284 : : {
8285 : 0 : FailParameter (tokpos, (const char *) "the item being passed is a function whereas the formal procedure parameter is a procedure", 89, Actual, ProcSym, i);
8286 : 0 : return;
8287 : : }
8288 : 580 : else if (((SymbolTable_GetSType (ActualType)) == SymbolTable_NulSym) && ((SymbolTable_GetSType (FormalType)) != SymbolTable_NulSym))
8289 : : {
8290 : : /* avoid dangling else. */
8291 : 0 : FailParameter (tokpos, (const char *) "the item being passed is a procedure whereas the formal procedure parameter is a function", 89, Actual, ProcSym, i);
8292 : 0 : return;
8293 : : }
8294 : 580 : else if (M2Base_AssignmentRequiresWarning (SymbolTable_GetSType (ActualType), SymbolTable_GetSType (FormalType)))
8295 : : {
8296 : : /* avoid dangling else. */
8297 : 0 : WarnParameter (tokpos, (const char *) "the return result of the procedure variable parameter may not be compatible on other targets with the return result of the item being passed", 140, Actual, ProcSym, i);
8298 : 0 : return;
8299 : : }
8300 : 580 : else if (((M2System_IsGenericSystemType (SymbolTable_GetSType (FormalType))) || (M2System_IsGenericSystemType (SymbolTable_GetSType (ActualType)))) || (M2Base_IsAssignmentCompatible (SymbolTable_GetSType (ActualType), SymbolTable_GetSType (FormalType))))
8301 : : {
8302 : : /* avoid dangling else. */
8303 : : }
8304 : : else
8305 : : {
8306 : : /* avoid dangling else. */
8307 : : /* pass */
8308 : 0 : FailParameter (tokpos, (const char *) "the return result of the procedure variable parameter is not compatible with the return result of the item being passed", 119, Actual, ProcSym, i);
8309 : 0 : return;
8310 : : }
8311 : : }
8312 : : /* now to check each parameter of the proc type */
8313 : 48015 : CheckProcTypeAndProcedure (tokpos, FormalType, Actual);
8314 : : }
8315 : 330192 : else if ((ActualType != FormalType) && (ActualType != SymbolTable_NulSym))
8316 : : {
8317 : : /* avoid dangling else. */
8318 : 15398 : if (SymbolTable_IsUnknown (FormalType))
8319 : : {
8320 : 0 : FailParameter (tokpos, (const char *) "procedure parameter type is undeclared", 38, Actual, ProcSym, i);
8321 : 0 : return;
8322 : : }
8323 : 15398 : if ((SymbolTable_IsUnbounded (ActualType)) && (! (SymbolTable_IsUnboundedParamAny (ProcSym, i))))
8324 : : {
8325 : 0 : FailParameter (tokpos, (const char *) "attempting to pass an unbounded array to a NON unbounded parameter", 66, Actual, ProcSym, i);
8326 : 0 : return;
8327 : : }
8328 : 15398 : else if (SymbolTable_IsUnboundedParamAny (ProcSym, i))
8329 : : {
8330 : : /* avoid dangling else. */
8331 : 9316 : if (! (LegalUnboundedParam (tokpos, ProcSym, i, ActualType, Actual, Dimension, Formal)))
8332 : : {
8333 : : return;
8334 : : }
8335 : : }
8336 : 6082 : else if (ActualType != FormalType)
8337 : : {
8338 : : /* avoid dangling else. */
8339 : 6082 : if (M2Base_AssignmentRequiresWarning (FormalType, ActualType))
8340 : : {
8341 : 0 : WarnParameter (tokpos, (const char *) "identifier being passed to this procedure may contain a possibly incompatible type when compiling for a different target", 120, Actual, ProcSym, i);
8342 : : }
8343 : 6082 : else if (((M2System_IsGenericSystemType (FormalType)) || (M2System_IsGenericSystemType (ActualType))) || (M2Base_IsAssignmentCompatible (ActualType, FormalType)))
8344 : : {
8345 : : /* avoid dangling else. */
8346 : : }
8347 : : else
8348 : : {
8349 : : /* avoid dangling else. */
8350 : : /* so far we know it is legal, but not all types have been resolved
8351 : : and so this is checked later on in another pass. */
8352 : 24 : FailParameter (tokpos, (const char *) "identifier with an incompatible type is being passed to this procedure", 70, Actual, ProcSym, i);
8353 : : }
8354 : : }
8355 : : }
8356 : 378189 : if (NewList)
8357 : : {
8358 : 378189 : Lists_KillList (&TypeList);
8359 : : }
8360 : : }
8361 : :
8362 : :
8363 : : /*
8364 : : DescribeType - returns a String describing a symbol, Sym, name and its type.
8365 : : */
8366 : :
8367 : 0 : static DynamicStrings_String DescribeType (unsigned int Sym)
8368 : : {
8369 : 0 : DynamicStrings_String s;
8370 : 0 : DynamicStrings_String s1;
8371 : 0 : DynamicStrings_String s2;
8372 : 0 : unsigned int Low;
8373 : 0 : unsigned int High;
8374 : 0 : unsigned int Subrange;
8375 : 0 : unsigned int Subscript;
8376 : 0 : unsigned int Type;
8377 : :
8378 : 0 : s = static_cast<DynamicStrings_String> (NULL);
8379 : 0 : if (SymbolTable_IsConstString (Sym))
8380 : : {
8381 : : /* If = 1 then it maybe treated as a char. */
8382 : 0 : if ((SymbolTable_IsConstStringKnown (Sym)) && ((SymbolTable_GetStringLength (SymbolTable_GetDeclaredMod (Sym), Sym)) == 1))
8383 : : {
8384 : 0 : s = DynamicStrings_InitString ((const char *) "(constant string) or {%kCHAR}", 29);
8385 : : }
8386 : : else
8387 : : {
8388 : 0 : s = DynamicStrings_InitString ((const char *) "(constant string)", 17);
8389 : : }
8390 : : }
8391 : 0 : else if (SymbolTable_IsConst (Sym))
8392 : : {
8393 : : /* avoid dangling else. */
8394 : 0 : s = DynamicStrings_InitString ((const char *) "(constant)", 10);
8395 : : }
8396 : 0 : else if (SymbolTable_IsUnknown (Sym))
8397 : : {
8398 : : /* avoid dangling else. */
8399 : 0 : s = DynamicStrings_InitString ((const char *) "(unknown)", 9);
8400 : : }
8401 : : else
8402 : : {
8403 : : /* avoid dangling else. */
8404 : 0 : Type = SymbolTable_GetSType (Sym);
8405 : 0 : if (Type == SymbolTable_NulSym)
8406 : : {
8407 : 0 : s = DynamicStrings_InitString ((const char *) "(unknown)", 9);
8408 : : }
8409 : 0 : else if (SymbolTable_IsUnbounded (Type))
8410 : : {
8411 : : /* avoid dangling else. */
8412 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (SymbolTable_GetSType (Type)))));
8413 : 0 : s = FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "{%%kARRAY} {%%kOF} %s", 21)), (const unsigned char *) &s1, (sizeof (s1)-1));
8414 : : }
8415 : 0 : else if (SymbolTable_IsArray (Type))
8416 : : {
8417 : : /* avoid dangling else. */
8418 : 0 : s = DynamicStrings_InitString ((const char *) "{%kARRAY} [", 11);
8419 : 0 : Subscript = SymbolTable_GetArraySubscript (Type);
8420 : 0 : if (Subscript != SymbolTable_NulSym)
8421 : : {
8422 : 0 : M2Debug_Assert (SymbolTable_IsSubscript (Subscript));
8423 : 0 : Subrange = SymbolTable_GetSType (Subscript);
8424 : 0 : if (! (SymbolTable_IsSubrange (Subrange)))
8425 : : {
8426 : 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);
8427 : : }
8428 : 0 : M2Debug_Assert (SymbolTable_IsSubrange (Subrange));
8429 : 0 : SymbolTable_GetSubrange (Subrange, &High, &Low);
8430 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Low))));
8431 : 0 : s2 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (High))));
8432 : 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))));
8433 : : }
8434 : 0 : s1 = DynamicStrings_Mark (DescribeType (Type));
8435 : 0 : s = DynamicStrings_ConCat (DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "] OF ", 5))), s1);
8436 : : }
8437 : : else
8438 : : {
8439 : : /* avoid dangling else. */
8440 : 0 : if (SymbolTable_IsUnknown (Type))
8441 : : {
8442 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Type))));
8443 : 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));
8444 : : }
8445 : : else
8446 : : {
8447 : 0 : s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Type)));
8448 : : }
8449 : : }
8450 : : }
8451 : 0 : return s;
8452 : : /* static analysis guarentees a RETURN statement will be used before here. */
8453 : : __builtin_unreachable ();
8454 : : }
8455 : :
8456 : :
8457 : : /*
8458 : : FailParameter - generates an error message indicating that a parameter
8459 : : declaration has failed.
8460 : :
8461 : : The parameters are:
8462 : :
8463 : : CurrentState - string describing the current failing state.
8464 : : Actual - actual parameter.
8465 : : ParameterNo - parameter number that has failed.
8466 : : ProcedureSym - procedure symbol where parameter has failed.
8467 : :
8468 : : If any parameter is Nul then it is ignored.
8469 : : */
8470 : :
8471 : 42 : static void FailParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo)
8472 : : {
8473 : 42 : unsigned int FormalParam;
8474 : 42 : DynamicStrings_String Msg;
8475 : 42 : char CurrentState[_CurrentState_high+1];
8476 : :
8477 : : /* make a local copy of each unbounded array. */
8478 : 42 : memcpy (CurrentState, CurrentState_, _CurrentState_high+1);
8479 : :
8480 : 84 : Msg = DynamicStrings_InitString ((const char *) "parameter mismatch between the {%2N} parameter of procedure {%1Ead}, ", 69);
8481 : 42 : Msg = DynamicStrings_ConCat (Msg, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) CurrentState, _CurrentState_high)));
8482 : 42 : M2MetaError_MetaErrorStringT2 (tokpos, Msg, ProcedureSym, ParameterNo);
8483 : 42 : if ((SymbolTable_NoOfParamAny (ProcedureSym)) >= ParameterNo)
8484 : : {
8485 : 42 : FormalParam = SymbolTable_GetNthParamAny (ProcedureSym, ParameterNo);
8486 : 42 : if (SymbolTable_IsUnboundedParamAny (ProcedureSym, ParameterNo))
8487 : : {
8488 : 18 : M2MetaError_MetaErrorT2 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "formal parameter {%1ad} has an open array type {%2tad}", 54, FormalParam, SymbolTable_GetSType (SymbolTable_GetSType (FormalParam)));
8489 : : }
8490 : : else
8491 : : {
8492 : 24 : M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "formal parameter {%1ad} has type {%1tad}", 40, FormalParam);
8493 : : }
8494 : : }
8495 : : else
8496 : : {
8497 : 0 : M2MetaError_MetaErrorT1 (SymbolTable_GetDeclaredMod (ProcedureSym), (const char *) "procedure declaration", 21, ProcedureSym);
8498 : : }
8499 : 42 : if ((SymbolTable_GetLType (Actual)) == SymbolTable_NulSym)
8500 : : {
8501 : 0 : M2MetaError_MetaError1 ((const char *) "actual parameter being passed is {%1Eda} {%1ad}", 47, Actual);
8502 : : }
8503 : : else
8504 : : {
8505 : 42 : if (SymbolTable_IsVar (Actual))
8506 : : {
8507 : 36 : M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (Actual), (const char *) "actual parameter variable being passed is {%1Eda} {%1ad} of an incompatible type {%1ts}", 87, Actual);
8508 : : }
8509 : : else
8510 : : {
8511 : 6 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "actual parameter being passed is {%1Eda} {%1ad} of an incompatible type {%1ts}", 78, Actual);
8512 : : }
8513 : : }
8514 : 42 : }
8515 : :
8516 : :
8517 : : /*
8518 : : WarnParameter - generates a warning message indicating that a parameter
8519 : : use might cause problems on another target.
8520 : :
8521 : : CurrentState - string describing the current failing state.
8522 : : Actual - actual parameter.
8523 : : ParameterNo - parameter number that has failed.
8524 : : ProcedureSym - procedure symbol where parameter has failed.
8525 : :
8526 : : If any parameter is Nul then it is ignored.
8527 : : */
8528 : :
8529 : 0 : static void WarnParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo)
8530 : : {
8531 : 0 : unsigned int FormalParam;
8532 : 0 : DynamicStrings_String Msg;
8533 : 0 : char CurrentState[_CurrentState_high+1];
8534 : :
8535 : : /* make a local copy of each unbounded array. */
8536 : 0 : memcpy (CurrentState, CurrentState_, _CurrentState_high+1);
8537 : :
8538 : 0 : Msg = DynamicStrings_InitString ((const char *) "{%W}parameter mismatch between the {%2N} parameter of procedure {%1ad}, ", 72);
8539 : 0 : Msg = DynamicStrings_ConCat (Msg, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) CurrentState, _CurrentState_high)));
8540 : 0 : M2MetaError_MetaErrorStringT2 (tokpos, Msg, ProcedureSym, ParameterNo);
8541 : 0 : if ((SymbolTable_NoOfParamAny (ProcedureSym)) >= ParameterNo)
8542 : : {
8543 : 0 : FormalParam = SymbolTable_GetNthParamAny (ProcedureSym, ParameterNo);
8544 : 0 : if (SymbolTable_IsUnboundedParamAny (ProcedureSym, ParameterNo))
8545 : : {
8546 : 0 : M2MetaError_MetaErrorT2 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "{%W}formal parameter {%1ad} has an open array type {%2tad}", 58, FormalParam, SymbolTable_GetSType (SymbolTable_GetSType (FormalParam)));
8547 : : }
8548 : : else
8549 : : {
8550 : 0 : M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "{%W}formal parameter {%1ad} has type {%1tad}", 44, FormalParam);
8551 : : }
8552 : : }
8553 : : else
8554 : : {
8555 : 0 : M2MetaError_MetaErrorT1 (SymbolTable_GetDeclaredMod (ProcedureSym), (const char *) "{%W}procedure declaration", 25, ProcedureSym);
8556 : : }
8557 : 0 : if ((SymbolTable_GetLType (Actual)) == SymbolTable_NulSym)
8558 : : {
8559 : 0 : M2MetaError_MetaError1 ((const char *) "actual parameter being passed is {%1Wda} {%1ad}", 47, Actual);
8560 : : }
8561 : : else
8562 : : {
8563 : 0 : if (SymbolTable_IsVar (Actual))
8564 : : {
8565 : 0 : M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (Actual), (const char *) "actual parameter variable being passed is {%1Wda} {%1ad} of type {%1ts}", 71, Actual);
8566 : : }
8567 : : else
8568 : : {
8569 : 0 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "actual parameter being passed is {%1Wda} {%1ad} of type {%1ts}", 62, Actual);
8570 : : }
8571 : : }
8572 : 0 : }
8573 : :
8574 : :
8575 : : /*
8576 : : doIndrX - perform des = *exp with a conversion if necessary.
8577 : : */
8578 : :
8579 : 14861 : static void doIndrX (unsigned int tok, unsigned int des, unsigned int exp)
8580 : : {
8581 : 14861 : unsigned int t;
8582 : :
8583 : 14861 : if ((SymbolTable_GetDType (des)) == (SymbolTable_GetDType (exp)))
8584 : : {
8585 : 14719 : GenQuadOtok (tok, M2Quads_IndrXOp, des, SymbolTable_GetSType (des), exp, true, tok, tok, tok);
8586 : : }
8587 : : else
8588 : : {
8589 : 142 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
8590 : 142 : SymbolTable_PutVar (t, SymbolTable_GetSType (exp));
8591 : 142 : GenQuadOtok (tok, M2Quads_IndrXOp, t, SymbolTable_GetSType (exp), exp, true, tok, tok, tok);
8592 : 142 : GenQuadOtok (tok, M2Quads_BecomesOp, des, SymbolTable_NulSym, doVal (SymbolTable_GetSType (des), t), true, tok, M2LexBuf_UnknownTokenNo, tok);
8593 : : }
8594 : 14861 : }
8595 : :
8596 : :
8597 : : /*
8598 : : MakeRightValue - returns a temporary which will have the RightValue of symbol, Sym.
8599 : : If Sym is a right value and has type, type, then no quadruples are
8600 : : generated and Sym is returned. Otherwise a new temporary is created
8601 : : and an IndrX quadruple is generated.
8602 : : */
8603 : :
8604 : 1070 : static unsigned int MakeRightValue (unsigned int tok, unsigned int Sym, unsigned int type)
8605 : : {
8606 : 1070 : unsigned int t;
8607 : :
8608 : 1070 : if ((SymbolTable_GetMode (Sym)) == SymbolTable_RightValue)
8609 : : {
8610 : 0 : if ((SymbolTable_GetSType (Sym)) == type)
8611 : : {
8612 : : return Sym;
8613 : : }
8614 : : else
8615 : : {
8616 : : /*
8617 : : type change or mode change, type changes are a pain, but I've
8618 : : left them here as it is perhaps easier to remove them later.
8619 : : */
8620 : 0 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
8621 : 0 : SymbolTable_PutVar (t, type);
8622 : 0 : GenQuadOtok (tok, M2Quads_BecomesOp, t, SymbolTable_NulSym, doVal (type, Sym), true, tok, tok, tok);
8623 : 0 : return t;
8624 : : }
8625 : : }
8626 : : else
8627 : : {
8628 : 1070 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
8629 : 1070 : SymbolTable_PutVar (t, type);
8630 : 1070 : CheckPointerThroughNil (tok, Sym);
8631 : 1070 : doIndrX (tok, t, Sym);
8632 : 1070 : return t;
8633 : : }
8634 : : /* static analysis guarentees a RETURN statement will be used before here. */
8635 : : __builtin_unreachable ();
8636 : : }
8637 : :
8638 : :
8639 : : /*
8640 : : MakeLeftValue - returns a temporary coresponding to the LeftValue of
8641 : : symbol, Sym. No quadruple is generated if Sym is already
8642 : : a LeftValue and has the same type.
8643 : : */
8644 : :
8645 : 186306 : static unsigned int MakeLeftValue (unsigned int tok, unsigned int Sym, SymbolTable_ModeOfAddr with, unsigned int type)
8646 : : {
8647 : 186306 : unsigned int t;
8648 : :
8649 : 186306 : if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
8650 : : {
8651 : 4984 : if ((SymbolTable_GetSType (Sym)) == type)
8652 : : {
8653 : : return Sym;
8654 : : }
8655 : : else
8656 : : {
8657 : : /*
8658 : : type change or mode change, type changes are a pain, but I've
8659 : : left them here as it is perhaps easier to remove them later
8660 : : */
8661 : 80 : t = SymbolTable_MakeTemporary (tok, with);
8662 : 80 : SymbolTable_PutVar (t, type);
8663 : 80 : GenQuadOtok (tok, M2Quads_BecomesOp, t, SymbolTable_NulSym, Sym, true, tok, M2LexBuf_UnknownTokenNo, tok);
8664 : 80 : return t;
8665 : : }
8666 : : }
8667 : : else
8668 : : {
8669 : 181322 : t = SymbolTable_MakeTemporary (tok, with);
8670 : 181322 : SymbolTable_PutVar (t, type);
8671 : 181322 : GenQuadOtok (tok, M2Quads_AddrOp, t, SymbolTable_NulSym, Sym, true, tok, M2LexBuf_UnknownTokenNo, tok);
8672 : 181322 : return t;
8673 : : }
8674 : : /* static analysis guarentees a RETURN statement will be used before here. */
8675 : : __builtin_unreachable ();
8676 : : }
8677 : :
8678 : :
8679 : : /*
8680 : : ManipulatePseudoCallParameters - manipulates the parameters to a pseudo function or
8681 : : procedure. It dereferences all LeftValue parameters
8682 : : and Boolean parameters.
8683 : : The Stack:
8684 : :
8685 : :
8686 : : Entry Exit
8687 : :
8688 : : Ptr -> exactly the same
8689 : : +----------------+
8690 : : | NoOfParameters |
8691 : : |----------------|
8692 : : | Param 1 |
8693 : : |----------------|
8694 : : | Param 2 |
8695 : : |----------------|
8696 : : . .
8697 : : . .
8698 : : . .
8699 : : |----------------|
8700 : : | Param # |
8701 : : |----------------|
8702 : : | ProcSym | Type |
8703 : : |----------------|
8704 : :
8705 : : */
8706 : :
8707 : 53322 : static void ManipulatePseudoCallParameters (void)
8708 : : {
8709 : 53322 : unsigned int NoOfParameters;
8710 : 53322 : unsigned int ProcSym;
8711 : 53322 : unsigned int Proc;
8712 : 53322 : unsigned int i;
8713 : 53322 : unsigned int pi;
8714 : 53322 : M2Quads_BoolFrame f;
8715 : :
8716 : 53322 : M2Quads_PopT (&NoOfParameters);
8717 : 53322 : M2Quads_PushT (NoOfParameters); /* restored to original state */
8718 : : /* Ptr points to the ProcSym */
8719 : 53322 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((NoOfParameters+1)+1));
8720 : 53322 : if (SymbolTable_IsVar (ProcSym))
8721 : : {
8722 : 0 : M2Error_InternalError ((const char *) "expecting a pseudo procedure or a type", 38);
8723 : : }
8724 : : else
8725 : : {
8726 : 53322 : Proc = ProcSym;
8727 : : }
8728 : 53322 : i = 1;
8729 : 53322 : pi = NoOfParameters+1;
8730 : 116554 : while (i <= NoOfParameters)
8731 : : {
8732 : 63238 : 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)))
8733 : : {
8734 : : /* must dereference LeftValue */
8735 : 884 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pi));
8736 : 884 : f->TrueExit = MakeRightValue (M2LexBuf_GetTokenNo (), M2Quads_OperandT (pi), SymbolTable_GetSType (M2Quads_OperandT (pi)));
8737 : : }
8738 : 63232 : i += 1;
8739 : 63232 : pi -= 1;
8740 : : }
8741 : 53316 : }
8742 : :
8743 : :
8744 : : /*
8745 : : ManipulateParameters - manipulates the procedure parameters in
8746 : : preparation for a procedure call.
8747 : : Prepares Boolean, Unbounded and VAR parameters.
8748 : : The Stack:
8749 : :
8750 : :
8751 : : Entry Exit
8752 : :
8753 : : Ptr -> exactly the same
8754 : : +----------------+
8755 : : | NoOfParameters |
8756 : : |----------------|
8757 : : | Param 1 |
8758 : : |----------------|
8759 : : | Param 2 |
8760 : : |----------------|
8761 : : . .
8762 : : . .
8763 : : . .
8764 : : |----------------|
8765 : : | Param # |
8766 : : |----------------|
8767 : : | ProcSym | Type |
8768 : : |----------------|
8769 : : */
8770 : :
8771 : 190437 : static void ManipulateParameters (bool IsForC)
8772 : : {
8773 : 190437 : unsigned int tokpos;
8774 : 190437 : unsigned int np;
8775 : 190437 : DynamicStrings_String s;
8776 : 190437 : unsigned int ArraySym;
8777 : 190437 : unsigned int UnboundedType;
8778 : 190437 : unsigned int ParamType;
8779 : 190437 : unsigned int NoOfParameters;
8780 : 190437 : unsigned int i;
8781 : 190437 : unsigned int pi;
8782 : 190437 : unsigned int ProcSym;
8783 : 190437 : unsigned int rw;
8784 : 190437 : unsigned int Proc;
8785 : 190437 : unsigned int t;
8786 : 190437 : M2Quads_BoolFrame f;
8787 : :
8788 : 190437 : M2Quads_PopT (&NoOfParameters);
8789 : 190437 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+1));
8790 : 190437 : tokpos = OperandTtok (NoOfParameters+1);
8791 : 190437 : if (SymbolTable_IsVar (ProcSym))
8792 : : {
8793 : : /* Procedure Variable ? */
8794 : 720 : Proc = SymbolTable_SkipType (M2Quads_OperandF (NoOfParameters+1));
8795 : : }
8796 : : else
8797 : : {
8798 : 189717 : Proc = PCSymBuild_SkipConst (ProcSym);
8799 : : }
8800 : 190437 : if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
8801 : : {
8802 : : /* avoid dangling else. */
8803 : 7716 : if (NoOfParameters < (SymbolTable_NoOfParamAny (Proc)))
8804 : : {
8805 : 0 : s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
8806 : 0 : np = SymbolTable_NoOfParamAny (Proc);
8807 : 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));
8808 : : }
8809 : : }
8810 : 182721 : else if (SymbolTable_UsesOptArgAny (Proc))
8811 : : {
8812 : : /* avoid dangling else. */
8813 : 3326 : if (! ((NoOfParameters == (SymbolTable_NoOfParamAny (Proc))) || ((NoOfParameters+1) == (SymbolTable_NoOfParamAny (Proc)))))
8814 : : {
8815 : 0 : s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
8816 : 0 : np = SymbolTable_NoOfParamAny (Proc);
8817 : 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));
8818 : : }
8819 : : }
8820 : 179395 : else if (NoOfParameters != (SymbolTable_NoOfParamAny (Proc)))
8821 : : {
8822 : : /* avoid dangling else. */
8823 : 0 : s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
8824 : 0 : np = SymbolTable_NoOfParamAny (Proc);
8825 : 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));
8826 : : }
8827 : 190437 : i = 1;
8828 : 190437 : pi = NoOfParameters;
8829 : 680324 : while (i <= NoOfParameters)
8830 : : {
8831 : 489887 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pi));
8832 : 489887 : rw = static_cast<unsigned int> (OperandMergeRW (pi));
8833 : 489887 : M2Debug_Assert (SymbolTable_IsLegal (rw));
8834 : 489887 : if (i > (SymbolTable_NoOfParamAny (Proc)))
8835 : : {
8836 : 7044 : if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
8837 : : {
8838 : : /* avoid dangling else. */
8839 : 7044 : if (((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym) && (SymbolTable_IsArray (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
8840 : : {
8841 : 156 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_RightValue, M2System_Address);
8842 : 156 : MarkAsReadWrite (rw);
8843 : : }
8844 : 6888 : else if (SymbolTable_IsConstString (M2Quads_OperandT (pi)))
8845 : : {
8846 : : /* avoid dangling else. */
8847 : 238 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), DeferMakeConstStringCnul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi)), SymbolTable_RightValue, M2System_Address);
8848 : 238 : MarkAsReadWrite (rw);
8849 : : }
8850 : 6650 : else if (((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (M2Quads_OperandT (pi)))))
8851 : : {
8852 : : /* avoid dangling else. */
8853 : 152 : MarkAsReadWrite (rw);
8854 : : /* pass the address field of an unbounded variable */
8855 : 152 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, M2Quads_OperandTok (pi));
8856 : 152 : PushTFAD (f->TrueExit, f->FalseExit, f->Unbounded, f->Dimension);
8857 : 152 : M2Quads_PushT (static_cast<unsigned int> (1));
8858 : 152 : BuildAdrFunction ();
8859 : 152 : M2Quads_PopT (&f->TrueExit);
8860 : : }
8861 : 6498 : else if ((SymbolTable_GetMode (M2Quads_OperandT (pi))) == SymbolTable_LeftValue)
8862 : : {
8863 : : /* avoid dangling else. */
8864 : 384 : MarkAsReadWrite (rw);
8865 : : /* must dereference LeftValue (even if we are passing variable as a vararg) */
8866 : 384 : t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
8867 : 384 : SymbolTable_PutVar (t, SymbolTable_GetSType (M2Quads_OperandT (pi)));
8868 : 384 : CheckPointerThroughNil (tokpos, M2Quads_OperandT (pi));
8869 : 384 : doIndrX (M2Quads_OperandTok (pi), t, M2Quads_OperandT (pi));
8870 : 384 : f->TrueExit = t;
8871 : : }
8872 : : }
8873 : : else
8874 : : {
8875 : 0 : M2MetaError_MetaErrorT2 (tokpos, (const char *) "attempting to pass too many parameters to procedure {%1a}, the {%2N} parameter does not exist", 93, Proc, i);
8876 : : }
8877 : : }
8878 : 482843 : else if (((IsForC && (SymbolTable_IsUnboundedParamAny (Proc, i))) && ((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym)) && (SymbolTable_IsArray (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
8879 : : {
8880 : : /* avoid dangling else. */
8881 : 24 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_RightValue, M2System_Address);
8882 : 24 : MarkAsReadWrite (rw);
8883 : : }
8884 : 482819 : else if (((IsForC && (SymbolTable_IsUnboundedParamAny (Proc, i))) && ((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym)) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
8885 : : {
8886 : : /* avoid dangling else. */
8887 : 184 : MarkAsReadWrite (rw);
8888 : : /* pass the address field of an unbounded variable */
8889 : 184 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, M2Quads_OperandTok (pi));
8890 : 184 : PushTFAD (f->TrueExit, f->FalseExit, f->Unbounded, f->Dimension);
8891 : 184 : M2Quads_PushT (static_cast<unsigned int> (1));
8892 : 184 : BuildAdrFunction ();
8893 : 184 : M2Quads_PopT (&f->TrueExit);
8894 : : }
8895 : 482635 : else if ((IsForC && (SymbolTable_IsConstString (M2Quads_OperandT (pi)))) && ((SymbolTable_IsUnboundedParamAny (Proc, i)) || ((SymbolTable_GetDType (SymbolTable_GetParam (Proc, i))) == M2System_Address)))
8896 : : {
8897 : : /* avoid dangling else. */
8898 : 7404 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), DeferMakeConstStringCnul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi)), SymbolTable_RightValue, M2System_Address);
8899 : 7404 : MarkAsReadWrite (rw);
8900 : : }
8901 : 475231 : else if (SymbolTable_IsUnboundedParamAny (Proc, i))
8902 : : {
8903 : : /* avoid dangling else. */
8904 : : /* always pass constant strings with a nul terminator, but leave the HIGH as before. */
8905 : 36556 : if (SymbolTable_IsConstString (M2Quads_OperandT (pi)))
8906 : : {
8907 : : /* this is a Modula-2 string which must be nul terminated. */
8908 : 24120 : f->TrueExit = DeferMakeConstStringM2nul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi));
8909 : : }
8910 : 36556 : t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
8911 : 36556 : UnboundedType = SymbolTable_GetSType (SymbolTable_GetParam (Proc, i));
8912 : 36556 : SymbolTable_PutVar (t, UnboundedType);
8913 : 36556 : ParamType = SymbolTable_GetSType (UnboundedType);
8914 : 36556 : if ((OperandD (pi)) == 0)
8915 : : {
8916 : 36508 : ArraySym = static_cast<unsigned int> (M2Quads_OperandT (pi));
8917 : : }
8918 : : else
8919 : : {
8920 : 48 : ArraySym = static_cast<unsigned int> (M2Quads_OperandA (pi));
8921 : : }
8922 : 36556 : if (SymbolTable_IsVarParamAny (Proc, i))
8923 : : {
8924 : 4348 : MarkArrayWritten (M2Quads_OperandT (pi));
8925 : 4348 : MarkArrayWritten (M2Quads_OperandA (pi));
8926 : 4348 : MarkAsReadWrite (rw);
8927 : 4348 : AssignUnboundedVar (OperandTtok (pi), M2Quads_OperandT (pi), ArraySym, t, ParamType, OperandD (pi));
8928 : : }
8929 : : else
8930 : : {
8931 : 32208 : MarkAsRead (rw);
8932 : 32208 : AssignUnboundedNonVar (OperandTtok (pi), M2Quads_OperandT (pi), ArraySym, t, ParamType, OperandD (pi));
8933 : : }
8934 : 36556 : f->TrueExit = t;
8935 : : }
8936 : 438675 : else if (SymbolTable_IsVarParamAny (Proc, i))
8937 : : {
8938 : : /* avoid dangling else. */
8939 : : /* must reference by address, but we contain the type of the referenced entity */
8940 : 14542 : MarkArrayWritten (M2Quads_OperandT (pi));
8941 : 14542 : MarkArrayWritten (M2Quads_OperandA (pi));
8942 : 14542 : MarkAsReadWrite (rw);
8943 : 14542 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_LeftValue, SymbolTable_GetSType (SymbolTable_GetParam (Proc, i)));
8944 : : }
8945 : 424133 : else if ((! (SymbolTable_IsVarParamAny (Proc, i))) && ((SymbolTable_GetMode (M2Quads_OperandT (pi))) == SymbolTable_LeftValue))
8946 : : {
8947 : : /* avoid dangling else. */
8948 : : /* must dereference LeftValue */
8949 : 1362 : t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
8950 : 1362 : SymbolTable_PutVar (t, SymbolTable_GetSType (M2Quads_OperandT (pi)));
8951 : 1362 : CheckPointerThroughNil (tokpos, M2Quads_OperandT (pi));
8952 : 1362 : doIndrX (M2Quads_OperandTok (pi), t, M2Quads_OperandT (pi));
8953 : 1362 : f->TrueExit = t;
8954 : 1362 : MarkAsRead (rw);
8955 : : }
8956 : : else
8957 : : {
8958 : : /* avoid dangling else. */
8959 : 422771 : MarkAsRead (rw);
8960 : : }
8961 : 489887 : i += 1;
8962 : 489887 : pi -= 1;
8963 : : }
8964 : 190437 : M2Quads_PushT (NoOfParameters);
8965 : 190437 : }
8966 : :
8967 : :
8968 : : /*
8969 : : CheckParameterOrdinals - check that ordinal values are within type range.
8970 : : */
8971 : :
8972 : 190437 : static void CheckParameterOrdinals (void)
8973 : : {
8974 : 190437 : unsigned int tokno;
8975 : 190437 : unsigned int Proc;
8976 : 190437 : unsigned int ProcSym;
8977 : 190437 : unsigned int Actual;
8978 : 190437 : unsigned int FormalI;
8979 : 190437 : unsigned int ParamTotal;
8980 : 190437 : unsigned int pi;
8981 : 190437 : unsigned int i;
8982 : :
8983 : 190437 : M2Quads_PopT (&ParamTotal);
8984 : 190437 : M2Quads_PushT (ParamTotal); /* Restore stack to origional state */
8985 : 190437 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((ParamTotal+1)+1)); /* Restore stack to origional state */
8986 : 190437 : if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (SymbolTable_GetDType (ProcSym))))
8987 : : {
8988 : : /* Indirect procedure call. */
8989 : 720 : Proc = SymbolTable_SkipType (M2Quads_OperandF ((ParamTotal+1)+1));
8990 : : }
8991 : : else
8992 : : {
8993 : 189717 : Proc = PCSymBuild_SkipConst (ProcSym);
8994 : : }
8995 : 190437 : i = 1;
8996 : 190437 : pi = ParamTotal+1; /* stack index referencing stacked parameter, i */
8997 : 680324 : while (i <= ParamTotal) /* stack index referencing stacked parameter, i */
8998 : : {
8999 : 489887 : if (i <= (SymbolTable_NoOfParamAny (Proc)))
9000 : : {
9001 : 482843 : FormalI = SymbolTable_GetParam (Proc, i);
9002 : 482843 : Actual = static_cast<unsigned int> (M2Quads_OperandT (pi));
9003 : 482843 : tokno = static_cast<unsigned int> (M2Quads_OperandTok (pi));
9004 : 482843 : if (M2Base_IsOrdinalType (SymbolTable_GetLType (FormalI)))
9005 : : {
9006 : 127002 : if (! (SymbolTable_IsSet (SymbolTable_GetDType (FormalI))))
9007 : : {
9008 : : /* tell code generator to test runtime values of assignment so ensure we
9009 : : catch overflow and underflow */
9010 : 127002 : BuildRange (M2Range_InitParameterRangeCheck (tokno, Proc, i, FormalI, Actual));
9011 : : }
9012 : : }
9013 : : }
9014 : 489887 : i += 1;
9015 : 489887 : pi -= 1;
9016 : : }
9017 : 190437 : }
9018 : :
9019 : :
9020 : : /*
9021 : : IsSameUnbounded - returns TRUE if unbounded types, t1, and, t2,
9022 : : are compatible.
9023 : : */
9024 : :
9025 : 36 : static bool IsSameUnbounded (unsigned int t1, unsigned int t2)
9026 : : {
9027 : 36 : M2Debug_Assert (SymbolTable_IsUnbounded (t1));
9028 : 36 : M2Debug_Assert (SymbolTable_IsUnbounded (t2));
9029 : 36 : return (SymbolTable_GetDType (t1)) == (SymbolTable_GetDType (t2));
9030 : : /* static analysis guarentees a RETURN statement will be used before here. */
9031 : : __builtin_unreachable ();
9032 : : }
9033 : :
9034 : :
9035 : : /*
9036 : : AssignUnboundedVar - assigns an Unbounded symbol fields,
9037 : : ArrayAddress and ArrayHigh, from an array symbol.
9038 : : UnboundedSym is not a VAR parameter and therefore
9039 : : this procedure can complete both of the fields.
9040 : : Sym can be a Variable with type Unbounded.
9041 : : Sym can be a Variable with type Array.
9042 : : Sym can be a String Constant.
9043 : :
9044 : : ParamType is the TYPE of the parameter
9045 : : */
9046 : :
9047 : 4348 : static void AssignUnboundedVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9048 : : {
9049 : 4348 : unsigned int Type;
9050 : :
9051 : 4348 : if (SymbolTable_IsConst (Sym))
9052 : : {
9053 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
9054 : : }
9055 : 4348 : else if (SymbolTable_IsVar (Sym))
9056 : : {
9057 : : /* avoid dangling else. */
9058 : 4348 : Type = SymbolTable_GetDType (Sym);
9059 : 4348 : if (Type == SymbolTable_NulSym)
9060 : : {
9061 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} has no type and cannot be passed to a VAR formal parameter", 65, Sym);
9062 : : }
9063 : 4348 : else if (SymbolTable_IsUnbounded (Type))
9064 : : {
9065 : : /* avoid dangling else. */
9066 : 1274 : if (Type == (SymbolTable_GetSType (UnboundedSym)))
9067 : : {
9068 : : /* Copy Unbounded Symbol ie. UnboundedSym := Sym */
9069 : 1238 : M2Quads_PushT (UnboundedSym);
9070 : 1238 : M2Quads_PushT (Sym);
9071 : 1238 : BuildAssignmentWithoutBounds (tok, false, true);
9072 : : }
9073 : 36 : else if ((IsSameUnbounded (Type, SymbolTable_GetSType (UnboundedSym))) || (M2System_IsGenericSystemType (ParamType)))
9074 : : {
9075 : : /* avoid dangling else. */
9076 : 36 : UnboundedVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9077 : : }
9078 : : else
9079 : : {
9080 : : /* avoid dangling else. */
9081 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
9082 : : }
9083 : : }
9084 : 3074 : else if ((SymbolTable_IsArray (Type)) || (M2System_IsGenericSystemType (ParamType)))
9085 : : {
9086 : : /* avoid dangling else. */
9087 : 3074 : UnboundedVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9088 : : }
9089 : : else
9090 : : {
9091 : : /* avoid dangling else. */
9092 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
9093 : : }
9094 : : }
9095 : : else
9096 : : {
9097 : : /* avoid dangling else. */
9098 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
9099 : : }
9100 : 4348 : }
9101 : :
9102 : :
9103 : : /*
9104 : : AssignUnboundedNonVar - assigns an Unbounded symbol fields,
9105 : : The difference between this procedure and
9106 : : AssignUnboundedVar is that this procedure cannot
9107 : : set the Unbounded.Address since the data from
9108 : : Sym will be copied because parameter is NOT a VAR
9109 : : parameter.
9110 : : UnboundedSym is not a VAR parameter and therefore
9111 : : this procedure can only complete the HIGH field
9112 : : and not the ADDRESS field.
9113 : : Sym can be a Variable with type Unbounded.
9114 : : Sym can be a Variable with type Array.
9115 : : Sym can be a String Constant.
9116 : :
9117 : : ParamType is the TYPE of the paramater
9118 : : */
9119 : :
9120 : 32208 : static void AssignUnboundedNonVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9121 : : {
9122 : 32208 : unsigned int Type;
9123 : :
9124 : 32208 : if (SymbolTable_IsConst (Sym)) /* was IsConstString(Sym) */
9125 : : {
9126 : 24168 : UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9127 : : }
9128 : 8040 : else if (SymbolTable_IsVar (Sym))
9129 : : {
9130 : : /* avoid dangling else. */
9131 : 8040 : Type = SymbolTable_GetDType (Sym);
9132 : 8040 : if (Type == SymbolTable_NulSym)
9133 : : {
9134 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} has no type and cannot be passed to a non VAR formal parameter", 69, Sym);
9135 : : }
9136 : 8040 : else if (SymbolTable_IsUnbounded (Type))
9137 : : {
9138 : : /* avoid dangling else. */
9139 : 3410 : UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9140 : : }
9141 : 4630 : else if ((SymbolTable_IsArray (Type)) || (M2System_IsGenericSystemType (ParamType)))
9142 : : {
9143 : : /* avoid dangling else. */
9144 : 4618 : UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9145 : : }
9146 : : else
9147 : : {
9148 : : /* avoid dangling else. */
9149 : 12 : M2MetaError_MetaErrorT1 (tok, (const char *) "illegal type parameter {%1Ead} expecting array or dynamic array", 63, Sym);
9150 : : }
9151 : : }
9152 : : else
9153 : : {
9154 : : /* avoid dangling else. */
9155 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "illegal parameter {%1Ead} which cannot be passed as {%kVAR} {%kARRAY} {%kOF} {%1tsad}", 85, Sym);
9156 : : }
9157 : 32208 : }
9158 : :
9159 : :
9160 : : /*
9161 : : GenHigh - generates a HighOp but it checks if op3 is a
9162 : : L value and if so it dereferences it. This
9163 : : is inefficient, however it is clean and we let the gcc
9164 : : backend detect these as common subexpressions.
9165 : : It will also detect that a R value -> L value -> R value
9166 : : via indirection and eleminate these.
9167 : : */
9168 : :
9169 : 37602 : static void GenHigh (unsigned int tok, unsigned int op1, unsigned int op2, unsigned int op3)
9170 : : {
9171 : 37602 : unsigned int sym;
9172 : :
9173 : 37602 : if (((SymbolTable_GetMode (op3)) == SymbolTable_LeftValue) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (op3))))
9174 : : {
9175 : 48 : sym = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
9176 : 48 : SymbolTable_PutVar (sym, SymbolTable_GetSType (op3));
9177 : 48 : doIndrX (tok, sym, op3);
9178 : 48 : GenQuadO (tok, M2Quads_HighOp, op1, op2, sym, true);
9179 : : }
9180 : : else
9181 : : {
9182 : 37554 : GenQuadO (tok, M2Quads_HighOp, op1, op2, op3, true);
9183 : : }
9184 : 37602 : }
9185 : :
9186 : :
9187 : : /*
9188 : : AssignHighField -
9189 : : */
9190 : :
9191 : 35462 : static void AssignHighField (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int actuali, unsigned int formali)
9192 : : {
9193 : 35462 : unsigned int ReturnVar;
9194 : 35462 : unsigned int ArrayType;
9195 : 35462 : unsigned int Field;
9196 : :
9197 : : /* Unbounded.ArrayHigh := HIGH(ArraySym) */
9198 : 35462 : M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
9199 : 35462 : Field = SymbolTable_GetUnboundedHighOffset (SymbolTable_GetSType (UnboundedSym), formali);
9200 : 35462 : M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
9201 : 35462 : M2Quads_PushT (static_cast<unsigned int> (1));
9202 : 35462 : M2Quads_BuildDesignatorRecord (tok);
9203 : 35462 : if (M2System_IsGenericSystemType (ParamType))
9204 : : {
9205 : 1146 : if (SymbolTable_IsConstString (Sym))
9206 : : {
9207 : 18 : M2Quads_PushTtok (DeferMakeLengthConst (tok, Sym), tok);
9208 : : }
9209 : : else
9210 : : {
9211 : 1128 : ArrayType = SymbolTable_GetSType (Sym);
9212 : 1128 : if (SymbolTable_IsUnbounded (ArrayType))
9213 : : {
9214 : : /*
9215 : : * SIZE(parameter) DIV TSIZE(ParamType)
9216 : : * however in this case parameter
9217 : : * is an unbounded symbol and therefore we must use
9218 : : * (HIGH(parameter)+1)*SIZE(unbounded type) DIV TSIZE(ParamType)
9219 : : *
9220 : : * we call upon the function SIZE(ArraySym)
9221 : : * remember SIZE doubles as
9222 : : * (HIGH(a)+1) * SIZE(ArrayType) for unbounded symbols
9223 : : */
9224 : 294 : M2Quads_PushTFtok (calculateMultipicand (tok, ArraySym, ArrayType, actuali-1), M2Base_Cardinal, tok);
9225 : 294 : M2Quads_PushT (M2Reserved_DivideTok); /* Divide by */
9226 : 294 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok); /* TSIZE(ParamType) */
9227 : 294 : M2Quads_PushTtok (ParamType, tok); /* TSIZE(ParamType) */
9228 : 294 : M2Quads_PushT (static_cast<unsigned int> (1)); /* 1 parameter for TSIZE() */
9229 : 294 : M2Quads_BuildFunctionCall (false); /* 1 parameter for TSIZE() */
9230 : 294 : M2Quads_BuildBinaryOp ();
9231 : : }
9232 : : else
9233 : : {
9234 : : /* SIZE(parameter) DIV TSIZE(ParamType) */
9235 : 834 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok); /* TSIZE(ArrayType) */
9236 : 834 : M2Quads_PushTtok (ArrayType, tok); /* TSIZE(ArrayType) */
9237 : 834 : M2Quads_PushT (static_cast<unsigned int> (1)); /* 1 parameter for TSIZE() */
9238 : 834 : M2Quads_BuildFunctionCall (true); /* 1 parameter for TSIZE() */
9239 : 834 : M2Quads_PushT (M2Reserved_DivideTok); /* Divide by */
9240 : 834 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok); /* TSIZE(ParamType) */
9241 : 834 : M2Quads_PushTtok (ParamType, tok); /* TSIZE(ParamType) */
9242 : 834 : M2Quads_PushT (static_cast<unsigned int> (1)); /* 1 parameter for TSIZE() */
9243 : 834 : M2Quads_BuildFunctionCall (true); /* 1 parameter for TSIZE() */
9244 : 834 : M2Quads_BuildBinaryOp ();
9245 : : }
9246 : : /* now convert from no of elements into HIGH by subtracting 1 */
9247 : 1128 : M2Quads_PushT (M2Reserved_MinusTok); /* -1 */
9248 : 1128 : M2Quads_PushTtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal), tok); /* -1 */
9249 : 1128 : M2Quads_BuildBinaryOp ();
9250 : : }
9251 : : }
9252 : : else
9253 : : {
9254 : 34316 : ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
9255 : 34316 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
9256 : 34316 : if (((actuali != formali) && (ArraySym != SymbolTable_NulSym)) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (ArraySym))))
9257 : : {
9258 : 12 : GenHigh (tok, ReturnVar, actuali, ArraySym);
9259 : : }
9260 : : else
9261 : : {
9262 : 34304 : GenHigh (tok, ReturnVar, formali, Sym);
9263 : : }
9264 : 34316 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), tok);
9265 : : }
9266 : 35462 : BuildAssignmentWithoutBounds (tok, false, true);
9267 : 35462 : }
9268 : :
9269 : :
9270 : : /*
9271 : : AssignHighFields -
9272 : : */
9273 : :
9274 : 35306 : static void AssignHighFields (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9275 : : {
9276 : 35306 : unsigned int type;
9277 : 35306 : unsigned int actuali;
9278 : 35306 : unsigned int formali;
9279 : 35306 : unsigned int actualn;
9280 : 35306 : unsigned int formaln;
9281 : :
9282 : 35306 : type = SymbolTable_GetDType (Sym);
9283 : 35306 : actualn = 1;
9284 : 35306 : if ((type != SymbolTable_NulSym) && ((SymbolTable_IsUnbounded (type)) || (SymbolTable_IsArray (type))))
9285 : : {
9286 : 10328 : actualn = SymbolTable_GetDimension (type);
9287 : : }
9288 : 35306 : actuali = dim+1;
9289 : 35306 : formali = 1;
9290 : 35306 : formaln = SymbolTable_GetDimension (SymbolTable_GetDType (UnboundedSym));
9291 : 70768 : while ((actuali < actualn) && (formali < formaln))
9292 : : {
9293 : 156 : AssignHighField (tok, Sym, ArraySym, UnboundedSym, SymbolTable_NulSym, actuali, formali);
9294 : 156 : actuali += 1;
9295 : 156 : formali += 1;
9296 : : }
9297 : 35306 : AssignHighField (tok, Sym, ArraySym, UnboundedSym, ParamType, actuali, formali);
9298 : 35306 : }
9299 : :
9300 : :
9301 : : /*
9302 : : UnboundedNonVarLinkToArray - links an array, ArraySym, to an unbounded
9303 : : array, UnboundedSym. The parameter is a
9304 : : NON VAR variety.
9305 : : */
9306 : :
9307 : 32196 : static void UnboundedNonVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9308 : : {
9309 : 32196 : unsigned int Field;
9310 : 32196 : unsigned int AddressField;
9311 : :
9312 : : /* Unbounded.ArrayAddress := to be assigned at runtime. */
9313 : 32196 : M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
9314 : 32196 : Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
9315 : 32196 : M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
9316 : 32196 : M2Quads_PushT (static_cast<unsigned int> (1));
9317 : 32196 : M2Quads_BuildDesignatorRecord (tok);
9318 : 32196 : M2Quads_PopT (&AddressField);
9319 : : /* caller saves non var unbounded array contents. */
9320 : 64392 : GenQuadO (tok, M2Quads_UnboundedOp, AddressField, SymbolTable_NulSym, Sym, false);
9321 : 32196 : AssignHighFields (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9322 : 32196 : }
9323 : :
9324 : :
9325 : : /*
9326 : : UnboundedVarLinkToArray - links an array, ArraySym, to an unbounded array,
9327 : : UnboundedSym. The parameter is a VAR variety.
9328 : : */
9329 : :
9330 : 3110 : static void UnboundedVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9331 : : {
9332 : 3110 : unsigned int SymType;
9333 : 3110 : unsigned int Field;
9334 : :
9335 : 3110 : SymType = SymbolTable_GetSType (Sym);
9336 : : /* Unbounded.ArrayAddress := ADR(Sym) */
9337 : 3110 : M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
9338 : 3110 : Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
9339 : 3110 : M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
9340 : 3110 : M2Quads_PushT (static_cast<unsigned int> (1));
9341 : 3110 : M2Quads_BuildDesignatorRecord (tok);
9342 : 3110 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok); /* ADR (Sym). */
9343 : 3110 : if ((SymbolTable_IsUnbounded (SymType)) && (dim == 0)) /* ADR (Sym). */
9344 : : {
9345 : 12 : PushTFADtok (Sym, SymType, UnboundedSym, dim, tok);
9346 : : }
9347 : : else
9348 : : {
9349 : 3098 : PushTFADtok (Sym, SymType, ArraySym, dim, tok);
9350 : : }
9351 : 3110 : M2Quads_PushT (static_cast<unsigned int> (1)); /* 1 parameter for ADR(). */
9352 : 3110 : M2Quads_BuildFunctionCall (false); /* 1 parameter for ADR(). */
9353 : 3110 : BuildAssignmentWithoutBounds (tok, false, true);
9354 : 3110 : AssignHighFields (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9355 : 3110 : }
9356 : :
9357 : :
9358 : : /*
9359 : : BuildPseudoProcedureCall - builds a pseudo procedure call.
9360 : : This procedure does not directly alter the
9361 : : stack, but by calling routines the stack
9362 : : will change in the following way when this
9363 : : procedure returns.
9364 : :
9365 : : The Stack:
9366 : :
9367 : :
9368 : : Entry Exit
9369 : :
9370 : : Ptr ->
9371 : : +----------------+
9372 : : | NoOfParam |
9373 : : |----------------|
9374 : : | Param 1 |
9375 : : |----------------|
9376 : : | Param 2 |
9377 : : |----------------|
9378 : : . .
9379 : : . .
9380 : : . .
9381 : : |----------------|
9382 : : | Param # |
9383 : : |----------------|
9384 : : | ProcSym | Type | Empty
9385 : : |----------------|
9386 : : */
9387 : :
9388 : 19204 : static void BuildPseudoProcedureCall (unsigned int tokno)
9389 : : {
9390 : 19204 : unsigned int NoOfParam;
9391 : 19204 : unsigned int ProcSym;
9392 : :
9393 : 19204 : M2Quads_PopT (&NoOfParam);
9394 : 19204 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
9395 : 19204 : M2Quads_PushT (NoOfParam);
9396 : : /* Compile time stack restored to entry state */
9397 : 19204 : if (ProcSym == M2Base_New)
9398 : : {
9399 : 604 : BuildNewProcedure (tokno);
9400 : : }
9401 : 18600 : else if (ProcSym == M2Base_Dispose)
9402 : : {
9403 : : /* avoid dangling else. */
9404 : 280 : BuildDisposeProcedure (tokno);
9405 : : }
9406 : 18320 : else if (ProcSym == M2Base_Inc)
9407 : : {
9408 : : /* avoid dangling else. */
9409 : 13320 : BuildIncProcedure ();
9410 : : }
9411 : 5000 : else if (ProcSym == M2Base_Dec)
9412 : : {
9413 : : /* avoid dangling else. */
9414 : 3642 : BuildDecProcedure ();
9415 : : }
9416 : 1358 : else if (ProcSym == M2Base_Incl)
9417 : : {
9418 : : /* avoid dangling else. */
9419 : 784 : BuildInclProcedure ();
9420 : : }
9421 : 574 : else if (ProcSym == M2Base_Excl)
9422 : : {
9423 : : /* avoid dangling else. */
9424 : 460 : BuildExclProcedure ();
9425 : : }
9426 : 114 : else if (ProcSym == M2System_Throw)
9427 : : {
9428 : : /* avoid dangling else. */
9429 : 114 : BuildThrowProcedure ();
9430 : : }
9431 : : else
9432 : : {
9433 : : /* avoid dangling else. */
9434 : 0 : M2Error_InternalError ((const char *) "pseudo procedure not implemented yet", 36);
9435 : : }
9436 : 19204 : }
9437 : :
9438 : :
9439 : : /*
9440 : : GetItemPointedTo - returns the symbol type that is being pointed to
9441 : : by Sym.
9442 : : */
9443 : :
9444 : 2298 : static unsigned int GetItemPointedTo (unsigned int Sym)
9445 : : {
9446 : 4604 : if (SymbolTable_IsPointer (Sym))
9447 : : {
9448 : 2298 : return SymbolTable_GetSType (Sym);
9449 : : }
9450 : 2306 : else if ((SymbolTable_IsVar (Sym)) || (SymbolTable_IsType (Sym)))
9451 : : {
9452 : : /* avoid dangling else. */
9453 : 2306 : return GetItemPointedTo (SymbolTable_GetSType (Sym));
9454 : : }
9455 : : else
9456 : : {
9457 : : /* avoid dangling else. */
9458 : : return SymbolTable_NulSym;
9459 : : }
9460 : : /* static analysis guarentees a RETURN statement will be used before here. */
9461 : : __builtin_unreachable ();
9462 : : }
9463 : :
9464 : :
9465 : : /*
9466 : : BuildThrowProcedure - builds the pseudo procedure call M2RTS.Throw.
9467 : : The Stack:
9468 : :
9469 : :
9470 : : Entry Exit
9471 : :
9472 : : Ptr ->
9473 : : +----------------+
9474 : : | NoOfParam |
9475 : : |----------------|
9476 : : | Param 1 |
9477 : : |----------------|
9478 : : | Param 2 |
9479 : : |----------------|
9480 : : . .
9481 : : . .
9482 : : . .
9483 : : |----------------|
9484 : : | Param # |
9485 : : |----------------|
9486 : : | ProcSym | Type | Empty
9487 : : |----------------|
9488 : : */
9489 : :
9490 : 114 : static void BuildThrowProcedure (void)
9491 : : {
9492 : 114 : unsigned int functok;
9493 : 114 : unsigned int op;
9494 : 114 : unsigned int NoOfParam;
9495 : :
9496 : 114 : M2Quads_PopT (&NoOfParam);
9497 : 114 : functok = OperandTtok (NoOfParam+1);
9498 : 114 : if (NoOfParam == 1)
9499 : : {
9500 : 114 : op = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
9501 : 114 : GenQuadO (functok, M2Quads_ThrowOp, SymbolTable_NulSym, SymbolTable_NulSym, op, false);
9502 : : }
9503 : : else
9504 : : {
9505 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure %{1Ea} takes one INTEGER parameter", 55, M2System_Throw);
9506 : : }
9507 : 114 : M2Quads_PopN (NoOfParam+1);
9508 : 114 : }
9509 : :
9510 : :
9511 : : /*
9512 : : BuildNewProcedure - builds the pseudo procedure call NEW.
9513 : : This procedure is traditionally a "macro" for
9514 : : NEW(x, ...) --> ALLOCATE(x, TSIZE(x^, ...))
9515 : : One method of implementation is to emulate a "macro"
9516 : : processor by pushing the relevant input tokens
9517 : : back onto the input stack.
9518 : : However this causes two problems:
9519 : :
9520 : : (i) Unnecessary code is produced for x^
9521 : : (ii) SIZE must be imported from SYSTEM
9522 : : Therefore we chose an alternative method of
9523 : : implementation;
9524 : : generate quadruples for ALLOCATE(x, TSIZE(x^, ...))
9525 : : this, although slightly more efficient,
9526 : : is more complex and circumvents problems (i) and (ii).
9527 : :
9528 : : The Stack:
9529 : :
9530 : :
9531 : : Entry Exit
9532 : :
9533 : : Ptr ->
9534 : : +----------------+
9535 : : | NoOfParam |
9536 : : |----------------|
9537 : : | Param 1 |
9538 : : |----------------|
9539 : : | Param 2 |
9540 : : |----------------|
9541 : : . .
9542 : : . .
9543 : : . .
9544 : : |----------------|
9545 : : | Param # |
9546 : : |----------------|
9547 : : | ProcSym | Type | Empty
9548 : : |----------------|
9549 : : */
9550 : :
9551 : 604 : static void BuildNewProcedure (unsigned int functok)
9552 : : {
9553 : 604 : unsigned int NoOfParam;
9554 : 604 : unsigned int SizeSym;
9555 : 604 : unsigned int PtrSym;
9556 : 604 : unsigned int ProcSym;
9557 : 604 : unsigned int paramtok;
9558 : 604 : unsigned int combinedtok;
9559 : :
9560 : 604 : M2Quads_PopT (&NoOfParam);
9561 : 604 : if (NoOfParam >= 1)
9562 : : {
9563 : 604 : ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "ALLOCATE", 8));
9564 : 604 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
9565 : : {
9566 : 604 : PtrSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
9567 : 604 : paramtok = OperandTtok (1);
9568 : 604 : if (IsReallyPointer (PtrSym))
9569 : : {
9570 : 604 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
9571 : : /*
9572 : : Build macro: ALLOCATE( PtrSym, SIZE(PtrSym^) )
9573 : : */
9574 : 604 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, paramtok); /* Procedure */
9575 : : /* x^ */
9576 : 604 : M2Quads_PushTtok (GetItemPointedTo (PtrSym), paramtok);
9577 : 604 : M2Quads_PushT (static_cast<unsigned int> (1)); /* One parameter */
9578 : 604 : M2Quads_BuildFunctionCall (false); /* One parameter */
9579 : 604 : M2Quads_PopT (&SizeSym);
9580 : 604 : M2Quads_PushTtok (ProcSym, combinedtok); /* ALLOCATE */
9581 : 604 : M2Quads_PushTtok (PtrSym, paramtok); /* x */
9582 : 604 : M2Quads_PushTtok (SizeSym, paramtok); /* TSIZE(x^) */
9583 : 604 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
9584 : 604 : M2Quads_BuildProcedureCall (combinedtok); /* Two parameters */
9585 : : }
9586 : : else
9587 : : {
9588 : 0 : M2MetaError_MetaErrorT0 (paramtok, (const char *) "parameter to {%EkNEW} must be a pointer", 39);
9589 : : }
9590 : : }
9591 : : else
9592 : : {
9593 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}ALLOCATE procedure not found for NEW substitution", 53);
9594 : : }
9595 : : }
9596 : : else
9597 : : {
9598 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the pseudo procedure {%EkNEW} has one or more parameters", 56);
9599 : : }
9600 : 604 : M2Quads_PopN (NoOfParam+1);
9601 : 604 : }
9602 : :
9603 : :
9604 : : /*
9605 : : BuildDisposeProcedure - builds the pseudo procedure call DISPOSE.
9606 : : This procedure is traditionally a "macro" for
9607 : : DISPOSE(x) --> DEALLOCATE(x, TSIZE(x^))
9608 : : One method of implementation is to emulate a "macro"
9609 : : processor by pushing the relevant input tokens
9610 : : back onto the input stack.
9611 : : However this causes two problems:
9612 : :
9613 : : (i) Unnecessary code is produced for x^
9614 : : (ii) TSIZE must be imported from SYSTEM
9615 : : Therefore we chose an alternative method of
9616 : : implementation;
9617 : : generate quadruples for DEALLOCATE(x, TSIZE(x^))
9618 : : this, although slightly more efficient,
9619 : : is more complex and circumvents problems (i)
9620 : : and (ii).
9621 : :
9622 : : The Stack:
9623 : :
9624 : :
9625 : : Entry Exit
9626 : :
9627 : : Ptr ->
9628 : : +----------------+
9629 : : | NoOfParam |
9630 : : |----------------|
9631 : : | Param 1 |
9632 : : |----------------|
9633 : : | Param 2 |
9634 : : |----------------|
9635 : : . .
9636 : : . .
9637 : : . .
9638 : : |----------------|
9639 : : | Param # |
9640 : : |----------------|
9641 : : | ProcSym | Type | Empty
9642 : : |----------------|
9643 : : */
9644 : :
9645 : 280 : static void BuildDisposeProcedure (unsigned int functok)
9646 : : {
9647 : 280 : unsigned int NoOfParam;
9648 : 280 : unsigned int SizeSym;
9649 : 280 : unsigned int PtrSym;
9650 : 280 : unsigned int ProcSym;
9651 : 280 : unsigned int combinedtok;
9652 : 280 : unsigned int paramtok;
9653 : :
9654 : 280 : M2Quads_PopT (&NoOfParam);
9655 : 280 : if (NoOfParam >= 1)
9656 : : {
9657 : 280 : ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "DEALLOCATE", 10));
9658 : 280 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
9659 : : {
9660 : 280 : PtrSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
9661 : 280 : paramtok = OperandTtok (1);
9662 : 280 : if (IsReallyPointer (PtrSym))
9663 : : {
9664 : 280 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
9665 : : /*
9666 : : Build macro: DEALLOCATE( PtrSym, TSIZE(PtrSym^) )
9667 : : */
9668 : 280 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, paramtok); /* Procedure */
9669 : : /* x^ */
9670 : 280 : M2Quads_PushTtok (GetItemPointedTo (PtrSym), paramtok);
9671 : 280 : M2Quads_PushT (static_cast<unsigned int> (1)); /* One parameter */
9672 : 280 : M2Quads_BuildFunctionCall (false); /* One parameter */
9673 : 280 : M2Quads_PopT (&SizeSym);
9674 : 280 : M2Quads_PushTtok (ProcSym, combinedtok); /* DEALLOCATE */
9675 : 280 : M2Quads_PushTtok (PtrSym, paramtok); /* x */
9676 : 280 : M2Quads_PushTtok (SizeSym, paramtok); /* TSIZE(x^) */
9677 : 280 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
9678 : 280 : M2Quads_BuildProcedureCall (combinedtok); /* Two parameters */
9679 : : }
9680 : : else
9681 : : {
9682 : 0 : M2MetaError_MetaErrorT0 (paramtok, (const char *) "argument to {%EkDISPOSE} must be a pointer", 42);
9683 : : }
9684 : : }
9685 : : else
9686 : : {
9687 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}DEALLOCATE procedure not found for DISPOSE substitution", 59);
9688 : : }
9689 : : }
9690 : : else
9691 : : {
9692 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the pseudo procedure {%EkDISPOSE} has one or more parameters", 60);
9693 : : }
9694 : 280 : M2Quads_PopN (NoOfParam+1);
9695 : 280 : }
9696 : :
9697 : :
9698 : : /*
9699 : : CheckRangeIncDec - performs des := des <tok> expr
9700 : : with range checking (if enabled).
9701 : :
9702 : : Stack
9703 : : Entry Exit
9704 : :
9705 : : +------------+
9706 : : empty | des + expr |
9707 : : |------------|
9708 : : */
9709 : :
9710 : 16962 : static void CheckRangeIncDec (unsigned int tokenpos, unsigned int des, unsigned int expr, NameKey_Name tok)
9711 : : {
9712 : 16962 : unsigned int dtype;
9713 : 16962 : unsigned int etype;
9714 : :
9715 : 16962 : dtype = SymbolTable_GetDType (des);
9716 : 16962 : etype = SymbolTable_GetDType (expr);
9717 : 16962 : if ((etype == SymbolTable_NulSym) && (SymbolTable_IsPointer (SymbolTable_GetTypeMode (des))))
9718 : : {
9719 : 24 : expr = ConvertToAddress (tokenpos, expr);
9720 : 24 : etype = M2System_Address;
9721 : : }
9722 : 16962 : if (M2Options_WholeValueChecking && ! MustNotCheckBounds)
9723 : : {
9724 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
9725 : 1476 : if (tok == M2Reserved_PlusTok)
9726 : : {
9727 : 792 : BuildRange (M2Range_InitIncRangeCheck (des, expr));
9728 : : }
9729 : : else
9730 : : {
9731 : 684 : BuildRange (M2Range_InitDecRangeCheck (des, expr));
9732 : : }
9733 : : }
9734 : 16962 : if (M2Base_IsExpressionCompatible (dtype, etype))
9735 : : {
9736 : : /* the easy case simulate a straightforward macro */
9737 : 15540 : M2Quads_PushTF (des, dtype);
9738 : 15540 : M2Quads_PushT (tok);
9739 : 15540 : M2Quads_PushTF (expr, etype);
9740 : 15540 : doBuildBinaryOp (false, true);
9741 : : }
9742 : : else
9743 : : {
9744 : 1422 : if ((((M2Base_IsOrdinalType (dtype)) || (dtype == M2System_Address)) || (SymbolTable_IsPointer (dtype))) && (((M2Base_IsOrdinalType (etype)) || (etype == M2System_Address)) || (SymbolTable_IsPointer (etype))))
9745 : : {
9746 : 1422 : M2Quads_PushTF (des, dtype);
9747 : 1422 : M2Quads_PushT (tok);
9748 : 1422 : M2Quads_PushTF (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym));
9749 : 1422 : M2Quads_PushT (dtype);
9750 : 1422 : M2Quads_PushT (expr);
9751 : 1422 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
9752 : 1422 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
9753 : 1422 : doBuildBinaryOp (false, true);
9754 : : }
9755 : : else
9756 : : {
9757 : 0 : if (tok == M2Reserved_PlusTok)
9758 : : {
9759 : 0 : M2MetaError_MetaError0 ((const char *) "cannot perform {%EkINC} using non ordinal types", 47);
9760 : : }
9761 : : else
9762 : : {
9763 : 0 : M2MetaError_MetaError0 ((const char *) "cannot perform {%EkDEC} using non ordinal types", 47);
9764 : : }
9765 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (tokenpos, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym), static_cast<unsigned int> (SymbolTable_NulSym), tokenpos);
9766 : : }
9767 : : }
9768 : 16962 : }
9769 : :
9770 : :
9771 : : /*
9772 : : BuildIncProcedure - builds the pseudo procedure call INC.
9773 : : INC is a procedure which increments a variable.
9774 : : It takes one or two parameters:
9775 : : INC(a, b) or INC(a)
9776 : : a := a+b or a := a+1
9777 : :
9778 : : The Stack:
9779 : :
9780 : :
9781 : : Entry Exit
9782 : :
9783 : : Ptr ->
9784 : : +----------------+
9785 : : | NoOfParam |
9786 : : |----------------|
9787 : : | Param 1 |
9788 : : |----------------|
9789 : : | Param 2 |
9790 : : |----------------|
9791 : : . .
9792 : : . .
9793 : : . .
9794 : : |----------------|
9795 : : | Param # |
9796 : : |----------------|
9797 : : | ProcSym | Type | Empty
9798 : : |----------------|
9799 : : */
9800 : :
9801 : 13320 : static void BuildIncProcedure (void)
9802 : : {
9803 : 13320 : unsigned int proctok;
9804 : 13320 : unsigned int NoOfParam;
9805 : 13320 : unsigned int dtype;
9806 : 13320 : unsigned int OperandSym;
9807 : 13320 : unsigned int VarSym;
9808 : 13320 : unsigned int TempSym;
9809 : :
9810 : 13320 : M2Quads_PopT (&NoOfParam);
9811 : 13320 : proctok = OperandTtok (NoOfParam+1);
9812 : 13320 : if ((NoOfParam == 1) || (NoOfParam == 2))
9813 : : {
9814 : 13320 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam)); /* bottom/first parameter */
9815 : 13320 : if (SymbolTable_IsVar (VarSym)) /* bottom/first parameter */
9816 : : {
9817 : 13320 : dtype = SymbolTable_GetDType (VarSym);
9818 : 13320 : if (NoOfParam == 2)
9819 : : {
9820 : 2476 : OperandSym = DereferenceLValue (M2Quads_OperandTok (1), M2Quads_OperandT (1));
9821 : : }
9822 : : else
9823 : : {
9824 : 10844 : PushOne (proctok, dtype, (const char *) "the {%EkINC} will cause an overflow {%1ad}", 42);
9825 : 10844 : M2Quads_PopT (&OperandSym);
9826 : : }
9827 : 13320 : M2Quads_PushT (VarSym);
9828 : 13320 : TempSym = DereferenceLValue (M2Quads_OperandTok (NoOfParam), VarSym);
9829 : 13320 : CheckRangeIncDec (proctok, TempSym, OperandSym, M2Reserved_PlusTok); /* TempSym + OperandSym */
9830 : 13320 : BuildAssignmentWithoutBounds (proctok, false, true); /* VarSym := TempSym + OperandSym */
9831 : : }
9832 : : else
9833 : : {
9834 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "base procedure {%EkINC} expects a variable as a parameter but was given {%1Ed}", 78, VarSym);
9835 : : }
9836 : : }
9837 : : else
9838 : : {
9839 : 0 : M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkINC} expects 1 or 2 parameters", 53);
9840 : : }
9841 : 13320 : M2Quads_PopN (NoOfParam+1);
9842 : 13320 : }
9843 : :
9844 : :
9845 : : /*
9846 : : BuildDecProcedure - builds the pseudo procedure call DEC.
9847 : : DEC is a procedure which decrements a variable.
9848 : : It takes one or two parameters:
9849 : : DEC(a, b) or DEC(a)
9850 : : a := a-b or a := a-1
9851 : :
9852 : : The Stack:
9853 : :
9854 : :
9855 : : Entry Exit
9856 : :
9857 : : Ptr ->
9858 : : +----------------+
9859 : : | NoOfParam |
9860 : : |----------------|
9861 : : | Param 1 |
9862 : : |----------------|
9863 : : | Param 2 |
9864 : : |----------------|
9865 : : . .
9866 : : . .
9867 : : . .
9868 : : |----------------|
9869 : : | Param # |
9870 : : |----------------|
9871 : : | ProcSym | Type | Empty
9872 : : |----------------|
9873 : : */
9874 : :
9875 : 3642 : static void BuildDecProcedure (void)
9876 : : {
9877 : 3642 : unsigned int proctok;
9878 : 3642 : unsigned int NoOfParam;
9879 : 3642 : unsigned int dtype;
9880 : 3642 : unsigned int OperandSym;
9881 : 3642 : unsigned int VarSym;
9882 : 3642 : unsigned int TempSym;
9883 : :
9884 : 3642 : M2Quads_PopT (&NoOfParam);
9885 : 3642 : proctok = OperandTtok (NoOfParam+1);
9886 : 3642 : if ((NoOfParam == 1) || (NoOfParam == 2))
9887 : : {
9888 : 3642 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam)); /* bottom/first parameter */
9889 : 3642 : if (SymbolTable_IsVar (VarSym)) /* bottom/first parameter */
9890 : : {
9891 : 3642 : dtype = SymbolTable_GetDType (VarSym);
9892 : 3642 : if (NoOfParam == 2)
9893 : : {
9894 : 1262 : OperandSym = DereferenceLValue (M2Quads_OperandTok (1), M2Quads_OperandT (1));
9895 : : }
9896 : : else
9897 : : {
9898 : 2380 : PushOne (proctok, dtype, (const char *) "the {%EkDEC} will cause an overflow {%1ad}", 42);
9899 : 2380 : M2Quads_PopT (&OperandSym);
9900 : : }
9901 : 3642 : M2Quads_PushT (VarSym);
9902 : 3642 : TempSym = DereferenceLValue (M2Quads_OperandTok (NoOfParam), VarSym);
9903 : 3642 : CheckRangeIncDec (proctok, TempSym, OperandSym, M2Reserved_MinusTok); /* TempSym - OperandSym */
9904 : 3642 : BuildAssignmentWithoutBounds (proctok, false, true); /* VarSym := TempSym - OperandSym */
9905 : : }
9906 : : else
9907 : : {
9908 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "base procedure {%EkDEC} expects a variable as a parameter but was given {%1Ed}", 78, VarSym);
9909 : : }
9910 : : }
9911 : : else
9912 : : {
9913 : 0 : M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkDEC} expects 1 or 2 parameters", 53);
9914 : : }
9915 : 3642 : M2Quads_PopN (NoOfParam+1);
9916 : 3642 : }
9917 : :
9918 : :
9919 : : /*
9920 : : DereferenceLValue - checks to see whether, operand, is declare as an LValue
9921 : : and if so it dereferences it.
9922 : : */
9923 : :
9924 : 22932 : static unsigned int DereferenceLValue (unsigned int tok, unsigned int operand)
9925 : : {
9926 : 22932 : unsigned int sym;
9927 : :
9928 : 22932 : if ((SymbolTable_GetMode (operand)) == SymbolTable_LeftValue)
9929 : : {
9930 : : /* dereference the pointer */
9931 : 1468 : sym = SymbolTable_MakeTemporary (tok, AreConstant (SymbolTable_IsConst (operand)));
9932 : 734 : SymbolTable_PutVar (sym, SymbolTable_GetSType (operand));
9933 : 734 : M2Quads_PushTtok (sym, tok);
9934 : 734 : M2Quads_PushTtok (operand, tok);
9935 : 734 : BuildAssignmentWithoutBounds (tok, false, true);
9936 : 734 : return sym;
9937 : : }
9938 : : else
9939 : : {
9940 : : return operand;
9941 : : }
9942 : : /* static analysis guarentees a RETURN statement will be used before here. */
9943 : : __builtin_unreachable ();
9944 : : }
9945 : :
9946 : :
9947 : : /*
9948 : : BuildInclProcedure - builds the pseudo procedure call INCL.
9949 : : INCL is a procedure which adds bit b into a BITSET a.
9950 : : It takes two parameters:
9951 : : INCL(a, b)
9952 : :
9953 : : a := a + {b}
9954 : :
9955 : : The Stack:
9956 : :
9957 : :
9958 : : Entry Exit
9959 : :
9960 : : Ptr ->
9961 : : +----------------+
9962 : : | NoOfParam |
9963 : : |----------------|
9964 : : | Param 1 |
9965 : : |----------------|
9966 : : | Param 2 |
9967 : : |----------------|
9968 : : | ProcSym | Type | Empty
9969 : : |----------------|
9970 : : */
9971 : :
9972 : 784 : static void BuildInclProcedure (void)
9973 : : {
9974 : 784 : unsigned int proctok;
9975 : 784 : unsigned int optok;
9976 : 784 : unsigned int NoOfParam;
9977 : 784 : unsigned int DerefSym;
9978 : 784 : unsigned int OperandSym;
9979 : 784 : unsigned int VarSym;
9980 : :
9981 : 784 : M2Quads_PopT (&NoOfParam);
9982 : 784 : proctok = OperandTtok (NoOfParam+1);
9983 : 784 : if (NoOfParam == 2)
9984 : : {
9985 : 784 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
9986 : 784 : MarkArrayWritten (M2Quads_OperandA (2));
9987 : 784 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
9988 : 784 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
9989 : 784 : if (SymbolTable_IsVar (VarSym))
9990 : : {
9991 : 778 : if (SymbolTable_IsSet (SymbolTable_GetDType (VarSym)))
9992 : : {
9993 : 778 : DerefSym = DereferenceLValue (optok, OperandSym);
9994 : 778 : BuildRange (M2Range_InitInclCheck (VarSym, DerefSym));
9995 : 778 : GenQuadO (proctok, M2Quads_InclOp, VarSym, SymbolTable_NulSym, DerefSym, false);
9996 : : }
9997 : : else
9998 : : {
9999 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "the first parameter to {%EkINCL} must be a set variable but is {%1Ed}", 69, VarSym);
10000 : : }
10001 : : }
10002 : : else
10003 : : {
10004 : 6 : M2MetaError_MetaErrorT1 (proctok, (const char *) "base procedure {%EkINCL} expects a variable as a parameter but is {%1Ed}", 72, VarSym);
10005 : : }
10006 : : }
10007 : : else
10008 : : {
10009 : 0 : M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkINCL} expects 1 or 2 parameters", 54);
10010 : : }
10011 : 784 : M2Quads_PopN (NoOfParam+1);
10012 : 784 : }
10013 : :
10014 : :
10015 : : /*
10016 : : BuildExclProcedure - builds the pseudo procedure call EXCL.
10017 : : INCL is a procedure which removes bit b from SET a.
10018 : : It takes two parameters:
10019 : : EXCL(a, b)
10020 : :
10021 : : a := a - {b}
10022 : :
10023 : : The Stack:
10024 : :
10025 : :
10026 : : Entry Exit
10027 : :
10028 : : Ptr ->
10029 : : +----------------+
10030 : : | NoOfParam |
10031 : : |----------------|
10032 : : | Param 1 |
10033 : : |----------------|
10034 : : | Param 2 |
10035 : : |----------------|
10036 : : | ProcSym | Type | Empty
10037 : : |----------------|
10038 : : */
10039 : :
10040 : 460 : static void BuildExclProcedure (void)
10041 : : {
10042 : 460 : unsigned int proctok;
10043 : 460 : unsigned int optok;
10044 : 460 : unsigned int NoOfParam;
10045 : 460 : unsigned int DerefSym;
10046 : 460 : unsigned int OperandSym;
10047 : 460 : unsigned int VarSym;
10048 : :
10049 : 460 : M2Quads_PopT (&NoOfParam);
10050 : 460 : proctok = OperandTtok (NoOfParam+1);
10051 : 460 : if (NoOfParam == 2)
10052 : : {
10053 : 460 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10054 : 460 : MarkArrayWritten (M2Quads_OperandA (2));
10055 : 460 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10056 : 460 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10057 : 460 : if (SymbolTable_IsVar (VarSym))
10058 : : {
10059 : 460 : if (SymbolTable_IsSet (SymbolTable_GetDType (VarSym)))
10060 : : {
10061 : 460 : DerefSym = DereferenceLValue (optok, OperandSym);
10062 : 460 : BuildRange (M2Range_InitExclCheck (VarSym, DerefSym));
10063 : 460 : GenQuadO (proctok, M2Quads_ExclOp, VarSym, SymbolTable_NulSym, DerefSym, false);
10064 : : }
10065 : : else
10066 : : {
10067 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "the first parameter to {%EkEXCL} must be a set variable but is {%1Ed}", 69, VarSym);
10068 : : }
10069 : : }
10070 : : else
10071 : : {
10072 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "base procedure {%EkEXCL} expects a variable as a parameter but is {%1Ed}", 72, VarSym);
10073 : : }
10074 : : }
10075 : : else
10076 : : {
10077 : 0 : M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkEXCL} expects 1 or 2 parameters", 54);
10078 : : }
10079 : 460 : M2Quads_PopN (NoOfParam+1);
10080 : 460 : }
10081 : :
10082 : :
10083 : : /*
10084 : : BuildTypeCoercion - builds the type coersion.
10085 : : Modula-2 allows types to be coersed with no runtime
10086 : : penility.
10087 : : It insists that the TSIZE(t1)=TSIZE(t2) where
10088 : : t2 variable := t2(variable of type t1).
10089 : : The ReturnVar on the stack is of type t2.
10090 : :
10091 : : The Stack:
10092 : :
10093 : :
10094 : : Entry Exit
10095 : :
10096 : : Ptr ->
10097 : : +----------------+
10098 : : | NoOfParam |
10099 : : |----------------|
10100 : : | Param 1 |
10101 : : |----------------|
10102 : : | Param 2 |
10103 : : |----------------|
10104 : : . .
10105 : : . .
10106 : : . .
10107 : : |----------------|
10108 : : | Param # | <- Ptr
10109 : : |----------------| +------------+
10110 : : | ProcSym | Type | | ReturnVar |
10111 : : |----------------| |------------|
10112 : :
10113 : : Quadruples:
10114 : :
10115 : : CoerceOp ReturnVar Type Param1
10116 : :
10117 : : A type coercion will only be legal if the different
10118 : : types have exactly the same size.
10119 : : Since we can only decide this after M2Eval has processed
10120 : : the symbol table then we create a quadruple explaining
10121 : : the coercion taking place, the code generator can test
10122 : : this assertion and report an error if the type sizes
10123 : : differ.
10124 : : */
10125 : :
10126 : 1478 : static void BuildTypeCoercion (bool ConstExpr)
10127 : : {
10128 : 1478 : unsigned int resulttok;
10129 : 1478 : unsigned int proctok;
10130 : 1478 : unsigned int exptok;
10131 : 1478 : unsigned int r;
10132 : 1478 : unsigned int exp;
10133 : 1478 : unsigned int NoOfParam;
10134 : 1478 : unsigned int ReturnVar;
10135 : 1478 : unsigned int ProcSym;
10136 : :
10137 : 1478 : M2Quads_PopT (&NoOfParam);
10138 : 1478 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
10139 : 1478 : proctok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
10140 : 1478 : if (! (SymbolTable_IsAModula2Type (ProcSym)))
10141 : : {
10142 : 0 : M2MetaError_MetaError1 ((const char *) "coersion expecting a type, seen {%1Ea} which is {%1Ed}", 54, ProcSym);
10143 : : }
10144 : 1478 : if (NoOfParam == 1)
10145 : : {
10146 : 1478 : PopTrwtok (&exp, &r, &exptok);
10147 : 1478 : MarkAsRead (r);
10148 : 1478 : resulttok = M2LexBuf_MakeVirtual2Tok (proctok, exptok);
10149 : 1478 : M2Quads_PopN (1); /* Pop procedure. */
10150 : 1478 : if (ConstExprError (ProcSym, exp, exptok, ConstExpr)) /* Pop procedure. */
10151 : : {
10152 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
10153 : 0 : SymbolTable_PutVar (ReturnVar, ProcSym); /* Set ReturnVar's TYPE. */
10154 : : }
10155 : : /* Set ReturnVar's TYPE. */
10156 : 1478 : else if ((SymbolTable_IsConst (exp)) || (SymbolTable_IsVar (exp)))
10157 : : {
10158 : : /* avoid dangling else. */
10159 : 2956 : ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (SymbolTable_IsConst (exp)));
10160 : 1478 : SymbolTable_PutVar (ReturnVar, ProcSym); /* Set ReturnVar's TYPE. */
10161 : 1478 : GenQuad (M2Quads_CoerceOp, ReturnVar, ProcSym, exp); /* Set ReturnVar's TYPE. */
10162 : : }
10163 : : else
10164 : : {
10165 : : /* avoid dangling else. */
10166 : 0 : M2MetaError_MetaError2 ((const char *) "trying to coerse {%1EMRad} which is not a variable or constant into {%2ad}", 74, exp, ProcSym);
10167 : 0 : M2MetaError_MetaError2 ((const char *) "trying to coerse {%1ECad} which is not a variable or constant into {%2ad}", 73, exp, ProcSym);
10168 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_RightValue);
10169 : 0 : SymbolTable_PutVar (ReturnVar, ProcSym); /* Set ReturnVar's TYPE. */
10170 : : }
10171 : 1478 : M2Quads_PushTFtok (ReturnVar, ProcSym, resulttok);
10172 : : }
10173 : : else
10174 : : {
10175 : 0 : M2MetaError_MetaError0 ((const char *) "{%E}only one parameter expected in a TYPE coersion", 50);
10176 : : }
10177 : 1478 : }
10178 : :
10179 : :
10180 : : /*
10181 : : BuildRealFunctionCall - builds a function call.
10182 : : The Stack:
10183 : :
10184 : :
10185 : : Entry Exit
10186 : :
10187 : : Ptr ->
10188 : : +----------------+
10189 : : | NoOfParam |
10190 : : |----------------|
10191 : : | Param 1 |
10192 : : |----------------|
10193 : : | Param 2 |
10194 : : |----------------|
10195 : : . .
10196 : : . .
10197 : : . .
10198 : : |----------------|
10199 : : | Param # | <- Ptr
10200 : : |----------------| +------------+
10201 : : | ProcSym | Type | | ReturnVar |
10202 : : |----------------| |------------|
10203 : : */
10204 : :
10205 : 42042 : static void BuildRealFunctionCall (unsigned int tokno, bool ConstExpr)
10206 : : {
10207 : 42042 : unsigned int NoOfParam;
10208 : 42042 : unsigned int ProcSym;
10209 : :
10210 : 42042 : M2Quads_PopT (&NoOfParam);
10211 : 42042 : M2Quads_PushT (NoOfParam);
10212 : 42042 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+2));
10213 : 42042 : ProcSym = PCSymBuild_SkipConst (ProcSym);
10214 : 42042 : if (SymbolTable_IsVar (ProcSym))
10215 : : {
10216 : : /* Procedure Variable therefore get its type to see if it is a FOR "C" call. */
10217 : 82 : ProcSym = SymbolTable_SkipType (M2Quads_OperandF (NoOfParam+2));
10218 : : }
10219 : 42042 : if ((SymbolTable_IsDefImp (SymbolTable_GetScope (ProcSym))) && (SymbolTable_IsDefinitionForC (SymbolTable_GetScope (ProcSym))))
10220 : : {
10221 : 4982 : BuildRealFuncProcCall (tokno, true, true, ConstExpr);
10222 : : }
10223 : : else
10224 : : {
10225 : 37060 : BuildRealFuncProcCall (tokno, true, false, ConstExpr);
10226 : : }
10227 : 42036 : }
10228 : :
10229 : :
10230 : : /*
10231 : : BuildPseudoFunctionCall - builds the pseudo function
10232 : : The Stack:
10233 : :
10234 : :
10235 : : Entry Exit
10236 : :
10237 : : Ptr ->
10238 : : +----------------+
10239 : : | NoOfParam |
10240 : : |----------------|
10241 : : | Param 1 |
10242 : : |----------------|
10243 : : | Param 2 |
10244 : : |----------------|
10245 : : . .
10246 : : . .
10247 : : . .
10248 : : |----------------|
10249 : : | Param # | <- Ptr
10250 : : |----------------| +------------+
10251 : : | ProcSym | Type | | ReturnVar |
10252 : : |----------------| |------------|
10253 : :
10254 : : */
10255 : :
10256 : 32664 : static void BuildPseudoFunctionCall (bool ConstExpr)
10257 : : {
10258 : 32664 : unsigned int NoOfParam;
10259 : 32664 : unsigned int ProcSym;
10260 : :
10261 : 32664 : M2Quads_PopT (&NoOfParam);
10262 : 32664 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
10263 : 32664 : ProcSym = PCSymBuild_SkipConst (ProcSym);
10264 : 32664 : M2Quads_PushT (NoOfParam);
10265 : : /* Compile time stack restored to entry state. */
10266 : 32664 : if (ProcSym == M2Base_High)
10267 : : {
10268 : 2314 : BuildHighFunction ();
10269 : : }
10270 : 30350 : else if (ProcSym == M2Base_LengthS)
10271 : : {
10272 : : /* avoid dangling else. */
10273 : 346 : BuildLengthFunction (ProcSym, ConstExpr);
10274 : : }
10275 : 30004 : else if (ProcSym == M2System_Adr)
10276 : : {
10277 : : /* avoid dangling else. */
10278 : 9806 : BuildAdrFunction ();
10279 : : }
10280 : 20198 : else if (ProcSym == M2Size_Size)
10281 : : {
10282 : : /* avoid dangling else. */
10283 : 2126 : BuildSizeFunction ();
10284 : : }
10285 : 18072 : else if (ProcSym == M2System_TSize)
10286 : : {
10287 : : /* avoid dangling else. */
10288 : 3480 : BuildTSizeFunction ();
10289 : : }
10290 : 14592 : else if (ProcSym == M2System_TBitSize)
10291 : : {
10292 : : /* avoid dangling else. */
10293 : 12 : BuildTBitSizeFunction ();
10294 : : }
10295 : 14580 : else if (ProcSym == M2Base_Convert)
10296 : : {
10297 : : /* avoid dangling else. */
10298 : 12 : BuildConvertFunction (ProcSym, ConstExpr);
10299 : : }
10300 : 14568 : else if (ProcSym == M2Base_Odd)
10301 : : {
10302 : : /* avoid dangling else. */
10303 : 50 : BuildOddFunction (ProcSym, ConstExpr);
10304 : : }
10305 : 14518 : else if (ProcSym == M2Base_Abs)
10306 : : {
10307 : : /* avoid dangling else. */
10308 : 128 : BuildAbsFunction (ProcSym, ConstExpr);
10309 : : }
10310 : 14390 : else if (ProcSym == M2Base_Cap)
10311 : : {
10312 : : /* avoid dangling else. */
10313 : 124 : BuildCapFunction (ProcSym, ConstExpr);
10314 : : }
10315 : 14266 : else if (ProcSym == M2Base_Val)
10316 : : {
10317 : : /* avoid dangling else. */
10318 : 3280 : BuildValFunction (ProcSym, ConstExpr);
10319 : : }
10320 : 10986 : else if (ProcSym == M2Base_Chr)
10321 : : {
10322 : : /* avoid dangling else. */
10323 : 454 : BuildChrFunction (ProcSym, ConstExpr);
10324 : : }
10325 : 10532 : else if (M2Base_IsOrd (ProcSym))
10326 : : {
10327 : : /* avoid dangling else. */
10328 : 3184 : BuildOrdFunction (ProcSym, ConstExpr);
10329 : : }
10330 : 7348 : else if (M2Base_IsInt (ProcSym))
10331 : : {
10332 : : /* avoid dangling else. */
10333 : 6 : BuildIntFunction (ProcSym, ConstExpr);
10334 : : }
10335 : 7342 : else if (M2Base_IsTrunc (ProcSym))
10336 : : {
10337 : : /* avoid dangling else. */
10338 : 60 : BuildTruncFunction (ProcSym, ConstExpr);
10339 : : }
10340 : 7282 : else if (M2Base_IsFloat (ProcSym))
10341 : : {
10342 : : /* avoid dangling else. */
10343 : 64 : BuildFloatFunction (ProcSym, ConstExpr);
10344 : : }
10345 : 7218 : else if (ProcSym == M2Base_Min)
10346 : : {
10347 : : /* avoid dangling else. */
10348 : 1092 : BuildMinFunction ();
10349 : : }
10350 : 6126 : else if (ProcSym == M2Base_Max)
10351 : : {
10352 : : /* avoid dangling else. */
10353 : 4352 : BuildMaxFunction ();
10354 : : }
10355 : 1774 : else if (ProcSym == M2System_AddAdr)
10356 : : {
10357 : : /* avoid dangling else. */
10358 : 36 : BuildAddAdrFunction (ProcSym, ConstExpr);
10359 : : }
10360 : 1738 : else if (ProcSym == M2System_SubAdr)
10361 : : {
10362 : : /* avoid dangling else. */
10363 : 12 : BuildSubAdrFunction (ProcSym, ConstExpr);
10364 : : }
10365 : 1726 : else if (ProcSym == M2System_DifAdr)
10366 : : {
10367 : : /* avoid dangling else. */
10368 : 12 : BuildDifAdrFunction (ProcSym, ConstExpr);
10369 : : }
10370 : 1714 : else if (ProcSym == M2System_Cast)
10371 : : {
10372 : : /* avoid dangling else. */
10373 : 156 : BuildCastFunction (ProcSym, ConstExpr);
10374 : : }
10375 : 1558 : else if (ProcSym == M2System_Shift)
10376 : : {
10377 : : /* avoid dangling else. */
10378 : 702 : BuildShiftFunction ();
10379 : : }
10380 : 856 : else if (ProcSym == M2System_Rotate)
10381 : : {
10382 : : /* avoid dangling else. */
10383 : 232 : BuildRotateFunction ();
10384 : : }
10385 : 624 : else if (ProcSym == M2System_MakeAdr)
10386 : : {
10387 : : /* avoid dangling else. */
10388 : 12 : BuildMakeAdrFunction ();
10389 : : }
10390 : 612 : else if (ProcSym == M2Base_Re)
10391 : : {
10392 : : /* avoid dangling else. */
10393 : 60 : BuildReFunction (ProcSym, ConstExpr);
10394 : : }
10395 : 552 : else if (ProcSym == M2Base_Im)
10396 : : {
10397 : : /* avoid dangling else. */
10398 : 60 : BuildImFunction (ProcSym, ConstExpr);
10399 : : }
10400 : 492 : else if (ProcSym == M2Base_Cmplx)
10401 : : {
10402 : : /* avoid dangling else. */
10403 : 492 : BuildCmplxFunction (ProcSym, ConstExpr);
10404 : : }
10405 : : else
10406 : : {
10407 : : /* avoid dangling else. */
10408 : 0 : M2Error_InternalError ((const char *) "pseudo function not implemented yet", 35);
10409 : : }
10410 : 32652 : }
10411 : :
10412 : :
10413 : : /*
10414 : : BuildAddAdrFunction - builds the pseudo procedure call ADDADR.
10415 : :
10416 : : PROCEDURE ADDADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
10417 : :
10418 : : Which returns address given by (addr + offset),
10419 : : [ the standard says that it _may_
10420 : : "raise an exception if this address is not valid."
10421 : : currently we do not generate any exception code ]
10422 : :
10423 : : The Stack:
10424 : :
10425 : : Entry Exit
10426 : :
10427 : : Ptr ->
10428 : : +----------------+
10429 : : | NoOfParam |
10430 : : |----------------|
10431 : : | Param 1 |
10432 : : |----------------|
10433 : : | Param 2 | <- Ptr
10434 : : |----------------| +------------+
10435 : : | ProcSym | Type | | ReturnVar |
10436 : : |----------------| |------------|
10437 : : */
10438 : :
10439 : 36 : static void BuildAddAdrFunction (unsigned int ProcSym, bool ConstExpr)
10440 : : {
10441 : 36 : unsigned int combinedtok;
10442 : 36 : unsigned int functok;
10443 : 36 : unsigned int vartok;
10444 : 36 : unsigned int optok;
10445 : 36 : unsigned int opa;
10446 : 36 : unsigned int ReturnVar;
10447 : 36 : unsigned int NoOfParam;
10448 : 36 : unsigned int OperandSym;
10449 : 36 : unsigned int VarSym;
10450 : :
10451 : 36 : M2Quads_PopT (&NoOfParam);
10452 : 36 : functok = OperandTtok (NoOfParam+1);
10453 : 36 : if (NoOfParam == 2)
10454 : : {
10455 : 36 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10456 : 36 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
10457 : 36 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10458 : 36 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10459 : 36 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
10460 : 36 : M2Quads_PopN (NoOfParam+1);
10461 : 36 : if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
10462 : : {
10463 : : /* Fake return result. */
10464 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10465 : : }
10466 : 36 : else if (SymbolTable_IsVar (VarSym))
10467 : : {
10468 : : /* avoid dangling else. */
10469 : 36 : if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
10470 : : {
10471 : 36 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
10472 : 36 : SymbolTable_PutVar (ReturnVar, M2System_Address);
10473 : 36 : opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
10474 : 72 : GenQuadOtok (combinedtok, M2Quads_AddOp, ReturnVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
10475 : 36 : M2Quads_PushTFtok (ReturnVar, M2System_Address, combinedtok);
10476 : : }
10477 : : else
10478 : : {
10479 : 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);
10480 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10481 : : }
10482 : : }
10483 : : else
10484 : : {
10485 : : /* avoid dangling else. */
10486 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure ADDADR expects a variable of type ADDRESS or POINTER as its first parameter", 96);
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 {%EkADDADR} 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 : 36 : }
10497 : :
10498 : :
10499 : : /*
10500 : : BuildSubAdrFunction - builds the pseudo procedure call ADDADR.
10501 : :
10502 : : PROCEDURE SUBADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
10503 : :
10504 : : Which returns address given by (addr - offset),
10505 : : [ the standard says that it _may_
10506 : : "raise an exception if this address is not valid."
10507 : : currently we do not generate any exception code ]
10508 : :
10509 : : The Stack:
10510 : :
10511 : : Entry Exit
10512 : :
10513 : : Ptr ->
10514 : : +----------------+
10515 : : | NoOfParam |
10516 : : |----------------|
10517 : : | Param 1 |
10518 : : |----------------|
10519 : : | Param 2 | <- Ptr
10520 : : |----------------| +------------+
10521 : : | ProcSym | Type | | ReturnVar |
10522 : : |----------------| |------------|
10523 : : */
10524 : :
10525 : 12 : static void BuildSubAdrFunction (unsigned int ProcSym, bool ConstExpr)
10526 : : {
10527 : 12 : unsigned int functok;
10528 : 12 : unsigned int combinedtok;
10529 : 12 : unsigned int optok;
10530 : 12 : unsigned int vartok;
10531 : 12 : unsigned int ReturnVar;
10532 : 12 : unsigned int NoOfParam;
10533 : 12 : unsigned int OperandSym;
10534 : 12 : unsigned int opa;
10535 : 12 : unsigned int VarSym;
10536 : :
10537 : 12 : M2Quads_PopT (&NoOfParam);
10538 : 12 : functok = OperandTtok (NoOfParam+1);
10539 : 12 : if (NoOfParam == 2)
10540 : : {
10541 : 12 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10542 : 12 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10543 : 12 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10544 : 12 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
10545 : 12 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
10546 : 12 : M2Quads_PopN (NoOfParam+1);
10547 : 12 : if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
10548 : : {
10549 : : /* Fake return result. */
10550 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10551 : : }
10552 : 12 : else if (SymbolTable_IsVar (VarSym))
10553 : : {
10554 : : /* avoid dangling else. */
10555 : 12 : if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
10556 : : {
10557 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
10558 : 12 : SymbolTable_PutVar (ReturnVar, M2System_Address);
10559 : 12 : opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
10560 : 24 : GenQuadOtok (combinedtok, M2Quads_SubOp, ReturnVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
10561 : 12 : M2Quads_PushTFtok (ReturnVar, M2System_Address, combinedtok);
10562 : : }
10563 : : else
10564 : : {
10565 : 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);
10566 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (vartok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, vartok);
10567 : : }
10568 : : }
10569 : : else
10570 : : {
10571 : : /* avoid dangling else. */
10572 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
10573 : 0 : M2MetaError_MetaErrorT0 (combinedtok, (const char *) "{%E}SYSTEM procedure {%EkSUBADR} expects a variable of type ADDRESS or POINTER as its first parameter", 101);
10574 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10575 : : }
10576 : : }
10577 : : else
10578 : : {
10579 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure {%EkSUBADR} expects 2 parameters", 53);
10580 : 0 : M2Quads_PopN (NoOfParam+1);
10581 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, functok);
10582 : : }
10583 : 12 : }
10584 : :
10585 : :
10586 : : /*
10587 : : BuildDifAdrFunction - builds the pseudo procedure call DIFADR.
10588 : :
10589 : : PROCEDURE DIFADR (addr1, addr2: ADDRESS): INTEGER ;
10590 : :
10591 : : Which returns address given by (addr1 - addr2),
10592 : : [ the standard says that it _may_
10593 : : "raise an exception if this address is invalid or
10594 : : address space is non-contiguous."
10595 : : currently we do not generate any exception code ]
10596 : :
10597 : : The Stack:
10598 : :
10599 : : Entry Exit
10600 : :
10601 : : Ptr ->
10602 : : +----------------+
10603 : : | NoOfParam |
10604 : : |----------------|
10605 : : | Param 1 |
10606 : : |----------------|
10607 : : | Param 2 | <- Ptr
10608 : : |----------------| +------------+
10609 : : | ProcSym | Type | | ReturnVar |
10610 : : |----------------| |------------|
10611 : : */
10612 : :
10613 : 12 : static void BuildDifAdrFunction (unsigned int ProcSym, bool ConstExpr)
10614 : : {
10615 : 12 : unsigned int functok;
10616 : 12 : unsigned int optok;
10617 : 12 : unsigned int vartok;
10618 : 12 : unsigned int combinedtok;
10619 : 12 : unsigned int TempVar;
10620 : 12 : unsigned int NoOfParam;
10621 : 12 : unsigned int OperandSym;
10622 : 12 : unsigned int opa;
10623 : 12 : unsigned int VarSym;
10624 : :
10625 : 12 : M2Quads_PopT (&NoOfParam);
10626 : 12 : functok = OperandTtok (NoOfParam+1);
10627 : 12 : if (NoOfParam >= 1)
10628 : : {
10629 : 12 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10630 : 12 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10631 : : }
10632 : : else
10633 : : {
10634 : : optok = functok;
10635 : : }
10636 : 12 : if (NoOfParam == 2)
10637 : : {
10638 : 12 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10639 : 12 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
10640 : 12 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
10641 : 12 : M2Quads_PopN (NoOfParam+1);
10642 : 12 : if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
10643 : : {
10644 : : /* Fake return result. */
10645 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10646 : : }
10647 : 12 : else if (SymbolTable_IsVar (VarSym))
10648 : : {
10649 : : /* avoid dangling else. */
10650 : 12 : if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
10651 : : {
10652 : 12 : if ((IsReallyPointer (OperandSym)) || ((SymbolTable_GetSType (OperandSym)) == M2System_Address))
10653 : : {
10654 : 12 : TempVar = SymbolTable_MakeTemporary (vartok, SymbolTable_RightValue);
10655 : 12 : SymbolTable_PutVar (TempVar, M2System_Address);
10656 : 12 : opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
10657 : 24 : GenQuadOtok (combinedtok, M2Quads_SubOp, TempVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
10658 : : /*
10659 : : Build macro: CONVERT( INTEGER, TempVar )
10660 : : */
10661 : 12 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
10662 : 12 : M2Quads_PushTtok (M2Base_Integer, functok);
10663 : 12 : M2Quads_PushTtok (TempVar, vartok);
10664 : 12 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
10665 : 12 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* Two parameters */
10666 : : }
10667 : : else
10668 : : {
10669 : 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);
10670 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10671 : : }
10672 : : }
10673 : : else
10674 : : {
10675 : 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);
10676 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10677 : : }
10678 : : }
10679 : : else
10680 : : {
10681 : : /* avoid dangling else. */
10682 : 0 : M2MetaError_MetaError0 ((const char *) "{%E}SYSTEM procedure {%EkDIFADR} expects a variable of type ADDRESS or POINTER as its first parameter", 101);
10683 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10684 : : }
10685 : : }
10686 : : else
10687 : : {
10688 : 0 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
10689 : 0 : M2MetaError_MetaErrorT0 (combinedtok, (const char *) "{%E}SYSTEM procedure {%EkDIFADR} expects 2 parameters", 53);
10690 : 0 : M2Quads_PopN (NoOfParam+1);
10691 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10692 : : }
10693 : 12 : }
10694 : :
10695 : :
10696 : : /*
10697 : : BuildHighFunction - checks the stack in preparation for generating
10698 : : quadruples which perform HIGH.
10699 : : This procedure does not alter the stack but
10700 : : determines whether, a, in HIGH(a) is an ArraySym
10701 : : or UnboundedSym.
10702 : : Both cases are different and appropriate quadruple
10703 : : generating routines are called.
10704 : :
10705 : : The Stack:
10706 : :
10707 : :
10708 : : Entry Exit
10709 : :
10710 : : Ptr ->
10711 : : +----------------+
10712 : : | NoOfParam |
10713 : : |----------------|
10714 : : | Param 1 |
10715 : : |----------------|
10716 : : | Param 2 |
10717 : : |----------------|
10718 : : . .
10719 : : . .
10720 : : . .
10721 : : |----------------|
10722 : : | Param # | <- Ptr
10723 : : |----------------| +------------+
10724 : : | ProcSym | Type | | ReturnVar |
10725 : : |----------------| |------------|
10726 : :
10727 : : */
10728 : :
10729 : 2314 : static void BuildHighFunction (void)
10730 : : {
10731 : 2314 : unsigned int functok;
10732 : 2314 : unsigned int combinedtok;
10733 : 2314 : unsigned int paramtok;
10734 : 2314 : unsigned int ProcSym;
10735 : 2314 : unsigned int Type;
10736 : 2314 : unsigned int NoOfParam;
10737 : 2314 : unsigned int Param;
10738 : :
10739 : 2314 : M2Quads_PopT (&NoOfParam);
10740 : 2314 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
10741 : 2314 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
10742 : 2314 : BuildSizeCheckEnd (ProcSym); /* quadruple generation now on */
10743 : 2314 : if (NoOfParam == 1) /* quadruple generation now on */
10744 : : {
10745 : 2314 : Param = static_cast<unsigned int> (M2Quads_OperandT (1));
10746 : 2314 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10747 : 2314 : combinedtok = M2LexBuf_MakeVirtualTok (paramtok, functok, paramtok);
10748 : 2314 : Type = SymbolTable_GetDType (Param);
10749 : : /* Restore stack to original form */
10750 : 2314 : M2Quads_PushT (NoOfParam);
10751 : 2314 : if (((! (SymbolTable_IsVar (Param))) && (! (SymbolTable_IsConstString (Param)))) && (! (SymbolTable_IsConst (Param))))
10752 : : {
10753 : : /* we cannot test for IsConst(Param) AND (GetSType(Param)=Char) as the type might not be assigned yet */
10754 : 0 : M2MetaError_MetaError1 ((const char *) "base procedure {%EkHIGH} expects a variable or string constant as its parameter {%1d:rather than {%1d}} {%1asa}", 111, Param);
10755 : : }
10756 : 2314 : else if (SymbolTable_IsUnbounded (Type))
10757 : : {
10758 : : /* avoid dangling else. */
10759 : 2204 : BuildHighFromUnbounded (combinedtok);
10760 : : }
10761 : : else
10762 : : {
10763 : : /* avoid dangling else. */
10764 : 110 : BuildConstHighFromSym (combinedtok);
10765 : : }
10766 : : }
10767 : : else
10768 : : {
10769 : 0 : M2MetaError_MetaError0 ((const char *) "base procedure {%EkHIGH} requires one parameter", 47);
10770 : 0 : M2Quads_PopN (2);
10771 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
10772 : : }
10773 : 2314 : }
10774 : :
10775 : :
10776 : : /*
10777 : : BuildConstHighFromSym - builds the pseudo function HIGH from an Sym.
10778 : : Sym is a constant or an array which has constant bounds
10779 : : and therefore it can be calculated at compile time.
10780 : :
10781 : : The Stack:
10782 : :
10783 : :
10784 : : Entry Exit
10785 : :
10786 : : Ptr ->
10787 : : +----------------+
10788 : : | NoOfParam |
10789 : : |----------------|
10790 : : | Param 1 |
10791 : : |----------------|
10792 : : | Param 2 |
10793 : : |----------------|
10794 : : . .
10795 : : . .
10796 : : . .
10797 : : |----------------|
10798 : : | Param # | <- Ptr
10799 : : |----------------| +------------+
10800 : : | ProcSym | Type | | ReturnVar |
10801 : : |----------------| |------------|
10802 : : */
10803 : :
10804 : 110 : static void BuildConstHighFromSym (unsigned int tok)
10805 : : {
10806 : 110 : unsigned int NoOfParam;
10807 : 110 : unsigned int ReturnVar;
10808 : :
10809 : 110 : M2Quads_PopT (&NoOfParam);
10810 : 110 : ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
10811 : 110 : SymbolTable_PutConst (ReturnVar, M2Base_Cardinal);
10812 : 110 : GenHigh (tok, ReturnVar, 1, M2Quads_OperandT (1));
10813 : 110 : M2Quads_PopN (NoOfParam+1);
10814 : 110 : M2Quads_PushTtok (ReturnVar, tok);
10815 : 110 : }
10816 : :
10817 : :
10818 : : /*
10819 : : BuildHighFromUnbounded - builds the pseudo function HIGH from an
10820 : : UnboundedSym.
10821 : :
10822 : : The Stack:
10823 : :
10824 : :
10825 : : Entry Exit
10826 : :
10827 : : Ptr ->
10828 : : +----------------+
10829 : : | NoOfParam |
10830 : : |----------------|
10831 : : | Param # | <- Ptr
10832 : : |----------------| +------------+
10833 : : | ProcSym | Type | | ReturnVar |
10834 : : |----------------| |------------|
10835 : :
10836 : : */
10837 : :
10838 : 2204 : static void BuildHighFromUnbounded (unsigned int tok)
10839 : : {
10840 : 2204 : unsigned int Dim;
10841 : 2204 : unsigned int NoOfParam;
10842 : 2204 : unsigned int ReturnVar;
10843 : :
10844 : 2204 : M2Quads_PopT (&NoOfParam);
10845 : 2204 : M2Debug_Assert (NoOfParam == 1);
10846 : 2204 : ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
10847 : 2204 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
10848 : 2204 : Dim = static_cast<unsigned int> (OperandD (1));
10849 : 2204 : Dim += 1;
10850 : 2204 : if (Dim > 1)
10851 : : {
10852 : 36 : GenHigh (tok, ReturnVar, Dim, M2Quads_OperandA (1));
10853 : : }
10854 : : else
10855 : : {
10856 : 2168 : GenHigh (tok, ReturnVar, Dim, M2Quads_OperandT (1));
10857 : : }
10858 : 2204 : M2Quads_PopN (2);
10859 : 2204 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), tok);
10860 : 2204 : }
10861 : :
10862 : :
10863 : : /*
10864 : : GetQualidentImport - returns the symbol as if it were qualified from, module.n.
10865 : : This is used to reference runtime support procedures and an
10866 : : error is generated if the symbol cannot be obtained.
10867 : : */
10868 : :
10869 : 45350 : static unsigned int GetQualidentImport (unsigned int tokno, NameKey_Name n, NameKey_Name module)
10870 : : {
10871 : 45350 : unsigned int ModSym;
10872 : :
10873 : 45350 : ModSym = M2Batch_MakeDefinitionSource (tokno, module);
10874 : 45350 : if (ModSym == SymbolTable_NulSym)
10875 : : {
10876 : 0 : M2MetaError_MetaErrorNT2 (tokno, (const char *) "module %a cannot be found and is needed to import %a", 52, module, n);
10877 : 0 : M2Error_FlushErrors ();
10878 : 0 : return SymbolTable_NulSym;
10879 : : }
10880 : 45350 : M2Debug_Assert (SymbolTable_IsDefImp (ModSym));
10881 : 45350 : if (((SymbolTable_GetExported (tokno, ModSym, n)) == SymbolTable_NulSym) || (SymbolTable_IsUnknown (SymbolTable_GetExported (tokno, ModSym, n))))
10882 : : {
10883 : 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);
10884 : 0 : M2Error_FlushErrors ();
10885 : 0 : return SymbolTable_NulSym;
10886 : : }
10887 : 45350 : return SymbolTable_GetExported (tokno, M2Batch_MakeDefinitionSource (tokno, module), n);
10888 : : /* static analysis guarentees a RETURN statement will be used before here. */
10889 : : __builtin_unreachable ();
10890 : : }
10891 : :
10892 : :
10893 : : /*
10894 : : ConstExprError - return TRUE if a constant expression is being built and Var is a variable.
10895 : : */
10896 : :
10897 : 54296 : static bool ConstExprError (unsigned int Func, unsigned int Var, unsigned int optok, bool ConstExpr)
10898 : : {
10899 : 54296 : if (ConstExpr && (SymbolTable_IsVar (Var)))
10900 : : {
10901 : 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);
10902 : 108 : return true;
10903 : : }
10904 : : else
10905 : : {
10906 : 54188 : return false;
10907 : : }
10908 : : /* static analysis guarentees a RETURN statement will be used before here. */
10909 : : __builtin_unreachable ();
10910 : : }
10911 : :
10912 : :
10913 : : /*
10914 : : DeferMakeLengthConst - creates a constant which contains the length of string, sym.
10915 : : */
10916 : :
10917 : 66 : static unsigned int DeferMakeLengthConst (unsigned int tok, unsigned int sym)
10918 : : {
10919 : 66 : unsigned int const_;
10920 : :
10921 : 66 : const_ = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
10922 : 66 : SymbolTable_PutVar (const_, M2Base_ZType);
10923 : 132 : GenQuadO (tok, M2Quads_StringLengthOp, const_, 0, sym, false);
10924 : 66 : return const_;
10925 : : /* static analysis guarentees a RETURN statement will be used before here. */
10926 : : __builtin_unreachable ();
10927 : : }
10928 : :
10929 : :
10930 : : /*
10931 : : BuildLengthFunction - builds the inline standard function LENGTH.
10932 : :
10933 : : The Stack:
10934 : :
10935 : :
10936 : : Entry Exit
10937 : :
10938 : : Ptr ->
10939 : : +----------------+
10940 : : | NoOfParam |
10941 : : |----------------|
10942 : : | Param 1 | <- Ptr
10943 : : |----------------| +------------+
10944 : : | ProcSym | Type | | ReturnVar |
10945 : : |----------------| |------------|
10946 : :
10947 : : */
10948 : :
10949 : 346 : static void BuildLengthFunction (unsigned int Function, bool ConstExpr)
10950 : : {
10951 : 346 : unsigned int combinedtok;
10952 : 346 : unsigned int paramtok;
10953 : 346 : unsigned int functok;
10954 : 346 : unsigned int ProcSym;
10955 : 346 : unsigned int Type;
10956 : 346 : unsigned int NoOfParam;
10957 : 346 : unsigned int Param;
10958 : 346 : unsigned int ReturnVar;
10959 : :
10960 : 346 : M2Quads_PopT (&NoOfParam);
10961 : 346 : Param = static_cast<unsigned int> (M2Quads_OperandT (1));
10962 : 346 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10963 : 346 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
10964 : : /* Restore stack to origional form. */
10965 : 346 : M2Quads_PushT (NoOfParam);
10966 : 346 : Type = SymbolTable_GetSType (Param); /* Get the type from the symbol, not the stack. */
10967 : 346 : if (NoOfParam != 1) /* Get the type from the symbol, not the stack. */
10968 : : {
10969 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "base procedure {%1EkLENGTH} expects 1 parameter, seen {%1n} parameters", 70, NoOfParam);
10970 : : }
10971 : 346 : if (NoOfParam >= 1)
10972 : : {
10973 : 346 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, paramtok);
10974 : 346 : if ((SymbolTable_IsConst (Param)) && ((SymbolTable_GetSType (Param)) == M2Base_Char))
10975 : : {
10976 : 6 : M2Quads_PopT (&NoOfParam);
10977 : 6 : M2Quads_PopN (NoOfParam+1);
10978 : 6 : ReturnVar = SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal);
10979 : 6 : M2Quads_PushTtok (ReturnVar, combinedtok);
10980 : : }
10981 : 340 : else if (SymbolTable_IsConstString (Param))
10982 : : {
10983 : : /* avoid dangling else. */
10984 : 48 : M2Quads_PopT (&NoOfParam);
10985 : 48 : ReturnVar = DeferMakeLengthConst (combinedtok, M2Quads_OperandT (1));
10986 : 48 : M2Quads_PopN (NoOfParam+1);
10987 : 48 : M2Quads_PushTtok (ReturnVar, combinedtok);
10988 : : }
10989 : : else
10990 : : {
10991 : : /* avoid dangling else. */
10992 : 292 : ProcSym = GetQualidentImport (functok, NameKey_MakeKey ((const char *) "Length", 6), NameKey_MakeKey ((const char *) "M2RTS", 5));
10993 : 292 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
10994 : : {
10995 : 292 : M2Quads_PopT (&NoOfParam);
10996 : 292 : if (SymbolTable_IsConst (Param))
10997 : : {
10998 : : /* This can be folded in M2GenGCC. */
10999 : 0 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_ImmediateValue);
11000 : 0 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
11001 : 0 : GenQuad (M2Quads_StandardFunctionOp, ReturnVar, ProcSym, Param);
11002 : 0 : M2Quads_PopN (NoOfParam+1);
11003 : 0 : M2Quads_PushTtok (ReturnVar, combinedtok);
11004 : : }
11005 : 292 : else if (ConstExprError (Function, Param, paramtok, ConstExpr))
11006 : : {
11007 : : /* avoid dangling else. */
11008 : : /* Fake a result as we have detected and reported an error. */
11009 : 6 : M2Quads_PopN (NoOfParam+1);
11010 : 6 : ReturnVar = SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal);
11011 : 6 : M2Quads_PushTtok (ReturnVar, combinedtok);
11012 : : }
11013 : : else
11014 : : {
11015 : : /* avoid dangling else. */
11016 : : /* We must resolve this at runtime or in the GCC optimizer. */
11017 : 286 : M2Quads_PopTF (&Param, &Type);
11018 : 286 : M2Quads_PopN (NoOfParam);
11019 : 286 : M2Quads_PushTtok (ProcSym, functok);
11020 : 286 : M2Quads_PushTFtok (Param, Type, paramtok);
11021 : 286 : M2Quads_PushT (NoOfParam);
11022 : 286 : BuildRealFunctionCall (functok, false);
11023 : : }
11024 : : }
11025 : : else
11026 : : {
11027 : 0 : M2Quads_PopT (&NoOfParam);
11028 : 0 : M2Quads_PopN (NoOfParam+1);
11029 : 0 : M2Quads_PushTtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), combinedtok);
11030 : 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);
11031 : : }
11032 : : }
11033 : : }
11034 : : else
11035 : : {
11036 : : /* NoOfParam is _very_ wrong, we flush all outstanding errors */
11037 : 0 : M2Error_FlushErrors ();
11038 : : }
11039 : 346 : }
11040 : :
11041 : :
11042 : : /*
11043 : : BuildOddFunction - builds the pseudo procedure call ODD.
11044 : : This procedure is actually a "macro" for
11045 : : ORD(x) --> VAL(BOOLEAN, x MOD 2)
11046 : : However we cannot push tokens back onto the input stack
11047 : : because the compiler is currently building a function
11048 : : call and expecting a ReturnVar on the stack.
11049 : : Hence we manipulate the stack and call
11050 : : BuildConvertFunction.
11051 : :
11052 : : The Stack:
11053 : :
11054 : :
11055 : : Entry Exit
11056 : :
11057 : : Ptr ->
11058 : : +----------------+
11059 : : | NoOfParam |
11060 : : |----------------|
11061 : : | Param 1 |
11062 : : |----------------|
11063 : : | Param 2 |
11064 : : |----------------|
11065 : : . .
11066 : : . .
11067 : : . .
11068 : : |----------------|
11069 : : | Param # |
11070 : : |----------------|
11071 : : | ProcSym | Type | Empty
11072 : : |----------------|
11073 : : */
11074 : :
11075 : 50 : static void BuildOddFunction (unsigned int ProcSym, bool ConstExpr)
11076 : : {
11077 : 50 : unsigned int combinedtok;
11078 : 50 : unsigned int optok;
11079 : 50 : unsigned int functok;
11080 : 50 : unsigned int NoOfParam;
11081 : 50 : unsigned int Res;
11082 : 50 : unsigned int Var;
11083 : :
11084 : 50 : M2Quads_PopT (&NoOfParam);
11085 : 50 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11086 : 50 : if (NoOfParam == 1)
11087 : : {
11088 : 50 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11089 : 50 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11090 : 50 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
11091 : 50 : if (ConstExprError (ProcSym, Var, optok, ConstExpr))
11092 : : {
11093 : : /* Nothing to do. */
11094 : 6 : M2Quads_PushTtok (M2Base_False, combinedtok);
11095 : : }
11096 : 44 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11097 : : {
11098 : : /* avoid dangling else. */
11099 : 44 : M2Quads_PopN (NoOfParam+1);
11100 : : /* compute (x MOD 2) */
11101 : 44 : M2Quads_PushTFtok (Var, SymbolTable_GetSType (Var), optok);
11102 : 44 : M2Quads_PushT (M2Reserved_ModTok);
11103 : 44 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (optok, NameKey_MakeKey ((const char *) "2", 1), M2Base_ZType), M2Base_ZType, optok);
11104 : 44 : M2Quads_BuildBinaryOp ();
11105 : 44 : M2Quads_PopT (&Res);
11106 : : /* compute IF ...=0 */
11107 : 44 : M2Quads_PushTtok (Res, optok);
11108 : 44 : M2Quads_PushT (M2Reserved_EqualTok);
11109 : 44 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (optok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType), M2Base_ZType, optok);
11110 : 44 : M2Quads_BuildRelOp (combinedtok);
11111 : 44 : M2Quads_BuildThenIf ();
11112 : 44 : Res = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
11113 : 44 : SymbolTable_PutVar (Res, M2Base_Boolean);
11114 : 44 : M2Quads_PushTtok (Res, combinedtok);
11115 : 44 : M2Quads_PushTtok (M2Base_False, combinedtok);
11116 : 44 : M2Quads_BuildAssignment (combinedtok);
11117 : 44 : M2Quads_BuildElse ();
11118 : 44 : M2Quads_PushTtok (Res, combinedtok);
11119 : 44 : M2Quads_PushTtok (M2Base_True, combinedtok);
11120 : 44 : M2Quads_BuildAssignment (combinedtok);
11121 : 44 : M2Quads_BuildEndIf ();
11122 : 44 : M2Quads_PushTtok (Res, combinedtok);
11123 : : }
11124 : : else
11125 : : {
11126 : : /* avoid dangling else. */
11127 : 0 : M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%1EkODD} must be a variable or constant, seen {%1ad}", 70, Var);
11128 : 0 : M2Quads_PushTtok (M2Base_False, combinedtok);
11129 : : }
11130 : : }
11131 : : else
11132 : : {
11133 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%E1kODD} only has one parameter, seen {%1n} parameters", 76, NoOfParam);
11134 : 0 : M2Quads_PushTtok (M2Base_False, functok);
11135 : : }
11136 : 50 : }
11137 : :
11138 : :
11139 : : /*
11140 : : BuildAbsFunction - builds a call to the standard function ABS.
11141 : :
11142 : : We cannot implement it as a macro or inline an
11143 : : IF THEN statement as the IF THEN ELSE requires
11144 : : we write the value to the same variable (or constant)
11145 : : twice. The macro implementation will fail as
11146 : : the compiler maybe building a function
11147 : : call and expecting a ReturnVar on the stack.
11148 : : The only method to implement this is to pass it to the
11149 : : gcc backend.
11150 : :
11151 : : The Stack:
11152 : :
11153 : :
11154 : : Entry Exit
11155 : :
11156 : : Ptr ->
11157 : : +----------------+
11158 : : | NoOfParam |
11159 : : |----------------|
11160 : : | Param 1 |
11161 : : |----------------|
11162 : : | Param 2 |
11163 : : |----------------|
11164 : : . .
11165 : : . .
11166 : : . .
11167 : : |----------------|
11168 : : | Param # |
11169 : : |----------------|
11170 : : | ProcSym | Type | Empty
11171 : : |----------------|
11172 : : */
11173 : :
11174 : 128 : static void BuildAbsFunction (unsigned int ProcSym, bool ConstExpr)
11175 : : {
11176 : 128 : unsigned int vartok;
11177 : 128 : unsigned int functok;
11178 : 128 : unsigned int combinedtok;
11179 : 128 : unsigned int NoOfParam;
11180 : 128 : unsigned int Res;
11181 : 128 : unsigned int Var;
11182 : :
11183 : 128 : M2Quads_PopT (&NoOfParam);
11184 : 128 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11185 : 128 : if (NoOfParam == 1)
11186 : : {
11187 : 128 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11188 : 128 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11189 : 128 : M2Quads_PopN (NoOfParam+1);
11190 : 128 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
11191 : 128 : if (ConstExprError (ProcSym, Var, vartok, ConstExpr))
11192 : : {
11193 : : /* Create fake result. */
11194 : 24 : Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11195 : 12 : SymbolTable_PutVar (Res, SymbolTable_GetSType (Var));
11196 : 12 : M2Quads_PushTFtok (Res, SymbolTable_GetSType (Var), combinedtok);
11197 : : }
11198 : 116 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11199 : : {
11200 : : /* avoid dangling else. */
11201 : 220 : Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11202 : 110 : SymbolTable_PutVar (Res, SymbolTable_GetSType (Var));
11203 : 220 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, Res, ProcSym, Var, false);
11204 : 110 : M2Quads_PushTFtok (Res, SymbolTable_GetSType (Var), combinedtok);
11205 : : }
11206 : : else
11207 : : {
11208 : : /* avoid dangling else. */
11209 : 6 : M2MetaError_MetaErrorT1 (vartok, (const char *) "the parameter to {%AkABS} must be a variable or constant, seen {%1ad}", 69, Var);
11210 : : }
11211 : : }
11212 : : else
11213 : : {
11214 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkABS} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
11215 : : }
11216 : 122 : }
11217 : :
11218 : :
11219 : : /*
11220 : : BuildCapFunction - builds the pseudo procedure call CAP.
11221 : : We generate a the following quad:
11222 : :
11223 : :
11224 : : StandardFunctionOp ReturnVal Cap Param1
11225 : :
11226 : : The Stack:
11227 : :
11228 : :
11229 : : Entry Exit
11230 : :
11231 : : Ptr ->
11232 : : +----------------+
11233 : : | NoOfParam = 1 |
11234 : : |----------------|
11235 : : | Param 1 |
11236 : : |----------------| +-------------+
11237 : : | ProcSym | Type | | ReturnVal |
11238 : : |----------------| |-------------|
11239 : : */
11240 : :
11241 : 124 : static void BuildCapFunction (unsigned int ProcSym, bool ConstExpr)
11242 : : {
11243 : 124 : unsigned int optok;
11244 : 124 : unsigned int functok;
11245 : 124 : unsigned int combinedtok;
11246 : 124 : unsigned int NoOfParam;
11247 : 124 : unsigned int Res;
11248 : 124 : unsigned int Var;
11249 : :
11250 : 124 : M2Quads_PopT (&NoOfParam);
11251 : 124 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11252 : 124 : if (NoOfParam == 1)
11253 : : {
11254 : 124 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11255 : 124 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11256 : 124 : M2Quads_PopN (NoOfParam+1);
11257 : 124 : if (ConstExprError (ProcSym, Var, optok, ConstExpr))
11258 : : {
11259 : : /* Create fake result. */
11260 : 12 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11261 : 24 : Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11262 : 12 : SymbolTable_PutVar (Res, M2Base_Char);
11263 : 12 : M2Quads_PushTFtok (Res, M2Base_Char, combinedtok);
11264 : : }
11265 : 112 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11266 : : {
11267 : : /* avoid dangling else. */
11268 : 112 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11269 : 224 : Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11270 : 112 : SymbolTable_PutVar (Res, M2Base_Char);
11271 : 224 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, Res, ProcSym, Var, false);
11272 : 112 : M2Quads_PushTFtok (Res, M2Base_Char, combinedtok);
11273 : : }
11274 : : else
11275 : : {
11276 : : /* avoid dangling else. */
11277 : 0 : M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%AkCAP} must be a variable or constant, seen {%1ad}", 69, Var);
11278 : : }
11279 : : }
11280 : : else
11281 : : {
11282 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkCAP} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
11283 : : }
11284 : 124 : }
11285 : :
11286 : :
11287 : : /*
11288 : : BuildChrFunction - builds the pseudo procedure call CHR.
11289 : : This procedure is actually a "macro" for
11290 : : CHR(x) --> CONVERT(CHAR, x)
11291 : : However we cannot push tokens back onto the input stack
11292 : : because the compiler is currently building a function
11293 : : call and expecting a ReturnVar on the stack.
11294 : : Hence we manipulate the stack and call
11295 : : BuildConvertFunction.
11296 : :
11297 : : The Stack:
11298 : :
11299 : :
11300 : : Entry Exit
11301 : :
11302 : : Ptr ->
11303 : : +----------------+
11304 : : | NoOfParam |
11305 : : |----------------|
11306 : : | Param 1 |
11307 : : |----------------|
11308 : : | Param 2 |
11309 : : |----------------|
11310 : : . .
11311 : : . .
11312 : : . .
11313 : : |----------------|
11314 : : | Param # |
11315 : : |----------------|
11316 : : | ProcSym | Type | Empty
11317 : : |----------------|
11318 : : */
11319 : :
11320 : 454 : static void BuildChrFunction (unsigned int ProcSym, bool ConstExpr)
11321 : : {
11322 : 454 : unsigned int functok;
11323 : 454 : unsigned int combinedtok;
11324 : 454 : unsigned int optok;
11325 : 454 : unsigned int ReturnVar;
11326 : 454 : unsigned int NoOfParam;
11327 : 454 : unsigned int Var;
11328 : :
11329 : 454 : M2Quads_PopT (&NoOfParam);
11330 : 454 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11331 : 454 : if (NoOfParam == 1)
11332 : : {
11333 : 454 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11334 : 454 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11335 : 454 : M2Quads_PopN (NoOfParam+1);
11336 : 454 : if (ConstExprError (ProcSym, Var, optok, ConstExpr))
11337 : : {
11338 : : /* Generate fake result. */
11339 : 12 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11340 : 24 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11341 : 12 : SymbolTable_PutVar (ReturnVar, M2Base_Char);
11342 : 12 : M2Quads_PushTFtok (ReturnVar, M2Base_Char, combinedtok);
11343 : : }
11344 : 442 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11345 : : {
11346 : : /* avoid dangling else. */
11347 : : /*
11348 : : Build macro: CONVERT( CHAR, Var )
11349 : : */
11350 : 442 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
11351 : 442 : M2Quads_PushTtok (M2Base_Char, functok);
11352 : 442 : M2Quads_PushTtok (Var, optok);
11353 : 442 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
11354 : 442 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* Two parameters */
11355 : : }
11356 : : else
11357 : : {
11358 : : /* avoid dangling else. */
11359 : 0 : M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%AkCHR} must be a variable or constant, seen {%1ad}", 69, Var);
11360 : : }
11361 : : }
11362 : : else
11363 : : {
11364 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkCHR} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
11365 : : }
11366 : 454 : }
11367 : :
11368 : :
11369 : : /*
11370 : : BuildOrdFunction - builds the pseudo procedure call ORD.
11371 : : This procedure is actually a "macro" for
11372 : : ORD(x) --> CONVERT(GetSType(sym), x)
11373 : : However we cannot push tokens back onto the input stack
11374 : : because the compiler is currently building a function
11375 : : call and expecting a ReturnVar on the stack.
11376 : : Hence we manipulate the stack and call
11377 : : BuildConvertFunction.
11378 : :
11379 : : The Stack:
11380 : :
11381 : :
11382 : : Entry Exit
11383 : :
11384 : : Ptr ->
11385 : : +----------------+
11386 : : | NoOfParam |
11387 : : |----------------|
11388 : : | Param 1 |
11389 : : |----------------|
11390 : : | Param 2 |
11391 : : |----------------|
11392 : : . .
11393 : : . .
11394 : : . .
11395 : : |----------------|
11396 : : | Param # |
11397 : : |----------------|
11398 : : | ProcSym | Type | Empty
11399 : : |----------------|
11400 : : */
11401 : :
11402 : 3184 : static void BuildOrdFunction (unsigned int Sym, bool ConstExpr)
11403 : : {
11404 : 3184 : unsigned int combinedtok;
11405 : 3184 : unsigned int functok;
11406 : 3184 : unsigned int optok;
11407 : 3184 : unsigned int ReturnVar;
11408 : 3184 : unsigned int NoOfParam;
11409 : 3184 : unsigned int Type;
11410 : 3184 : unsigned int Var;
11411 : :
11412 : 3184 : M2Quads_PopT (&NoOfParam);
11413 : 3184 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11414 : 3184 : if (NoOfParam == 1)
11415 : : {
11416 : 3184 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11417 : 3184 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11418 : 3184 : M2Quads_PopN (NoOfParam+1);
11419 : 3184 : if (ConstExprError (Sym, Var, optok, ConstExpr))
11420 : : {
11421 : : /* Generate fake result. */
11422 : 12 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11423 : 24 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11424 : 12 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
11425 : 12 : M2Quads_PushTFtok (ReturnVar, M2Base_Cardinal, combinedtok);
11426 : : }
11427 : 3172 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11428 : : {
11429 : : /* avoid dangling else. */
11430 : 3172 : Type = SymbolTable_GetSType (Sym);
11431 : : /*
11432 : : Build macro: CONVERT( CARDINAL, Var )
11433 : : */
11434 : 3172 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
11435 : 3172 : M2Quads_PushTtok (Type, optok);
11436 : 3172 : M2Quads_PushTtok (Var, optok);
11437 : 3172 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
11438 : 3172 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* Two parameters */
11439 : : }
11440 : : else
11441 : : {
11442 : : /* avoid dangling else. */
11443 : 0 : M2MetaError_MetaErrorT2 (optok, (const char *) "the parameter to {%1Aa} must be a variable or constant, seen {%2ad}", 67, Sym, Var);
11444 : : }
11445 : : }
11446 : : else
11447 : : {
11448 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the pseudo procedure {%1Aa} only has one parameter, seen {%2n} parameters", 73, Sym, NoOfParam);
11449 : : }
11450 : 3184 : }
11451 : :
11452 : :
11453 : : /*
11454 : : BuildIntFunction - builds the pseudo procedure call INT.
11455 : : This procedure is actually a "macro" for
11456 : : INT(x) --> CONVERT(INTEGER, x)
11457 : : However we cannot push tokens back onto the input stack
11458 : : because the compiler is currently building a function
11459 : : call and expecting a ReturnVar on the stack.
11460 : : Hence we manipulate the stack and call
11461 : : BuildConvertFunction.
11462 : :
11463 : : The Stack:
11464 : :
11465 : :
11466 : : Entry Exit
11467 : :
11468 : : Ptr ->
11469 : : +----------------+
11470 : : | NoOfParam |
11471 : : |----------------|
11472 : : | Param 1 |
11473 : : |----------------|
11474 : : | Param 2 |
11475 : : |----------------|
11476 : : . .
11477 : : . .
11478 : : . .
11479 : : |----------------|
11480 : : | Param # |
11481 : : |----------------|
11482 : : | ProcSym | Type | Empty
11483 : : |----------------|
11484 : : */
11485 : :
11486 : 6 : static void BuildIntFunction (unsigned int Sym, bool ConstExpr)
11487 : : {
11488 : 6 : unsigned int combinedtok;
11489 : 6 : unsigned int functok;
11490 : 6 : unsigned int optok;
11491 : 6 : unsigned int ReturnVar;
11492 : 6 : unsigned int NoOfParam;
11493 : 6 : unsigned int Type;
11494 : 6 : unsigned int Var;
11495 : :
11496 : 6 : M2Quads_PopT (&NoOfParam);
11497 : 6 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11498 : 6 : if (NoOfParam == 1)
11499 : : {
11500 : 6 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11501 : 6 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11502 : 6 : M2Quads_PopN (NoOfParam+1);
11503 : 6 : if (ConstExprError (Sym, Var, optok, ConstExpr))
11504 : : {
11505 : : /* Generate fake result. */
11506 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11507 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11508 : 6 : SymbolTable_PutVar (ReturnVar, M2Base_Integer);
11509 : 6 : M2Quads_PushTFtok (ReturnVar, M2Base_Integer, combinedtok);
11510 : : }
11511 : 0 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11512 : : {
11513 : : /* avoid dangling else. */
11514 : 0 : Type = SymbolTable_GetSType (Sym); /* return type of function */
11515 : : /* Build macro: CONVERT( CARDINAL, Var ). */
11516 : 0 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
11517 : 0 : M2Quads_PushTtok (Type, functok);
11518 : 0 : M2Quads_PushTtok (Var, optok);
11519 : 0 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
11520 : 0 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* Two parameters */
11521 : : }
11522 : : else
11523 : : {
11524 : : /* avoid dangling else. */
11525 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, optok, optok);
11526 : 0 : M2MetaError_MetaErrorT2 (optok, (const char *) "the parameter to {%1Ea} must be a variable or constant, seen {%2ad}", 67, Sym, Var);
11527 : 0 : M2Quads_PushTtok (combinedtok, SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType));
11528 : : }
11529 : : }
11530 : : else
11531 : : {
11532 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the pseudo procedure {%1Ea} only has one parameter, seen {%2n} parameters", 73, Sym, NoOfParam);
11533 : 0 : M2Quads_PushTtok (functok, SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType));
11534 : : }
11535 : 6 : }
11536 : :
11537 : :
11538 : : /*
11539 : : BuildMakeAdrFunction - builds the pseudo procedure call MAKEADR.
11540 : :
11541 : : The Stack:
11542 : :
11543 : :
11544 : : Entry Exit
11545 : :
11546 : : Ptr ->
11547 : : +----------------+
11548 : : | NoOfParam |
11549 : : |----------------|
11550 : : | Param 1 |
11551 : : |----------------|
11552 : : | Param 2 |
11553 : : |----------------|
11554 : : . .
11555 : : . .
11556 : : . .
11557 : : |----------------|
11558 : : | Param # |
11559 : : |----------------|
11560 : : | ProcSym | Type | Empty
11561 : : |----------------|
11562 : : */
11563 : :
11564 : 12 : static void BuildMakeAdrFunction (void)
11565 : : {
11566 : 12 : unsigned int functok;
11567 : 12 : unsigned int starttok;
11568 : 12 : unsigned int endtok;
11569 : 12 : unsigned int resulttok;
11570 : 12 : bool AreConst;
11571 : 12 : unsigned int i;
11572 : 12 : unsigned int pi;
11573 : 12 : unsigned int NoOfParameters;
11574 : 12 : unsigned int ReturnVar;
11575 : :
11576 : 12 : M2Quads_PopT (&NoOfParameters);
11577 : 12 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParameters+1));
11578 : 12 : if (NoOfParameters > 0)
11579 : : {
11580 : 12 : starttok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParameters+1)); /* ADR token. */
11581 : 12 : endtok = static_cast<unsigned int> (M2Quads_OperandTok (1)); /* last parameter. */
11582 : 24 : GenQuad (M2Quads_ParamOp, 0, M2System_MakeAdr, M2System_MakeAdr); /* last parameter. */
11583 : 12 : i = NoOfParameters;
11584 : : /* stack index referencing stacked parameter, i */
11585 : 12 : pi = 1;
11586 : 24 : while (i > 0)
11587 : : {
11588 : 12 : GenQuadO (M2Quads_OperandTok (pi), M2Quads_ParamOp, i, M2System_MakeAdr, M2Quads_OperandT (pi), true);
11589 : 12 : i -= 1;
11590 : 12 : pi += 1;
11591 : : }
11592 : : AreConst = true;
11593 : : i = 1;
11594 : 24 : while (i <= NoOfParameters)
11595 : : {
11596 : 12 : if (SymbolTable_IsVar (M2Quads_OperandT (i)))
11597 : : {
11598 : : AreConst = false;
11599 : : }
11600 : 12 : else if (! (SymbolTable_IsConst (M2Quads_OperandT (i))))
11601 : : {
11602 : : /* avoid dangling else. */
11603 : 0 : M2MetaError_MetaError1 ((const char *) "problem in the {%1EN} argument for {%kMAKEADR}, all arguments to {%kMAKEADR} must be either variables or constants", 114, i);
11604 : : }
11605 : 12 : i += 1;
11606 : : }
11607 : : /* ReturnVar - will have the type of the procedure */
11608 : 12 : resulttok = M2LexBuf_MakeVirtualTok (starttok, starttok, endtok);
11609 : 12 : ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (AreConst));
11610 : 12 : SymbolTable_PutVar (ReturnVar, SymbolTable_GetSType (M2System_MakeAdr));
11611 : 24 : GenQuadO (resulttok, M2Quads_FunctValueOp, ReturnVar, SymbolTable_NulSym, M2System_MakeAdr, true);
11612 : 12 : M2Quads_PopN (NoOfParameters+1);
11613 : 12 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (M2System_MakeAdr), resulttok);
11614 : : }
11615 : : else
11616 : : {
11617 : 0 : M2MetaError_MetaError1 ((const char *) "the pseudo procedure {%EkMAKEADR} requires at least one parameter, seen {%1n}", 77, NoOfParameters);
11618 : 0 : M2Quads_PopN (1);
11619 : 0 : M2Quads_PushTFtok (M2Base_Nil, SymbolTable_GetSType (M2System_MakeAdr), functok);
11620 : : }
11621 : 12 : }
11622 : :
11623 : :
11624 : : /*
11625 : : BuildShiftFunction - builds the pseudo procedure call SHIFT.
11626 : :
11627 : : PROCEDURE SHIFT (val: <any type>;
11628 : : num: INTEGER): <any type> ;
11629 : :
11630 : : "Returns a bit sequence obtained from val by
11631 : : shifting up or down (left or right) by the
11632 : : absolute value of num, introducing
11633 : : zeros as necessary. The direction is down if
11634 : : the sign of num is negative, otherwise the
11635 : : direction is up."
11636 : :
11637 : : The Stack:
11638 : :
11639 : : Entry Exit
11640 : :
11641 : : Ptr ->
11642 : : +----------------+
11643 : : | NoOfParam |
11644 : : |----------------|
11645 : : | Param 1 |
11646 : : |----------------|
11647 : : | Param 2 | <- Ptr
11648 : : |----------------| +------------+
11649 : : | ProcSym | Type | | ReturnVar |
11650 : : |----------------| |------------|
11651 : : */
11652 : :
11653 : 702 : static void BuildShiftFunction (void)
11654 : : {
11655 : 702 : unsigned int combinedtok;
11656 : 702 : unsigned int paramtok;
11657 : 702 : unsigned int functok;
11658 : 702 : unsigned int vartok;
11659 : 702 : unsigned int exptok;
11660 : 702 : unsigned int r;
11661 : 702 : unsigned int procSym;
11662 : 702 : unsigned int returnVar;
11663 : 702 : unsigned int NoOfParam;
11664 : 702 : unsigned int derefExp;
11665 : 702 : unsigned int Exp;
11666 : 702 : unsigned int varSet;
11667 : :
11668 : 702 : M2Quads_PopT (&NoOfParam);
11669 : 702 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11670 : 702 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11671 : 702 : if (NoOfParam == 2)
11672 : : {
11673 : 702 : PopTrwtok (&Exp, &r, &exptok);
11674 : 702 : MarkAsRead (r);
11675 : 702 : M2Quads_PopTtok (&varSet, &vartok);
11676 : 702 : M2Quads_PopT (&procSym);
11677 : 702 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
11678 : 702 : if (((SymbolTable_GetSType (varSet)) != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_GetDType (varSet))))
11679 : : {
11680 : 702 : derefExp = DereferenceLValue (exptok, Exp);
11681 : 702 : BuildRange (M2Range_InitShiftCheck (varSet, derefExp));
11682 : 702 : returnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
11683 : 702 : SymbolTable_PutVar (returnVar, SymbolTable_GetSType (varSet));
11684 : 1404 : GenQuadO (combinedtok, M2Quads_LogicalShiftOp, returnVar, varSet, derefExp, true);
11685 : 702 : M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (varSet), combinedtok);
11686 : : }
11687 : : else
11688 : : {
11689 : 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);
11690 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, combinedtok);
11691 : : }
11692 : : }
11693 : : else
11694 : : {
11695 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
11696 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%kSHIFT} requires at least two parameters, seen {%1En}", 76, NoOfParam);
11697 : 0 : M2Quads_PopN (NoOfParam+1);
11698 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, combinedtok);
11699 : : }
11700 : 702 : }
11701 : :
11702 : :
11703 : : /*
11704 : : BuildRotateFunction - builds the pseudo procedure call ROTATE.
11705 : :
11706 : : PROCEDURE ROTATE (val: <any type>;
11707 : : num: INTEGER): <any type> ;
11708 : :
11709 : : "Returns a bit sequence obtained from val
11710 : : by rotating up or down (left or right) by
11711 : : the absolute value of num. The direction is
11712 : : down if the sign of num is negative, otherwise
11713 : : the direction is up."
11714 : :
11715 : : The Stack:
11716 : :
11717 : : Entry Exit
11718 : :
11719 : : Ptr ->
11720 : : +----------------+
11721 : : | NoOfParam |
11722 : : |----------------|
11723 : : | Param 1 |
11724 : : |----------------|
11725 : : | Param 2 | <- Ptr
11726 : : |----------------| +------------+
11727 : : | ProcSym | Type | | ReturnVar |
11728 : : |----------------| |------------|
11729 : : */
11730 : :
11731 : 232 : static void BuildRotateFunction (void)
11732 : : {
11733 : 232 : unsigned int combinedtok;
11734 : 232 : unsigned int functok;
11735 : 232 : unsigned int vartok;
11736 : 232 : unsigned int exptok;
11737 : 232 : unsigned int r;
11738 : 232 : unsigned int procSym;
11739 : 232 : unsigned int returnVar;
11740 : 232 : unsigned int NoOfParam;
11741 : 232 : unsigned int derefExp;
11742 : 232 : unsigned int Exp;
11743 : 232 : unsigned int varSet;
11744 : :
11745 : 232 : M2Quads_PopT (&NoOfParam);
11746 : 232 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11747 : 232 : if (NoOfParam == 2)
11748 : : {
11749 : 232 : PopTrwtok (&Exp, &r, &exptok);
11750 : 232 : MarkAsRead (r);
11751 : 232 : M2Quads_PopTtok (&varSet, &vartok);
11752 : 232 : M2Quads_PopT (&procSym);
11753 : 232 : if (((SymbolTable_GetSType (varSet)) != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_GetDType (varSet))))
11754 : : {
11755 : 232 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
11756 : 232 : derefExp = DereferenceLValue (exptok, Exp);
11757 : 232 : BuildRange (M2Range_InitRotateCheck (varSet, derefExp));
11758 : 232 : returnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
11759 : 232 : SymbolTable_PutVar (returnVar, SymbolTable_GetSType (varSet));
11760 : 464 : GenQuadO (combinedtok, M2Quads_LogicalRotateOp, returnVar, varSet, derefExp, true);
11761 : 232 : M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (varSet), combinedtok);
11762 : : }
11763 : : else
11764 : : {
11765 : 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);
11766 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
11767 : : }
11768 : : }
11769 : : else
11770 : : {
11771 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "SYSTEM procedure {%EkROTATE} expects 2 parameters and was given {%1n} parameters", 80, NoOfParam);
11772 : 0 : M2Quads_PopN (NoOfParam+1);
11773 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
11774 : : }
11775 : 232 : }
11776 : :
11777 : :
11778 : : /*
11779 : : BuildValFunction - builds the pseudo procedure call VAL.
11780 : : This procedure is actually a "macro" for
11781 : : VAL(Type, x) --> CONVERT(Type, x)
11782 : : However we cannot push tokens back onto the input stack
11783 : : because the compiler is currently building a function
11784 : : call and expecting a ReturnVar on the stack.
11785 : : Hence we manipulate the stack and call
11786 : : BuildConvertFunction.
11787 : :
11788 : : The Stack:
11789 : :
11790 : :
11791 : : Entry Exit
11792 : :
11793 : : Ptr ->
11794 : : +----------------+
11795 : : | NoOfParam |
11796 : : |----------------|
11797 : : | Param 1 |
11798 : : |----------------|
11799 : : | Param 2 |
11800 : : |----------------|
11801 : : . .
11802 : : . .
11803 : : . .
11804 : : |----------------|
11805 : : | Param # |
11806 : : |----------------|
11807 : : | ProcSym | Type | Empty
11808 : : |----------------|
11809 : : */
11810 : :
11811 : 3280 : static void BuildValFunction (unsigned int ProcSym, bool ConstExpr)
11812 : : {
11813 : 3280 : unsigned int combinedtok;
11814 : 3280 : unsigned int functok;
11815 : 3280 : unsigned int ReturnVar;
11816 : 3280 : unsigned int NoOfParam;
11817 : 3280 : unsigned int Exp;
11818 : 3280 : unsigned int Type;
11819 : 3280 : unsigned int tok;
11820 : 3280 : unsigned int r;
11821 : 3280 : unsigned int typetok;
11822 : 3280 : unsigned int exptok;
11823 : :
11824 : 3280 : M2Quads_PopT (&NoOfParam);
11825 : 3280 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11826 : 3280 : if (NoOfParam == 2)
11827 : : {
11828 : 3280 : PopTrwtok (&Exp, &r, &exptok);
11829 : 3280 : MarkAsRead (r);
11830 : 3280 : M2Quads_PopTtok (&Type, &typetok);
11831 : 3280 : M2Quads_PopTtok (&ProcSym, &tok);
11832 : 3280 : if (SymbolTable_IsUnknown (Type))
11833 : : {
11834 : : /* non recoverable error. */
11835 : 6 : M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type found in builtin procedure function {%AkVAL} {%1ad}", 67, Type);
11836 : : }
11837 : 3274 : else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
11838 : : {
11839 : : /* avoid dangling else. */
11840 : : /* Generate fake result. */
11841 : 6 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
11842 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
11843 : 6 : SymbolTable_PutVar (ReturnVar, Type);
11844 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
11845 : : }
11846 : 3268 : 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))))
11847 : : {
11848 : : /* avoid dangling else. */
11849 : : /*
11850 : : Build macro: CONVERT( Type, Var )
11851 : : */
11852 : 3268 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
11853 : 3268 : M2Quads_PushTtok (Type, typetok);
11854 : 3268 : M2Quads_PushTtok (Exp, exptok);
11855 : 3268 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
11856 : 3268 : BuildConvertFunction (M2Base_Convert, ConstExpr);
11857 : : }
11858 : : else
11859 : : {
11860 : : /* avoid dangling else. */
11861 : : /* non recoverable error. */
11862 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkVAL} has the following formal parameter declaration {%kVAL} (type, expression)", 104);
11863 : : }
11864 : : }
11865 : : else
11866 : : {
11867 : : /* non recoverable error. */
11868 : 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);
11869 : : }
11870 : 3274 : }
11871 : :
11872 : :
11873 : : /*
11874 : : BuildCastFunction - builds the pseudo procedure call CAST.
11875 : : This procedure is actually a "macro" for
11876 : : CAST(Type, x) --> Type(x)
11877 : : However we cannot push tokens back onto the input stack
11878 : : because the compiler is currently building a function
11879 : : call and expecting a ReturnVar on the stack.
11880 : : Hence we manipulate the stack and call
11881 : : BuildConvertFunction.
11882 : :
11883 : : The Stack:
11884 : :
11885 : :
11886 : : Entry Exit
11887 : :
11888 : : Ptr ->
11889 : : +----------------+
11890 : : | NoOfParam |
11891 : : |----------------|
11892 : : | Param 1 |
11893 : : |----------------|
11894 : : | Param 2 |
11895 : : |----------------|
11896 : : . .
11897 : : . .
11898 : : . .
11899 : : |----------------|
11900 : : | Param # |
11901 : : |----------------|
11902 : : | ProcSym | Type | Empty
11903 : : |----------------|
11904 : : */
11905 : :
11906 : 156 : static void BuildCastFunction (unsigned int ProcSym, bool ConstExpr)
11907 : : {
11908 : 156 : unsigned int combinedtok;
11909 : 156 : unsigned int exptok;
11910 : 156 : unsigned int typetok;
11911 : 156 : unsigned int functok;
11912 : 156 : unsigned int ReturnVar;
11913 : 156 : unsigned int NoOfParam;
11914 : 156 : unsigned int Exp;
11915 : 156 : unsigned int Type;
11916 : :
11917 : 156 : M2Quads_PopT (&NoOfParam);
11918 : 156 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11919 : 156 : if (NoOfParam == 2)
11920 : : {
11921 : 156 : Type = static_cast<unsigned int> (M2Quads_OperandT (2));
11922 : 156 : typetok = static_cast<unsigned int> (M2Quads_OperandTok (2));
11923 : 156 : Exp = static_cast<unsigned int> (M2Quads_OperandT (1));
11924 : 156 : exptok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11925 : 156 : if (SymbolTable_IsUnknown (Type))
11926 : : {
11927 : : /* non recoverable error. */
11928 : 0 : M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type {%1Aad} found in {%kCAST}", 41, Type);
11929 : : }
11930 : 156 : else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
11931 : : {
11932 : : /* avoid dangling else. */
11933 : : /* Generate fake result. */
11934 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
11935 : 0 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
11936 : 0 : SymbolTable_PutVar (ReturnVar, Type);
11937 : 0 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
11938 : : }
11939 : 156 : else if (((((((SymbolTable_IsSet (Type)) || (SymbolTable_IsEnumeration (Type))) || (SymbolTable_IsSubrange (Type))) || (SymbolTable_IsType (Type))) || (SymbolTable_IsPointer (Type))) || (SymbolTable_IsArray (Type))) || (SymbolTable_IsProcType (Type)))
11940 : : {
11941 : : /* avoid dangling else. */
11942 : 156 : if (SymbolTable_IsConst (Exp))
11943 : : {
11944 : 30 : M2Quads_PopN (NoOfParam+1);
11945 : : /*
11946 : : Build macro: Type( Var )
11947 : : */
11948 : 30 : M2Quads_PushTFtok (Type, static_cast<unsigned int> (SymbolTable_NulSym), typetok);
11949 : 30 : M2Quads_PushTtok (Exp, exptok);
11950 : 30 : M2Quads_PushT (static_cast<unsigned int> (1)); /* one parameter */
11951 : 30 : BuildTypeCoercion (ConstExpr); /* one parameter */
11952 : : }
11953 : 126 : else if ((SymbolTable_IsVar (Exp)) || (SymbolTable_IsProcedure (Exp)))
11954 : : {
11955 : : /* avoid dangling else. */
11956 : 126 : M2Quads_PopN (NoOfParam+1);
11957 : 126 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, exptok);
11958 : 126 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
11959 : 126 : SymbolTable_PutVar (ReturnVar, Type);
11960 : 252 : GenQuadO (combinedtok, M2Quads_CastOp, ReturnVar, Type, Exp, false);
11961 : 126 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
11962 : : }
11963 : : else
11964 : : {
11965 : : /* avoid dangling else. */
11966 : : /* non recoverable error. */
11967 : 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);
11968 : : }
11969 : : }
11970 : : else
11971 : : {
11972 : : /* avoid dangling else. */
11973 : : /* non recoverable error. */
11974 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkCAST} has the following formal parameter declaration {%kCAST} (type, expression)", 106);
11975 : : }
11976 : : }
11977 : : else
11978 : : {
11979 : : /* non recoverable error. */
11980 : 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);
11981 : : }
11982 : 156 : }
11983 : :
11984 : :
11985 : : /*
11986 : : BuildConvertFunction - builds the pseudo function CONVERT.
11987 : : CONVERT( Type, Variable ) ;
11988 : :
11989 : : The Stack:
11990 : :
11991 : :
11992 : : Entry Exit
11993 : :
11994 : : Ptr ->
11995 : : +----------------+
11996 : : | NoOfParam |
11997 : : |----------------|
11998 : : | Param 1 |
11999 : : |----------------|
12000 : : | Param 2 |
12001 : : |----------------|
12002 : : . .
12003 : : . .
12004 : : . .
12005 : : |----------------|
12006 : : | Param # | <- Ptr
12007 : : |----------------| +---------------------+
12008 : : | ProcSym | Type | | ReturnVar | Param1 |
12009 : : |----------------| |---------------------|
12010 : :
12011 : : Quadruples:
12012 : :
12013 : : ConvertOp ReturnVar Param1 Param2
12014 : :
12015 : : Converts variable Param2 into a variable Param1
12016 : : with a type Param1.
12017 : : */
12018 : :
12019 : 43802 : static void BuildConvertFunction (unsigned int ProcSym, bool ConstExpr)
12020 : : {
12021 : 43802 : unsigned int combinedtok;
12022 : 43802 : unsigned int functok;
12023 : 43802 : unsigned int typetok;
12024 : 43802 : unsigned int exptok;
12025 : 43802 : unsigned int t;
12026 : 43802 : unsigned int r;
12027 : 43802 : unsigned int Exp;
12028 : 43802 : unsigned int Type;
12029 : 43802 : unsigned int NoOfParam;
12030 : 43802 : unsigned int ReturnVar;
12031 : :
12032 : 43802 : M2Quads_PopT (&NoOfParam);
12033 : 43802 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
12034 : 43802 : if (NoOfParam == 2)
12035 : : {
12036 : 43802 : PopTrwtok (&Exp, &r, &exptok);
12037 : 43802 : MarkAsRead (r);
12038 : 43802 : M2Quads_PopTtok (&Type, &typetok);
12039 : 43802 : M2Quads_PopT (&ProcSym);
12040 : 43802 : if (SymbolTable_IsUnknown (Type))
12041 : : {
12042 : : /* non recoverable error. */
12043 : 0 : M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type {%1Aad} found in {%kCONVERT}", 44, Type);
12044 : : }
12045 : 43802 : else if (SymbolTable_IsUnknown (Exp))
12046 : : {
12047 : : /* avoid dangling else. */
12048 : : /* non recoverable error. */
12049 : 0 : M2MetaError_MetaErrorT1 (typetok, (const char *) "unknown {%1Ad} {%1ad} found in {%kCONVERT}", 42, Exp);
12050 : : }
12051 : 43802 : else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
12052 : : {
12053 : : /* avoid dangling else. */
12054 : : /* Generate fake result. */
12055 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
12056 : 0 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
12057 : 0 : SymbolTable_PutVar (ReturnVar, Type);
12058 : 0 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12059 : : }
12060 : 43802 : 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))))
12061 : : {
12062 : : /* avoid dangling else. */
12063 : : /* firstly dereference Var */
12064 : 43796 : if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
12065 : : {
12066 : 0 : t = SymbolTable_MakeTemporary (exptok, SymbolTable_RightValue);
12067 : 0 : SymbolTable_PutVar (t, SymbolTable_GetSType (Exp));
12068 : 0 : CheckPointerThroughNil (exptok, Exp);
12069 : 0 : doIndrX (exptok, t, Exp);
12070 : 0 : Exp = t;
12071 : : }
12072 : 43796 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
12073 : 87592 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
12074 : 43796 : SymbolTable_PutVar (ReturnVar, Type);
12075 : 87592 : GenQuadO (combinedtok, M2Quads_ConvertOp, ReturnVar, Type, Exp, true);
12076 : 43796 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12077 : : }
12078 : : else
12079 : : {
12080 : : /* avoid dangling else. */
12081 : : /* non recoverable error. */
12082 : 6 : M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkCONVERT} has the following formal parameter declaration {%kCONVERT} (type, expression)", 112);
12083 : : }
12084 : : }
12085 : : else
12086 : : {
12087 : : /* non recoverable error. */
12088 : 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);
12089 : : }
12090 : 43796 : }
12091 : :
12092 : :
12093 : : /*
12094 : : CheckBaseTypeValue - checks to see whether the value, min, really exists.
12095 : : */
12096 : :
12097 : 1800 : static unsigned int CheckBaseTypeValue (unsigned int tok, unsigned int type, unsigned int min, unsigned int func)
12098 : : {
12099 : 1800 : if (((type == M2Base_Real) || (type == M2Base_LongReal)) || (type == M2Base_ShortReal))
12100 : : {
12101 : 78 : SymbolTable_PushValue (min);
12102 : 78 : if (! (M2ALU_IsValueAndTreeKnown ()))
12103 : : {
12104 : 0 : M2MetaError_MetaErrorT2 (tok, (const char *) "{%1Ead} ({%2ad}) cannot be calculated at compile time for the target architecture", 81, func, type);
12105 : 0 : return SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType);
12106 : : }
12107 : : }
12108 : : return min;
12109 : : /* static analysis guarentees a RETURN statement will be used before here. */
12110 : : __builtin_unreachable ();
12111 : : }
12112 : :
12113 : :
12114 : : /*
12115 : : GetTypeMin - returns the minimium value of type.
12116 : : */
12117 : :
12118 : 1092 : static unsigned int GetTypeMin (unsigned int tok, unsigned int func, unsigned int type)
12119 : : {
12120 : 1156 : unsigned int min;
12121 : 1156 : unsigned int max;
12122 : :
12123 : 1156 : if (SymbolTable_IsSubrange (type))
12124 : : {
12125 : 234 : min = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
12126 : 234 : SymbolTable_PutVar (min, type);
12127 : 468 : GenQuad (M2Quads_SubrangeLowOp, min, SymbolTable_NulSym, type);
12128 : 234 : return min;
12129 : : }
12130 : 922 : else if (SymbolTable_IsSet (SymbolTable_SkipType (type)))
12131 : : {
12132 : : /* avoid dangling else. */
12133 : 48 : return GetTypeMin (tok, func, SymbolTable_GetSType (SymbolTable_SkipType (type)));
12134 : : }
12135 : 874 : else if ((M2Base_IsBaseType (type)) || (SymbolTable_IsEnumeration (type)))
12136 : : {
12137 : : /* avoid dangling else. */
12138 : 678 : M2Base_GetBaseTypeMinMax (type, &min, &max);
12139 : 678 : min = CheckBaseTypeValue (tok, type, min, func);
12140 : 678 : return min;
12141 : : }
12142 : 196 : else if (M2System_IsSystemType (type))
12143 : : {
12144 : : /* avoid dangling else. */
12145 : 180 : M2System_GetSystemTypeMinMax (type, &min, &max);
12146 : 180 : return min;
12147 : : }
12148 : 16 : else if ((SymbolTable_GetSType (type)) == SymbolTable_NulSym)
12149 : : {
12150 : : /* avoid dangling else. */
12151 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "unable to obtain the {%AkMIN} value for type {%1ad}", 51, type);
12152 : : /* non recoverable error. */
12153 : 0 : M2Error_InternalError ((const char *) "MetaErrorT1 {%AkMIN} should call abort", 38);
12154 : : }
12155 : : else
12156 : : {
12157 : : /* avoid dangling else. */
12158 : 16 : return GetTypeMin (tok, func, SymbolTable_GetSType (type));
12159 : : }
12160 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
12161 : : __builtin_unreachable ();
12162 : : }
12163 : :
12164 : :
12165 : : /*
12166 : : GetTypeMax - returns the maximum value of type.
12167 : : */
12168 : :
12169 : 4352 : static unsigned int GetTypeMax (unsigned int tok, unsigned int func, unsigned int type)
12170 : : {
12171 : 7078 : unsigned int min;
12172 : 7078 : unsigned int max;
12173 : :
12174 : 7078 : if (SymbolTable_IsSubrange (type))
12175 : : {
12176 : 3034 : max = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
12177 : 3034 : SymbolTable_PutVar (max, type);
12178 : 6068 : GenQuad (M2Quads_SubrangeHighOp, max, SymbolTable_NulSym, type);
12179 : 3034 : return max;
12180 : : }
12181 : 4044 : else if (SymbolTable_IsSet (SymbolTable_SkipType (type)))
12182 : : {
12183 : : /* avoid dangling else. */
12184 : 2710 : return GetTypeMax (tok, func, SymbolTable_GetSType (SymbolTable_SkipType (type)));
12185 : : }
12186 : 1334 : else if ((M2Base_IsBaseType (type)) || (SymbolTable_IsEnumeration (type)))
12187 : : {
12188 : : /* avoid dangling else. */
12189 : 1122 : M2Base_GetBaseTypeMinMax (type, &min, &max);
12190 : 1122 : min = CheckBaseTypeValue (tok, type, min, func);
12191 : 1122 : return max;
12192 : : }
12193 : 212 : else if (M2System_IsSystemType (type))
12194 : : {
12195 : : /* avoid dangling else. */
12196 : 196 : M2System_GetSystemTypeMinMax (type, &min, &max);
12197 : 196 : return max;
12198 : : }
12199 : 16 : else if ((SymbolTable_GetSType (type)) == SymbolTable_NulSym)
12200 : : {
12201 : : /* avoid dangling else. */
12202 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "unable to obtain the {%AkMAX} value for type {%1ad}", 51, type);
12203 : : /* non recoverable error. */
12204 : 0 : M2Error_InternalError ((const char *) "MetaErrorT1 {%AkMAX} should call abort", 38);
12205 : : }
12206 : : else
12207 : : {
12208 : : /* avoid dangling else. */
12209 : 16 : return GetTypeMax (tok, func, SymbolTable_GetSType (type));
12210 : : }
12211 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
12212 : : __builtin_unreachable ();
12213 : : }
12214 : :
12215 : :
12216 : : /*
12217 : : BuildMinFunction - builds the pseudo function call Min.
12218 : :
12219 : : The Stack:
12220 : :
12221 : : Entry Exit
12222 : :
12223 : : Ptr ->
12224 : : +----------------+
12225 : : | NoOfParam=1 |
12226 : : |----------------|
12227 : : | Param 1 |
12228 : : |----------------|
12229 : : | ProcSym | Type | Empty
12230 : : |----------------|
12231 : : */
12232 : :
12233 : 1092 : static void BuildMinFunction (void)
12234 : : {
12235 : 1092 : unsigned int combinedtok;
12236 : 1092 : unsigned int functok;
12237 : 1092 : unsigned int vartok;
12238 : 1092 : unsigned int func;
12239 : 1092 : unsigned int min;
12240 : 1092 : unsigned int NoOfParam;
12241 : 1092 : unsigned int Var;
12242 : :
12243 : 1092 : M2Quads_PopT (&NoOfParam);
12244 : 1092 : func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12245 : 1092 : functok = OperandTtok (NoOfParam+1);
12246 : 1092 : if (NoOfParam == 1)
12247 : : {
12248 : 1092 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12249 : 1092 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12250 : 1092 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12251 : 1092 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok); /* destroy arguments to this function */
12252 : 1092 : if (SymbolTable_IsAModula2Type (Var))
12253 : : {
12254 : 1092 : min = GetTypeMin (vartok, func, Var);
12255 : 1092 : M2Quads_PushTFtok (min, SymbolTable_GetSType (min), combinedtok);
12256 : : }
12257 : 0 : else if (SymbolTable_IsVar (Var))
12258 : : {
12259 : : /* avoid dangling else. */
12260 : 0 : min = GetTypeMin (vartok, func, SymbolTable_GetSType (Var));
12261 : 0 : M2Quads_PushTFtok (min, SymbolTable_GetSType (Var), combinedtok);
12262 : : }
12263 : : else
12264 : : {
12265 : : /* avoid dangling else. */
12266 : : /* non recoverable error. */
12267 : 0 : M2MetaError_MetaErrorT1 (vartok, (const char *) "parameter to {%AkMIN} must be a type or a variable, seen {%1ad}", 63, Var);
12268 : : }
12269 : : }
12270 : : else
12271 : : {
12272 : : /* non recoverable error. */
12273 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkMIN} only has one parameter, seen {%1n}", 82, NoOfParam);
12274 : : }
12275 : 1092 : }
12276 : :
12277 : :
12278 : : /*
12279 : : BuildMaxFunction - builds the pseudo function call Max.
12280 : :
12281 : : The Stack:
12282 : :
12283 : : Entry Exit
12284 : :
12285 : : Ptr ->
12286 : : +----------------+
12287 : : | NoOfParam=1 |
12288 : : |----------------|
12289 : : | Param 1 |
12290 : : |----------------|
12291 : : | ProcSym | Type | Empty
12292 : : |----------------|
12293 : : */
12294 : :
12295 : 4352 : static void BuildMaxFunction (void)
12296 : : {
12297 : 4352 : unsigned int combinedtok;
12298 : 4352 : unsigned int functok;
12299 : 4352 : unsigned int vartok;
12300 : 4352 : unsigned int func;
12301 : 4352 : unsigned int max;
12302 : 4352 : unsigned int NoOfParam;
12303 : 4352 : unsigned int Var;
12304 : :
12305 : 4352 : M2Quads_PopT (&NoOfParam);
12306 : 4352 : func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12307 : 4352 : functok = OperandTtok (NoOfParam+1);
12308 : 4352 : if (NoOfParam == 1)
12309 : : {
12310 : 4352 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12311 : 4352 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12312 : 4352 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12313 : 4352 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok); /* destroy arguments to this function */
12314 : 4352 : if (SymbolTable_IsAModula2Type (Var))
12315 : : {
12316 : 4352 : max = GetTypeMax (vartok, func, Var);
12317 : 4352 : M2Quads_PushTFtok (max, SymbolTable_GetSType (max), combinedtok);
12318 : : }
12319 : 0 : else if (SymbolTable_IsVar (Var))
12320 : : {
12321 : : /* avoid dangling else. */
12322 : 0 : max = GetTypeMax (vartok, func, SymbolTable_GetSType (Var));
12323 : 0 : M2Quads_PushTFtok (max, SymbolTable_GetSType (Var), combinedtok);
12324 : : }
12325 : : else
12326 : : {
12327 : : /* avoid dangling else. */
12328 : : /* non recoverable error. */
12329 : 0 : M2MetaError_MetaErrorT1 (vartok, (const char *) "parameter to {%AkMAX} must be a type or a variable, seen {%1ad}", 63, Var);
12330 : : }
12331 : : }
12332 : : else
12333 : : {
12334 : : /* non recoverable error. */
12335 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkMAX} only has one parameter, seen {%1n}", 81, NoOfParam);
12336 : : }
12337 : 4352 : }
12338 : :
12339 : :
12340 : : /*
12341 : : BuildTruncFunction - builds the pseudo procedure call TRUNC.
12342 : : This procedure is actually a "macro" for
12343 : : TRUNC(x) --> CONVERT(INTEGER, x)
12344 : : However we cannot push tokens back onto the input stack
12345 : : because the compiler is currently building a function
12346 : : call and expecting a ReturnVar on the stack.
12347 : : Hence we manipulate the stack and call
12348 : : BuildConvertFunction.
12349 : :
12350 : : The Stack:
12351 : :
12352 : :
12353 : : Entry Exit
12354 : :
12355 : : Ptr ->
12356 : : +----------------+
12357 : : | NoOfParam |
12358 : : |----------------|
12359 : : | Param 1 |
12360 : : |----------------|
12361 : : | Param 2 |
12362 : : |----------------|
12363 : : . .
12364 : : . .
12365 : : . .
12366 : : |----------------|
12367 : : | Param # |
12368 : : |----------------|
12369 : : | ProcSym | Type | Empty
12370 : : |----------------|
12371 : : */
12372 : :
12373 : 60 : static void BuildTruncFunction (unsigned int Sym, bool ConstExpr)
12374 : : {
12375 : 60 : unsigned int combinedtok;
12376 : 60 : unsigned int vartok;
12377 : 60 : unsigned int functok;
12378 : 60 : unsigned int NoOfParam;
12379 : 60 : unsigned int ReturnVar;
12380 : 60 : unsigned int ProcSym;
12381 : 60 : unsigned int Type;
12382 : 60 : unsigned int Var;
12383 : :
12384 : 60 : M2Quads_PopT (&NoOfParam);
12385 : 60 : M2Debug_Assert (M2Base_IsTrunc (M2Quads_OperandT (NoOfParam+1)));
12386 : 60 : functok = OperandTtok (NoOfParam+1);
12387 : 60 : if (NoOfParam == 1)
12388 : : {
12389 : 60 : ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "CONVERT", 7));
12390 : 60 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
12391 : : {
12392 : 60 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12393 : 60 : vartok = OperandTtok (1);
12394 : 60 : Type = SymbolTable_GetSType (Sym);
12395 : 60 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12396 : 60 : if (ConstExprError (Sym, Var, vartok, ConstExpr))
12397 : : {
12398 : : /* Generate fake result. */
12399 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
12400 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12401 : 6 : SymbolTable_PutVar (ReturnVar, Type);
12402 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12403 : : }
12404 : 54 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
12405 : : {
12406 : : /* avoid dangling else. */
12407 : 54 : if (M2Base_IsRealType (SymbolTable_GetSType (Var)))
12408 : : {
12409 : : /* build macro: CONVERT( INTEGER, Var ). */
12410 : 54 : M2Quads_PushTFtok (ProcSym, static_cast<unsigned int> (SymbolTable_NulSym), functok);
12411 : 54 : M2Quads_PushTtok (Type, functok);
12412 : 54 : M2Quads_PushTtok (Var, vartok);
12413 : 54 : M2Quads_PushT (static_cast<unsigned int> (2)); /* two parameters */
12414 : 54 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* two parameters */
12415 : : }
12416 : : else
12417 : : {
12418 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "argument to {%1Ead} must be a float point type", 46, Sym);
12419 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), Type), Type, functok);
12420 : : }
12421 : : }
12422 : : else
12423 : : {
12424 : : /* avoid dangling else. */
12425 : 0 : M2MetaError_MetaErrorT2 (vartok, (const char *) "argument to {%1Ead} must be a variable or constant, seen {%2ad}", 63, Sym, Var);
12426 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), Type), Type, functok);
12427 : : }
12428 : : }
12429 : : else
12430 : : {
12431 : 0 : M2Error_InternalError ((const char *) "CONVERT procedure not found for TRUNC substitution", 50);
12432 : : }
12433 : : }
12434 : : else
12435 : : {
12436 : : /* non recoverable error. */
12437 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkTRUNC} only has one parameter, seen {%1n}", 84, NoOfParam);
12438 : : }
12439 : 60 : }
12440 : :
12441 : :
12442 : : /*
12443 : : BuildFloatFunction - builds the pseudo procedure call FLOAT.
12444 : : This procedure is actually a "macro" for
12445 : : FLOAT(x) --> CONVERT(REAL, x)
12446 : : However we cannot push tokens back onto the input stack
12447 : : because the compiler is currently building a function
12448 : : call and expecting a ReturnVar on the stack.
12449 : : Hence we manipulate the stack and call
12450 : : BuildConvertFunction.
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 : 64 : static void BuildFloatFunction (unsigned int Sym, bool ConstExpr)
12476 : : {
12477 : 64 : unsigned int combinedtok;
12478 : 64 : unsigned int vartok;
12479 : 64 : unsigned int functok;
12480 : 64 : unsigned int NoOfParam;
12481 : 64 : unsigned int ReturnVar;
12482 : 64 : unsigned int Type;
12483 : 64 : unsigned int Var;
12484 : 64 : unsigned int ProcSym;
12485 : :
12486 : 64 : M2Quads_PopT (&NoOfParam);
12487 : 64 : functok = OperandTtok (NoOfParam+1);
12488 : 64 : Type = SymbolTable_GetSType (Sym);
12489 : 64 : if (NoOfParam == 1)
12490 : : {
12491 : 64 : ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "CONVERT", 7));
12492 : 64 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
12493 : : {
12494 : 64 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12495 : 64 : vartok = OperandTtok (1);
12496 : 64 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function. */
12497 : 64 : if (ConstExprError (Sym, Var, vartok, ConstExpr))
12498 : : {
12499 : : /* Generate fake result. */
12500 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
12501 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12502 : 6 : SymbolTable_PutVar (ReturnVar, Type);
12503 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12504 : : }
12505 : 58 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
12506 : : {
12507 : : /* avoid dangling else. */
12508 : : /* build macro: CONVERT (REAL, Var). */
12509 : 58 : M2Quads_PushTFtok (ProcSym, static_cast<unsigned int> (SymbolTable_NulSym), functok);
12510 : 58 : M2Quads_PushTtok (Type, functok);
12511 : 58 : M2Quads_PushTtok (Var, vartok);
12512 : 58 : M2Quads_PushT (static_cast<unsigned int> (2)); /* two parameters. */
12513 : 58 : BuildConvertFunction (ProcSym, ConstExpr); /* two parameters. */
12514 : : }
12515 : : else
12516 : : {
12517 : : /* avoid dangling else. */
12518 : 0 : M2MetaError_MetaErrorT1 (vartok, (const char *) "argument to {%1Ead} must be a variable or constant", 50, ProcSym);
12519 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0.0", 3), Type), Type, functok);
12520 : : }
12521 : : }
12522 : : else
12523 : : {
12524 : 0 : M2Error_InternalError ((const char *) "CONVERT procedure not found for FLOAT substitution", 50);
12525 : : }
12526 : : }
12527 : : else
12528 : : {
12529 : 0 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function. */
12530 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter", 61, Sym); /* destroy arguments to this function. */
12531 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0.0", 3), Type), Type, functok);
12532 : : }
12533 : 64 : }
12534 : :
12535 : :
12536 : : /*
12537 : : BuildReFunction - builds the pseudo procedure call RE.
12538 : :
12539 : : The Stack:
12540 : :
12541 : :
12542 : : Entry Exit
12543 : :
12544 : : Ptr ->
12545 : : +----------------+
12546 : : | NoOfParam |
12547 : : |----------------|
12548 : : | Param 1 |
12549 : : |----------------|
12550 : : | Param 2 |
12551 : : |----------------|
12552 : : . .
12553 : : . .
12554 : : . .
12555 : : |----------------|
12556 : : | Param # |
12557 : : |----------------|
12558 : : | ProcSym | Type | Empty
12559 : : |----------------|
12560 : : */
12561 : :
12562 : 60 : static void BuildReFunction (unsigned int Sym, bool ConstExpr)
12563 : : {
12564 : 60 : unsigned int func;
12565 : 60 : unsigned int combinedtok;
12566 : 60 : unsigned int vartok;
12567 : 60 : unsigned int functok;
12568 : 60 : unsigned int NoOfParam;
12569 : 60 : unsigned int ReturnVar;
12570 : 60 : unsigned int Type;
12571 : 60 : unsigned int Var;
12572 : :
12573 : 60 : M2Quads_PopT (&NoOfParam);
12574 : 60 : functok = OperandTtok (NoOfParam+1);
12575 : 60 : func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12576 : 60 : if (NoOfParam == 1)
12577 : : {
12578 : 60 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12579 : 60 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12580 : 60 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
12581 : 60 : Type = M2Base_ComplexToScalar (SymbolTable_GetDType (Var));
12582 : 60 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12583 : 60 : if (ConstExprError (Sym, Var, vartok, ConstExpr))
12584 : : {
12585 : : /* Generate fake result. */
12586 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
12587 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12588 : 6 : SymbolTable_PutVar (ReturnVar, Type);
12589 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12590 : : }
12591 : 54 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
12592 : : {
12593 : : /* avoid dangling else. */
12594 : 108 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12595 : 54 : SymbolTable_PutVar (ReturnVar, Type);
12596 : 108 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Re, Var, false);
12597 : 54 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12598 : : }
12599 : : else
12600 : : {
12601 : : /* avoid dangling else. */
12602 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, combinedtok);
12603 : 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);
12604 : : }
12605 : : }
12606 : : else
12607 : : {
12608 : 0 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12609 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, functok); /* destroy arguments to this function */
12610 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter, seen {%2n}", 73, func, NoOfParam);
12611 : : }
12612 : 60 : }
12613 : :
12614 : :
12615 : : /*
12616 : : BuildImFunction - builds the pseudo procedure call IM.
12617 : :
12618 : : The Stack:
12619 : :
12620 : :
12621 : : Entry Exit
12622 : :
12623 : : Ptr ->
12624 : : +----------------+
12625 : : | NoOfParam |
12626 : : |----------------|
12627 : : | Param 1 |
12628 : : |----------------|
12629 : : | Param 2 |
12630 : : |----------------|
12631 : : . .
12632 : : . .
12633 : : . .
12634 : : |----------------|
12635 : : | Param # |
12636 : : |----------------|
12637 : : | ProcSym | Type | Empty
12638 : : |----------------|
12639 : : */
12640 : :
12641 : 60 : static void BuildImFunction (unsigned int Sym, bool ConstExpr)
12642 : : {
12643 : 60 : unsigned int func;
12644 : 60 : unsigned int combinedtok;
12645 : 60 : unsigned int vartok;
12646 : 60 : unsigned int functok;
12647 : 60 : unsigned int NoOfParam;
12648 : 60 : unsigned int ReturnVar;
12649 : 60 : unsigned int Type;
12650 : 60 : unsigned int Var;
12651 : :
12652 : 60 : M2Quads_PopT (&NoOfParam);
12653 : 60 : functok = OperandTtok (NoOfParam+1);
12654 : 60 : func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12655 : 60 : if (NoOfParam == 1)
12656 : : {
12657 : 60 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12658 : 60 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12659 : 60 : Type = M2Base_ComplexToScalar (SymbolTable_GetDType (Var));
12660 : 60 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
12661 : 60 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12662 : 60 : if (ConstExprError (Sym, Var, vartok, ConstExpr))
12663 : : {
12664 : : /* Generate fake result. */
12665 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
12666 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12667 : 6 : SymbolTable_PutVar (ReturnVar, Type);
12668 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12669 : : }
12670 : 54 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
12671 : : {
12672 : : /* avoid dangling else. */
12673 : 108 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12674 : 54 : SymbolTable_PutVar (ReturnVar, M2Base_ComplexToScalar (SymbolTable_GetDType (Var)));
12675 : 108 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Im, Var, false);
12676 : 54 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), combinedtok);
12677 : : }
12678 : : else
12679 : : {
12680 : : /* avoid dangling else. */
12681 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, combinedtok);
12682 : 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);
12683 : : }
12684 : : }
12685 : : else
12686 : : {
12687 : 0 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12688 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, functok); /* destroy arguments to this function */
12689 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter, seen {%2n}", 73, func, NoOfParam);
12690 : : }
12691 : 60 : }
12692 : :
12693 : :
12694 : : /*
12695 : : BuildCmplxFunction - builds the pseudo procedure call CMPLX.
12696 : :
12697 : : The Stack:
12698 : :
12699 : :
12700 : : Entry Exit
12701 : :
12702 : : Ptr ->
12703 : : +----------------+
12704 : : | NoOfParam |
12705 : : |----------------|
12706 : : | Param 1 |
12707 : : |----------------|
12708 : : | Param 2 |
12709 : : |----------------|
12710 : : . .
12711 : : . .
12712 : : . .
12713 : : |----------------|
12714 : : | Param # |
12715 : : |----------------|
12716 : : | ProcSym | Type | Empty
12717 : : |----------------|
12718 : : */
12719 : :
12720 : 492 : static void BuildCmplxFunction (unsigned int func, bool ConstExpr)
12721 : : {
12722 : 492 : bool failure;
12723 : 492 : unsigned int functok;
12724 : 492 : unsigned int rtok;
12725 : 492 : unsigned int ltok;
12726 : 492 : unsigned int combinedtok;
12727 : 492 : unsigned int NoOfParam;
12728 : 492 : unsigned int type;
12729 : 492 : unsigned int ReturnVar;
12730 : 492 : unsigned int l;
12731 : 492 : unsigned int r;
12732 : :
12733 : 492 : M2Quads_PopT (&NoOfParam);
12734 : 492 : functok = OperandTtok (NoOfParam+1);
12735 : 492 : if (NoOfParam == 2)
12736 : : {
12737 : 492 : l = static_cast<unsigned int> (M2Quads_OperandT (2));
12738 : 492 : ltok = OperandTtok (2);
12739 : 492 : r = static_cast<unsigned int> (M2Quads_OperandT (1));
12740 : 492 : rtok = OperandTtok (1);
12741 : 492 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, rtok);
12742 : 492 : M2Quads_PopN (NoOfParam+1); /* Destroy arguments to this function. */
12743 : 492 : type = M2Base_GetCmplxReturnType (SymbolTable_GetDType (l), SymbolTable_GetDType (r)); /* Destroy arguments to this function. */
12744 : 570 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant ((SymbolTable_IsConst (l)) && (SymbolTable_IsConst (r))));
12745 : 492 : SymbolTable_PutVar (ReturnVar, type);
12746 : 492 : failure = false;
12747 : 492 : if (ConstExprError (func, l, ltok, ConstExpr))
12748 : : {
12749 : : /* ConstExprError has generated an error message we will fall through
12750 : : and check the right operand. */
12751 : : failure = true;
12752 : : }
12753 : 492 : if (ConstExprError (func, r, rtok, ConstExpr))
12754 : : {
12755 : : /* Right operand is in error as a variable. */
12756 : : failure = true;
12757 : : }
12758 : 486 : if (failure)
12759 : : {
12760 : : /* Generate a fake result if either operand was a variable (and we
12761 : : are in a const expression). */
12762 : 6 : M2Quads_PushTFtok (ReturnVar, type, combinedtok);
12763 : : }
12764 : 486 : else if (((SymbolTable_IsVar (l)) || (SymbolTable_IsConst (l))) && ((SymbolTable_IsVar (r)) || (SymbolTable_IsConst (r))))
12765 : : {
12766 : : /* avoid dangling else. */
12767 : 486 : M2Base_CheckExpressionCompatible (combinedtok, SymbolTable_GetSType (l), SymbolTable_GetSType (r));
12768 : 486 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Cmplx, SymbolTable_Make2Tuple (l, r), true);
12769 : 486 : M2Quads_PushTFtok (ReturnVar, type, combinedtok);
12770 : : }
12771 : : else
12772 : : {
12773 : : /* avoid dangling else. */
12774 : 0 : if ((SymbolTable_IsVar (l)) || (SymbolTable_IsConst (l)))
12775 : : {
12776 : 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);
12777 : : }
12778 : : else
12779 : : {
12780 : 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);
12781 : : }
12782 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_CType), M2Base_CType, combinedtok);
12783 : : }
12784 : : }
12785 : : else
12786 : : {
12787 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure {%1Ead} requires two parameters, seen {%2n}", 65, func, NoOfParam);
12788 : 0 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12789 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_CType), M2Base_CType, functok); /* destroy arguments to this function */
12790 : : }
12791 : 492 : }
12792 : :
12793 : :
12794 : : /*
12795 : : BuildAdrFunction - builds the pseudo function ADR
12796 : : The Stack:
12797 : :
12798 : :
12799 : : Entry Exit
12800 : :
12801 : : Ptr ->
12802 : : +----------------+
12803 : : | NoOfParam |
12804 : : |----------------|
12805 : : | Param 1 |
12806 : : |----------------|
12807 : : | Param 2 |
12808 : : |----------------|
12809 : : . .
12810 : : . .
12811 : : . .
12812 : : |----------------|
12813 : : | Param # | <- Ptr
12814 : : |----------------| +------------+
12815 : : | ProcSym | Type | | ReturnVar |
12816 : : |----------------| |------------|
12817 : :
12818 : : */
12819 : :
12820 : 171776 : static void BuildAdrFunction (void)
12821 : : {
12822 : 171776 : unsigned int endtok;
12823 : 171776 : unsigned int combinedTok;
12824 : 171776 : unsigned int procTok;
12825 : 171776 : unsigned int t;
12826 : 171776 : unsigned int UnboundedSym;
12827 : 171776 : unsigned int Dim;
12828 : 171776 : unsigned int Field;
12829 : 171776 : unsigned int noOfParameters;
12830 : 171776 : unsigned int procSym;
12831 : 171776 : unsigned int returnVar;
12832 : 171776 : unsigned int Type;
12833 : 171776 : unsigned int rw;
12834 : :
12835 : 171776 : M2Quads_DisplayStack ();
12836 : 171776 : M2Quads_PopT (&noOfParameters);
12837 : 171776 : procSym = static_cast<unsigned int> (M2Quads_OperandT (noOfParameters+1));
12838 : 171776 : procTok = static_cast<unsigned int> (M2Quads_OperandTok (noOfParameters+1)); /* token of procedure ADR. */
12839 : 171776 : endtok = static_cast<unsigned int> (M2Quads_OperandTok (1)); /* last parameter. */
12840 : 171776 : combinedTok = M2LexBuf_MakeVirtualTok (procTok, procTok, endtok); /* last parameter. */
12841 : 171776 : if (noOfParameters != 1)
12842 : : {
12843 : 0 : M2MetaError_MetaErrorNT0 (combinedTok, (const char *) "SYSTEM procedure ADR expects 1 parameter", 40);
12844 : 0 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
12845 : 0 : M2Quads_PushTF (M2Base_Nil, M2System_Address); /* destroy the arguments and function */
12846 : : }
12847 : 171776 : else if (SymbolTable_IsConstString (M2Quads_OperandT (1)))
12848 : : {
12849 : : /* avoid dangling else. */
12850 : 163918 : returnVar = MakeLeftValue (combinedTok, M2Quads_OperandT (1), SymbolTable_RightValue, SymbolTable_GetSType (procSym));
12851 : 163918 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
12852 : 163918 : M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (returnVar), combinedTok); /* destroy the arguments and function */
12853 : : }
12854 : 7858 : else if ((! (SymbolTable_IsVar (M2Quads_OperandT (1)))) && (! (SymbolTable_IsProcedure (M2Quads_OperandT (1)))))
12855 : : {
12856 : : /* avoid dangling else. */
12857 : 0 : M2MetaError_MetaErrorNT0 (combinedTok, (const char *) "SYSTEM procedure ADR expects a variable, procedure or a constant string as its parameter", 88);
12858 : 0 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
12859 : 0 : M2Quads_PushTFtok (M2Base_Nil, M2System_Address, combinedTok); /* destroy the arguments and function */
12860 : : }
12861 : 7858 : else if (SymbolTable_IsProcedure (M2Quads_OperandT (1)))
12862 : : {
12863 : : /* avoid dangling else. */
12864 : 24 : returnVar = MakeLeftValue (combinedTok, M2Quads_OperandT (1), SymbolTable_RightValue, SymbolTable_GetSType (procSym));
12865 : 24 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
12866 : 24 : M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (returnVar), combinedTok); /* destroy the arguments and function */
12867 : : }
12868 : : else
12869 : : {
12870 : : /* avoid dangling else. */
12871 : 7834 : Type = SymbolTable_GetSType (M2Quads_OperandT (1));
12872 : 7834 : Dim = static_cast<unsigned int> (OperandD (1));
12873 : 7834 : MarkArrayWritten (M2Quads_OperandT (1));
12874 : 7834 : MarkArrayWritten (M2Quads_OperandA (1));
12875 : : /* if the operand is an unbounded which has not been indexed
12876 : : then we will lookup its address from the unbounded record.
12877 : : Otherwise we obtain the address of the operand.
12878 : : */
12879 : 7834 : if ((SymbolTable_IsUnbounded (Type)) && (Dim == 0))
12880 : : {
12881 : : /* we will reference the address field of the unbounded structure */
12882 : 2366 : UnboundedSym = static_cast<unsigned int> (M2Quads_OperandT (1));
12883 : 2366 : rw = static_cast<unsigned int> (OperandRW (1));
12884 : 2366 : PushTFrw (UnboundedSym, SymbolTable_GetSType (UnboundedSym), rw);
12885 : 2366 : Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
12886 : 2366 : M2Quads_PushTF (Field, SymbolTable_GetSType (Field));
12887 : 2366 : M2Quads_PushT (static_cast<unsigned int> (1));
12888 : 2366 : M2Quads_BuildDesignatorRecord (combinedTok);
12889 : 2366 : PopTrw (&returnVar, &rw);
12890 : 2366 : if ((SymbolTable_GetMode (returnVar)) == SymbolTable_LeftValue)
12891 : : {
12892 : 0 : t = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
12893 : 0 : SymbolTable_PutVar (t, SymbolTable_GetSType (procSym));
12894 : 0 : doIndrX (combinedTok, t, returnVar);
12895 : 0 : returnVar = t;
12896 : : }
12897 : : else
12898 : : {
12899 : : /* we need to cast returnVar into ADDRESS */
12900 : 2366 : t = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
12901 : 2366 : SymbolTable_PutVar (t, SymbolTable_GetSType (procSym));
12902 : 2366 : GenQuadO (combinedTok, M2Quads_ConvertOp, t, SymbolTable_GetSType (procSym), returnVar, false);
12903 : 2366 : returnVar = t;
12904 : : }
12905 : : }
12906 : : else
12907 : : {
12908 : 5468 : returnVar = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
12909 : 5468 : SymbolTable_PutVar (returnVar, SymbolTable_GetSType (procSym));
12910 : 5468 : if ((SymbolTable_GetMode (M2Quads_OperandT (1))) == SymbolTable_LeftValue)
12911 : : {
12912 : 524 : SymbolTable_PutVar (returnVar, SymbolTable_GetSType (procSym));
12913 : 524 : GenQuadO (combinedTok, M2Quads_ConvertOp, returnVar, SymbolTable_GetSType (procSym), M2Quads_OperandT (1), false);
12914 : : }
12915 : : else
12916 : : {
12917 : 4944 : GenQuadO (combinedTok, M2Quads_AddrOp, returnVar, SymbolTable_NulSym, M2Quads_OperandT (1), false);
12918 : : }
12919 : 5468 : SymbolTable_PutWriteQuad (M2Quads_OperandT (1), SymbolTable_GetMode (M2Quads_OperandT (1)), NextQuad-1);
12920 : 5468 : rw = static_cast<unsigned int> (OperandMergeRW (1));
12921 : 5468 : M2Debug_Assert (SymbolTable_IsLegal (rw));
12922 : : }
12923 : 7834 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
12924 : 7834 : PushTFrwtok (returnVar, SymbolTable_GetSType (returnVar), rw, combinedTok); /* destroy the arguments and function */
12925 : : }
12926 : 171776 : }
12927 : :
12928 : :
12929 : : /*
12930 : : BuildSizeFunction - builds the pseudo function SIZE
12931 : : The Stack:
12932 : :
12933 : :
12934 : : Entry Exit
12935 : :
12936 : : Ptr ->
12937 : : +----------------+
12938 : : | NoOfParam |
12939 : : |----------------|
12940 : : | Param 1 |
12941 : : |----------------|
12942 : : | Param 2 |
12943 : : |----------------|
12944 : : . .
12945 : : . .
12946 : : . .
12947 : : |----------------|
12948 : : | Param # | <- Ptr
12949 : : |----------------| +------------+
12950 : : | ProcSym | Type | | ReturnVar |
12951 : : |----------------| |------------|
12952 : : */
12953 : :
12954 : 2126 : static void BuildSizeFunction (void)
12955 : : {
12956 : 2126 : unsigned int resulttok;
12957 : 2126 : unsigned int paramtok;
12958 : 2126 : unsigned int functok;
12959 : 2126 : unsigned int dim;
12960 : 2126 : unsigned int Type;
12961 : 2126 : unsigned int NoOfParam;
12962 : 2126 : unsigned int ProcSym;
12963 : 2126 : unsigned int ReturnVar;
12964 : :
12965 : 2126 : M2Quads_PopT (&NoOfParam);
12966 : 2126 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12967 : 2126 : functok = OperandTtok (NoOfParam+1);
12968 : 2126 : if (NoOfParam != 1)
12969 : : {
12970 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "{%E} SYSTEM procedure function {%kSIZE} requires one parameter, seen {%1n}", 74, NoOfParam);
12971 : 0 : resulttok = functok;
12972 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
12973 : : }
12974 : 2126 : else if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
12975 : : {
12976 : : /* avoid dangling else. */
12977 : 1088 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12978 : 1088 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
12979 : 1088 : BuildSizeCheckEnd (ProcSym); /* Quadruple generation now on. */
12980 : 1088 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue); /* Quadruple generation now on. */
12981 : 1088 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, M2Quads_OperandT (1), true);
12982 : : }
12983 : 1038 : else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
12984 : : {
12985 : : /* avoid dangling else. */
12986 : 1032 : BuildSizeCheckEnd (ProcSym); /* Quadruple generation now on. */
12987 : 1032 : Type = SymbolTable_GetSType (M2Quads_OperandT (1)); /* Quadruple generation now on. */
12988 : 1032 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12989 : 1032 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
12990 : 1032 : if (SymbolTable_IsUnbounded (Type))
12991 : : {
12992 : : /* Eg. SIZE(a) ; where a is unbounded dereference HIGH and multiply by the TYPE. */
12993 : 168 : dim = static_cast<unsigned int> (OperandD (1));
12994 : 168 : if (dim == 0)
12995 : : {
12996 : 72 : ReturnVar = calculateMultipicand (resulttok, M2Quads_OperandT (1), Type, dim);
12997 : : }
12998 : : else
12999 : : {
13000 : 96 : ReturnVar = calculateMultipicand (resulttok, M2Quads_OperandA (1), Type, dim);
13001 : : }
13002 : : }
13003 : : else
13004 : : {
13005 : 864 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13006 : 864 : if (Type == SymbolTable_NulSym)
13007 : : {
13008 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "cannot get the type and size of {%1Ead}", 39, M2Quads_OperandT (1));
13009 : : }
13010 : 864 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, Type, true);
13011 : : }
13012 : : }
13013 : : else
13014 : : {
13015 : : /* avoid dangling else. */
13016 : 6 : resulttok = functok;
13017 : 6 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure {%kSIZE} expects a variable as its parameter, seen {%1Ed}", 78, M2Quads_OperandT (1));
13018 : 6 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13019 : : }
13020 : 2126 : M2Quads_PopN (NoOfParam+1); /* Destroy the arguments and function. */
13021 : 2126 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok); /* Destroy the arguments and function. */
13022 : 2126 : }
13023 : :
13024 : :
13025 : : /*
13026 : : BuildTSizeFunction - builds the pseudo function TSIZE
13027 : : The Stack:
13028 : :
13029 : :
13030 : : Entry Exit
13031 : :
13032 : : Ptr ->
13033 : : +----------------+
13034 : : | NoOfParam |
13035 : : |----------------|
13036 : : | Param 1 |
13037 : : |----------------|
13038 : : | Param 2 |
13039 : : |----------------|
13040 : : . .
13041 : : . .
13042 : : . .
13043 : : |----------------|
13044 : : | Param # | <- Ptr
13045 : : |----------------| +------------+
13046 : : | ProcSym | Type | | ReturnVar |
13047 : : |----------------| |------------|
13048 : :
13049 : : */
13050 : :
13051 : 3480 : static void BuildTSizeFunction (void)
13052 : : {
13053 : 3480 : unsigned int resulttok;
13054 : 3480 : unsigned int paramtok;
13055 : 3480 : unsigned int functok;
13056 : 3480 : unsigned int NoOfParam;
13057 : 3480 : unsigned int ProcSym;
13058 : 3480 : unsigned int Record;
13059 : 3480 : unsigned int ReturnVar;
13060 : :
13061 : 3480 : M2Quads_PopT (&NoOfParam);
13062 : 3480 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
13063 : 3480 : functok = OperandTtok (NoOfParam);
13064 : 3480 : BuildSizeCheckEnd (ProcSym); /* quadruple generation now on */
13065 : 3480 : if (NoOfParam == 1) /* quadruple generation now on */
13066 : : {
13067 : 3480 : paramtok = OperandTtok (1);
13068 : 3480 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13069 : 3480 : if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
13070 : : {
13071 : 3452 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13072 : 3452 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
13073 : 3452 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, M2Quads_OperandT (1), false);
13074 : : }
13075 : 28 : else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
13076 : : {
13077 : : /* avoid dangling else. */
13078 : 28 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13079 : 28 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
13080 : 28 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, SymbolTable_GetSType (M2Quads_OperandT (1)), false);
13081 : : }
13082 : : else
13083 : : {
13084 : : /* avoid dangling else. */
13085 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTSIZE} expects a variable as its first parameter, seen {%1Ed}", 94, M2Quads_OperandT (1));
13086 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13087 : : }
13088 : : }
13089 : 0 : else if (NoOfParam == 0)
13090 : : {
13091 : : /* avoid dangling else. */
13092 : 0 : resulttok = functok;
13093 : 0 : M2MetaError_MetaErrorT0 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTSIZE} expects either one or two parameters, seen none", 87);
13094 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13095 : : }
13096 : : else
13097 : : {
13098 : : /* avoid dangling else. */
13099 : 0 : Record = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
13100 : 0 : paramtok = OperandTtok (1);
13101 : 0 : resulttok = OperandTtok (NoOfParam);
13102 : 0 : if (SymbolTable_IsRecord (Record))
13103 : : {
13104 : 0 : paramtok = OperandTtok (1);
13105 : 0 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13106 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13107 : 0 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
13108 : 0 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, Record, false);
13109 : : }
13110 : : else
13111 : : {
13112 : 0 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13113 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTSIZE} expects the first parameter to be a record type, seen {%1d}", 99, Record);
13114 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13115 : : }
13116 : : }
13117 : 3480 : M2Quads_PopN (NoOfParam+1); /* destroy the arguments and function */
13118 : 3480 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok); /* destroy the arguments and function */
13119 : 3480 : }
13120 : :
13121 : :
13122 : : /*
13123 : : BuildTBitSizeFunction - builds the pseudo function TBITSIZE
13124 : : The Stack:
13125 : :
13126 : :
13127 : : Entry Exit
13128 : :
13129 : : Ptr ->
13130 : : +----------------+
13131 : : | NoOfParam |
13132 : : |----------------|
13133 : : | Param 1 |
13134 : : |----------------|
13135 : : | Param 2 |
13136 : : |----------------|
13137 : : . .
13138 : : . .
13139 : : . .
13140 : : |----------------|
13141 : : | Param # | <- Ptr
13142 : : |----------------| +------------+
13143 : : | ProcSym | Type | | ReturnVar |
13144 : : |----------------| |------------|
13145 : :
13146 : : */
13147 : :
13148 : 12 : static void BuildTBitSizeFunction (void)
13149 : : {
13150 : 12 : unsigned int resulttok;
13151 : 12 : unsigned int paramtok;
13152 : 12 : unsigned int functok;
13153 : 12 : unsigned int NoOfParam;
13154 : 12 : unsigned int ProcSym;
13155 : 12 : unsigned int Record;
13156 : 12 : unsigned int ReturnVar;
13157 : :
13158 : 12 : M2Quads_PopT (&NoOfParam);
13159 : 12 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
13160 : 12 : functok = OperandTtok (NoOfParam);
13161 : 12 : BuildSizeCheckEnd (ProcSym); /* quadruple generation now on */
13162 : 12 : if (NoOfParam == 1) /* quadruple generation now on */
13163 : : {
13164 : 12 : paramtok = OperandTtok (1);
13165 : 12 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13166 : 12 : if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
13167 : : {
13168 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13169 : 0 : GenQuadO (resulttok, M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1), false);
13170 : : }
13171 : 12 : else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
13172 : : {
13173 : : /* avoid dangling else. */
13174 : 12 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13175 : 12 : GenQuadO (resulttok, M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1), false);
13176 : : }
13177 : : else
13178 : : {
13179 : : /* avoid dangling else. */
13180 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTBITSIZE} expects a variable as its first parameter, seen {%1d}", 96, M2Quads_OperandT (1));
13181 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13182 : : }
13183 : : }
13184 : 0 : else if (NoOfParam == 0)
13185 : : {
13186 : : /* avoid dangling else. */
13187 : 0 : resulttok = functok;
13188 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure function {%kTBITSIZE} expects either one or two parameters, seen none", 90);
13189 : 0 : ReturnVar = SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13190 : : }
13191 : : else
13192 : : {
13193 : : /* avoid dangling else. */
13194 : 0 : Record = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
13195 : 0 : paramtok = OperandTtok (1);
13196 : 0 : resulttok = OperandTtok (NoOfParam);
13197 : 0 : if (SymbolTable_IsRecord (Record))
13198 : : {
13199 : 0 : paramtok = OperandTtok (1);
13200 : 0 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13201 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13202 : 0 : GenQuad (M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1));
13203 : : }
13204 : : else
13205 : : {
13206 : 0 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13207 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTBITSIZE} expects the first parameter to be a record type, seen {%1d}", 102, Record);
13208 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13209 : : }
13210 : : }
13211 : 12 : M2Quads_PopN (NoOfParam+1); /* destroy the arguments and function */
13212 : 12 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok); /* destroy the arguments and function */
13213 : 12 : }
13214 : :
13215 : :
13216 : : /*
13217 : : ExpectingParameterType -
13218 : : */
13219 : :
13220 : 76008 : static void ExpectingParameterType (unsigned int BlockSym, unsigned int Type)
13221 : : {
13222 : 76008 : if (! (SymbolTable_IsAModula2Type (Type)))
13223 : : {
13224 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13225 : 6 : if (((Type == SymbolTable_NulSym) || (SymbolTable_IsPartialUnbounded (Type))) || (SymbolTable_IsUnknown (Type)))
13226 : : {
13227 : 0 : M2MetaError_MetaError1 ((const char *) "the type used in the formal parameter declaration in {%1Md} {%1a} is unknown", 76, BlockSym);
13228 : : }
13229 : : else
13230 : : {
13231 : 6 : M2MetaError_MetaError2 ((const char *) "the type {%1Ead} used in the formal parameter declaration in {%2Md} {%2a} was not declared as a type", 100, Type, BlockSym);
13232 : : }
13233 : : }
13234 : 76008 : }
13235 : :
13236 : :
13237 : : /*
13238 : : ExpectingVariableType -
13239 : : */
13240 : :
13241 : 76554 : static void ExpectingVariableType (unsigned int BlockSym, unsigned int Type)
13242 : : {
13243 : 76554 : if (! (SymbolTable_IsAModula2Type (Type)))
13244 : : {
13245 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13246 : 0 : if (Type == SymbolTable_NulSym)
13247 : : {
13248 : 0 : M2MetaError_MetaError1 ((const char *) "the type used during the variable declaration section in procedure {%1EMad} is unknown", 86, BlockSym);
13249 : 0 : M2MetaError_MetaError1 ((const char *) "the type used during the variable declaration section in procedure {%1Ead} is unknown", 85, BlockSym);
13250 : : }
13251 : 0 : else if ((SymbolTable_IsPartialUnbounded (Type)) || (SymbolTable_IsUnknown (Type)))
13252 : : {
13253 : : /* avoid dangling else. */
13254 : 0 : M2MetaError_MetaError2 ((const char *) "the type {%1EMad} used during variable declaration section in procedure {%2ad} is unknown", 89, Type, BlockSym);
13255 : 0 : M2MetaError_MetaError2 ((const char *) "the type {%1Ead} used during variable declaration section in procedure {%2Mad} is unknown", 89, Type, BlockSym);
13256 : : }
13257 : : else
13258 : : {
13259 : : /* avoid dangling else. */
13260 : 0 : M2MetaError_MetaError2 ((const char *) "the {%1d} {%1Ea} is not a type and therefore cannot be used to declare a variable in {%2d} {%2a}", 96, Type, BlockSym);
13261 : : }
13262 : : }
13263 : 76554 : }
13264 : :
13265 : :
13266 : : /*
13267 : : CheckVariablesAndParameterTypesInBlock - checks to make sure that block, BlockSym, has
13268 : : parameters types and variable types which are legal.
13269 : : */
13270 : :
13271 : 151867 : static void CheckVariablesAndParameterTypesInBlock (unsigned int BlockSym)
13272 : : {
13273 : 151867 : unsigned int i;
13274 : 151867 : unsigned int n;
13275 : 151867 : unsigned int ParamNo;
13276 : :
13277 : 151867 : if (SymbolTable_IsProcedure (BlockSym))
13278 : : {
13279 : 71745 : ParamNo = SymbolTable_NoOfParamAny (BlockSym);
13280 : : }
13281 : : else
13282 : : {
13283 : : ParamNo = 0;
13284 : : }
13285 : 151867 : i = 1;
13286 : 1121324 : do {
13287 : 1121324 : n = SymbolTable_GetNth (BlockSym, i);
13288 : 1121324 : if (((n != SymbolTable_NulSym) && (! (SymbolTable_IsTemporary (n)))) && ((SymbolTable_IsProcedure (BlockSym)) || (((SymbolTable_IsDefImp (BlockSym)) && ((SymbolTable_GetMainModule ()) == BlockSym)) || (SymbolTable_IsModule (BlockSym)))))
13289 : : {
13290 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13291 : 152562 : if (i <= ParamNo)
13292 : : {
13293 : : /* n is a parameter */
13294 : 76008 : ExpectingParameterType (BlockSym, SymbolTable_GetSType (n));
13295 : : }
13296 : : else
13297 : : {
13298 : : /* n is a local variable */
13299 : 76554 : ExpectingVariableType (BlockSym, SymbolTable_GetSType (n));
13300 : : }
13301 : : }
13302 : 1121324 : i += 1;
13303 : 1121324 : } while (! (n == SymbolTable_NulSym));
13304 : 151867 : }
13305 : :
13306 : :
13307 : : /*
13308 : : IsNeverAltered - returns TRUE if variable, sym, is never altered
13309 : : between quadruples: Start..End
13310 : : */
13311 : :
13312 : 30 : static bool IsNeverAltered (unsigned int sym, unsigned int Start, unsigned int End)
13313 : : {
13314 : 30 : unsigned int WriteStart;
13315 : 30 : unsigned int WriteEnd;
13316 : :
13317 : 30 : SymbolTable_GetWriteLimitQuads (sym, SymbolTable_GetMode (sym), Start, End, &WriteStart, &WriteEnd);
13318 : 30 : return (WriteStart == 0) && (WriteEnd == 0);
13319 : : /* static analysis guarentees a RETURN statement will be used before here. */
13320 : : __builtin_unreachable ();
13321 : : }
13322 : :
13323 : :
13324 : : /*
13325 : : IsConditionVariable - returns TRUE if the condition at quadruple, q, is variable.
13326 : : */
13327 : :
13328 : 24 : static bool IsConditionVariable (unsigned int q, unsigned int Start, unsigned int End)
13329 : : {
13330 : 24 : M2Quads_QuadOperator op;
13331 : 24 : unsigned int op1;
13332 : 24 : unsigned int op2;
13333 : 24 : unsigned int op3;
13334 : 24 : bool LeftFixed;
13335 : 24 : bool RightFixed;
13336 : :
13337 : 24 : M2Quads_GetQuad (q, &op, &op1, &op2, &op3);
13338 : 24 : if (op == M2Quads_GotoOp)
13339 : : {
13340 : : return false;
13341 : : }
13342 : : else
13343 : : {
13344 : 24 : LeftFixed = SymbolTable_IsConst (op1);
13345 : 24 : RightFixed = SymbolTable_IsConst (op2);
13346 : 24 : if (! LeftFixed)
13347 : : {
13348 : 24 : LeftFixed = IsNeverAltered (op1, Start, End);
13349 : : }
13350 : 24 : if (! RightFixed)
13351 : : {
13352 : 6 : RightFixed = IsNeverAltered (op2, Start, End);
13353 : : }
13354 : 24 : return ! (LeftFixed && RightFixed);
13355 : : }
13356 : : /* static analysis guarentees a RETURN statement will be used before here. */
13357 : : __builtin_unreachable ();
13358 : : }
13359 : :
13360 : :
13361 : : /*
13362 : : IsInfiniteLoop - returns TRUE if an infinite loop is found.
13363 : : Given a backwards jump at, End, it returns a BOOLEAN which depends on
13364 : : whether a jump is found to jump beyond, End. If a conditonal jump is found
13365 : : to pass over, End, the condition is tested for global variables, procedure variables and
13366 : : constants.
13367 : :
13368 : : constant - ignored
13369 : : variables - tested to see whether they are altered inside the loop
13370 : : global variable - the procedure tests to see whether it is altered as above
13371 : : but will also test to see whether this loop calls a procedure
13372 : : in which case it believes the loop NOT to be infinite
13373 : : (as this procedure call might alter the global variable)
13374 : :
13375 : : Note that this procedure can easily be fooled by the user altering variables
13376 : : with pointers.
13377 : : */
13378 : :
13379 : 24 : static bool IsInfiniteLoop (unsigned int End)
13380 : : {
13381 : 24 : bool SeenCall;
13382 : 24 : bool IsGlobal;
13383 : 24 : unsigned int Current;
13384 : 24 : unsigned int Start;
13385 : 24 : M2Quads_QuadOperator op;
13386 : 24 : unsigned int op1;
13387 : 24 : unsigned int op2;
13388 : 24 : unsigned int op3;
13389 : :
13390 : 24 : SeenCall = false;
13391 : 24 : IsGlobal = false;
13392 : 24 : M2Quads_GetQuad (End, &op, &op1, &op2, &Start);
13393 : 24 : Current = Start;
13394 : 204 : while (Current != End)
13395 : : {
13396 : 204 : M2Quads_GetQuad (Current, &op, &op1, &op2, &op3);
13397 : : /* remember that this function is only called once we have optimized the redundant gotos and conditionals */
13398 : 204 : if ((M2Quads_IsConditional (Current)) && ! IsGlobal)
13399 : : {
13400 : 24 : IsGlobal = ((SymbolTable_IsVar (op1)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op1))))) || ((SymbolTable_IsVar (op2)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op2)))));
13401 : : }
13402 : 204 : if (op == M2Quads_CallOp)
13403 : : {
13404 : 12 : SeenCall = true;
13405 : : }
13406 : 204 : if ((op == M2Quads_GotoOp) || ((M2Quads_IsConditional (Current)) && (IsConditionVariable (Current, Start, End))))
13407 : : {
13408 : 24 : if ((op3 > End) || (op3 < Start))
13409 : : {
13410 : : return false; /* may jump out of this loop, good */
13411 : : }
13412 : : }
13413 : 180 : Current = M2Quads_GetNextQuad (Current);
13414 : : }
13415 : 0 : M2Quads_GetQuad (End, &op, &op1, &op2, &op3);
13416 : 0 : if (M2Quads_IsConditional (End))
13417 : : {
13418 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13419 : 0 : if (IsConditionVariable (End, Start, End))
13420 : : {
13421 : : return false;
13422 : : }
13423 : : else
13424 : : {
13425 : 0 : if (! IsGlobal)
13426 : : {
13427 : 0 : IsGlobal = ((SymbolTable_IsVar (op1)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op1))))) || ((SymbolTable_IsVar (op2)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op2)))));
13428 : : }
13429 : : }
13430 : : }
13431 : : /* we have found a likely infinite loop if no conditional uses a global and no procedure call was seen */
13432 : 0 : return ! (IsGlobal && SeenCall);
13433 : : /* static analysis guarentees a RETURN statement will be used before here. */
13434 : : __builtin_unreachable ();
13435 : : }
13436 : :
13437 : :
13438 : : /*
13439 : : CheckVariablesInBlock - given a block, BlockSym, check whether all variables are used.
13440 : : */
13441 : :
13442 : 151867 : static void CheckVariablesInBlock (unsigned int BlockSym)
13443 : : {
13444 : 0 : CheckVariablesAndParameterTypesInBlock (BlockSym);
13445 : 0 : }
13446 : :
13447 : :
13448 : : /*
13449 : : CheckFunctionReturn - checks to see that a RETURN statement was present in a function.
13450 : : */
13451 : :
13452 : 71745 : static void CheckFunctionReturn (unsigned int ProcSym)
13453 : : {
13454 : 71745 : M2Quads_QuadOperator Op;
13455 : 71745 : unsigned int Op1;
13456 : 71745 : unsigned int Op2;
13457 : 71745 : unsigned int Op3;
13458 : 71745 : unsigned int Scope;
13459 : 71745 : unsigned int Start;
13460 : 71745 : unsigned int End;
13461 : :
13462 : 71745 : if ((SymbolTable_GetSType (ProcSym)) != SymbolTable_NulSym)
13463 : : {
13464 : : /* yes it is a function */
13465 : 12302 : SymbolTable_GetProcedureQuads (ProcSym, &Scope, &Start, &End);
13466 : 12302 : M2Quads_GetQuad (Start, &Op, &Op1, &Op2, &Op3);
13467 : 12302 : if (Start == 0)
13468 : : {
13469 : 0 : M2Error_InternalError ((const char *) "incorrect start quad", 20);
13470 : : }
13471 : 473200 : while (((Start != End) && (Op != M2Quads_ReturnValueOp)) && (Op != M2Quads_InlineOp))
13472 : : {
13473 : 460898 : Start = M2Quads_GetNextQuad (Start);
13474 : 460898 : M2Quads_GetQuad (Start, &Op, &Op1, &Op2, &Op3);
13475 : : }
13476 : 12302 : if ((Op != M2Quads_ReturnValueOp) && (Op != M2Quads_InlineOp))
13477 : : {
13478 : : /* an InlineOp can always be used to emulate a RETURN */
13479 : 6 : M2MetaError_MetaError1 ((const char *) "procedure function {%1Ea} does not RETURN a value", 49, ProcSym);
13480 : : }
13481 : : }
13482 : 71745 : }
13483 : :
13484 : :
13485 : : /*
13486 : : CheckReturnType - checks to see that the return type from currentProc is
13487 : : assignment compatible with actualType.
13488 : : */
13489 : :
13490 : 19044 : static void CheckReturnType (unsigned int tokno, unsigned int currentProc, unsigned int actualVal, unsigned int actualType)
13491 : : {
13492 : 19044 : unsigned int procType;
13493 : 19044 : DynamicStrings_String s1;
13494 : 19044 : DynamicStrings_String s2;
13495 : 19044 : NameKey_Name n1;
13496 : 19044 : NameKey_Name n2;
13497 : :
13498 : 19044 : procType = SymbolTable_GetSType (currentProc);
13499 : 19044 : if (procType == SymbolTable_NulSym)
13500 : : {
13501 : 0 : M2MetaError_MetaError1 ((const char *) "attempting to RETURN a value from procedure {%1Ea} which was not a declared as a procedure function", 99, currentProc);
13502 : : }
13503 : 19044 : else if (M2Base_AssignmentRequiresWarning (actualType, SymbolTable_GetSType (currentProc)))
13504 : : {
13505 : : /* avoid dangling else. */
13506 : 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);
13507 : : }
13508 : 19044 : else if (! (M2Base_IsAssignmentCompatible (actualType, procType)))
13509 : : {
13510 : : /* avoid dangling else. */
13511 : 0 : n1 = SymbolTable_GetSymName (actualType);
13512 : 0 : n2 = SymbolTable_GetSymName (procType);
13513 : 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));
13514 : : }
13515 : 19044 : else if ((SymbolTable_IsProcedure (actualVal)) && (! (M2Base_IsAssignmentCompatible (actualVal, procType))))
13516 : : {
13517 : : /* avoid dangling else. */
13518 : : /*
13519 : : MetaWarnings2('attempting to RETURN a value with an incompatible type {%1ad} from function {%2a} which returns {%2ta}',
13520 : : actualVal, currentProc)
13521 : :
13522 : : --fixme-- introduce MetaWarning, MetaWarning2, MetaWarning3 into M2MetaError
13523 : : */
13524 : 0 : s1 = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (actualVal)));
13525 : 0 : s2 = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (procType)));
13526 : 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)));
13527 : : }
13528 : 19044 : else if ((SymbolTable_IsProcedure (actualVal)) && (! (M2Base_IsAssignmentCompatible (actualVal, SymbolTable_GetSType (CurrentProc)))))
13529 : : {
13530 : : /* avoid dangling else. */
13531 : 0 : n1 = SymbolTable_GetSymName (actualVal);
13532 : 0 : n2 = SymbolTable_GetSymName (SymbolTable_GetSType (currentProc));
13533 : 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));
13534 : : }
13535 : : else
13536 : : {
13537 : : /* avoid dangling else. */
13538 : : /* this checks the types are compatible, not the data contents. */
13539 : 19044 : BuildRange (M2Range_InitTypesAssignmentCheck (tokno, currentProc, actualVal));
13540 : : }
13541 : 19044 : }
13542 : :
13543 : :
13544 : : /*
13545 : : IsReadOnly - a helper procedure function to detect constants.
13546 : : */
13547 : :
13548 : 237981 : static bool IsReadOnly (unsigned int sym)
13549 : : {
13550 : 237981 : return (SymbolTable_IsConst (sym)) || ((SymbolTable_IsVar (sym)) && (SymbolTable_IsVarConst (sym)));
13551 : : /* static analysis guarentees a RETURN statement will be used before here. */
13552 : : __builtin_unreachable ();
13553 : : }
13554 : :
13555 : :
13556 : : /*
13557 : : BuildDesignatorError - removes the designator from the stack and replaces
13558 : : it with an error symbol.
13559 : : */
13560 : :
13561 : 48 : static void BuildDesignatorError (const char *message_, unsigned int _message_high)
13562 : : {
13563 : 48 : unsigned int combinedTok;
13564 : 48 : unsigned int arrayTok;
13565 : 48 : unsigned int exprTok;
13566 : 48 : unsigned int e;
13567 : 48 : unsigned int d;
13568 : 48 : unsigned int error;
13569 : 48 : unsigned int Sym;
13570 : 48 : unsigned int Type;
13571 : 48 : char message[_message_high+1];
13572 : :
13573 : : /* make a local copy of each unbounded array. */
13574 : 48 : memcpy (message, message_, _message_high+1);
13575 : :
13576 : 48 : M2Quads_PopTtok (&e, &exprTok);
13577 : 48 : PopTFDtok (&Sym, &Type, &d, &arrayTok);
13578 : 48 : combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, exprTok);
13579 : 48 : error = SymbolTable_MakeError (combinedTok, NameKey_MakeKey ((const char *) message, _message_high));
13580 : 48 : PushTFDtok (error, Type, d, arrayTok);
13581 : 48 : }
13582 : :
13583 : :
13584 : : /*
13585 : : BuildStaticArray - Builds the array referencing for static arrays.
13586 : : The Stack is expected to contain:
13587 : :
13588 : :
13589 : : Entry Exit
13590 : : ===== ====
13591 : :
13592 : : Ptr ->
13593 : : +--------------+
13594 : : | e | <- Ptr
13595 : : |--------------| +------------+
13596 : : | Sym | Type | | S | T |
13597 : : |--------------| |------------|
13598 : : */
13599 : :
13600 : 41204 : static void BuildStaticArray (void)
13601 : : {
13602 : 41204 : unsigned int combinedTok;
13603 : 41204 : unsigned int indexTok;
13604 : 41204 : unsigned int arrayTok;
13605 : 41204 : unsigned int rw;
13606 : 41204 : unsigned int Dim;
13607 : 41204 : unsigned int Array;
13608 : 41204 : unsigned int Index;
13609 : 41204 : unsigned int BackEndType;
13610 : 41204 : unsigned int Type;
13611 : 41204 : unsigned int Adr;
13612 : :
13613 : 41204 : Index = static_cast<unsigned int> (M2Quads_OperandT (1));
13614 : 41204 : indexTok = OperandTtok (1);
13615 : 41204 : Array = static_cast<unsigned int> (M2Quads_OperandT (2));
13616 : 41204 : arrayTok = OperandTtok (2);
13617 : 41204 : Type = SymbolTable_SkipType (M2Quads_OperandF (2));
13618 : 41204 : rw = static_cast<unsigned int> (OperandMergeRW (2));
13619 : 41204 : M2Debug_Assert (SymbolTable_IsLegal (rw));
13620 : 41204 : Dim = static_cast<unsigned int> (OperandD (2));
13621 : 41204 : Dim += 1;
13622 : 41204 : if ((SymbolTable_GetMode (Index)) == SymbolTable_LeftValue)
13623 : : {
13624 : 186 : Index = MakeRightValue (indexTok, Index, SymbolTable_GetSType (Index));
13625 : : }
13626 : 41198 : BuildRange (M2Range_InitStaticArraySubscriptRangeCheck (SymbolTable_GetArraySubscript (Type), Index, Dim));
13627 : : /* now make Adr point to the address of the indexed element */
13628 : 41198 : combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, indexTok);
13629 : 41198 : Adr = SymbolTable_MakeTemporary (combinedTok, SymbolTable_LeftValue);
13630 : 41198 : if (SymbolTable_IsVar (Array))
13631 : : {
13632 : : /* BuildDesignatorArray may have detected des is a constant. */
13633 : 41198 : SymbolTable_PutVarConst (Adr, SymbolTable_IsVarConst (Array));
13634 : : }
13635 : 41198 : SymbolTable_PutVarArrayRef (Adr, true);
13636 : : /*
13637 : : From now on it must reference the array element by its lvalue
13638 : : - so we create the type of the referenced entity
13639 : : */
13640 : 41198 : BackEndType = SymbolTable_MakePointer (combinedTok, NameKey_NulName);
13641 : 41198 : SymbolTable_PutPointer (BackEndType, SymbolTable_GetDType (Type));
13642 : : /* PutVar(Adr, BackEndType) ; */
13643 : 41198 : SymbolTable_PutLeftValueFrontBackType (Adr, SymbolTable_GetDType (Type), BackEndType);
13644 : 82396 : GenQuadO (combinedTok, M2Quads_ArrayOp, Adr, Index, Array, true);
13645 : 41198 : M2Quads_PopN (2); /* remove all parameters to this procedure */
13646 : 41198 : PushTFDrwtok (Adr, SymbolTable_GetSType (Adr), Dim, rw, combinedTok); /* remove all parameters to this procedure */
13647 : 41198 : }
13648 : :
13649 : :
13650 : : /*
13651 : : calculateMultipicand - generates quadruples which calculate the
13652 : : multiplicand for the array at dimension, dim.
13653 : : */
13654 : :
13655 : 9096 : static unsigned int calculateMultipicand (unsigned int tok, unsigned int arraySym, unsigned int arrayType, unsigned int dim)
13656 : : {
13657 : 9096 : unsigned int ti;
13658 : 9096 : unsigned int tj;
13659 : 9096 : unsigned int tk;
13660 : 9096 : unsigned int tl;
13661 : :
13662 : 9096 : if (dim == (SymbolTable_GetDimension (arrayType)))
13663 : : {
13664 : : /* ti has no type since constant */
13665 : 8124 : ti = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
13666 : 8124 : SymbolTable_PutVar (ti, M2Base_Cardinal);
13667 : 8124 : GenQuadO (tok, M2Quads_ElementSizeOp, ti, arrayType, 1, true);
13668 : : }
13669 : : else
13670 : : {
13671 : 972 : dim += 1;
13672 : 972 : tk = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
13673 : 972 : SymbolTable_PutVar (tk, M2Base_Cardinal);
13674 : 972 : GenHigh (tok, tk, dim, arraySym);
13675 : 972 : tl = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
13676 : 972 : SymbolTable_PutVar (tl, M2Base_Cardinal);
13677 : 972 : GenQuadOtok (tok, M2Quads_AddOp, tl, tk, SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal), true, tok, tok, tok);
13678 : 972 : tj = calculateMultipicand (tok, arraySym, arrayType, dim);
13679 : 972 : ti = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
13680 : 972 : SymbolTable_PutVar (ti, M2Base_Cardinal);
13681 : 972 : GenQuadO (tok, M2Quads_MultOp, ti, tj, tl, true);
13682 : : }
13683 : 9096 : return ti;
13684 : : /* static analysis guarentees a RETURN statement will be used before here. */
13685 : : __builtin_unreachable ();
13686 : : }
13687 : :
13688 : :
13689 : : /*
13690 : : ConvertToAddress - convert sym to an address.
13691 : : */
13692 : :
13693 : 7746 : static unsigned int ConvertToAddress (unsigned int tokpos, unsigned int sym)
13694 : : {
13695 : 7746 : unsigned int adr;
13696 : :
13697 : 7746 : if ((SymbolTable_GetSType (sym)) == M2System_Address)
13698 : : {
13699 : : return sym;
13700 : : }
13701 : : else
13702 : : {
13703 : 7734 : M2Quads_PushTF (SymbolTable_RequestSym (tokpos, NameKey_MakeKey ((const char *) "CONVERT", 7)), static_cast<unsigned int> (SymbolTable_NulSym));
13704 : 7734 : M2Quads_PushT (M2System_Address);
13705 : 7734 : M2Quads_PushTtok (sym, tokpos);
13706 : 7734 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
13707 : 7734 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
13708 : 7734 : M2Quads_PopT (&adr);
13709 : 7734 : return adr;
13710 : : }
13711 : : /* static analysis guarentees a RETURN statement will be used before here. */
13712 : : __builtin_unreachable ();
13713 : : }
13714 : :
13715 : :
13716 : : /*
13717 : : BuildDynamicArray - Builds the array referencing for dynamic arrays.
13718 : : The Stack is expected to contain:
13719 : :
13720 : :
13721 : : Entry Exit
13722 : : ===== ====
13723 : :
13724 : : Ptr ->
13725 : : +-----------------------+
13726 : : | Index | <- Ptr
13727 : : |-----------------------| +---------------------------+
13728 : : | ArraySym | Type | Dim | | S | T | ArraySym | Dim+1 |
13729 : : |-----------------------| |---------------------------|
13730 : :
13731 : :
13732 : : if Dim=1
13733 : : then
13734 : : S := base of ArraySym + TSIZE(Type)*Index
13735 : : else
13736 : : S := S + TSIZE(Type)*Index
13737 : : fi
13738 : : */
13739 : :
13740 : 7662 : static void BuildDynamicArray (void)
13741 : : {
13742 : 7662 : unsigned int combinedTok;
13743 : 7662 : unsigned int arrayTok;
13744 : 7662 : unsigned int indexTok;
13745 : 7662 : unsigned int Sym;
13746 : 7662 : unsigned int idx;
13747 : 7662 : unsigned int Type;
13748 : 7662 : unsigned int Adr;
13749 : 7662 : unsigned int ArraySym;
13750 : 7662 : unsigned int BackEndType;
13751 : 7662 : unsigned int UnboundedType;
13752 : 7662 : unsigned int PtrToBase;
13753 : 7662 : unsigned int Base;
13754 : 7662 : unsigned int Dim;
13755 : 7662 : unsigned int rw;
13756 : 7662 : unsigned int ti;
13757 : 7662 : unsigned int tj;
13758 : 7662 : unsigned int tk;
13759 : 7662 : unsigned int tka;
13760 : :
13761 : 7662 : M2Quads_DisplayStack ();
13762 : 7662 : Sym = static_cast<unsigned int> (M2Quads_OperandT (2));
13763 : 7662 : Type = SymbolTable_SkipType (M2Quads_OperandF (2));
13764 : 7662 : arrayTok = static_cast<unsigned int> (M2Quads_OperandTok (2));
13765 : 7662 : indexTok = static_cast<unsigned int> (M2Quads_OperandTok (1));
13766 : 7662 : combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, indexTok);
13767 : 7662 : Dim = static_cast<unsigned int> (OperandD (2));
13768 : 7662 : rw = static_cast<unsigned int> (OperandMergeRW (2));
13769 : 7662 : M2Debug_Assert (SymbolTable_IsLegal (rw));
13770 : 7662 : Dim += 1;
13771 : 7662 : if (Dim == 1)
13772 : : {
13773 : : /*
13774 : : Base has type address since
13775 : : BuildDesignatorRecord references by address.
13776 : :
13777 : : Build a record for retrieving the address of dynamic array.
13778 : : BuildDesignatorRecord will generate the required quadruples,
13779 : : therefore build sets up the stack for BuildDesignatorRecord
13780 : : which will generate the quads to access the record.
13781 : : */
13782 : 7524 : ArraySym = Sym;
13783 : 7524 : UnboundedType = SymbolTable_GetUnboundedRecordType (SymbolTable_GetSType (Sym));
13784 : 7524 : PushTFrwtok (Sym, UnboundedType, rw, arrayTok);
13785 : 7524 : M2Quads_PushTF (SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (Sym)), SymbolTable_GetSType (SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (Sym))));
13786 : 7524 : M2Quads_PushT (static_cast<unsigned int> (1)); /* One record field to dereference */
13787 : 7524 : M2Quads_BuildDesignatorRecord (combinedTok); /* One record field to dereference */
13788 : 7524 : M2Quads_PopT (&PtrToBase);
13789 : 7524 : M2Quads_DisplayStack ();
13790 : : /* Now actually copy Unbounded.ArrayAddress into base */
13791 : 7524 : if ((SymbolTable_GetMode (PtrToBase)) == SymbolTable_LeftValue)
13792 : : {
13793 : 0 : Base = SymbolTable_MakeTemporary (arrayTok, SymbolTable_RightValue);
13794 : 0 : SymbolTable_PutVar (Base, M2System_Address); /* has type ADDRESS */
13795 : 0 : CheckPointerThroughNil (arrayTok, PtrToBase); /* has type ADDRESS */
13796 : 0 : GenQuad (M2Quads_IndrXOp, Base, M2System_Address, PtrToBase); /* Base = *PtrToBase */
13797 : : }
13798 : : else
13799 : : {
13800 : 7524 : M2Debug_Assert ((SymbolTable_GetMode (PtrToBase)) != SymbolTable_ImmediateValue);
13801 : 7524 : Base = PtrToBase;
13802 : : }
13803 : : }
13804 : : else
13805 : : {
13806 : : /* Base already calculated previously and pushed to stack */
13807 : 138 : UnboundedType = SymbolTable_SkipType (M2Quads_OperandF (2));
13808 : 138 : Base = Sym;
13809 : 138 : ArraySym = static_cast<unsigned int> (M2Quads_OperandA (2));
13810 : : }
13811 : 7662 : M2Debug_Assert ((SymbolTable_GetSType (Sym)) == Type);
13812 : 7662 : ti = calculateMultipicand (indexTok, Sym, Type, Dim);
13813 : 7662 : idx = static_cast<unsigned int> (M2Quads_OperandT (1));
13814 : 7662 : if ((SymbolTable_IsConst (idx)) && (SymbolTable_IsConst (ti)))
13815 : : {
13816 : : /* tj has no type since constant */
13817 : 376 : tj = SymbolTable_MakeTemporary (indexTok, SymbolTable_ImmediateValue);
13818 : 376 : tk = SymbolTable_MakeTemporary (indexTok, SymbolTable_ImmediateValue);
13819 : 376 : SymbolTable_PutVar (tj, M2Base_Cardinal);
13820 : 376 : SymbolTable_PutVar (tk, M2Base_Cardinal);
13821 : : }
13822 : : else
13823 : : {
13824 : : /* tj has Cardinal type since we have multiplied array indices */
13825 : 7286 : tj = SymbolTable_MakeTemporary (indexTok, SymbolTable_RightValue);
13826 : 7286 : if ((SymbolTable_GetSType (idx)) != M2Base_Cardinal)
13827 : : {
13828 : 756 : M2Quads_PushTF (SymbolTable_RequestSym (indexTok, NameKey_MakeKey ((const char *) "CONVERT", 7)), static_cast<unsigned int> (SymbolTable_NulSym));
13829 : 756 : M2Quads_PushT (M2Base_Cardinal);
13830 : 756 : M2Quads_PushTtok (idx, indexTok);
13831 : 756 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
13832 : 756 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
13833 : 756 : M2Quads_PopT (&idx);
13834 : : }
13835 : 7286 : SymbolTable_PutVar (tj, M2Base_Cardinal);
13836 : 7286 : tk = SymbolTable_MakeTemporary (indexTok, SymbolTable_RightValue);
13837 : 7286 : SymbolTable_PutVar (tk, M2Base_Cardinal);
13838 : : }
13839 : 7662 : BuildRange (M2Range_InitDynamicArraySubscriptRangeCheck (ArraySym, idx, Dim));
13840 : 7662 : M2Quads_PushTtok (tj, indexTok);
13841 : 7662 : M2Quads_PushTtok (idx, indexTok);
13842 : 7662 : BuildAssignmentWithoutBounds (indexTok, false, true);
13843 : 15324 : GenQuad (M2Quads_MultOp, tk, ti, tj);
13844 : 15324 : Adr = SymbolTable_MakeTemporary (combinedTok, SymbolTable_LeftValue);
13845 : 7662 : SymbolTable_PutVarArrayRef (Adr, true);
13846 : : /*
13847 : : Ok must reference by address
13848 : : - but we contain the type of the referenced entity
13849 : : */
13850 : 7662 : BackEndType = SymbolTable_MakePointer (combinedTok, NameKey_NulName);
13851 : 7662 : SymbolTable_PutPointer (BackEndType, SymbolTable_GetSType (Type));
13852 : : /* Create a temporary pointer for addition. */
13853 : 7662 : tka = ConvertToAddress (combinedTok, tk);
13854 : 7662 : if (Dim == (SymbolTable_GetDimension (Type)))
13855 : : {
13856 : 7344 : SymbolTable_PutLeftValueFrontBackType (Adr, SymbolTable_GetSType (Type), BackEndType);
13857 : 14688 : GenQuadOtok (combinedTok, M2Quads_AddOp, Adr, Base, tka, false, combinedTok, combinedTok, combinedTok);
13858 : 7344 : M2Quads_PopN (2);
13859 : 7344 : PushTFADrwtok (Adr, SymbolTable_GetSType (Adr), ArraySym, Dim, rw, combinedTok);
13860 : : }
13861 : : else
13862 : : {
13863 : : /* more to index */
13864 : 318 : SymbolTable_PutLeftValueFrontBackType (Adr, Type, BackEndType);
13865 : 636 : GenQuadOtok (combinedTok, M2Quads_AddOp, Adr, Base, tka, false, combinedTok, combinedTok, combinedTok);
13866 : 318 : M2Quads_PopN (2);
13867 : 318 : PushTFADrwtok (Adr, SymbolTable_GetSType (Adr), ArraySym, Dim, rw, combinedTok);
13868 : : }
13869 : 7662 : }
13870 : :
13871 : :
13872 : : /*
13873 : : DebugLocation -
13874 : : */
13875 : :
13876 : 46434 : static void DebugLocation (unsigned int tok, const char *message_, unsigned int _message_high)
13877 : : {
13878 : 46434 : char message[_message_high+1];
13879 : :
13880 : : /* make a local copy of each unbounded array. */
13881 : 46434 : memcpy (message, message_, _message_high+1);
13882 : :
13883 : 46434 : if (DebugTokPos)
13884 : : {
13885 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) message, _message_high), tok);
13886 : : }
13887 : 46434 : }
13888 : :
13889 : :
13890 : : /*
13891 : : PushWith - pushes sym and type onto the with stack. It checks for
13892 : : previous declaration of this record type.
13893 : : */
13894 : :
13895 : 6030 : static void PushWith (unsigned int Sym, unsigned int Type, unsigned int Ref, unsigned int Tok)
13896 : : {
13897 : 6030 : unsigned int i;
13898 : 6030 : unsigned int n;
13899 : 6030 : M2Quads_WithFrame f;
13900 : :
13901 : 6030 : if (M2Options_Pedantic)
13902 : : {
13903 : 0 : n = M2StackAddress_NoOfItemsInStackAddress (WithStack);
13904 : 0 : i = 1; /* Top of the stack. */
13905 : : /* Search for other declarations of the with using Type. */
13906 : 0 : while (i <= n)
13907 : : {
13908 : 0 : f = static_cast<M2Quads_WithFrame> (M2StackAddress_PeepAddress (WithStack, i));
13909 : 0 : if (f->RecordSym == Type)
13910 : : {
13911 : 0 : M2MetaError_MetaErrorT1 (Tok, (const char *) "cannot have nested {%kWITH} statements referencing the same {%kRECORD} {%1Ead}", 78, Sym);
13912 : 0 : M2MetaError_MetaErrorT1 (f->RecordTokPos, (const char *) "cannot have nested {%kWITH} statements referencing the same {%kRECORD} {%1Ead}", 78, f->RecordSym);
13913 : : }
13914 : 0 : i += 1;
13915 : : }
13916 : : }
13917 : 6030 : Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T4));
13918 : 6030 : f->RecordSym = Sym;
13919 : 6030 : f->RecordType = Type;
13920 : 6030 : f->RecordRef = Ref;
13921 : 6030 : f->rw = Sym;
13922 : 6030 : f->RecordTokPos = Tok;
13923 : 6030 : M2StackAddress_PushAddress (WithStack, reinterpret_cast <void *> (f));
13924 : 6030 : }
13925 : :
13926 : 6030 : static void PopWith (void)
13927 : : {
13928 : 6030 : M2Quads_WithFrame f;
13929 : :
13930 : 6030 : f = static_cast<M2Quads_WithFrame> (M2StackAddress_PopAddress (WithStack));
13931 : 6030 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T4));
13932 : 6030 : }
13933 : :
13934 : :
13935 : : /*
13936 : : BuildAccessWithField - similar to BuildDesignatorRecord except it
13937 : : does not perform the address operation.
13938 : : The address will have been computed at the
13939 : : beginning of the WITH statement.
13940 : : It also stops the GenQuad procedure from examining the
13941 : : with stack.
13942 : :
13943 : : The Stack
13944 : :
13945 : : Entry
13946 : :
13947 : : Ptr ->
13948 : : +--------------+
13949 : : | Field | Type1| <- Ptr
13950 : : |-------|------| +-------------+
13951 : : | Adr | Type2| | Sym | Type1|
13952 : : |--------------| |-------------|
13953 : : */
13954 : :
13955 : 30612 : static void BuildAccessWithField (void)
13956 : : {
13957 : 30612 : unsigned int rectok;
13958 : 30612 : unsigned int fieldtok;
13959 : 30612 : bool OldSuppressWith;
13960 : 30612 : unsigned int rw;
13961 : 30612 : unsigned int Field;
13962 : 30612 : unsigned int FieldType;
13963 : 30612 : unsigned int Record;
13964 : 30612 : unsigned int RecordType;
13965 : 30612 : unsigned int Ref;
13966 : :
13967 : 30612 : OldSuppressWith = SuppressWith;
13968 : 30612 : SuppressWith = true;
13969 : : /*
13970 : : now the WITH cannot look at the stack of outstanding WITH records.
13971 : : */
13972 : 30612 : M2Quads_PopTFtok (&Field, &FieldType, &fieldtok);
13973 : 30612 : PopTFrwtok (&Record, &RecordType, &rw, &rectok);
13974 : 30612 : Ref = SymbolTable_MakeComponentRef (SymbolTable_MakeComponentRecord (fieldtok, SymbolTable_RightValue, Record), Field);
13975 : 30612 : SymbolTable_PutVarConst (Ref, IsReadOnly (Record));
13976 : 61224 : GenQuadO (fieldtok, M2Quads_RecordFieldOp, Ref, Record, Field, true);
13977 : 30612 : PushTFrwtok (Ref, FieldType, rw, fieldtok);
13978 : 30612 : SuppressWith = OldSuppressWith;
13979 : 30612 : }
13980 : :
13981 : :
13982 : : /*
13983 : : PushConstructor -
13984 : : */
13985 : :
13986 : 31716 : static void PushConstructor (unsigned int sym)
13987 : : {
13988 : 31716 : M2Quads_ConstructorFrame c;
13989 : :
13990 : 31716 : Storage_ALLOCATE ((void **) &c, sizeof (M2Quads__T1));
13991 : 31716 : c->type = SymbolTable_SkipType (sym);
13992 : 31716 : c->index = 1;
13993 : 31716 : M2StackAddress_PushAddress (ConstructorStack, reinterpret_cast <void *> (c));
13994 : 31716 : }
13995 : :
13996 : :
13997 : : /*
13998 : : AddFieldTo - adds field, e, to, value.
13999 : : */
14000 : :
14001 : 24278 : static unsigned int AddFieldTo (unsigned int value, unsigned int e)
14002 : : {
14003 : 24278 : if (SymbolTable_IsSet (SymbolTable_GetDType (value)))
14004 : : {
14005 : 10674 : SymbolTable_PutConstSet (value);
14006 : 10674 : M2Quads_PushT (value);
14007 : 10674 : M2Quads_PushT (e);
14008 : 10674 : M2Quads_BuildInclBit ();
14009 : 10674 : M2Quads_PopT (&value);
14010 : : }
14011 : : else
14012 : : {
14013 : 13604 : SymbolTable_PushValue (value);
14014 : 13604 : M2ALU_AddField (M2LexBuf_GetTokenNo (), e);
14015 : 13604 : SymbolTable_PopValue (value);
14016 : : }
14017 : 24278 : return value;
14018 : : /* static analysis guarentees a RETURN statement will be used before here. */
14019 : : __builtin_unreachable ();
14020 : : }
14021 : :
14022 : :
14023 : : /*
14024 : : CheckLogicalOperator - returns a logical operator if the operands imply
14025 : : a logical operation should be performed.
14026 : : */
14027 : :
14028 : 57031 : static NameKey_Name CheckLogicalOperator (NameKey_Name Tok, unsigned int left, unsigned int lefttype)
14029 : : {
14030 : 57031 : if ((((Tok == M2Reserved_PlusTok) || (Tok == M2Reserved_TimesTok)) || (Tok == M2Reserved_DivideTok)) || (Tok == M2Reserved_MinusTok))
14031 : : {
14032 : : /* --fixme-- when we add complex arithmetic, we must check constructor is not a complex constant. */
14033 : 48738 : if ((((lefttype != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_SkipType (lefttype)))) || (SymbolTable_IsConstSet (left))) || (SymbolTable_IsConstructor (left)))
14034 : : {
14035 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
14036 : 1266 : if (Tok == M2Reserved_PlusTok)
14037 : : {
14038 : 1128 : return LogicalOrTok;
14039 : : }
14040 : 138 : else if (Tok == M2Reserved_DivideTok)
14041 : : {
14042 : : /* avoid dangling else. */
14043 : 12 : return LogicalXorTok;
14044 : : }
14045 : 126 : else if (Tok == M2Reserved_TimesTok)
14046 : : {
14047 : : /* avoid dangling else. */
14048 : 60 : return LogicalAndTok;
14049 : : }
14050 : 66 : else if (Tok == M2Reserved_MinusTok)
14051 : : {
14052 : : /* avoid dangling else. */
14053 : 66 : return LogicalDifferenceTok;
14054 : : }
14055 : : }
14056 : : }
14057 : : return Tok;
14058 : : /* static analysis guarentees a RETURN statement will be used before here. */
14059 : : __builtin_unreachable ();
14060 : : }
14061 : :
14062 : :
14063 : : /*
14064 : : CheckDivModRem - initiates calls to check the divisor for DIV, MOD, REM
14065 : : expressions.
14066 : : */
14067 : :
14068 : 56467 : static void CheckDivModRem (unsigned int TokPos, NameKey_Name tok, unsigned int d, unsigned int e)
14069 : : {
14070 : 56467 : if (tok == M2Reserved_DivTok)
14071 : : {
14072 : 6079 : BuildRange (M2Range_InitWholeZeroDivisionCheck (TokPos, d, e));
14073 : : }
14074 : 50388 : else if (tok == M2Reserved_ModTok)
14075 : : {
14076 : : /* avoid dangling else. */
14077 : 2118 : BuildRange (M2Range_InitWholeZeroDivisionCheck (TokPos, d, e));
14078 : : }
14079 : 48270 : else if (tok == M2Reserved_RemTok)
14080 : : {
14081 : : /* avoid dangling else. */
14082 : 96 : BuildRange (M2Range_InitWholeZeroRemainderCheck (TokPos, d, e));
14083 : : }
14084 : 56467 : }
14085 : :
14086 : :
14087 : : /*
14088 : : doConvert - convert, sym, to a new symbol with, type.
14089 : : Return the new symbol.
14090 : : */
14091 : :
14092 : 4308 : static unsigned int doConvert (unsigned int type, unsigned int sym)
14093 : : {
14094 : 4308 : if ((SymbolTable_GetSType (sym)) != type)
14095 : : {
14096 : 670 : M2Quads_PushTF (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym));
14097 : 670 : M2Quads_PushT (type);
14098 : 670 : M2Quads_PushT (sym);
14099 : 670 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
14100 : 670 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
14101 : 664 : M2Quads_PopT (&sym);
14102 : : }
14103 : 4302 : return sym;
14104 : : /* static analysis guarentees a RETURN statement will be used before here. */
14105 : : __builtin_unreachable ();
14106 : : }
14107 : :
14108 : :
14109 : : /*
14110 : : doBuildBinaryOp - build the binary op, with or without type
14111 : : checking.
14112 : : */
14113 : :
14114 : 68705 : static void doBuildBinaryOp (bool checkTypes, bool checkOverflow)
14115 : : {
14116 : 68705 : DynamicStrings_String s;
14117 : 68705 : NameKey_Name NewOp;
14118 : 68705 : NameKey_Name Operator;
14119 : 68705 : unsigned int OperatorPos;
14120 : 68705 : unsigned int OldPos;
14121 : 68705 : unsigned int leftrw;
14122 : 68705 : unsigned int rightrw;
14123 : 68705 : unsigned int t1;
14124 : 68705 : unsigned int f1;
14125 : 68705 : unsigned int t2;
14126 : 68705 : unsigned int f2;
14127 : 68705 : unsigned int lefttype;
14128 : 68705 : unsigned int righttype;
14129 : 68705 : unsigned int left;
14130 : 68705 : unsigned int right;
14131 : 68705 : unsigned int leftpos;
14132 : 68705 : unsigned int rightpos;
14133 : 68705 : unsigned int value;
14134 : :
14135 : 68705 : Operator = static_cast<NameKey_Name> (M2Quads_OperandT (2));
14136 : 68705 : if (Operator == M2Reserved_OrTok)
14137 : : {
14138 : 3394 : CheckBooleanId ();
14139 : 3394 : PopBooltok (&t1, &f1, &rightpos);
14140 : 3394 : M2Quads_PopTtok (&Operator, &OperatorPos);
14141 : 3394 : PopBooltok (&t2, &f2, &leftpos);
14142 : 3394 : M2Debug_Assert (f2 == 0);
14143 : 3394 : OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
14144 : 3394 : PushBooltok (Merge (t1, t2), f1, OperatorPos);
14145 : : }
14146 : 65311 : else if ((Operator == M2Reserved_AndTok) || (Operator == M2Reserved_AmbersandTok))
14147 : : {
14148 : : /* avoid dangling else. */
14149 : 8280 : CheckBooleanId ();
14150 : 8280 : PopBooltok (&t1, &f1, &rightpos);
14151 : 8280 : M2Quads_PopTtok (&Operator, &OperatorPos);
14152 : 8280 : PopBooltok (&t2, &f2, &leftpos);
14153 : 8280 : M2Debug_Assert (t2 == 0);
14154 : 8280 : OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
14155 : 8280 : PushBooltok (t1, Merge (f1, f2), OperatorPos);
14156 : : }
14157 : : else
14158 : : {
14159 : : /* avoid dangling else. */
14160 : 57031 : PopTFrwtok (&right, &righttype, &rightrw, &rightpos);
14161 : 57031 : M2Quads_PopTtok (&Operator, &OperatorPos);
14162 : 57031 : PopTFrwtok (&left, &lefttype, &leftrw, &leftpos);
14163 : 57031 : MarkAsRead (rightrw);
14164 : 57031 : MarkAsRead (leftrw);
14165 : 57031 : NewOp = CheckLogicalOperator (Operator, left, lefttype); /* right, righttype, */
14166 : 57031 : if (NewOp == Operator)
14167 : : {
14168 : : /* avoid dangling else. */
14169 : : /*
14170 : : BinaryOps and UnaryOps only work with immediate and
14171 : : offset addressing. This is fine for calculating
14172 : : array and record offsets but we need to get the real
14173 : : values to perform normal arithmetic. Not address
14174 : : arithmetic.
14175 : :
14176 : : However the set operators will dereference LValues
14177 : : (to optimize large set arithemetic)
14178 : : */
14179 : 55765 : if ((SymbolTable_GetMode (right)) == SymbolTable_LeftValue)
14180 : : {
14181 : 286 : value = SymbolTable_MakeTemporary (rightpos, SymbolTable_RightValue);
14182 : 286 : SymbolTable_PutVar (value, righttype);
14183 : 286 : CheckPointerThroughNil (rightpos, right);
14184 : 286 : doIndrX (rightpos, value, right);
14185 : 286 : right = value;
14186 : : }
14187 : 55765 : if ((SymbolTable_GetMode (left)) == SymbolTable_LeftValue)
14188 : : {
14189 : 652 : value = SymbolTable_MakeTemporary (leftpos, SymbolTable_RightValue);
14190 : 652 : SymbolTable_PutVar (value, lefttype);
14191 : 652 : CheckPointerThroughNil (leftpos, left);
14192 : 652 : doIndrX (leftpos, value, left);
14193 : 652 : left = value;
14194 : : }
14195 : : }
14196 : : /* CheckForGenericNulSet(e1, e2, t1, t2) */
14197 : 57031 : OldPos = OperatorPos;
14198 : 57031 : OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
14199 : 57031 : if (((Operator == M2Reserved_PlusTok) && (SymbolTable_IsConstString (left))) && (SymbolTable_IsConstString (right)))
14200 : : {
14201 : 456 : value = SymbolTable_MakeConstString (OperatorPos, NameKey_NulName);
14202 : 456 : SymbolTable_PutConstStringKnown (OperatorPos, value, NameKey_NulName, false, false);
14203 : 456 : GenQuadOtok (OperatorPos, MakeOp (M2Reserved_PlusTok), value, left, right, false, OperatorPos, leftpos, rightpos);
14204 : : }
14205 : : else
14206 : : {
14207 : 56575 : if (checkTypes)
14208 : : {
14209 : 39613 : BuildRange (M2Range_InitTypesExpressionCheck (OperatorPos, left, right, false, false));
14210 : : }
14211 : 92879 : value = SymbolTable_MakeTemporaryFromExpressions (OperatorPos, right, left, AreConstant ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right))));
14212 : 56467 : CheckDivModRem (OperatorPos, NewOp, value, right);
14213 : 56467 : if (DebugTokPos)
14214 : : {
14215 : : s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (M2LexBuf_GetTokenName (Operator)));
14216 : : M2Error_WarnStringAt (s, OldPos);
14217 : : s = DynamicStrings_InitString ((const char *) "left", 4);
14218 : : M2Error_WarnStringAt (s, leftpos);
14219 : : s = DynamicStrings_InitString ((const char *) "right", 5);
14220 : : M2Error_WarnStringAt (s, rightpos);
14221 : : s = DynamicStrings_InitString ((const char *) "caret", 5);
14222 : : M2Error_WarnStringAt (s, OldPos);
14223 : : s = DynamicStrings_InitString ((const char *) "combined", 8);
14224 : : M2Error_WarnStringAt (s, OperatorPos);
14225 : : }
14226 : : /* MetaErrorT1 (GetDeclaredMod (t), 'in binary with a {%1a}', t) */
14227 : 56467 : GenQuadOtok (OperatorPos, MakeOp (NewOp), value, left, right, checkOverflow, OperatorPos, leftpos, rightpos);
14228 : : }
14229 : 56923 : M2Quads_PushTFtok (value, SymbolTable_GetSType (value), OperatorPos);
14230 : : }
14231 : 68597 : }
14232 : :
14233 : :
14234 : : /*
14235 : : AreConstant - returns immediate addressing mode if b is true else
14236 : : offset mode is returned. b determines whether the
14237 : : operands are all constant - in which case we can use
14238 : : a constant temporary variable.
14239 : : */
14240 : :
14241 : 122049 : static SymbolTable_ModeOfAddr AreConstant (bool b)
14242 : : {
14243 : 122049 : if (b)
14244 : : {
14245 : : return SymbolTable_ImmediateValue;
14246 : : }
14247 : : else
14248 : : {
14249 : 46828 : return SymbolTable_RightValue;
14250 : : }
14251 : : /* static analysis guarentees a RETURN statement will be used before here. */
14252 : : __builtin_unreachable ();
14253 : : }
14254 : :
14255 : :
14256 : : /*
14257 : : ConvertBooleanToVariable - converts a BoolStack(i) from a Boolean True|False
14258 : : exit pair into a variable containing the value TRUE or
14259 : : FALSE. The parameter i is relative to the top
14260 : : of the stack.
14261 : : */
14262 : :
14263 : 6498 : static void ConvertBooleanToVariable (unsigned int tok, unsigned int i)
14264 : : {
14265 : 6498 : unsigned int Des;
14266 : 6498 : M2Quads_BoolFrame f;
14267 : :
14268 : 6498 : M2Debug_Assert (IsBoolean (i));
14269 : : /* We need to convert the boolean top of stack into a variable or
14270 : : constant boolean. */
14271 : 12996 : Des = SymbolTable_MakeTemporary (tok, AreConstant (M2Quads_IsInConstExpression ()));
14272 : 6498 : SymbolTable_PutVar (Des, M2Base_Boolean);
14273 : 6498 : SymbolTable_PutVarConditional (Des, true);
14274 : 6498 : M2Quads_PushTtok (Des, tok); /* we have just increased the stack so we must use i+1 */
14275 : 6498 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, i+1)); /* we have just increased the stack so we must use i+1 */
14276 : 12996 : PushBool (f->TrueExit, f->FalseExit);
14277 : 6498 : BuildAssignmentWithoutBounds (tok, false, true);
14278 : : /* Restored stack after the BuildAssign... above. */
14279 : 6498 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, i));
14280 : 6498 : f->TrueExit = Des; /* Alter Stack(i) to contain the variable. */
14281 : 6498 : f->FalseExit = M2Base_Boolean; /* Alter Stack(i) to contain the variable. */
14282 : 6498 : f->BooleanOp = false; /* No longer a Boolean True|False pair. */
14283 : 6498 : f->Unbounded = SymbolTable_NulSym; /* No longer a Boolean True|False pair. */
14284 : 6498 : f->Dimension = 0;
14285 : 6498 : f->ReadWrite = SymbolTable_NulSym;
14286 : 6498 : f->tokenno = tok;
14287 : 6498 : f->Annotation = DynamicStrings_KillString (f->Annotation);
14288 : 6498 : f->Annotation = DynamicStrings_InitString ((const char *) "%1s(%1d)|%2s(%2d)||boolean var|type", 35);
14289 : 6498 : }
14290 : :
14291 : :
14292 : : /*
14293 : : DumpQuadSummary -
14294 : : */
14295 : :
14296 : 0 : static void DumpQuadSummary (unsigned int quad)
14297 : : {
14298 : 0 : M2Quads_QuadFrame f;
14299 : :
14300 : 0 : if (quad != 0)
14301 : : {
14302 : 0 : f = GetQF (quad);
14303 : 0 : M2Printf_printf2 ((const char *) "%d op3 = %d\\n", 14, (const unsigned char *) &quad, (sizeof (quad)-1), (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
14304 : : }
14305 : 0 : }
14306 : :
14307 : :
14308 : : /*
14309 : : BuildRelOpFromBoolean - builds a relational operator sequence of quadruples
14310 : : instead of using a temporary boolean variable.
14311 : : This function can only be used when we perform
14312 : : the following translation:
14313 : :
14314 : : (a=b) # (c=d) alternatively (a=b) = (c=d)
14315 : : ^ ^
14316 : :
14317 : : it only allows # = to be used as >= <= > < all
14318 : : assume a particular value for TRUE and FALSE.
14319 : : (In which case the user should specify ORD)
14320 : :
14321 : :
14322 : : before
14323 : :
14324 : : q if r1 op1 op2 t2
14325 : : q+1 Goto f2
14326 : : ...
14327 : : q+n if r2 op3 op4 t1
14328 : : q+n+1 Goto f1
14329 : :
14330 : : after (in case of =)
14331 : :
14332 : : q if r1 op1 op2 q+2
14333 : : q+1 Goto q+4
14334 : : q+2 if r2 op3 op4 t
14335 : : q+3 Goto f
14336 : : q+4 if r2 op3 op4 f
14337 : : q+5 Goto t
14338 : :
14339 : : after (in case of #)
14340 : :
14341 : : q if r1 op1 op2 q+2
14342 : : q+1 Goto q+n+2
14343 : : q+2 ...
14344 : : ... ...
14345 : : q+n if r2 op3 op4 f
14346 : : q+n+1 Goto t
14347 : : q+n+2 if r2 op3 op4 t
14348 : : q+n+3 Goto f
14349 : :
14350 : : The Stack is expected to contain:
14351 : :
14352 : :
14353 : : Entry Exit
14354 : : ===== ====
14355 : :
14356 : : Ptr ->
14357 : : +------------+
14358 : : | t1 | f1 |
14359 : : |------------|
14360 : : | Operator | <- Ptr
14361 : : |------------| +------------+
14362 : : | t2 | f2 | | t | f |
14363 : : |------------| |------------|
14364 : :
14365 : :
14366 : : */
14367 : :
14368 : 0 : static void BuildRelOpFromBoolean (unsigned int tokpos)
14369 : : {
14370 : 0 : unsigned int Tok;
14371 : 0 : unsigned int t1;
14372 : 0 : unsigned int f1;
14373 : 0 : unsigned int t2;
14374 : 0 : unsigned int f2;
14375 : 0 : M2Quads_QuadFrame f;
14376 : :
14377 : 0 : M2Debug_Assert ((IsBoolean (1)) && (IsBoolean (3)));
14378 : 0 : if ((M2Quads_OperandT (2)) == M2Reserved_EqualTok)
14379 : : {
14380 : : /* Are the two boolean expressions the same? */
14381 : 0 : PopBool (&t1, &f1);
14382 : 0 : M2Quads_PopT (&Tok);
14383 : 0 : PopBool (&t2, &f2);
14384 : : /* Give the false exit a second chance. */
14385 : 0 : BackPatch (t2, t1); /* q if _ _ q+2 */
14386 : 0 : BackPatch (f2, NextQuad); /* q+1 if _ _ q+4 */
14387 : 0 : M2Debug_Assert (NextQuad == (f1+1)); /* q+1 if _ _ q+4 */
14388 : 0 : f = GetQF (t1);
14389 : 0 : GenQuadO (tokpos, f->Operator, f->Operand1, f->Operand2, 0, false);
14390 : 0 : GenQuadO (tokpos, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
14391 : 0 : PushBooltok (Merge (NextQuad-1, t1), Merge (NextQuad-2, f1), tokpos);
14392 : : }
14393 : 0 : else if (((M2Quads_OperandT (2)) == M2Reserved_HashTok) || ((M2Quads_OperandT (2)) == M2Reserved_LessGreaterTok))
14394 : : {
14395 : : /* avoid dangling else. */
14396 : 0 : if (M2Options_CompilerDebugging)
14397 : : {
14398 : 0 : M2Printf_printf0 ((const char *) "BuildRelOpFromBoolean (NotEqualTok)\\n", 37);
14399 : 0 : M2Quads_DisplayStack ();
14400 : : }
14401 : : /* Are the two boolean expressions different? */
14402 : 0 : PopBool (&t1, &f1);
14403 : 0 : M2Quads_PopT (&Tok);
14404 : 0 : PopBool (&t2, &f2);
14405 : 0 : if (M2Options_CompilerDebugging)
14406 : : {
14407 : 0 : M2Printf_printf2 ((const char *) "t1 = %d, f1 = %d\\n", 18, (const unsigned char *) &t1, (sizeof (t1)-1), (const unsigned char *) &f1, (sizeof (f1)-1));
14408 : 0 : M2Printf_printf2 ((const char *) "t2 = %d, f2 = %d\\n", 18, (const unsigned char *) &t2, (sizeof (t2)-1), (const unsigned char *) &f2, (sizeof (f2)-1));
14409 : 0 : DumpQuadSummary (t1);
14410 : 0 : DumpQuadSummary (f1);
14411 : 0 : DumpQuadSummary (t2);
14412 : 0 : DumpQuadSummary (f2);
14413 : : }
14414 : : /* Give the false exit a second chance. */
14415 : 0 : BackPatch (t2, t1); /* q if _ _ q+2 */
14416 : 0 : BackPatch (f2, NextQuad); /* q+1 if _ _ q+4 */
14417 : 0 : M2Debug_Assert (NextQuad == (f1+1)); /* q+1 if _ _ q+4 */
14418 : 0 : f = GetQF (t1);
14419 : 0 : GenQuadO (tokpos, f->Operator, f->Operand1, f->Operand2, 0, false);
14420 : 0 : GenQuadO (tokpos, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
14421 : 0 : PushBooltok (Merge (NextQuad-2, f1), Merge (NextQuad-1, t1), tokpos);
14422 : : }
14423 : : else
14424 : : {
14425 : : /* avoid dangling else. */
14426 : 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);
14427 : : }
14428 : 0 : }
14429 : :
14430 : :
14431 : : /*
14432 : : CheckVariableOrConstantOrProcedure - checks to make sure sym is a variable, constant or procedure.
14433 : : */
14434 : :
14435 : 154704 : static void CheckVariableOrConstantOrProcedure (unsigned int tokpos, unsigned int sym)
14436 : : {
14437 : 154704 : unsigned int type;
14438 : :
14439 : 154704 : type = SymbolTable_GetSType (sym);
14440 : 154704 : if (SymbolTable_IsUnknown (sym))
14441 : : {
14442 : 0 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1EUad} has not been declared", 30, sym);
14443 : 0 : SymbolTable_UnknownReported (sym);
14444 : : }
14445 : 154704 : else if ((M2System_IsPseudoSystemFunction (sym)) || (M2Base_IsPseudoBaseFunction (sym)))
14446 : : {
14447 : : /* avoid dangling else. */
14448 : 6 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1Ead} expected a variable, procedure, constant or expression, not an intrinsic procedure function", 99, sym);
14449 : : }
14450 : 154698 : else if (((((! (SymbolTable_IsConst (sym))) && (! (SymbolTable_IsVar (sym)))) && (! (SymbolTable_IsProcedure (sym)))) && (! (SymbolTable_IsTemporary (sym)))) && ! MustNotCheckBounds)
14451 : : {
14452 : : /* avoid dangling else. */
14453 : 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);
14454 : : }
14455 : 154698 : else if ((type != SymbolTable_NulSym) && (SymbolTable_IsArray (type)))
14456 : : {
14457 : : /* avoid dangling else. */
14458 : 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);
14459 : : }
14460 : 154698 : else if (((SymbolTable_IsConstString (sym)) && (SymbolTable_IsConstStringKnown (sym))) && ((SymbolTable_GetStringLength (tokpos, sym)) > 1))
14461 : : {
14462 : : /* avoid dangling else. */
14463 : 0 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1EU} not expecting a string constant as an operand for either comparison or binary operation", 94, sym);
14464 : : }
14465 : 154704 : }
14466 : :
14467 : :
14468 : : /*
14469 : : MakeOp - returns the equalent quadruple operator to a token, t.
14470 : : */
14471 : :
14472 : 134275 : static M2Quads_QuadOperator MakeOp (NameKey_Name t)
14473 : : {
14474 : 134275 : if (t == ArithPlusTok)
14475 : : {
14476 : : return M2Quads_ArithAddOp;
14477 : : }
14478 : 134275 : else if (t == M2Reserved_PlusTok)
14479 : : {
14480 : : /* avoid dangling else. */
14481 : : return M2Quads_AddOp;
14482 : : }
14483 : 110053 : else if (t == M2Reserved_MinusTok)
14484 : : {
14485 : : /* avoid dangling else. */
14486 : : return M2Quads_SubOp;
14487 : : }
14488 : 97529 : else if (t == M2Reserved_DivTok)
14489 : : {
14490 : : /* avoid dangling else. */
14491 : : return M2Quads_DivM2Op;
14492 : : }
14493 : 91450 : else if (t == M2Reserved_DivideTok)
14494 : : {
14495 : : /* avoid dangling else. */
14496 : : return M2Quads_DivTruncOp;
14497 : : }
14498 : 89906 : else if (t == M2Reserved_RemTok)
14499 : : {
14500 : : /* avoid dangling else. */
14501 : : return M2Quads_ModTruncOp;
14502 : : }
14503 : 89810 : else if (t == M2Reserved_ModTok)
14504 : : {
14505 : : /* avoid dangling else. */
14506 : : return M2Quads_ModM2Op;
14507 : : }
14508 : 87692 : else if (t == M2Reserved_TimesTok)
14509 : : {
14510 : : /* avoid dangling else. */
14511 : : return M2Quads_MultOp;
14512 : : }
14513 : 78600 : else if (t == M2Reserved_HashTok)
14514 : : {
14515 : : /* avoid dangling else. */
14516 : : return M2Quads_IfNotEquOp;
14517 : : }
14518 : 67332 : else if (t == M2Reserved_LessGreaterTok)
14519 : : {
14520 : : /* avoid dangling else. */
14521 : : return M2Quads_IfNotEquOp;
14522 : : }
14523 : 67248 : else if (t == M2Reserved_GreaterEqualTok)
14524 : : {
14525 : : /* avoid dangling else. */
14526 : : return M2Quads_IfGreEquOp;
14527 : : }
14528 : 58374 : else if (t == M2Reserved_LessEqualTok)
14529 : : {
14530 : : /* avoid dangling else. */
14531 : : return M2Quads_IfLessEquOp;
14532 : : }
14533 : 54020 : else if (t == M2Reserved_EqualTok)
14534 : : {
14535 : : /* avoid dangling else. */
14536 : : return M2Quads_IfEquOp;
14537 : : }
14538 : 13830 : else if (t == M2Reserved_LessTok)
14539 : : {
14540 : : /* avoid dangling else. */
14541 : : return M2Quads_IfLessOp;
14542 : : }
14543 : 8194 : else if (t == M2Reserved_GreaterTok)
14544 : : {
14545 : : /* avoid dangling else. */
14546 : : return M2Quads_IfGreOp;
14547 : : }
14548 : 2876 : else if (t == M2Reserved_InTok)
14549 : : {
14550 : : /* avoid dangling else. */
14551 : : return M2Quads_IfInOp;
14552 : : }
14553 : 1248 : else if (t == LogicalOrTok)
14554 : : {
14555 : : /* avoid dangling else. */
14556 : : return M2Quads_LogicalOrOp;
14557 : : }
14558 : 138 : else if (t == LogicalAndTok)
14559 : : {
14560 : : /* avoid dangling else. */
14561 : : return M2Quads_LogicalAndOp;
14562 : : }
14563 : 78 : else if (t == LogicalXorTok)
14564 : : {
14565 : : /* avoid dangling else. */
14566 : : return M2Quads_LogicalXorOp;
14567 : : }
14568 : 66 : else if (t == LogicalDifferenceTok)
14569 : : {
14570 : : /* avoid dangling else. */
14571 : : return M2Quads_LogicalDiffOp;
14572 : : }
14573 : : else
14574 : : {
14575 : : /* avoid dangling else. */
14576 : 0 : M2Error_InternalError ((const char *) "binary operation not implemented yet", 36);
14577 : : }
14578 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
14579 : : __builtin_unreachable ();
14580 : : }
14581 : :
14582 : :
14583 : : /*
14584 : : GenQuadO - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
14585 : : */
14586 : :
14587 : 4125332 : static void GenQuadO (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow)
14588 : : {
14589 : 1042160 : GenQuadOTrash (TokPos, Operation, Op1, Op2, Op3, overflow, SymbolTable_NulSym);
14590 : 628851 : }
14591 : :
14592 : :
14593 : : /*
14594 : : GenQuadOTrash - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
14595 : : */
14596 : :
14597 : 4126746 : static void GenQuadOTrash (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow, unsigned int trash)
14598 : : {
14599 : 4126746 : M2Quads_QuadFrame f;
14600 : :
14601 : : /* WriteString('Potential Quad: ') ; */
14602 : 4126746 : if (QuadrupleGeneration)
14603 : : {
14604 : 4124696 : if (NextQuad != Head)
14605 : : {
14606 : 4109651 : f = GetQF (NextQuad-1);
14607 : 4109651 : f->Next = NextQuad;
14608 : : }
14609 : 4124696 : PutQuadO (NextQuad, Operation, Op1, Op2, Op3, overflow);
14610 : 4124696 : f = GetQF (NextQuad);
14611 : 4124696 : f->Trash = trash;
14612 : 4124696 : f->Next = 0;
14613 : 4124696 : f->LineNo = M2LexBuf_GetLineNo ();
14614 : 4124696 : if (TokPos == M2LexBuf_UnknownTokenNo)
14615 : : {
14616 : 2328843 : f->TokenNo = M2LexBuf_GetTokenNo ();
14617 : : }
14618 : : else
14619 : : {
14620 : 1795853 : f->TokenNo = TokPos;
14621 : : }
14622 : 4124696 : if (M2Options_GetDebugTraceQuad ())
14623 : : {
14624 : 0 : M2Printf_printf0 ((const char *) "generating: ", 12);
14625 : 0 : M2Quads_DisplayQuad (NextQuad);
14626 : : }
14627 : : /* MetaErrorT1 (TokenNo, '{%1On}', NextQuad) */
14628 : 4124696 : CheckBreak (NextQuad);
14629 : 4124696 : NewQuad (&NextQuad);
14630 : : }
14631 : 4126746 : }
14632 : :
14633 : :
14634 : : /*
14635 : : GenQuad - Generate a quadruple with Operation, Op1, Op2, Op3.
14636 : : */
14637 : :
14638 : 2270893 : static void GenQuad (M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3)
14639 : : {
14640 : 1429905 : GenQuadO (M2LexBuf_UnknownTokenNo, Operation, Op1, Op2, Op3, true);
14641 : 513412 : }
14642 : :
14643 : :
14644 : : /*
14645 : : GenQuadOtok - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
14646 : : */
14647 : :
14648 : 496059 : 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)
14649 : : {
14650 : 399663 : GenQuadOTypetok (TokPos, Operation, Op1, Op2, Op3, overflow, true, Op1Pos, Op2Pos, Op3Pos);
14651 : 228469 : }
14652 : :
14653 : :
14654 : : /*
14655 : : GenQuadOTypetok - assigns the fields of the quadruple with
14656 : : the parameters.
14657 : : */
14658 : :
14659 : 742942 : 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)
14660 : : {
14661 : 742942 : M2Quads_QuadFrame f;
14662 : :
14663 : : /* WriteString('Potential Quad: ') ; */
14664 : 742942 : if (QuadrupleGeneration)
14665 : : {
14666 : 742252 : if (NextQuad != Head)
14667 : : {
14668 : 742252 : f = GetQF (NextQuad-1);
14669 : 742252 : f->Next = NextQuad;
14670 : : }
14671 : 742252 : PutQuadOType (NextQuad, Operation, Op1, Op2, Op3, overflow, typecheck);
14672 : 742252 : f = GetQF (NextQuad);
14673 : 742252 : f->Next = 0;
14674 : 742252 : f->LineNo = M2LexBuf_GetLineNo ();
14675 : 742252 : if (TokPos == M2LexBuf_UnknownTokenNo)
14676 : : {
14677 : 17520 : f->TokenNo = M2LexBuf_GetTokenNo ();
14678 : : }
14679 : : else
14680 : : {
14681 : 724732 : f->TokenNo = TokPos;
14682 : : }
14683 : 742252 : f->op1pos = Op1Pos;
14684 : 742252 : f->op2pos = Op2Pos;
14685 : 742252 : f->op3pos = Op3Pos;
14686 : 742252 : if (M2Options_GetDebugTraceQuad ())
14687 : : {
14688 : 0 : M2Printf_printf0 ((const char *) "generating: ", 12);
14689 : 0 : M2Quads_DisplayQuad (NextQuad);
14690 : : }
14691 : : /* MetaErrorT1 (TokenNo, '{%1On}', NextQuad) */
14692 : 742252 : CheckBreak (NextQuad);
14693 : 742252 : NewQuad (&NextQuad);
14694 : : }
14695 : 742942 : }
14696 : :
14697 : :
14698 : : /*
14699 : : DumpUntil - dump all quadruples until we seen the ending quadruple
14700 : : with procsym in the third operand.
14701 : : Return the quad number containing the match.
14702 : : */
14703 : :
14704 : 0 : static unsigned int DumpUntil (M2Quads_QuadOperator ending, unsigned int procsym, unsigned int quad)
14705 : : {
14706 : 0 : M2Quads_QuadOperator op;
14707 : 0 : unsigned int op1;
14708 : 0 : unsigned int op2;
14709 : 0 : unsigned int op3;
14710 : 0 : M2Quads_QuadFrame f;
14711 : :
14712 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "\\n...\\n\\n", 9);
14713 : 0 : do {
14714 : 0 : M2Quads_GetQuad (quad, &op, &op1, &op2, &op3);
14715 : 0 : M2Quads_DisplayQuad (quad);
14716 : 0 : f = GetQF (quad);
14717 : 0 : quad = f->Next;
14718 : 0 : } while (! ((op == ending) && (op3 == procsym)));
14719 : 0 : return quad;
14720 : : /* static analysis guarentees a RETURN statement will be used before here. */
14721 : : __builtin_unreachable ();
14722 : : }
14723 : :
14724 : :
14725 : : /*
14726 : : GetCtorInit - return the init procedure for the module.
14727 : : */
14728 : :
14729 : 0 : static unsigned int GetCtorInit (unsigned int sym)
14730 : : {
14731 : 0 : unsigned int ctor;
14732 : 0 : unsigned int init;
14733 : 0 : unsigned int fini;
14734 : 0 : unsigned int dep;
14735 : :
14736 : 0 : SymbolTable_GetModuleCtors (sym, &ctor, &init, &fini, &dep);
14737 : 0 : return init;
14738 : : /* static analysis guarentees a RETURN statement will be used before here. */
14739 : : __builtin_unreachable ();
14740 : : }
14741 : :
14742 : :
14743 : : /*
14744 : : GetCtorFini - return the fini procedure for the module.
14745 : : */
14746 : :
14747 : 0 : static unsigned int GetCtorFini (unsigned int sym)
14748 : : {
14749 : 0 : unsigned int ctor;
14750 : 0 : unsigned int init;
14751 : 0 : unsigned int fini;
14752 : 0 : unsigned int dep;
14753 : :
14754 : 0 : SymbolTable_GetModuleCtors (sym, &ctor, &init, &fini, &dep);
14755 : 0 : return fini;
14756 : : /* static analysis guarentees a RETURN statement will be used before here. */
14757 : : __builtin_unreachable ();
14758 : : }
14759 : :
14760 : :
14761 : : /*
14762 : : DumpQuadrupleFilter -
14763 : : */
14764 : :
14765 : 0 : static void DumpQuadrupleFilter (void)
14766 : : {
14767 : 0 : M2Quads_QuadFrame f;
14768 : 0 : unsigned int i;
14769 : 0 : M2Quads_QuadOperator op;
14770 : 0 : unsigned int op1;
14771 : 0 : unsigned int op2;
14772 : 0 : unsigned int op3;
14773 : :
14774 : 0 : i = Head;
14775 : 0 : while (i != 0)
14776 : : {
14777 : 0 : M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
14778 : 0 : if ((op == M2Quads_ProcedureScopeOp) && (M2LangDump_IsDumpRequired (op3, true)))
14779 : : {
14780 : 0 : i = DumpUntil (M2Quads_KillLocalVarOp, op3, i);
14781 : : }
14782 : 0 : else if ((op == M2Quads_InitStartOp) && (M2LangDump_IsDumpRequired (GetCtorInit (op3), true)))
14783 : : {
14784 : : /* avoid dangling else. */
14785 : 0 : i = DumpUntil (M2Quads_InitEndOp, op3, i);
14786 : : }
14787 : 0 : else if ((op == M2Quads_FinallyStartOp) && (M2LangDump_IsDumpRequired (GetCtorFini (op3), true)))
14788 : : {
14789 : : /* avoid dangling else. */
14790 : 0 : i = DumpUntil (M2Quads_FinallyEndOp, op3, i);
14791 : : }
14792 : : else
14793 : : {
14794 : : /* avoid dangling else. */
14795 : 0 : f = GetQF (i);
14796 : 0 : i = f->Next;
14797 : : }
14798 : : }
14799 : 0 : }
14800 : :
14801 : :
14802 : : /*
14803 : : DumpQuadrupleAll - dump all quadruples.
14804 : : */
14805 : :
14806 : 0 : static void DumpQuadrupleAll (void)
14807 : : {
14808 : 0 : M2Quads_QuadFrame f;
14809 : 0 : unsigned int i;
14810 : :
14811 : 0 : i = Head;
14812 : 0 : while (i != 0)
14813 : : {
14814 : 0 : M2Quads_DisplayQuad (i);
14815 : 0 : f = GetQF (i);
14816 : 0 : i = f->Next;
14817 : : }
14818 : 0 : }
14819 : :
14820 : :
14821 : : /*
14822 : : BackPatch - Makes each of the quadruples on the list pointed to by
14823 : : QuadNo take quadruple Value as a target.
14824 : : */
14825 : :
14826 : 347836 : static void BackPatch (unsigned int QuadNo, unsigned int Value)
14827 : : {
14828 : 347836 : unsigned int i;
14829 : 347836 : M2Quads_QuadFrame f;
14830 : :
14831 : 347836 : if (QuadrupleGeneration)
14832 : : {
14833 : 550369 : while (QuadNo != 0)
14834 : : {
14835 : 202545 : f = GetQF (QuadNo);
14836 : 202545 : i = f->Operand3; /* Next Link along the BackPatch */
14837 : 202545 : ManipulateReference (QuadNo, Value); /* Filling in the BackPatch. */
14838 : 202545 : QuadNo = i;
14839 : : }
14840 : : }
14841 : 347836 : }
14842 : :
14843 : :
14844 : : /*
14845 : : Merge - joins two quad lists, QuadList2 to the end of QuadList1.
14846 : : A QuadList of value zero is a nul list.
14847 : : */
14848 : :
14849 : 45703 : static unsigned int Merge (unsigned int QuadList1, unsigned int QuadList2)
14850 : : {
14851 : 45703 : unsigned int i;
14852 : 45703 : unsigned int j;
14853 : 45703 : M2Quads_QuadFrame f;
14854 : :
14855 : 45703 : if (QuadList1 == 0)
14856 : : {
14857 : : return QuadList2;
14858 : : }
14859 : 23430 : else if (QuadList2 == 0)
14860 : : {
14861 : : /* avoid dangling else. */
14862 : : return QuadList1;
14863 : : }
14864 : : else
14865 : : {
14866 : : /* avoid dangling else. */
14867 : : i = QuadList1;
14868 : 49062 : do {
14869 : 49062 : j = i;
14870 : 49062 : f = GetQF (i);
14871 : 49062 : i = f->Operand3;
14872 : 49062 : } while (! (i == 0));
14873 : 20426 : ManipulateReference (j, QuadList2);
14874 : 20426 : return QuadList1;
14875 : : }
14876 : : /* static analysis guarentees a RETURN statement will be used before here. */
14877 : : __builtin_unreachable ();
14878 : : }
14879 : :
14880 : :
14881 : : /*
14882 : : DisplayProcedureAttributes -
14883 : : */
14884 : :
14885 : 0 : static void DisplayProcedureAttributes (unsigned int proc)
14886 : : {
14887 : 0 : if (SymbolTable_IsCtor (proc))
14888 : : {
14889 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (ctor)", 7);
14890 : : }
14891 : 0 : if (SymbolTable_IsPublic (proc))
14892 : : {
14893 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (public)", 9);
14894 : : }
14895 : 0 : if (SymbolTable_IsExtern (proc))
14896 : : {
14897 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (extern)", 9);
14898 : : }
14899 : 0 : if (SymbolTable_IsMonoName (proc))
14900 : : {
14901 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (mononame)", 11);
14902 : : }
14903 : 0 : }
14904 : :
14905 : :
14906 : : /*
14907 : : WriteQuad - Writes out the Quad BufferQuad.
14908 : : */
14909 : :
14910 : 0 : static void WriteQuad (unsigned int BufferQuad)
14911 : : {
14912 : 0 : NameKey_Name n1;
14913 : 0 : NameKey_Name n2;
14914 : 0 : M2Quads_QuadFrame f;
14915 : 0 : NameKey_Name n;
14916 : 0 : unsigned int l;
14917 : :
14918 : 0 : f = GetQF (BufferQuad);
14919 : 0 : M2Quads_WriteOperator (f->Operator);
14920 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " [%d]", 5, (const unsigned char *) &f->NoOfTimesReferenced, (sizeof (f->NoOfTimesReferenced)-1));
14921 : 0 : if (f->ConstExpr)
14922 : : {
14923 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " const ", 7);
14924 : : }
14925 : : else
14926 : : {
14927 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 7);
14928 : : }
14929 : 0 : switch (f->Operator)
14930 : : {
14931 : 0 : case M2Quads_LastForIteratorOp:
14932 : 0 : M2Quads_WriteOperand (f->Operand1);
14933 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
14934 : 0 : M2Quads_WriteOperand (f->Operand2);
14935 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
14936 : 0 : M2Quads_WriteOperand (f->Operand3);
14937 : 0 : break;
14938 : :
14939 : 0 : case M2Quads_HighOp:
14940 : 0 : M2Quads_WriteOperand (f->Operand1);
14941 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %4d ", 7, (const unsigned char *) &f->Operand2, (sizeof (f->Operand2)-1));
14942 : 0 : M2Quads_WriteOperand (f->Operand3);
14943 : 0 : break;
14944 : :
14945 : 0 : case M2Quads_InitAddressOp:
14946 : 0 : case M2Quads_SavePriorityOp:
14947 : 0 : case M2Quads_RestorePriorityOp:
14948 : 0 : case M2Quads_SubrangeLowOp:
14949 : 0 : case M2Quads_SubrangeHighOp:
14950 : 0 : case M2Quads_BecomesOp:
14951 : 0 : case M2Quads_InclOp:
14952 : 0 : case M2Quads_ExclOp:
14953 : 0 : case M2Quads_UnboundedOp:
14954 : 0 : case M2Quads_ReturnValueOp:
14955 : 0 : case M2Quads_FunctValueOp:
14956 : 0 : case M2Quads_NegateOp:
14957 : 0 : case M2Quads_AddrOp:
14958 : 0 : case M2Quads_StringConvertCnulOp:
14959 : 0 : case M2Quads_StringConvertM2nulOp:
14960 : 0 : case M2Quads_StringLengthOp:
14961 : 0 : M2Quads_WriteOperand (f->Operand1);
14962 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
14963 : 0 : M2Quads_WriteOperand (f->Operand3);
14964 : 0 : break;
14965 : :
14966 : 0 : case M2Quads_ElementSizeOp:
14967 : 0 : case M2Quads_IfInOp:
14968 : 0 : case M2Quads_IfNotInOp:
14969 : 0 : case M2Quads_IfNotEquOp:
14970 : 0 : case M2Quads_IfEquOp:
14971 : 0 : case M2Quads_IfLessOp:
14972 : 0 : case M2Quads_IfGreOp:
14973 : 0 : case M2Quads_IfLessEquOp:
14974 : 0 : case M2Quads_IfGreEquOp:
14975 : 0 : M2Quads_WriteOperand (f->Operand1);
14976 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
14977 : 0 : M2Quads_WriteOperand (f->Operand2);
14978 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %4d", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
14979 : 0 : break;
14980 : :
14981 : 0 : case M2Quads_InlineOp:
14982 : 0 : case M2Quads_RetryOp:
14983 : 0 : case M2Quads_TryOp:
14984 : 0 : case M2Quads_GotoOp:
14985 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d", 3, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
14986 : 0 : break;
14987 : :
14988 : 0 : case M2Quads_StatementNoteOp:
14989 : 0 : l = M2LexBuf_TokenToLineNo (f->Operand3, 0);
14990 : 0 : n = M2LexBuf_GetTokenName (f->Operand3);
14991 : 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));
14992 : 0 : break;
14993 : :
14994 : 0 : case M2Quads_LineNumberOp:
14995 : 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));
14996 : 0 : break;
14997 : :
14998 : 0 : case M2Quads_EndFileOp:
14999 : 0 : n1 = SymbolTable_GetSymName (f->Operand3);
15000 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%a", 2, (const unsigned char *) &n1, (sizeof (n1)-1));
15001 : 0 : break;
15002 : :
15003 : 0 : case M2Quads_ThrowOp:
15004 : 0 : case M2Quads_ReturnOp:
15005 : 0 : case M2Quads_CallOp:
15006 : 0 : case M2Quads_KillLocalVarOp:
15007 : 0 : M2Quads_WriteOperand (f->Operand3);
15008 : 0 : break;
15009 : :
15010 : 0 : case M2Quads_ProcedureScopeOp:
15011 : 0 : n1 = SymbolTable_GetSymName (f->Operand2);
15012 : 0 : n2 = SymbolTable_GetSymName (f->Operand3);
15013 : 0 : M2Printf_fprintf4 (M2LangDump_GetDumpFile (), (const char *) " %4d %a %a(%d)", 17, (const unsigned char *) &f->Operand1, (sizeof (f->Operand1)-1), (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1), (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
15014 : 0 : DisplayProcedureAttributes (f->Operand3);
15015 : 0 : break;
15016 : :
15017 : 0 : case M2Quads_NewLocalVarOp:
15018 : 0 : case M2Quads_FinallyStartOp:
15019 : 0 : case M2Quads_FinallyEndOp:
15020 : 0 : case M2Quads_InitEndOp:
15021 : 0 : case M2Quads_InitStartOp:
15022 : 0 : n1 = SymbolTable_GetSymName (f->Operand2);
15023 : 0 : n2 = SymbolTable_GetSymName (f->Operand3);
15024 : 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));
15025 : 0 : break;
15026 : :
15027 : 0 : case M2Quads_ModuleScopeOp:
15028 : 0 : case M2Quads_StartModFileOp:
15029 : 0 : n1 = SymbolTable_GetSymName (f->Operand3);
15030 : 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));
15031 : 0 : break;
15032 : :
15033 : 0 : case M2Quads_StartDefFileOp:
15034 : 0 : n1 = SymbolTable_GetSymName (f->Operand3);
15035 : 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));
15036 : 0 : break;
15037 : :
15038 : 0 : case M2Quads_OptParamOp:
15039 : 0 : case M2Quads_ParamOp:
15040 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d ", 5, (const unsigned char *) &f->Operand1, (sizeof (f->Operand1)-1));
15041 : 0 : M2Quads_WriteOperand (f->Operand2);
15042 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15043 : 0 : M2Quads_WriteOperand (f->Operand3);
15044 : 0 : break;
15045 : :
15046 : 0 : case M2Quads_SizeOp:
15047 : 0 : case M2Quads_RecordFieldOp:
15048 : 0 : case M2Quads_IndrXOp:
15049 : 0 : case M2Quads_XIndrOp:
15050 : 0 : case M2Quads_ArrayOp:
15051 : 0 : case M2Quads_LogicalShiftOp:
15052 : 0 : case M2Quads_LogicalRotateOp:
15053 : 0 : case M2Quads_LogicalOrOp:
15054 : 0 : case M2Quads_LogicalAndOp:
15055 : 0 : case M2Quads_LogicalXorOp:
15056 : 0 : case M2Quads_LogicalDiffOp:
15057 : 0 : case M2Quads_ArithAddOp:
15058 : 0 : case M2Quads_CoerceOp:
15059 : 0 : case M2Quads_ConvertOp:
15060 : 0 : case M2Quads_CastOp:
15061 : 0 : case M2Quads_AddOp:
15062 : 0 : case M2Quads_SubOp:
15063 : 0 : case M2Quads_MultOp:
15064 : 0 : case M2Quads_DivM2Op:
15065 : 0 : case M2Quads_ModM2Op:
15066 : 0 : case M2Quads_ModFloorOp:
15067 : 0 : case M2Quads_DivCeilOp:
15068 : 0 : case M2Quads_ModCeilOp:
15069 : 0 : case M2Quads_DivFloorOp:
15070 : 0 : case M2Quads_ModTruncOp:
15071 : 0 : case M2Quads_DivTruncOp:
15072 : 0 : M2Quads_WriteOperand (f->Operand1);
15073 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15074 : 0 : M2Quads_WriteOperand (f->Operand2);
15075 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15076 : 0 : M2Quads_WriteOperand (f->Operand3);
15077 : 0 : break;
15078 : :
15079 : : case M2Quads_DummyOp:
15080 : : case M2Quads_CodeOnOp:
15081 : : case M2Quads_CodeOffOp:
15082 : : case M2Quads_ProfileOnOp:
15083 : : case M2Quads_ProfileOffOp:
15084 : : case M2Quads_OptimizeOnOp:
15085 : : case M2Quads_OptimizeOffOp:
15086 : : break;
15087 : :
15088 : 0 : case M2Quads_BuiltinConstOp:
15089 : 0 : M2Quads_WriteOperand (f->Operand1);
15090 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %a", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
15091 : 0 : break;
15092 : :
15093 : 0 : case M2Quads_BuiltinTypeInfoOp:
15094 : 0 : M2Quads_WriteOperand (f->Operand1);
15095 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %a", 5, (const unsigned char *) &f->Operand2, (sizeof (f->Operand2)-1));
15096 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %a", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
15097 : 0 : break;
15098 : :
15099 : 0 : case M2Quads_StandardFunctionOp:
15100 : 0 : M2Quads_WriteOperand (f->Operand1);
15101 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15102 : 0 : M2Quads_WriteOperand (f->Operand2);
15103 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15104 : 0 : M2Quads_WriteOperand (f->Operand3);
15105 : 0 : break;
15106 : :
15107 : : case M2Quads_CatchBeginOp:
15108 : : case M2Quads_CatchEndOp:
15109 : : break;
15110 : :
15111 : 0 : case M2Quads_RangeCheckOp:
15112 : 0 : case M2Quads_ErrorOp:
15113 : 0 : M2Range_WriteRangeCheck (f->Operand3);
15114 : 0 : break;
15115 : :
15116 : 0 : case M2Quads_SaveExceptionOp:
15117 : 0 : case M2Quads_RestoreExceptionOp:
15118 : 0 : M2Quads_WriteOperand (f->Operand1);
15119 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15120 : 0 : M2Quads_WriteOperand (f->Operand3);
15121 : 0 : break;
15122 : :
15123 : :
15124 : 0 : default:
15125 : 0 : M2Error_InternalError ((const char *) "quadruple not recognised", 24);
15126 : 0 : break;
15127 : : }
15128 : 0 : }
15129 : :
15130 : :
15131 : : /*
15132 : : WriteOperand - displays the operands name, symbol id and mode of addressing.
15133 : : */
15134 : :
15135 : 0 : static void WriteMode (SymbolTable_ModeOfAddr Mode)
15136 : : {
15137 : 0 : switch (Mode)
15138 : : {
15139 : 0 : case SymbolTable_ImmediateValue:
15140 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "i", 1);
15141 : 0 : break;
15142 : :
15143 : 0 : case SymbolTable_NoValue:
15144 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "n", 1);
15145 : 0 : break;
15146 : :
15147 : 0 : case SymbolTable_RightValue:
15148 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "r", 1);
15149 : 0 : break;
15150 : :
15151 : 0 : case SymbolTable_LeftValue:
15152 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "l", 1);
15153 : 0 : break;
15154 : :
15155 : :
15156 : 0 : default:
15157 : 0 : M2Error_InternalError ((const char *) "unrecognised mode", 17);
15158 : 0 : break;
15159 : : }
15160 : 0 : }
15161 : :
15162 : :
15163 : : /*
15164 : : PushExit - pushes the exit value onto the EXIT stack.
15165 : : */
15166 : :
15167 : 624 : static void PushExit (unsigned int Exit)
15168 : : {
15169 : 0 : M2StackWord_PushWord (ExitStack, Exit);
15170 : 94 : }
15171 : :
15172 : :
15173 : : /*
15174 : : PopExit - pops the exit value from the EXIT stack.
15175 : : */
15176 : :
15177 : 624 : static unsigned int PopExit (void)
15178 : : {
15179 : 0 : return M2StackWord_PopWord (ExitStack);
15180 : : /* static analysis guarentees a RETURN statement will be used before here. */
15181 : : __builtin_unreachable ();
15182 : : }
15183 : :
15184 : :
15185 : : /*
15186 : : PushFor - pushes the exit value onto the FOR stack.
15187 : : */
15188 : :
15189 : 8598 : static void PushFor (unsigned int Exit)
15190 : : {
15191 : 0 : M2StackWord_PushWord (ForStack, Exit);
15192 : 0 : }
15193 : :
15194 : :
15195 : : /*
15196 : : PopFor - pops the exit value from the FOR stack.
15197 : : */
15198 : :
15199 : 8592 : static unsigned int PopFor (void)
15200 : : {
15201 : 0 : return M2StackWord_PopWord (ForStack);
15202 : : /* static analysis guarentees a RETURN statement will be used before here. */
15203 : : __builtin_unreachable ();
15204 : : }
15205 : :
15206 : :
15207 : : /*
15208 : : OperandTno - returns the ident operand stored in the true position
15209 : : on the boolean stack. This is exactly the same as
15210 : : OperandT but it has no IsBoolean checking.
15211 : : */
15212 : :
15213 : 127632557 : static unsigned int OperandTno (unsigned int pos)
15214 : : {
15215 : 127632557 : M2Quads_BoolFrame f;
15216 : :
15217 : 127632557 : M2Debug_Assert (pos > 0);
15218 : 127632557 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15219 : 127632557 : return static_cast<unsigned int> (f->TrueExit);
15220 : : /* static analysis guarentees a RETURN statement will be used before here. */
15221 : : __builtin_unreachable ();
15222 : : }
15223 : :
15224 : :
15225 : : /*
15226 : : OperandFno - returns the ident operand stored in the false position
15227 : : on the boolean stack. This is exactly the same as
15228 : : OperandF but it has no IsBoolean checking.
15229 : : */
15230 : :
15231 : 152484 : static unsigned int OperandFno (unsigned int pos)
15232 : : {
15233 : 152484 : M2Quads_BoolFrame f;
15234 : :
15235 : 152484 : M2Debug_Assert (pos > 0);
15236 : 152484 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15237 : 152484 : return static_cast<unsigned int> (f->FalseExit);
15238 : : /* static analysis guarentees a RETURN statement will be used before here. */
15239 : : __builtin_unreachable ();
15240 : : }
15241 : :
15242 : :
15243 : : /*
15244 : : OperandTtok - returns the token associated with the position, pos
15245 : : on the boolean stack.
15246 : : */
15247 : :
15248 : 37125006 : static unsigned int OperandTtok (unsigned int pos)
15249 : : {
15250 : 37125006 : M2Quads_BoolFrame f;
15251 : :
15252 : 37125006 : M2Debug_Assert (pos > 0);
15253 : 37125006 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15254 : 37125006 : return f->tokenno;
15255 : : /* static analysis guarentees a RETURN statement will be used before here. */
15256 : : __builtin_unreachable ();
15257 : : }
15258 : :
15259 : :
15260 : : /*
15261 : : PopBooltok - Pops a True and a False exit quad number from the True/False
15262 : : stack.
15263 : : */
15264 : :
15265 : 189227 : static void PopBooltok (unsigned int *True, unsigned int *False, unsigned int *tokno)
15266 : : {
15267 : 189227 : M2Quads_BoolFrame f;
15268 : :
15269 : 189227 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15270 : 189227 : (*True) = f->TrueExit;
15271 : 189227 : (*False) = f->FalseExit;
15272 : 189227 : (*tokno) = f->tokenno;
15273 : 189227 : M2Debug_Assert (f->BooleanOp);
15274 : 189227 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15275 : 189227 : }
15276 : :
15277 : :
15278 : : /*
15279 : : PushBooltok - Push a True and a False exit quad numbers onto the
15280 : : True/False stack.
15281 : : */
15282 : :
15283 : 195725 : static void PushBooltok (unsigned int True, unsigned int False, unsigned int tokno)
15284 : : {
15285 : 195725 : M2Quads_BoolFrame f;
15286 : :
15287 : 195725 : M2Debug_Assert (True <= NextQuad);
15288 : 195725 : M2Debug_Assert (False <= NextQuad);
15289 : 195725 : f = newBoolFrame ();
15290 : 195725 : f->TrueExit = True;
15291 : 195725 : f->FalseExit = False;
15292 : 195725 : f->BooleanOp = true;
15293 : 195725 : f->tokenno = tokno;
15294 : 195725 : f->Annotation = static_cast<DynamicStrings_String> (NULL);
15295 : 195725 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15296 : 195725 : M2Quads_Annotate ((const char *) "<q%1d>|<q%2d>||true quad|false quad", 35);
15297 : 195725 : }
15298 : :
15299 : :
15300 : : /*
15301 : : PopBool - Pops a True and a False exit quad number from the True/False
15302 : : stack.
15303 : : */
15304 : :
15305 : 159849 : static void PopBool (unsigned int *True, unsigned int *False)
15306 : : {
15307 : 159849 : unsigned int tokno;
15308 : :
15309 : 8778 : PopBooltok (True, False, &tokno);
15310 : 0 : }
15311 : :
15312 : :
15313 : : /*
15314 : : PushBool - Push a True and a False exit quad numbers onto the
15315 : : True/False stack.
15316 : : */
15317 : :
15318 : 100669 : static void PushBool (unsigned int True, unsigned int False)
15319 : : {
15320 : 6498 : PushBooltok (True, False, M2LexBuf_UnknownTokenNo);
15321 : 11674 : }
15322 : :
15323 : :
15324 : : /*
15325 : : IsBoolean - returns true is the Stack position pos contains a Boolean
15326 : : Exit. False is returned if an Ident is stored.
15327 : : */
15328 : :
15329 : 166982673 : static bool IsBoolean (unsigned int pos)
15330 : : {
15331 : 166982673 : M2Quads_BoolFrame f;
15332 : :
15333 : 166982673 : M2Debug_Assert (pos > 0);
15334 : 166982673 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15335 : 166982673 : return f->BooleanOp;
15336 : : /* static analysis guarentees a RETURN statement will be used before here. */
15337 : : __builtin_unreachable ();
15338 : : }
15339 : :
15340 : :
15341 : : /*
15342 : : OperandD - returns possible array dimension associated with the ident
15343 : : operand stored on the boolean stack.
15344 : : */
15345 : :
15346 : 615027 : static unsigned int OperandD (unsigned int pos)
15347 : : {
15348 : 615027 : M2Quads_BoolFrame f;
15349 : :
15350 : 615027 : M2Debug_Assert (pos > 0);
15351 : 615027 : M2Debug_Assert (! (IsBoolean (pos)));
15352 : 615027 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15353 : 615027 : return static_cast<unsigned int> (f->Dimension);
15354 : : /* static analysis guarentees a RETURN statement will be used before here. */
15355 : : __builtin_unreachable ();
15356 : : }
15357 : :
15358 : :
15359 : : /*
15360 : : OperandRW - returns the rw operand stored on the boolean stack.
15361 : : */
15362 : :
15363 : 664793 : static unsigned int OperandRW (unsigned int pos)
15364 : : {
15365 : 664793 : M2Quads_BoolFrame f;
15366 : :
15367 : 664793 : M2Debug_Assert (pos > 0);
15368 : 664793 : M2Debug_Assert (! (IsBoolean (pos)));
15369 : 664793 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15370 : 664793 : return static_cast<unsigned int> (f->ReadWrite);
15371 : : /* static analysis guarentees a RETURN statement will be used before here. */
15372 : : __builtin_unreachable ();
15373 : : }
15374 : :
15375 : :
15376 : : /*
15377 : : OperandMergeRW - returns the rw operand if not NulSym else it
15378 : : returns True.
15379 : : */
15380 : :
15381 : 644095 : static unsigned int OperandMergeRW (unsigned int pos)
15382 : : {
15383 : 644095 : if ((OperandRW (pos)) == SymbolTable_NulSym)
15384 : : {
15385 : 625763 : return M2Quads_OperandT (pos);
15386 : : }
15387 : : else
15388 : : {
15389 : 18332 : return OperandRW (pos);
15390 : : }
15391 : : /* static analysis guarentees a RETURN statement will be used before here. */
15392 : : __builtin_unreachable ();
15393 : : }
15394 : :
15395 : :
15396 : : /*
15397 : : UseLineNote - uses the line note and returns it to the free list.
15398 : : */
15399 : :
15400 : 4308 : static void UseLineNote (M2Quads_LineNote l)
15401 : : {
15402 : 4308 : M2Quads_QuadFrame f;
15403 : :
15404 : 4308 : f = GetQF (NextQuad-1);
15405 : 4308 : if ((f->Operator == M2Quads_LineNumberOp) && (f->Operand1 == ((unsigned int ) (l->File))))
15406 : : {} /* empty. */
15407 : : else
15408 : : {
15409 : : /* do nothing */
15410 : : if (false)
15411 : : {
15412 : : GenQuad (M2Quads_LineNumberOp, (unsigned int ) (l->File), SymbolTable_NulSym, (unsigned int ) (l->Line));
15413 : : }
15414 : : }
15415 : 4308 : l->Next = FreeLineList;
15416 : 4308 : FreeLineList = l;
15417 : 4308 : }
15418 : :
15419 : :
15420 : : /*
15421 : : PopLineNo - pops a line note from the line stack.
15422 : : */
15423 : :
15424 : 4308 : static M2Quads_LineNote PopLineNo (void)
15425 : : {
15426 : 4308 : M2Quads_LineNote l;
15427 : :
15428 : 4308 : l = static_cast<M2Quads_LineNote> (M2StackAddress_PopAddress (LineStack));
15429 : 4308 : if (l == NULL)
15430 : : {
15431 : 0 : M2Error_InternalError ((const char *) "no line note available", 22);
15432 : : }
15433 : 4308 : return l;
15434 : : /* static analysis guarentees a RETURN statement will be used before here. */
15435 : : __builtin_unreachable ();
15436 : : }
15437 : :
15438 : :
15439 : : /*
15440 : : InitLineNote - creates a line note and initializes it to
15441 : : contain, file, line.
15442 : : */
15443 : :
15444 : 4308 : static M2Quads_LineNote InitLineNote (NameKey_Name file, unsigned int line)
15445 : : {
15446 : 4308 : M2Quads_LineNote l;
15447 : :
15448 : 4308 : if (FreeLineList == NULL)
15449 : : {
15450 : 2212 : Storage_ALLOCATE ((void **) &l, sizeof (M2Quads__T6));
15451 : : }
15452 : : else
15453 : : {
15454 : 2096 : l = FreeLineList;
15455 : 2096 : FreeLineList = FreeLineList->Next;
15456 : : }
15457 : 4308 : l->File = file;
15458 : 4308 : l->Line = line;
15459 : 4308 : return l;
15460 : : /* static analysis guarentees a RETURN statement will be used before here. */
15461 : : __builtin_unreachable ();
15462 : : }
15463 : :
15464 : :
15465 : : /*
15466 : : PushLineNote -
15467 : : */
15468 : :
15469 : 4308 : static void PushLineNote (M2Quads_LineNote l)
15470 : : {
15471 : 0 : M2StackAddress_PushAddress (LineStack, reinterpret_cast <void *> (l));
15472 : 0 : }
15473 : :
15474 : :
15475 : : /*
15476 : : BuildStmtNoteTok - adds a nop (with an assigned tokenno location) to the code.
15477 : : */
15478 : :
15479 : 466138 : static void BuildStmtNoteTok (unsigned int tokenno)
15480 : : {
15481 : 466138 : NameKey_Name filename;
15482 : 466138 : M2Quads_QuadFrame f;
15483 : :
15484 : 466138 : f = GetQF (NextQuad-1);
15485 : : /* no need to have multiple notes at the same position. */
15486 : 466138 : if ((f->Operator != M2Quads_StatementNoteOp) || (f->Operand3 != tokenno))
15487 : : {
15488 : 459256 : filename = NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()));
15489 : 459256 : GenQuad (M2Quads_StatementNoteOp, (unsigned int ) (filename), SymbolTable_NulSym, tokenno);
15490 : : }
15491 : 466138 : }
15492 : :
15493 : :
15494 : : /*
15495 : : GetRecordOrField -
15496 : : */
15497 : :
15498 : 1218 : static unsigned int GetRecordOrField (void)
15499 : : {
15500 : 1218 : unsigned int f;
15501 : :
15502 : 1218 : VarientFieldNo += 1;
15503 : 1218 : f = static_cast<unsigned int> (Lists_GetItemFromList (VarientFields, VarientFieldNo));
15504 : 1218 : if (DebugVarients)
15505 : : {
15506 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
15507 : : if (SymbolTable_IsRecord (f))
15508 : : {
15509 : : 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));
15510 : : }
15511 : : else
15512 : : {
15513 : : 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));
15514 : : }
15515 : : }
15516 : 1218 : return f;
15517 : : /* static analysis guarentees a RETURN statement will be used before here. */
15518 : : __builtin_unreachable ();
15519 : : }
15520 : :
15521 : :
15522 : : /*
15523 : : PushTFAD - Push True, False, Array, Dim, numbers onto the
15524 : : True/False stack. True and False are assumed to
15525 : : contain Symbols or Ident etc.
15526 : : */
15527 : :
15528 : 336 : static void PushTFAD (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim)
15529 : : {
15530 : 336 : M2Quads_BoolFrame f;
15531 : :
15532 : 336 : f = newBoolFrame ();
15533 : 336 : f->TrueExit = static_cast<unsigned int> (True);
15534 : 336 : f->FalseExit = static_cast<unsigned int> (False);
15535 : 336 : f->Unbounded = static_cast<unsigned int> (Array);
15536 : 336 : f->Dimension = static_cast<unsigned int> (Dim);
15537 : 336 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15538 : 336 : }
15539 : :
15540 : :
15541 : : /*
15542 : : PushTFADtok - Push True, False, Array, Dim, numbers onto the
15543 : : True/False stack. True and False are assumed to
15544 : : contain Symbols or Ident etc.
15545 : : */
15546 : :
15547 : 3110 : static void PushTFADtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int tokno)
15548 : : {
15549 : 3110 : M2Quads_BoolFrame f;
15550 : :
15551 : 3110 : f = newBoolFrame ();
15552 : 3110 : f->TrueExit = static_cast<unsigned int> (True);
15553 : 3110 : f->FalseExit = static_cast<unsigned int> (False);
15554 : 3110 : f->Unbounded = static_cast<unsigned int> (Array);
15555 : 3110 : f->Dimension = static_cast<unsigned int> (Dim);
15556 : 3110 : f->tokenno = tokno;
15557 : 3110 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15558 : 3110 : }
15559 : :
15560 : :
15561 : : /*
15562 : : PushTFADrwtok - Push True, False, Array, Dim, rw, numbers onto the
15563 : : True/False stack. True and False are assumed to
15564 : : contain Symbols or Ident etc.
15565 : : */
15566 : :
15567 : 7662 : static void PushTFADrwtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int rw, unsigned int Tok)
15568 : : {
15569 : 7662 : M2Quads_BoolFrame f;
15570 : :
15571 : 7662 : f = newBoolFrame ();
15572 : 7662 : f->TrueExit = static_cast<unsigned int> (True);
15573 : 7662 : f->FalseExit = static_cast<unsigned int> (False);
15574 : 7662 : f->Unbounded = static_cast<unsigned int> (Array);
15575 : 7662 : f->Dimension = static_cast<unsigned int> (Dim);
15576 : 7662 : f->ReadWrite = static_cast<unsigned int> (rw);
15577 : 7662 : f->tokenno = Tok;
15578 : 7662 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15579 : 7662 : }
15580 : :
15581 : :
15582 : : /*
15583 : : PopTFrwtok - Pop a True and False number from the True/False stack.
15584 : : True and False are assumed to contain Symbols or Ident etc.
15585 : : */
15586 : :
15587 : 268394 : static void PopTFrwtok (unsigned int *True, unsigned int *False, unsigned int *rw, unsigned int *tokno)
15588 : : {
15589 : 268394 : M2Quads_BoolFrame f;
15590 : :
15591 : 268394 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15592 : 268394 : (*True) = static_cast<unsigned int> (f->TrueExit);
15593 : 268394 : (*False) = static_cast<unsigned int> (f->FalseExit);
15594 : 268394 : M2Debug_Assert (! f->BooleanOp);
15595 : 268394 : (*rw) = static_cast<unsigned int> (f->ReadWrite);
15596 : 268394 : (*tokno) = f->tokenno;
15597 : 268394 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15598 : 268394 : }
15599 : :
15600 : :
15601 : : /*
15602 : : PushTFrwtok - Push an item onto the stack in the T (true) position,
15603 : : it is assummed to be a token and its token location is recorded.
15604 : : */
15605 : :
15606 : 300176 : static void PushTFrwtok (unsigned int True, unsigned int False, unsigned int rw, unsigned int tokno)
15607 : : {
15608 : 300176 : M2Quads_BoolFrame f;
15609 : :
15610 : 300176 : f = newBoolFrame ();
15611 : 300176 : f->TrueExit = static_cast<unsigned int> (True);
15612 : 300176 : f->FalseExit = static_cast<unsigned int> (False);
15613 : 300176 : f->ReadWrite = static_cast<unsigned int> (rw);
15614 : 300176 : f->tokenno = tokno;
15615 : 300176 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15616 : 300176 : }
15617 : :
15618 : :
15619 : : /*
15620 : : PushTFDtok - Push True, False, Dim, numbers onto the
15621 : : True/False stack. True and False are assumed to
15622 : : contain Symbols or Ident etc.
15623 : : */
15624 : :
15625 : 222 : static void PushTFDtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int Tok)
15626 : : {
15627 : 222 : M2Quads_BoolFrame f;
15628 : :
15629 : 222 : f = newBoolFrame ();
15630 : 222 : f->TrueExit = static_cast<unsigned int> (True);
15631 : 222 : f->FalseExit = static_cast<unsigned int> (False);
15632 : 222 : f->Dimension = static_cast<unsigned int> (Dim);
15633 : 222 : f->tokenno = Tok;
15634 : 222 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15635 : 222 : }
15636 : :
15637 : :
15638 : : /*
15639 : : PopTFDtok - Pop a True, False, Dim number from the True/False stack.
15640 : : True and False are assumed to contain Symbols or Ident etc.
15641 : : */
15642 : :
15643 : 222 : static void PopTFDtok (unsigned int *True, unsigned int *False, unsigned int *Dim, unsigned int *Tok)
15644 : : {
15645 : 222 : M2Quads_BoolFrame f;
15646 : :
15647 : 222 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15648 : 222 : (*True) = static_cast<unsigned int> (f->TrueExit);
15649 : 222 : (*False) = static_cast<unsigned int> (f->FalseExit);
15650 : 222 : (*Dim) = static_cast<unsigned int> (f->Dimension);
15651 : 222 : (*Tok) = f->tokenno;
15652 : 222 : M2Debug_Assert (! f->BooleanOp);
15653 : 222 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15654 : 222 : }
15655 : :
15656 : :
15657 : : /*
15658 : : PushTFDrwtok - Push True, False, Dim, numbers onto the
15659 : : True/False stack. True and False are assumed to
15660 : : contain Symbols or Ident etc.
15661 : : */
15662 : :
15663 : 41198 : static void PushTFDrwtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int rw, unsigned int Tok)
15664 : : {
15665 : 41198 : M2Quads_BoolFrame f;
15666 : :
15667 : 41198 : f = newBoolFrame ();
15668 : 41198 : f->TrueExit = static_cast<unsigned int> (True);
15669 : 41198 : f->FalseExit = static_cast<unsigned int> (False);
15670 : 41198 : f->Dimension = static_cast<unsigned int> (Dim);
15671 : 41198 : f->ReadWrite = static_cast<unsigned int> (rw);
15672 : 41198 : f->tokenno = Tok;
15673 : 41198 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15674 : 41198 : }
15675 : :
15676 : :
15677 : : /*
15678 : : PushTFrw - Push a True and False numbers onto the True/False stack.
15679 : : True and False are assumed to contain Symbols or Ident etc.
15680 : : It also pushes the higher level symbol which is associated
15681 : : with the True symbol. Eg record variable or array variable.
15682 : : */
15683 : :
15684 : 2366 : static void PushTFrw (unsigned int True, unsigned int False, unsigned int rw)
15685 : : {
15686 : 2366 : M2Quads_BoolFrame f;
15687 : :
15688 : 2366 : f = newBoolFrame ();
15689 : 2366 : f->TrueExit = static_cast<unsigned int> (True);
15690 : 2366 : f->FalseExit = static_cast<unsigned int> (False);
15691 : 2366 : f->ReadWrite = rw;
15692 : 2366 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15693 : 2366 : }
15694 : :
15695 : :
15696 : : /*
15697 : : PopTFrw - Pop a True and False number from the True/False stack.
15698 : : True and False are assumed to contain Symbols or Ident etc.
15699 : : */
15700 : :
15701 : 30612 : static void PopTFrw (unsigned int *True, unsigned int *False, unsigned int *rw)
15702 : : {
15703 : 30612 : M2Quads_BoolFrame f;
15704 : :
15705 : 30612 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15706 : 30612 : (*True) = static_cast<unsigned int> (f->TrueExit);
15707 : 30612 : (*False) = static_cast<unsigned int> (f->FalseExit);
15708 : 30612 : M2Debug_Assert (! f->BooleanOp);
15709 : 30612 : (*rw) = static_cast<unsigned int> (f->ReadWrite);
15710 : 30612 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15711 : 30612 : }
15712 : :
15713 : :
15714 : : /*
15715 : : newBoolFrame - creates a new BoolFrame with all fields initialised to their defaults.
15716 : : */
15717 : :
15718 : 204033301 : static M2Quads_BoolFrame newBoolFrame (void)
15719 : : {
15720 : 204033301 : M2Quads_BoolFrame f;
15721 : :
15722 : 204033301 : Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15723 : 204033301 : f->TrueExit = 0;
15724 : 204033301 : f->FalseExit = 0;
15725 : 204033301 : f->Unbounded = SymbolTable_NulSym;
15726 : 204033301 : f->BooleanOp = false;
15727 : 204033301 : f->Dimension = 0;
15728 : 204033301 : f->ReadWrite = SymbolTable_NulSym;
15729 : 204033301 : f->name = SymbolTable_NulSym;
15730 : 204033301 : f->Annotation = static_cast<DynamicStrings_String> (NULL);
15731 : 204033301 : f->tokenno = M2LexBuf_UnknownTokenNo;
15732 : 204033301 : return f;
15733 : : /* static analysis guarentees a RETURN statement will be used before here. */
15734 : : __builtin_unreachable ();
15735 : : }
15736 : :
15737 : :
15738 : : /*
15739 : : PushTrwtok - Push an item onto the True/False stack. The False value will be zero.
15740 : : */
15741 : :
15742 : 144 : static void PushTrwtok (unsigned int True, unsigned int rw, unsigned int tok)
15743 : : {
15744 : 144 : M2Quads_BoolFrame f;
15745 : :
15746 : 144 : f = newBoolFrame ();
15747 : 144 : f->TrueExit = static_cast<unsigned int> (True);
15748 : 144 : f->ReadWrite = static_cast<unsigned int> (rw);
15749 : 144 : f->tokenno = tok;
15750 : 144 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15751 : 144 : }
15752 : :
15753 : :
15754 : : /*
15755 : : PopTrw - Pop a True field and rw symbol from the stack.
15756 : : */
15757 : :
15758 : 2366 : static void PopTrw (unsigned int *True, unsigned int *rw)
15759 : : {
15760 : 2366 : M2Quads_BoolFrame f;
15761 : :
15762 : 2366 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15763 : 2366 : (*True) = static_cast<unsigned int> (f->TrueExit);
15764 : 2366 : M2Debug_Assert (! f->BooleanOp);
15765 : 2366 : (*rw) = static_cast<unsigned int> (f->ReadWrite);
15766 : 2366 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15767 : 2366 : }
15768 : :
15769 : :
15770 : : /*
15771 : : PopTrwtok - Pop a True field and rw symbol from the stack.
15772 : : */
15773 : :
15774 : 906229 : static void PopTrwtok (unsigned int *True, unsigned int *rw, unsigned int *tok)
15775 : : {
15776 : 906229 : M2Quads_BoolFrame f;
15777 : :
15778 : 906229 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15779 : 906229 : (*True) = static_cast<unsigned int> (f->TrueExit);
15780 : 906229 : M2Debug_Assert (! f->BooleanOp);
15781 : 906229 : (*rw) = static_cast<unsigned int> (f->ReadWrite);
15782 : 906229 : (*tok) = f->tokenno;
15783 : 906229 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15784 : 906229 : }
15785 : :
15786 : :
15787 : : /*
15788 : : Init - initialize the M2Quads module, all the stacks, all the lists
15789 : : and the quads list.
15790 : : */
15791 : :
15792 : 15392 : static void Init (void)
15793 : : {
15794 : 15392 : LogicalOrTok = NameKey_MakeKey ((const char *) "_LOR", 4);
15795 : 15392 : LogicalAndTok = NameKey_MakeKey ((const char *) "_LAND", 5);
15796 : 15392 : LogicalXorTok = NameKey_MakeKey ((const char *) "_LXOR", 5);
15797 : 15392 : LogicalDifferenceTok = NameKey_MakeKey ((const char *) "_LDIFF", 6);
15798 : 15392 : ArithPlusTok = NameKey_MakeKey ((const char *) "_ARITH_+", 8);
15799 : 15392 : QuadArray = Indexing_InitIndexTuned (1, (1024*1024) / 16, 16);
15800 : 15392 : FreeList = 1;
15801 : 15392 : NewQuad (&NextQuad);
15802 : 15392 : M2Debug_Assert (NextQuad == 1);
15803 : 15392 : BoolStack = M2StackAddress_InitStackAddress ();
15804 : 15392 : ExitStack = M2StackWord_InitStackWord ();
15805 : 15392 : RepeatStack = M2StackWord_InitStackWord ();
15806 : 15392 : WhileStack = M2StackWord_InitStackWord ();
15807 : 15392 : ForStack = M2StackWord_InitStackWord ();
15808 : 15392 : WithStack = M2StackAddress_InitStackAddress ();
15809 : 15392 : ReturnStack = M2StackWord_InitStackWord ();
15810 : 15392 : LineStack = M2StackAddress_InitStackAddress ();
15811 : 15392 : PriorityStack = M2StackWord_InitStackWord ();
15812 : 15392 : TryStack = M2StackWord_InitStackWord ();
15813 : 15392 : CatchStack = M2StackWord_InitStackWord ();
15814 : 15392 : ExceptStack = M2StackWord_InitStackWord ();
15815 : 15392 : ConstructorStack = M2StackAddress_InitStackAddress ();
15816 : 15392 : ConstParamStack = M2StackWord_InitStackWord ();
15817 : 15392 : ConstExprStack = M2StackWord_InitStackWord ();
15818 : : /* StressStack ; */
15819 : 15392 : SuppressWith = false;
15820 : 15392 : Head = 1;
15821 : 15392 : LastQuadNo = 0;
15822 : 15392 : MustNotCheckBounds = false;
15823 : 15392 : InitQuad = 0;
15824 : 15392 : GrowInitialization = 0;
15825 : 15392 : ForInfo = Indexing_InitIndex (1);
15826 : 15392 : QuadrupleGeneration = true;
15827 : 15392 : BuildingHigh = false;
15828 : 15392 : BuildingSize = false;
15829 : 15392 : AutoStack = M2StackWord_InitStackWord ();
15830 : 15392 : IsAutoOn = true;
15831 : 15392 : InConstExpression = false;
15832 : 15392 : InConstParameters = false;
15833 : 15392 : FreeLineList = NULL;
15834 : 15392 : Lists_InitList (&VarientFields);
15835 : 15392 : VarientFieldNo = 0;
15836 : 15392 : NoOfQuads = 0;
15837 : 15392 : }
15838 : :
15839 : :
15840 : : /*
15841 : : SetOptionCoding - builds a code quadruple if the profiling
15842 : : option was given to the compiler.
15843 : : */
15844 : :
15845 : 0 : extern "C" void M2Quads_SetOptionCoding (bool b)
15846 : : {
15847 : 0 : if (b != M2Options_Coding)
15848 : : {
15849 : 0 : if (b)
15850 : : {
15851 : 0 : M2Quads_BuildCodeOn ();
15852 : : }
15853 : : else
15854 : : {
15855 : 0 : M2Quads_BuildCodeOff ();
15856 : : }
15857 : 0 : M2Options_Coding = b;
15858 : : }
15859 : 0 : }
15860 : :
15861 : :
15862 : : /*
15863 : : SetOptionProfiling - builds a profile quadruple if the profiling
15864 : : option was given to the compiler.
15865 : : */
15866 : :
15867 : 0 : extern "C" void M2Quads_SetOptionProfiling (bool b)
15868 : : {
15869 : 0 : if (b != M2Options_Profiling)
15870 : : {
15871 : 0 : if (b)
15872 : : {
15873 : 0 : M2Quads_BuildProfileOn ();
15874 : : }
15875 : : else
15876 : : {
15877 : 0 : M2Quads_BuildProfileOff ();
15878 : : }
15879 : 0 : M2Options_Profiling = b;
15880 : : }
15881 : 0 : }
15882 : :
15883 : :
15884 : : /*
15885 : : SetOptionOptimizing - builds a quadruple to say that the optimization option
15886 : : has been found in a comment.
15887 : : */
15888 : :
15889 : 0 : extern "C" void M2Quads_SetOptionOptimizing (bool b)
15890 : : {
15891 : 0 : if (b)
15892 : : {
15893 : 0 : M2Quads_BuildOptimizeOn ();
15894 : : }
15895 : : else
15896 : : {
15897 : 0 : M2Quads_BuildOptimizeOff ();
15898 : : }
15899 : 0 : }
15900 : :
15901 : :
15902 : : /*
15903 : : Opposite - returns the opposite comparison operator.
15904 : : */
15905 : :
15906 : 68195 : extern "C" M2Quads_QuadOperator M2Quads_Opposite (M2Quads_QuadOperator Operator)
15907 : : {
15908 : 68195 : M2Quads_QuadOperator Op;
15909 : :
15910 : 68195 : switch (Operator)
15911 : : {
15912 : : case M2Quads_IfNotEquOp:
15913 : : Op = M2Quads_IfEquOp;
15914 : : break;
15915 : :
15916 : : case M2Quads_IfEquOp:
15917 : : Op = M2Quads_IfNotEquOp;
15918 : : break;
15919 : :
15920 : : case M2Quads_IfLessEquOp:
15921 : : Op = M2Quads_IfGreOp;
15922 : : break;
15923 : :
15924 : : case M2Quads_IfGreOp:
15925 : : Op = M2Quads_IfLessEquOp;
15926 : : break;
15927 : :
15928 : : case M2Quads_IfGreEquOp:
15929 : : Op = M2Quads_IfLessOp;
15930 : : break;
15931 : :
15932 : : case M2Quads_IfLessOp:
15933 : : Op = M2Quads_IfGreEquOp;
15934 : : break;
15935 : :
15936 : : case M2Quads_IfInOp:
15937 : : Op = M2Quads_IfNotInOp;
15938 : : break;
15939 : :
15940 : : case M2Quads_IfNotInOp:
15941 : : Op = M2Quads_IfInOp;
15942 : : break;
15943 : :
15944 : :
15945 : 0 : default:
15946 : 0 : M2Error_InternalError ((const char *) "unexpected operator", 19);
15947 : 68195 : break;
15948 : : }
15949 : 68195 : return Op;
15950 : : /* static analysis guarentees a RETURN statement will be used before here. */
15951 : : __builtin_unreachable ();
15952 : : }
15953 : :
15954 : :
15955 : : /*
15956 : : IsReferenced - returns true if QuadNo is referenced by another quadruple.
15957 : : */
15958 : :
15959 : 167717058 : extern "C" bool M2Quads_IsReferenced (unsigned int QuadNo)
15960 : : {
15961 : 167717058 : M2Quads_QuadFrame f;
15962 : :
15963 : 167717058 : f = GetQF (QuadNo);
15964 : 167717058 : return ((f->Operator == M2Quads_ProcedureScopeOp) || (f->Operator == M2Quads_NewLocalVarOp)) || (f->NoOfTimesReferenced > 0);
15965 : : /* static analysis guarentees a RETURN statement will be used before here. */
15966 : : __builtin_unreachable ();
15967 : : }
15968 : :
15969 : :
15970 : : /*
15971 : : IsBackReference - returns TRUE if quadruple, q, is referenced from a quad further on.
15972 : : */
15973 : :
15974 : 7367 : extern "C" bool M2Quads_IsBackReference (unsigned int q)
15975 : : {
15976 : 7367 : unsigned int i;
15977 : 7367 : M2Quads_QuadOperator op;
15978 : 7367 : unsigned int op1;
15979 : 7367 : unsigned int op2;
15980 : 7367 : unsigned int op3;
15981 : :
15982 : 7367 : i = q;
15983 : 27104 : while (i != 0)
15984 : : {
15985 : 27104 : M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
15986 : 27104 : switch (op)
15987 : : {
15988 : : case M2Quads_NewLocalVarOp:
15989 : : case M2Quads_KillLocalVarOp:
15990 : : case M2Quads_FinallyStartOp:
15991 : : case M2Quads_FinallyEndOp:
15992 : : case M2Quads_InitEndOp:
15993 : : case M2Quads_InitStartOp:
15994 : : case M2Quads_EndFileOp:
15995 : : case M2Quads_StartDefFileOp:
15996 : : case M2Quads_StartModFileOp:
15997 : : return false; /* run into end of procedure or module */
15998 : 708 : break;
15999 : :
16000 : 708 : case M2Quads_GotoOp:
16001 : 708 : case M2Quads_IfEquOp:
16002 : 708 : case M2Quads_IfLessEquOp:
16003 : 708 : case M2Quads_IfGreEquOp:
16004 : 708 : case M2Quads_IfGreOp:
16005 : 708 : case M2Quads_IfLessOp:
16006 : 708 : case M2Quads_IfNotEquOp:
16007 : 708 : case M2Quads_IfInOp:
16008 : 708 : case M2Quads_IfNotInOp:
16009 : 708 : if (op3 == q) /* run into end of procedure or module */
16010 : : {
16011 : : return true;
16012 : : }
16013 : : break;
16014 : :
16015 : :
16016 : : default:
16017 : : break;
16018 : : }
16019 : 19737 : i = M2Quads_GetNextQuad (i);
16020 : : }
16021 : 0 : M2Error_InternalError ((const char *) "fix this for the sake of efficiency..", 37);
16022 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
16023 : : __builtin_unreachable ();
16024 : : }
16025 : :
16026 : :
16027 : : /*
16028 : : IsUnConditional - returns true if QuadNo is an unconditional jump.
16029 : : */
16030 : :
16031 : 313451188 : extern "C" bool M2Quads_IsUnConditional (unsigned int QuadNo)
16032 : : {
16033 : 313451188 : M2Quads_QuadFrame f;
16034 : :
16035 : 313451188 : f = GetQF (QuadNo);
16036 : 313451188 : switch (f->Operator)
16037 : : {
16038 : : case M2Quads_ThrowOp:
16039 : : case M2Quads_RetryOp:
16040 : : case M2Quads_CallOp:
16041 : : case M2Quads_ReturnOp:
16042 : : case M2Quads_GotoOp:
16043 : : return true;
16044 : 298283117 : break;
16045 : :
16046 : :
16047 : 298283117 : default:
16048 : 298283117 : return false;
16049 : : break;
16050 : : }
16051 : : /* static analysis guarentees a RETURN statement will be used before here. */
16052 : : __builtin_unreachable ();
16053 : : }
16054 : :
16055 : :
16056 : : /*
16057 : : IsConditional - returns true if QuadNo is a conditional jump.
16058 : : */
16059 : :
16060 : 313468029 : extern "C" bool M2Quads_IsConditional (unsigned int QuadNo)
16061 : : {
16062 : 313468029 : M2Quads_QuadFrame f;
16063 : :
16064 : 313468029 : f = GetQF (QuadNo);
16065 : 313468029 : switch (f->Operator)
16066 : : {
16067 : : case M2Quads_IfInOp:
16068 : : case M2Quads_IfNotInOp:
16069 : : case M2Quads_IfEquOp:
16070 : : case M2Quads_IfNotEquOp:
16071 : : case M2Quads_IfLessOp:
16072 : : case M2Quads_IfLessEquOp:
16073 : : case M2Quads_IfGreOp:
16074 : : case M2Quads_IfGreEquOp:
16075 : : return true;
16076 : 310415889 : break;
16077 : :
16078 : :
16079 : 310415889 : default:
16080 : 310415889 : return false;
16081 : : break;
16082 : : }
16083 : : /* static analysis guarentees a RETURN statement will be used before here. */
16084 : : __builtin_unreachable ();
16085 : : }
16086 : :
16087 : :
16088 : : /*
16089 : : IsBackReferenceConditional - returns TRUE if quadruple, q, is referenced from
16090 : : a conditional quad further on.
16091 : : */
16092 : :
16093 : 0 : extern "C" bool M2Quads_IsBackReferenceConditional (unsigned int q)
16094 : : {
16095 : 0 : unsigned int i;
16096 : 0 : M2Quads_QuadOperator op;
16097 : 0 : unsigned int op1;
16098 : 0 : unsigned int op2;
16099 : 0 : unsigned int op3;
16100 : :
16101 : 0 : i = q;
16102 : 0 : while (i != 0)
16103 : : {
16104 : 0 : M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
16105 : 0 : switch (op)
16106 : : {
16107 : : case M2Quads_NewLocalVarOp:
16108 : : case M2Quads_KillLocalVarOp:
16109 : : case M2Quads_FinallyStartOp:
16110 : : case M2Quads_FinallyEndOp:
16111 : : case M2Quads_InitEndOp:
16112 : : case M2Quads_InitStartOp:
16113 : : case M2Quads_EndFileOp:
16114 : : case M2Quads_StartDefFileOp:
16115 : : case M2Quads_StartModFileOp:
16116 : : return false; /* run into end of procedure or module */
16117 : 0 : break;
16118 : :
16119 : 0 : case M2Quads_TryOp:
16120 : 0 : case M2Quads_RetryOp:
16121 : 0 : case M2Quads_GotoOp:
16122 : 0 : case M2Quads_IfEquOp:
16123 : 0 : case M2Quads_IfLessEquOp:
16124 : 0 : case M2Quads_IfGreEquOp:
16125 : 0 : case M2Quads_IfGreOp:
16126 : 0 : case M2Quads_IfLessOp:
16127 : 0 : case M2Quads_IfNotEquOp:
16128 : 0 : case M2Quads_IfInOp:
16129 : 0 : case M2Quads_IfNotInOp:
16130 : 0 : if ((op3 == q) && (M2Quads_IsConditional (q))) /* run into end of procedure or module */
16131 : : {
16132 : : return true;
16133 : : }
16134 : 0 : break;
16135 : :
16136 : :
16137 : : default:
16138 : : return false;
16139 : 0 : break;
16140 : : }
16141 : 0 : i = M2Quads_GetNextQuad (i);
16142 : : }
16143 : 0 : M2Error_InternalError ((const char *) "fix this for the sake of efficiency..", 37);
16144 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
16145 : : __builtin_unreachable ();
16146 : : }
16147 : :
16148 : :
16149 : : /*
16150 : : IsGoto - returns true if QuadNo is a goto operation.
16151 : : */
16152 : :
16153 : 7367 : extern "C" bool M2Quads_IsGoto (unsigned int QuadNo)
16154 : : {
16155 : 7367 : return IsQuadA (QuadNo, M2Quads_GotoOp);
16156 : : /* static analysis guarentees a RETURN statement will be used before here. */
16157 : : __builtin_unreachable ();
16158 : : }
16159 : :
16160 : :
16161 : : /*
16162 : : IsCall - returns true if QuadNo is a call operation.
16163 : : */
16164 : :
16165 : 313458555 : extern "C" bool M2Quads_IsCall (unsigned int QuadNo)
16166 : : {
16167 : 313458555 : return IsQuadA (QuadNo, M2Quads_CallOp);
16168 : : /* static analysis guarentees a RETURN statement will be used before here. */
16169 : : __builtin_unreachable ();
16170 : : }
16171 : :
16172 : :
16173 : : /*
16174 : : IsReturn - returns true if QuadNo is a return operation.
16175 : : */
16176 : :
16177 : 313557871 : extern "C" bool M2Quads_IsReturn (unsigned int QuadNo)
16178 : : {
16179 : 313557871 : return IsQuadA (QuadNo, M2Quads_ReturnOp);
16180 : : /* static analysis guarentees a RETURN statement will be used before here. */
16181 : : __builtin_unreachable ();
16182 : : }
16183 : :
16184 : :
16185 : : /*
16186 : : IsProcedureScope - returns true if QuadNo is a ProcedureScope operation.
16187 : : */
16188 : :
16189 : 0 : extern "C" bool M2Quads_IsProcedureScope (unsigned int QuadNo)
16190 : : {
16191 : 0 : return IsQuadA (QuadNo, M2Quads_ProcedureScopeOp);
16192 : : /* static analysis guarentees a RETURN statement will be used before here. */
16193 : : __builtin_unreachable ();
16194 : : }
16195 : :
16196 : :
16197 : : /*
16198 : : IsNewLocalVar - returns true if QuadNo is a NewLocalVar operation.
16199 : : */
16200 : :
16201 : 0 : extern "C" bool M2Quads_IsNewLocalVar (unsigned int QuadNo)
16202 : : {
16203 : 0 : return IsQuadA (QuadNo, M2Quads_NewLocalVarOp);
16204 : : /* static analysis guarentees a RETURN statement will be used before here. */
16205 : : __builtin_unreachable ();
16206 : : }
16207 : :
16208 : :
16209 : : /*
16210 : : IsKillLocalVar - returns true if QuadNo is a KillLocalVar operation.
16211 : : */
16212 : :
16213 : 102165 : extern "C" bool M2Quads_IsKillLocalVar (unsigned int QuadNo)
16214 : : {
16215 : 102165 : return IsQuadA (QuadNo, M2Quads_KillLocalVarOp);
16216 : : /* static analysis guarentees a RETURN statement will be used before here. */
16217 : : __builtin_unreachable ();
16218 : : }
16219 : :
16220 : :
16221 : : /*
16222 : : IsCatchBegin - returns true if QuadNo is a catch begin quad.
16223 : : */
16224 : :
16225 : 78094 : extern "C" bool M2Quads_IsCatchBegin (unsigned int QuadNo)
16226 : : {
16227 : 78094 : return IsQuadA (QuadNo, M2Quads_CatchBeginOp);
16228 : : /* static analysis guarentees a RETURN statement will be used before here. */
16229 : : __builtin_unreachable ();
16230 : : }
16231 : :
16232 : :
16233 : : /*
16234 : : IsCatchEnd - returns true if QuadNo is a catch end quad.
16235 : : */
16236 : :
16237 : 90280 : extern "C" bool M2Quads_IsCatchEnd (unsigned int QuadNo)
16238 : : {
16239 : 90280 : return IsQuadA (QuadNo, M2Quads_CatchEndOp);
16240 : : /* static analysis guarentees a RETURN statement will be used before here. */
16241 : : __builtin_unreachable ();
16242 : : }
16243 : :
16244 : :
16245 : : /*
16246 : : IsInitStart - returns true if QuadNo is a init start quad.
16247 : : */
16248 : :
16249 : 78094 : extern "C" bool M2Quads_IsInitStart (unsigned int QuadNo)
16250 : : {
16251 : 78094 : return IsQuadA (QuadNo, M2Quads_InitStartOp);
16252 : : /* static analysis guarentees a RETURN statement will be used before here. */
16253 : : __builtin_unreachable ();
16254 : : }
16255 : :
16256 : :
16257 : : /*
16258 : : IsInitEnd - returns true if QuadNo is a init end quad.
16259 : : */
16260 : :
16261 : 78094 : extern "C" bool M2Quads_IsInitEnd (unsigned int QuadNo)
16262 : : {
16263 : 78094 : return IsQuadA (QuadNo, M2Quads_InitEndOp);
16264 : : /* static analysis guarentees a RETURN statement will be used before here. */
16265 : : __builtin_unreachable ();
16266 : : }
16267 : :
16268 : :
16269 : : /*
16270 : : IsFinallyStart - returns true if QuadNo is a finally start quad.
16271 : : */
16272 : :
16273 : 73852 : extern "C" bool M2Quads_IsFinallyStart (unsigned int QuadNo)
16274 : : {
16275 : 73852 : return IsQuadA (QuadNo, M2Quads_FinallyStartOp);
16276 : : /* static analysis guarentees a RETURN statement will be used before here. */
16277 : : __builtin_unreachable ();
16278 : : }
16279 : :
16280 : :
16281 : : /*
16282 : : IsFinallyEnd - returns true if QuadNo is a finally end quad.
16283 : : */
16284 : :
16285 : 69610 : extern "C" bool M2Quads_IsFinallyEnd (unsigned int QuadNo)
16286 : : {
16287 : 69610 : return IsQuadA (QuadNo, M2Quads_FinallyEndOp);
16288 : : /* static analysis guarentees a RETURN statement will be used before here. */
16289 : : __builtin_unreachable ();
16290 : : }
16291 : :
16292 : :
16293 : : /*
16294 : : IsBecomes - return TRUE if QuadNo is a BecomesOp.
16295 : : */
16296 : :
16297 : 0 : extern "C" bool M2Quads_IsBecomes (unsigned int QuadNo)
16298 : : {
16299 : 0 : return IsQuadA (QuadNo, M2Quads_BecomesOp);
16300 : : /* static analysis guarentees a RETURN statement will be used before here. */
16301 : : __builtin_unreachable ();
16302 : : }
16303 : :
16304 : :
16305 : : /*
16306 : : IsDummy - return TRUE if QuadNo is a DummyOp.
16307 : : */
16308 : :
16309 : 0 : extern "C" bool M2Quads_IsDummy (unsigned int QuadNo)
16310 : : {
16311 : 0 : return IsQuadA (QuadNo, M2Quads_DummyOp);
16312 : : /* static analysis guarentees a RETURN statement will be used before here. */
16313 : : __builtin_unreachable ();
16314 : : }
16315 : :
16316 : :
16317 : : /*
16318 : : IsQuadConstExpr - returns TRUE if QuadNo is part of a constant expression.
16319 : : */
16320 : :
16321 : 0 : extern "C" bool M2Quads_IsQuadConstExpr (unsigned int QuadNo)
16322 : : {
16323 : 0 : M2Quads_QuadFrame f;
16324 : :
16325 : 0 : f = GetQF (QuadNo);
16326 : 0 : return f->ConstExpr;
16327 : : /* static analysis guarentees a RETURN statement will be used before here. */
16328 : : __builtin_unreachable ();
16329 : : }
16330 : :
16331 : :
16332 : : /*
16333 : : SetQuadConstExpr - sets the constexpr field to value.
16334 : : */
16335 : :
16336 : 0 : extern "C" void M2Quads_SetQuadConstExpr (unsigned int QuadNo, bool value)
16337 : : {
16338 : 0 : M2Quads_QuadFrame f;
16339 : :
16340 : 0 : f = GetQF (QuadNo);
16341 : 0 : f->ConstExpr = value;
16342 : 0 : }
16343 : :
16344 : :
16345 : : /*
16346 : : GetQuadDest - returns the jump destination associated with quad.
16347 : : */
16348 : :
16349 : 0 : extern "C" unsigned int M2Quads_GetQuadDest (unsigned int QuadNo)
16350 : : {
16351 : 0 : return M2Quads_GetQuadOp3 (QuadNo);
16352 : : /* static analysis guarentees a RETURN statement will be used before here. */
16353 : : __builtin_unreachable ();
16354 : : }
16355 : :
16356 : :
16357 : : /*
16358 : : GetQuadOp1 - returns the 1st operand associated with quad.
16359 : : */
16360 : :
16361 : 0 : extern "C" unsigned int M2Quads_GetQuadOp1 (unsigned int QuadNo)
16362 : : {
16363 : 0 : M2Quads_QuadFrame f;
16364 : :
16365 : 0 : f = GetQF (QuadNo);
16366 : 0 : return f->Operand1;
16367 : : /* static analysis guarentees a RETURN statement will be used before here. */
16368 : : __builtin_unreachable ();
16369 : : }
16370 : :
16371 : :
16372 : : /*
16373 : : GetQuadOp2 - returns the 2nd operand associated with quad.
16374 : : */
16375 : :
16376 : 0 : extern "C" unsigned int M2Quads_GetQuadOp2 (unsigned int QuadNo)
16377 : : {
16378 : 0 : M2Quads_QuadFrame f;
16379 : :
16380 : 0 : f = GetQF (QuadNo);
16381 : 0 : return f->Operand2;
16382 : : /* static analysis guarentees a RETURN statement will be used before here. */
16383 : : __builtin_unreachable ();
16384 : : }
16385 : :
16386 : :
16387 : : /*
16388 : : GetQuadOp3 - returns the 3rd operand associated with quad.
16389 : : */
16390 : :
16391 : 0 : extern "C" unsigned int M2Quads_GetQuadOp3 (unsigned int QuadNo)
16392 : : {
16393 : 0 : M2Quads_QuadFrame f;
16394 : :
16395 : 0 : f = GetQF (QuadNo);
16396 : 0 : return f->Operand3;
16397 : : /* static analysis guarentees a RETURN statement will be used before here. */
16398 : : __builtin_unreachable ();
16399 : : }
16400 : :
16401 : :
16402 : : /*
16403 : : IsInitialisingConst - returns TRUE if the quadruple is setting
16404 : : a const (op1) with a value.
16405 : : */
16406 : :
16407 : 0 : extern "C" bool M2Quads_IsInitialisingConst (unsigned int QuadNo)
16408 : : {
16409 : 0 : M2Quads_QuadOperator op;
16410 : 0 : unsigned int op1;
16411 : 0 : unsigned int op2;
16412 : 0 : unsigned int op3;
16413 : :
16414 : 0 : M2Quads_GetQuad (QuadNo, &op, &op1, &op2, &op3);
16415 : 0 : return (OpUsesOp1 (op)) && (SymbolTable_IsConst (op1));
16416 : : /* static analysis guarentees a RETURN statement will be used before here. */
16417 : : __builtin_unreachable ();
16418 : : }
16419 : :
16420 : :
16421 : : /*
16422 : : IsConstQuad - return TRUE if the quadruple is marked as a constexpr.
16423 : : */
16424 : :
16425 : 0 : extern "C" bool M2Quads_IsConstQuad (unsigned int quad)
16426 : : {
16427 : 0 : M2Quads_QuadFrame f;
16428 : :
16429 : 0 : f = GetQF (quad);
16430 : 0 : return f->ConstExpr;
16431 : : /* static analysis guarentees a RETURN statement will be used before here. */
16432 : : __builtin_unreachable ();
16433 : : }
16434 : :
16435 : :
16436 : : /*
16437 : : IsConditionalBooleanQuad - return TRUE if operand 1 is a boolean result.
16438 : : */
16439 : :
16440 : 315619 : extern "C" bool M2Quads_IsConditionalBooleanQuad (unsigned int quad)
16441 : : {
16442 : 315619 : M2Quads_QuadFrame f;
16443 : :
16444 : 315619 : f = GetQF (quad);
16445 : 315619 : return ((OpUsesOp1 (f->Operator)) && ((SymbolTable_IsVar (f->Operand1)) || (SymbolTable_IsConst (f->Operand1)))) && (SymbolTable_IsVarConditional (f->Operand1));
16446 : : /* static analysis guarentees a RETURN statement will be used before here. */
16447 : : __builtin_unreachable ();
16448 : : }
16449 : :
16450 : :
16451 : : /*
16452 : : IsOptimizeOn - returns true if the Optimize flag was true at QuadNo.
16453 : : */
16454 : :
16455 : 0 : extern "C" bool M2Quads_IsOptimizeOn (unsigned int QuadNo)
16456 : : {
16457 : 0 : M2Quads_QuadFrame f;
16458 : 0 : unsigned int n;
16459 : 0 : unsigned int q;
16460 : 0 : bool On;
16461 : :
16462 : 0 : On = M2Options_Optimizing;
16463 : 0 : q = Head;
16464 : 0 : while ((q != 0) && (q != QuadNo))
16465 : : {
16466 : 0 : f = GetQF (q);
16467 : 0 : if (f->Operator == M2Quads_OptimizeOnOp)
16468 : : {
16469 : : On = true;
16470 : : }
16471 : 0 : else if (f->Operator == M2Quads_OptimizeOffOp)
16472 : : {
16473 : : /* avoid dangling else. */
16474 : 0 : On = false;
16475 : : }
16476 : 0 : n = f->Next;
16477 : 0 : q = n;
16478 : : }
16479 : 0 : return On;
16480 : : /* static analysis guarentees a RETURN statement will be used before here. */
16481 : : __builtin_unreachable ();
16482 : : }
16483 : :
16484 : :
16485 : : /*
16486 : : IsProfileOn - returns true if the Profile flag was true at QuadNo.
16487 : : */
16488 : :
16489 : 0 : extern "C" bool M2Quads_IsProfileOn (unsigned int QuadNo)
16490 : : {
16491 : 0 : M2Quads_QuadFrame f;
16492 : 0 : unsigned int n;
16493 : 0 : unsigned int q;
16494 : 0 : bool On;
16495 : :
16496 : 0 : On = M2Options_Profiling;
16497 : 0 : q = Head;
16498 : 0 : while ((q != 0) && (q != QuadNo))
16499 : : {
16500 : 0 : f = GetQF (q);
16501 : 0 : if (f->Operator == M2Quads_ProfileOnOp)
16502 : : {
16503 : : On = true;
16504 : : }
16505 : 0 : else if (f->Operator == M2Quads_ProfileOffOp)
16506 : : {
16507 : : /* avoid dangling else. */
16508 : 0 : On = false;
16509 : : }
16510 : 0 : n = f->Next;
16511 : 0 : q = n;
16512 : : }
16513 : 0 : return On;
16514 : : /* static analysis guarentees a RETURN statement will be used before here. */
16515 : : __builtin_unreachable ();
16516 : : }
16517 : :
16518 : :
16519 : : /*
16520 : : IsCodeOn - returns true if the Code flag was true at QuadNo.
16521 : : */
16522 : :
16523 : 0 : extern "C" bool M2Quads_IsCodeOn (unsigned int QuadNo)
16524 : : {
16525 : 0 : M2Quads_QuadFrame f;
16526 : 0 : unsigned int n;
16527 : 0 : unsigned int q;
16528 : 0 : bool On;
16529 : :
16530 : 0 : On = M2Options_Coding;
16531 : 0 : q = Head;
16532 : 0 : while ((q != 0) && (q != QuadNo))
16533 : : {
16534 : 0 : f = GetQF (q);
16535 : 0 : if (f->Operator == M2Quads_CodeOnOp)
16536 : : {
16537 : : On = true;
16538 : : }
16539 : 0 : else if (f->Operator == M2Quads_CodeOffOp)
16540 : : {
16541 : : /* avoid dangling else. */
16542 : 0 : On = false;
16543 : : }
16544 : 0 : n = f->Next;
16545 : 0 : q = n;
16546 : : }
16547 : 0 : return On;
16548 : : /* static analysis guarentees a RETURN statement will be used before here. */
16549 : : __builtin_unreachable ();
16550 : : }
16551 : :
16552 : :
16553 : : /*
16554 : : IsPseudoQuad - returns true if QuadNo is a compiler directive.
16555 : : ie code, profile and optimize.
16556 : : StartFile, EndFile,
16557 : : */
16558 : :
16559 : 18747319 : extern "C" bool M2Quads_IsPseudoQuad (unsigned int QuadNo)
16560 : : {
16561 : 18747319 : M2Quads_QuadFrame f;
16562 : :
16563 : 18747319 : f = GetQF (QuadNo);
16564 : 18747319 : 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);
16565 : : /* static analysis guarentees a RETURN statement will be used before here. */
16566 : : __builtin_unreachable ();
16567 : : }
16568 : :
16569 : :
16570 : : /*
16571 : : IsDefOrModFile - returns TRUE if QuadNo is a start of Module or Def file
16572 : : directive.
16573 : : */
16574 : :
16575 : 313451188 : extern "C" bool M2Quads_IsDefOrModFile (unsigned int QuadNo)
16576 : : {
16577 : 313451188 : M2Quads_QuadFrame f;
16578 : :
16579 : 313451188 : f = GetQF (QuadNo);
16580 : 313451188 : return (f->Operator == M2Quads_StartDefFileOp) || (f->Operator == M2Quads_StartModFileOp);
16581 : : /* static analysis guarentees a RETURN statement will be used before here. */
16582 : : __builtin_unreachable ();
16583 : : }
16584 : :
16585 : :
16586 : : /*
16587 : : DumpQuadruples - dump all quadruples providing the -fq, -fdump-lang-quad,
16588 : : -fdump-lang-quad= or -fdump-lang-all were issued to the
16589 : : command line.
16590 : : */
16591 : :
16592 : 72381 : extern "C" void M2Quads_DumpQuadruples (const char *title_, unsigned int _title_high)
16593 : : {
16594 : 72381 : char title[_title_high+1];
16595 : :
16596 : : /* make a local copy of each unbounded array. */
16597 : 72381 : memcpy (title, title_, _title_high+1);
16598 : :
16599 : 72381 : if (M2Options_GetDumpQuad ())
16600 : : {
16601 : 0 : M2LangDump_CreateDumpQuad ((const char *) title, _title_high);
16602 : 0 : if ((M2Options_GetM2DumpFilter ()) == NULL)
16603 : : {
16604 : 0 : DumpQuadrupleAll ();
16605 : : }
16606 : : else
16607 : : {
16608 : 0 : DumpQuadrupleFilter ();
16609 : : }
16610 : 0 : M2LangDump_CloseDumpQuad ();
16611 : : }
16612 : 72381 : }
16613 : :
16614 : :
16615 : : /*
16616 : : DisplayQuadRange - displays all quads in list range, start..end.
16617 : : */
16618 : :
16619 : 0 : extern "C" void M2Quads_DisplayQuadRange (unsigned int scope, unsigned int start, unsigned int end)
16620 : : {
16621 : 0 : M2Quads_QuadFrame f;
16622 : :
16623 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "Quadruples for scope: %d\\n", 26, (const unsigned char *) &scope, (sizeof (scope)-1));
16624 : 0 : while ((start <= end) && (start != 0))
16625 : : {
16626 : 0 : M2Quads_DisplayQuad (start);
16627 : 0 : f = GetQF (start);
16628 : 0 : start = f->Next;
16629 : : }
16630 : 0 : }
16631 : :
16632 : :
16633 : : /*
16634 : : DisplayQuad - displays a quadruple, QuadNo.
16635 : : */
16636 : :
16637 : 0 : extern "C" void M2Quads_DisplayQuad (unsigned int QuadNo)
16638 : : {
16639 : 0 : DSdbEnter ();
16640 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d ", 5, (const unsigned char *) &QuadNo, (sizeof (QuadNo)-1));
16641 : 0 : WriteQuad (QuadNo);
16642 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "\\n", 2);
16643 : 0 : DSdbExit ();
16644 : 0 : }
16645 : :
16646 : :
16647 : : /*
16648 : : GetLastFileQuad - returns the Quadruple number of the last StartDefFile or
16649 : : StartModFile quadruple.
16650 : : */
16651 : :
16652 : 0 : extern "C" unsigned int M2Quads_GetLastFileQuad (unsigned int QuadNo)
16653 : : {
16654 : 0 : M2Quads_QuadFrame f;
16655 : 0 : unsigned int q;
16656 : 0 : unsigned int i;
16657 : 0 : unsigned int FileQuad;
16658 : :
16659 : 0 : q = Head;
16660 : 0 : FileQuad = 0;
16661 : 0 : do {
16662 : 0 : f = GetQF (q);
16663 : 0 : if ((f->Operator == M2Quads_StartModFileOp) || (f->Operator == M2Quads_StartDefFileOp))
16664 : : {
16665 : 0 : FileQuad = q;
16666 : : }
16667 : 0 : i = f->Next;
16668 : 0 : q = i;
16669 : 0 : } while (! ((i == QuadNo) || (i == 0)));
16670 : 0 : M2Debug_Assert (i != 0);
16671 : 0 : M2Debug_Assert (FileQuad != 0);
16672 : 0 : return FileQuad;
16673 : : /* static analysis guarentees a RETURN statement will be used before here. */
16674 : : __builtin_unreachable ();
16675 : : }
16676 : :
16677 : :
16678 : : /*
16679 : : GetLastQuadNo - returns the last quadruple number referenced
16680 : : by a GetQuad.
16681 : : */
16682 : :
16683 : 0 : extern "C" unsigned int M2Quads_GetLastQuadNo (void)
16684 : : {
16685 : 0 : return LastQuadNo;
16686 : : /* static analysis guarentees a RETURN statement will be used before here. */
16687 : : __builtin_unreachable ();
16688 : : }
16689 : :
16690 : :
16691 : : /*
16692 : : QuadToTokenNo - Converts a QuadNo into the approprate token number of the
16693 : : source file, the line number is returned.
16694 : :
16695 : : This may be used to yield an idea where abouts in the
16696 : : source file the code generetion is
16697 : : processing.
16698 : : */
16699 : :
16700 : 5942363 : extern "C" unsigned int M2Quads_QuadToTokenNo (unsigned int QuadNo)
16701 : : {
16702 : 5942363 : M2Quads_QuadFrame f;
16703 : :
16704 : 5942363 : if ((((LastQuadNo == 0) && (! (M2Pass_IsNoPass ()))) && (! (M2Pass_IsPassCodeGeneration ()))) || (! (Indexing_InBounds (QuadArray, QuadNo))))
16705 : : {
16706 : 0 : return 0;
16707 : : }
16708 : : else
16709 : : {
16710 : 5942363 : f = GetQF (QuadNo);
16711 : 5942363 : return f->TokenNo;
16712 : : }
16713 : : /* static analysis guarentees a RETURN statement will be used before here. */
16714 : : __builtin_unreachable ();
16715 : : }
16716 : :
16717 : :
16718 : : /*
16719 : : QuadToLineNo - Converts a QuadNo into the approprate line number of the
16720 : : source file, the line number is returned.
16721 : :
16722 : : This may be used to yield an idea where abouts in the
16723 : : source file the code generetion is
16724 : : processing.
16725 : : */
16726 : :
16727 : 0 : extern "C" unsigned int M2Quads_QuadToLineNo (unsigned int QuadNo)
16728 : : {
16729 : 0 : M2Quads_QuadFrame f;
16730 : :
16731 : 0 : if ((((LastQuadNo == 0) && (! (M2Pass_IsNoPass ()))) && (! (M2Pass_IsPassCodeGeneration ()))) || (! (Indexing_InBounds (QuadArray, QuadNo))))
16732 : : {
16733 : 0 : return 0;
16734 : : }
16735 : : else
16736 : : {
16737 : 0 : f = GetQF (QuadNo);
16738 : 0 : return f->LineNo;
16739 : : }
16740 : : /* static analysis guarentees a RETURN statement will be used before here. */
16741 : : __builtin_unreachable ();
16742 : : }
16743 : :
16744 : :
16745 : : /*
16746 : : GetQuad - returns the Quadruple QuadNo.
16747 : : */
16748 : :
16749 : 830461225 : extern "C" void M2Quads_GetQuad (unsigned int QuadNo, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3)
16750 : : {
16751 : 830461225 : M2Quads_QuadFrame f;
16752 : :
16753 : 830461225 : f = GetQF (QuadNo);
16754 : 830461225 : LastQuadNo = QuadNo;
16755 : 830461225 : (*Op) = f->Operator;
16756 : 830461225 : (*Oper1) = f->Operand1;
16757 : 830461225 : (*Oper2) = f->Operand2;
16758 : 830461225 : (*Oper3) = f->Operand3;
16759 : 830461225 : }
16760 : :
16761 : :
16762 : : /*
16763 : : GetQuadOp - returns the operator for quad.
16764 : : */
16765 : :
16766 : 24 : extern "C" M2Quads_QuadOperator M2Quads_GetQuadOp (unsigned int quad)
16767 : : {
16768 : 24 : M2Quads_QuadFrame f;
16769 : :
16770 : 24 : f = GetQF (quad);
16771 : 24 : return f->Operator;
16772 : : /* static analysis guarentees a RETURN statement will be used before here. */
16773 : : __builtin_unreachable ();
16774 : : }
16775 : :
16776 : :
16777 : : /*
16778 : : GetM2OperatorDesc - returns the Modula-2 string associated with the quad operator
16779 : : (if possible). It returns NIL if no there is not an obvious match
16780 : : in Modula-2. It is assummed that the string will be used during
16781 : : construction of error messages and therefore keywords are
16782 : : wrapped with a format specifier.
16783 : : */
16784 : :
16785 : 31 : extern "C" DynamicStrings_String M2Quads_GetM2OperatorDesc (M2Quads_QuadOperator op)
16786 : : {
16787 : 31 : switch (op)
16788 : : {
16789 : 6 : case M2Quads_NegateOp:
16790 : 6 : return DynamicStrings_InitString ((const char *) "-", 1);
16791 : 18 : break;
16792 : :
16793 : 18 : case M2Quads_AddOp:
16794 : 18 : return DynamicStrings_InitString ((const char *) "+", 1);
16795 : 0 : break;
16796 : :
16797 : 0 : case M2Quads_SubOp:
16798 : 0 : return DynamicStrings_InitString ((const char *) "-", 1);
16799 : 0 : break;
16800 : :
16801 : 0 : case M2Quads_MultOp:
16802 : 0 : return DynamicStrings_InitString ((const char *) "*", 1);
16803 : 0 : break;
16804 : :
16805 : 0 : case M2Quads_DivM2Op:
16806 : 0 : case M2Quads_DivCeilOp:
16807 : 0 : case M2Quads_DivFloorOp:
16808 : 0 : case M2Quads_DivTruncOp:
16809 : 0 : return DynamicStrings_InitString ((const char *) "{%kDIV}", 7);
16810 : 0 : break;
16811 : :
16812 : 0 : case M2Quads_ModM2Op:
16813 : 0 : case M2Quads_ModCeilOp:
16814 : 0 : case M2Quads_ModFloorOp:
16815 : 0 : return DynamicStrings_InitString ((const char *) "{%kMOD}", 7);
16816 : 0 : break;
16817 : :
16818 : 0 : case M2Quads_ModTruncOp:
16819 : 0 : return DynamicStrings_InitString ((const char *) "{%kREM}", 7);
16820 : 0 : break;
16821 : :
16822 : 0 : case M2Quads_LogicalOrOp:
16823 : 0 : return DynamicStrings_InitString ((const char *) "{%kOR}", 6);
16824 : 0 : break;
16825 : :
16826 : 0 : case M2Quads_LogicalAndOp:
16827 : 0 : return DynamicStrings_InitString ((const char *) "{%kAND}", 7);
16828 : 0 : break;
16829 : :
16830 : 0 : case M2Quads_InclOp:
16831 : 0 : return DynamicStrings_InitString ((const char *) "{%kINCL}", 8);
16832 : 0 : break;
16833 : :
16834 : 0 : case M2Quads_ExclOp:
16835 : 0 : return DynamicStrings_InitString ((const char *) "{%kEXCL}", 8);
16836 : 7 : break;
16837 : :
16838 : 7 : case M2Quads_IfEquOp:
16839 : 7 : return DynamicStrings_InitString ((const char *) "=", 1);
16840 : 0 : break;
16841 : :
16842 : 0 : case M2Quads_IfLessEquOp:
16843 : 0 : return DynamicStrings_InitString ((const char *) "<=", 2);
16844 : 0 : break;
16845 : :
16846 : 0 : case M2Quads_IfGreEquOp:
16847 : 0 : return DynamicStrings_InitString ((const char *) ">=", 2);
16848 : 0 : break;
16849 : :
16850 : 0 : case M2Quads_IfGreOp:
16851 : 0 : return DynamicStrings_InitString ((const char *) ">", 1);
16852 : 0 : break;
16853 : :
16854 : 0 : case M2Quads_IfLessOp:
16855 : 0 : return DynamicStrings_InitString ((const char *) "<", 1);
16856 : 0 : break;
16857 : :
16858 : 0 : case M2Quads_IfNotEquOp:
16859 : 0 : return DynamicStrings_InitString ((const char *) "#", 1);
16860 : 0 : break;
16861 : :
16862 : 0 : case M2Quads_IfInOp:
16863 : 0 : return DynamicStrings_InitString ((const char *) "IN", 2);
16864 : 0 : break;
16865 : :
16866 : 0 : case M2Quads_IfNotInOp:
16867 : 0 : return DynamicStrings_InitString ((const char *) "NOT IN", 6);
16868 : : break;
16869 : :
16870 : :
16871 : : default:
16872 : : return static_cast<DynamicStrings_String> (NULL);
16873 : : break;
16874 : : }
16875 : : /* static analysis guarentees a RETURN statement will be used before here. */
16876 : : __builtin_unreachable ();
16877 : : }
16878 : :
16879 : :
16880 : : /*
16881 : : GetQuadtok - returns the Quadruple QuadNo.
16882 : : */
16883 : :
16884 : 102497546 : 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)
16885 : : {
16886 : 102497546 : M2Quads_QuadFrame f;
16887 : :
16888 : 102497546 : f = GetQF (QuadNo);
16889 : 102497546 : LastQuadNo = QuadNo;
16890 : 102497546 : (*Op) = f->Operator;
16891 : 102497546 : (*Oper1) = f->Operand1;
16892 : 102497546 : (*Oper2) = f->Operand2;
16893 : 102497546 : (*Oper3) = f->Operand3;
16894 : 102497546 : (*Op1Pos) = f->op1pos;
16895 : 102497546 : (*Op2Pos) = f->op2pos;
16896 : 102497546 : (*Op3Pos) = f->op3pos;
16897 : 102497546 : }
16898 : :
16899 : :
16900 : : /*
16901 : : GetQuadOtok - returns the Quadruple QuadNo.
16902 : : */
16903 : :
16904 : 5084944 : 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)
16905 : : {
16906 : 5084944 : M2Quads_QuadFrame f;
16907 : :
16908 : 5084944 : f = GetQF (QuadNo);
16909 : 5084944 : LastQuadNo = QuadNo;
16910 : 5084944 : (*Op) = f->Operator;
16911 : 5084944 : (*Oper1) = f->Operand1;
16912 : 5084944 : (*Oper2) = f->Operand2;
16913 : 5084944 : (*Oper3) = f->Operand3;
16914 : 5084944 : (*Op1Pos) = f->op1pos;
16915 : 5084944 : (*Op2Pos) = f->op2pos;
16916 : 5084944 : (*Op3Pos) = f->op3pos;
16917 : 5084944 : (*tok) = f->TokenNo;
16918 : 5084944 : (*overflowChecking) = f->CheckOverflow;
16919 : 5084944 : (*constExpr) = f->ConstExpr;
16920 : 5084944 : }
16921 : :
16922 : :
16923 : : /*
16924 : : GetQuadOTypetok - returns the fields associated with quadruple QuadNo.
16925 : : */
16926 : :
16927 : 4906 : 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)
16928 : : {
16929 : 4906 : M2Quads_QuadFrame f;
16930 : :
16931 : 4906 : f = GetQF (QuadNo);
16932 : 4906 : LastQuadNo = QuadNo;
16933 : 4906 : (*Op) = f->Operator;
16934 : 4906 : (*Oper1) = f->Operand1;
16935 : 4906 : (*Oper2) = f->Operand2;
16936 : 4906 : (*Oper3) = f->Operand3;
16937 : 4906 : (*Op1Pos) = f->op1pos;
16938 : 4906 : (*Op2Pos) = f->op2pos;
16939 : 4906 : (*Op3Pos) = f->op3pos;
16940 : 4906 : (*tok) = f->TokenNo;
16941 : 4906 : (*overflowChecking) = f->CheckOverflow;
16942 : 4906 : (*typeChecking) = f->CheckType;
16943 : 4906 : (*constExpr) = f->ConstExpr;
16944 : 4906 : }
16945 : :
16946 : :
16947 : : /*
16948 : : PutQuadOtok - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
16949 : : sets a boolean to determinine whether overflow should be checked.
16950 : : */
16951 : :
16952 : 68188 : 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)
16953 : : {
16954 : 68188 : M2Quads_QuadFrame f;
16955 : :
16956 : 68188 : if (QuadrupleGeneration)
16957 : : {
16958 : 68188 : M2Quads_EraseQuad (QuadNo);
16959 : 68188 : AddQuadInformation (QuadNo, Op, Oper1, Oper2, Oper3);
16960 : 68188 : f = GetQF (QuadNo);
16961 : 68188 : f->Operator = Op;
16962 : 68188 : f->Operand1 = Oper1;
16963 : 68188 : f->Operand2 = Oper2;
16964 : 68188 : f->Operand3 = Oper3;
16965 : 68188 : f->CheckOverflow = overflowChecking;
16966 : 68188 : f->op1pos = Op1Pos;
16967 : 68188 : f->op2pos = Op2Pos;
16968 : 68188 : f->op3pos = Op3Pos;
16969 : 68188 : f->TokenNo = tok;
16970 : 68188 : f->ConstExpr = constExpr;
16971 : : }
16972 : 68188 : }
16973 : :
16974 : :
16975 : : /*
16976 : : PutQuad - overwrites a quadruple QuadNo with Op, Oper1, Oper2, Oper3
16977 : : */
16978 : :
16979 : 11443 : extern "C" void M2Quads_PutQuad (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
16980 : : {
16981 : 11443 : PutQuadO (QuadNo, Op, Oper1, Oper2, Oper3, true);
16982 : 11443 : }
16983 : :
16984 : :
16985 : : /*
16986 : : GetFirstQuad - returns the first quadruple.
16987 : : */
16988 : :
16989 : 603565 : extern "C" unsigned int M2Quads_GetFirstQuad (void)
16990 : : {
16991 : 603565 : return Head;
16992 : : /* static analysis guarentees a RETURN statement will be used before here. */
16993 : : __builtin_unreachable ();
16994 : : }
16995 : :
16996 : :
16997 : : /*
16998 : : GetNextQuad - returns the Quadruple number following QuadNo.
16999 : : */
17000 : :
17001 : 1246898459 : extern "C" unsigned int M2Quads_GetNextQuad (unsigned int QuadNo)
17002 : : {
17003 : 1246898459 : M2Quads_QuadFrame f;
17004 : :
17005 : 1246898459 : f = GetQF (QuadNo);
17006 : 1246898459 : return f->Next;
17007 : : /* static analysis guarentees a RETURN statement will be used before here. */
17008 : : __builtin_unreachable ();
17009 : : }
17010 : :
17011 : :
17012 : : /*
17013 : : GetRealQuad - returns the Quadruple number of the real quadruple
17014 : : at QuadNo or beyond.
17015 : : */
17016 : :
17017 : 12501856 : extern "C" unsigned int M2Quads_GetRealQuad (unsigned int QuadNo)
17018 : : {
17019 : 12501856 : M2Quads_QuadFrame f;
17020 : :
17021 : 18707677 : while (QuadNo != 0)
17022 : : {
17023 : 18707677 : if (Indexing_InBounds (QuadArray, QuadNo))
17024 : : {
17025 : 18643761 : f = GetQF (QuadNo);
17026 : 18643761 : if ((((! (M2Quads_IsPseudoQuad (QuadNo))) && (f->Operator != M2Quads_DummyOp)) && (f->Operator != M2Quads_LineNumberOp)) && (f->Operator != M2Quads_StatementNoteOp))
17027 : : {
17028 : : return QuadNo;
17029 : : }
17030 : 6205821 : QuadNo += 1;
17031 : : }
17032 : : else
17033 : : {
17034 : : return 0;
17035 : : }
17036 : : }
17037 : : return 0;
17038 : : /* static analysis guarentees a RETURN statement will be used before here. */
17039 : : __builtin_unreachable ();
17040 : : }
17041 : :
17042 : :
17043 : : /*
17044 : : SubQuad - subtracts a quadruple QuadNo from a list Head.
17045 : : */
17046 : :
17047 : 1300522 : extern "C" void M2Quads_SubQuad (unsigned int QuadNo)
17048 : : {
17049 : 1300522 : unsigned int i;
17050 : 1300522 : M2Quads_QuadFrame f;
17051 : 1300522 : M2Quads_QuadFrame g;
17052 : :
17053 : 1300522 : CheckBreak (QuadNo);
17054 : 1300522 : f = GetQF (QuadNo);
17055 : 1300522 : AlterReference (Head, QuadNo, f->Next);
17056 : 1300522 : UndoReadWriteInfo (QuadNo, f->Operator, f->Operand1, f->Operand2, f->Operand3);
17057 : 1300522 : if (Head == QuadNo)
17058 : : {
17059 : 0 : Head = f->Next;
17060 : : }
17061 : : else
17062 : : {
17063 : 1300522 : i = Head;
17064 : 1300522 : g = GetQF (i);
17065 : 1559205575 : while (g->Next != QuadNo)
17066 : : {
17067 : 1556604531 : i = g->Next;
17068 : 1556604531 : g = GetQF (i);
17069 : : }
17070 : 1300522 : g->Next = f->Next;
17071 : : }
17072 : 1300522 : f->Operator = M2Quads_DummyOp;
17073 : 1300522 : NoOfQuads -= 1;
17074 : 1300522 : }
17075 : :
17076 : :
17077 : : /*
17078 : : EraseQuad - erases a quadruple QuadNo, the quadruple is still in the list
17079 : : but wiped clean.
17080 : : */
17081 : :
17082 : 4946579 : extern "C" void M2Quads_EraseQuad (unsigned int QuadNo)
17083 : : {
17084 : 4946579 : M2Quads_QuadFrame f;
17085 : :
17086 : 4946579 : CheckBreak (QuadNo);
17087 : 4946579 : f = GetQF (QuadNo);
17088 : 4946579 : UndoReadWriteInfo (QuadNo, f->Operator, f->Operand1, f->Operand2, f->Operand3);
17089 : 4946579 : f->Operator = M2Quads_DummyOp; /* finally blank it out */
17090 : 4946579 : f->Operand1 = 0; /* finally blank it out */
17091 : 4946579 : f->Operand2 = 0;
17092 : 4946579 : f->Operand3 = 0;
17093 : 4946579 : f->Trash = 0;
17094 : 4946579 : f->op1pos = M2LexBuf_UnknownTokenNo;
17095 : 4946579 : f->op2pos = M2LexBuf_UnknownTokenNo;
17096 : 4946579 : f->op3pos = M2LexBuf_UnknownTokenNo;
17097 : 4946579 : f->ConstExpr = false;
17098 : 4946579 : }
17099 : :
17100 : :
17101 : : /*
17102 : : CountQuads - returns the number of quadruples.
17103 : : */
17104 : :
17105 : 6971480 : extern "C" unsigned int M2Quads_CountQuads (void)
17106 : : {
17107 : 6971480 : return NoOfQuads;
17108 : : /* static analysis guarentees a RETURN statement will be used before here. */
17109 : : __builtin_unreachable ();
17110 : : }
17111 : :
17112 : :
17113 : : /*
17114 : : BuildScaffold - generate the main, init, finish functions if
17115 : : no -c and this is the application module.
17116 : : */
17117 : :
17118 : 15429 : extern "C" void M2Quads_BuildScaffold (unsigned int tok, unsigned int moduleSym)
17119 : : {
17120 : 15429 : if ((SymbolTable_GetMainModule ()) == moduleSym)
17121 : : {
17122 : 15045 : M2Scaffold_DeclareScaffold (tok);
17123 : 15045 : if (M2Options_ScaffoldMain || ! M2Options_cflag)
17124 : : {
17125 : : /* There are module init/fini functions and
17126 : : application init/fini functions.
17127 : : Here we create the application pair. */
17128 : 2544 : BuildM2LinkFunction (tok);
17129 : 2544 : BuildM2MainFunction (tok);
17130 : 2544 : BuildM2InitFunction (tok, moduleSym); /* Application init. */
17131 : 2544 : BuildM2FiniFunction (tok, moduleSym); /* Application fini. */
17132 : : }
17133 : : /* Application fini. */
17134 : 15045 : BuildM2DepFunction (tok, moduleSym); /* Per module dependency. */
17135 : : /* Each module needs a ctor to register the module
17136 : : init/finish/dep with M2RTS. */
17137 : 15045 : BuildM2CtorFunction (tok, moduleSym);
17138 : : }
17139 : 384 : else if (M2Options_WholeProgram)
17140 : : {
17141 : : /* avoid dangling else. */
17142 : 384 : M2Scaffold_DeclareScaffold (tok);
17143 : 384 : BuildM2DepFunction (tok, moduleSym); /* Per module dependency. */
17144 : : /* Each module needs a ctor to register the module
17145 : : init/finish/dep with M2RTS. */
17146 : 384 : BuildM2CtorFunction (tok, moduleSym);
17147 : : }
17148 : 15429 : }
17149 : :
17150 : :
17151 : : /*
17152 : : StartBuildDefFile - generates a StartFileDefOp quadruple indicating the file
17153 : : that has produced the subsequent quadruples.
17154 : : The code generator uses the StartDefFileOp quadruples
17155 : : to relate any error to the appropriate file.
17156 : :
17157 : :
17158 : : Entry Exit
17159 : : ===== ====
17160 : :
17161 : :
17162 : : Ptr -> <- Ptr
17163 : : +------------+ +------------+
17164 : : | ModuleName | | ModuleName |
17165 : : |------------| |------------|
17166 : :
17167 : :
17168 : : Quadruples Produced
17169 : :
17170 : : q StartDefFileOp _ _ ModuleSym
17171 : : */
17172 : :
17173 : 119630 : extern "C" void M2Quads_StartBuildDefFile (unsigned int tok)
17174 : : {
17175 : 119630 : NameKey_Name ModuleName;
17176 : :
17177 : 119630 : M2Quads_PopT (&ModuleName);
17178 : 119630 : M2Quads_PushT (ModuleName);
17179 : 119630 : GenQuadO (tok, M2Quads_StartDefFileOp, tok, SymbolTable_NulSym, SymbolTable_GetModule (ModuleName), false);
17180 : 119630 : }
17181 : :
17182 : :
17183 : : /*
17184 : : StartBuildModFile - generates a StartModFileOp quadruple indicating the file
17185 : : that has produced the subsequent quadruples.
17186 : : The code generator uses the StartModFileOp quadruples
17187 : : to relate any error to the appropriate file.
17188 : :
17189 : :
17190 : : Entry Exit
17191 : : ===== ====
17192 : :
17193 : :
17194 : : Ptr -> <- Ptr
17195 : : +------------+ +------------+
17196 : : | ModuleName | | ModuleName |
17197 : : |------------| |------------|
17198 : :
17199 : :
17200 : : Quadruples Produced
17201 : :
17202 : : q StartModFileOp lineno filename ModuleSym
17203 : : */
17204 : :
17205 : 64255 : extern "C" void M2Quads_StartBuildModFile (unsigned int tok)
17206 : : {
17207 : 64255 : GenQuadO (tok, M2Quads_StartModFileOp, tok, (unsigned int ) (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()))), SymbolTable_GetFileModule (), false);
17208 : 64255 : }
17209 : :
17210 : :
17211 : : /*
17212 : : EndBuildFile - generates an EndFileOp quadruple indicating the file
17213 : : that has produced the previous quadruples has ended.
17214 : :
17215 : : Entry Exit
17216 : : ===== ====
17217 : :
17218 : :
17219 : : Ptr -> <- Ptr
17220 : : +------------+ +------------+
17221 : : | ModuleName | | ModuleName |
17222 : : |------------| |------------|
17223 : :
17224 : :
17225 : : Quadruples Produced
17226 : :
17227 : : q EndFileOp _ _ ModuleSym
17228 : : */
17229 : :
17230 : 183687 : extern "C" void M2Quads_EndBuildFile (unsigned int tok)
17231 : : {
17232 : 183687 : NameKey_Name ModuleName;
17233 : :
17234 : 183687 : ModuleName = static_cast<NameKey_Name> (M2Quads_OperandT (1));
17235 : 183687 : GenQuadO (tok, M2Quads_EndFileOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_GetModule (ModuleName), false);
17236 : 183687 : }
17237 : :
17238 : :
17239 : : /*
17240 : : StartBuildInit - Sets the start of initialization code of the
17241 : : current module to the next quadruple.
17242 : : */
17243 : :
17244 : 64615 : extern "C" void M2Quads_StartBuildInit (unsigned int tok)
17245 : : {
17246 : 64615 : NameKey_Name name;
17247 : 64615 : unsigned int ModuleSym;
17248 : :
17249 : 64615 : M2Quads_PopT (&name);
17250 : 64615 : ModuleSym = SymbolTable_GetCurrentModule ();
17251 : 129230 : M2Debug_Assert ((SymbolTable_IsModule (ModuleSym)) || (SymbolTable_IsDefImp (ModuleSym)));
17252 : 64615 : M2Debug_Assert ((SymbolTable_GetSymName (ModuleSym)) == name);
17253 : 64609 : SymbolTable_PutModuleStartQuad (ModuleSym, NextQuad);
17254 : 64609 : GenQuad (M2Quads_InitStartOp, tok, SymbolTable_GetFileModule (), ModuleSym);
17255 : 64609 : M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
17256 : 64609 : M2Quads_PushT (name);
17257 : 64609 : CheckVariablesAt (ModuleSym);
17258 : 64609 : CheckNeedPriorityBegin (tok, ModuleSym, ModuleSym);
17259 : 64609 : M2StackWord_PushWord (TryStack, NextQuad);
17260 : 64609 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
17261 : 64609 : if (SymbolTable_HasExceptionBlock (ModuleSym))
17262 : : {
17263 : 48 : GenQuad (M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
17264 : : }
17265 : 64609 : }
17266 : :
17267 : :
17268 : : /*
17269 : : EndBuildInit - Sets the end initialization code of a module.
17270 : : */
17271 : :
17272 : 64477 : extern "C" void M2Quads_EndBuildInit (unsigned int tok)
17273 : : {
17274 : 64477 : if (SymbolTable_HasExceptionBlock (SymbolTable_GetCurrentModule ()))
17275 : : {
17276 : 48 : BuildRTExceptLeave (tok, true);
17277 : 48 : GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17278 : : }
17279 : 64477 : BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
17280 : 64477 : CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
17281 : 64477 : SymbolTable_PutModuleEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
17282 : 64477 : CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
17283 : 64477 : GenQuadO (tok, M2Quads_InitEndOp, tok, SymbolTable_GetFileModule (), SymbolTable_GetCurrentModule (), false);
17284 : 64477 : }
17285 : :
17286 : :
17287 : : /*
17288 : : StartBuildFinally - Sets the start of finalization code of the
17289 : : current module to the next quadruple.
17290 : : */
17291 : :
17292 : 15651 : extern "C" void M2Quads_StartBuildFinally (unsigned int tok)
17293 : : {
17294 : 15651 : NameKey_Name name;
17295 : 15651 : unsigned int ModuleSym;
17296 : :
17297 : 15651 : M2Quads_PopT (&name);
17298 : 15645 : ModuleSym = SymbolTable_GetCurrentModule ();
17299 : 31290 : M2Debug_Assert ((SymbolTable_IsModule (ModuleSym)) || (SymbolTable_IsDefImp (ModuleSym)));
17300 : 15645 : M2Debug_Assert ((SymbolTable_GetSymName (ModuleSym)) == name);
17301 : 15645 : SymbolTable_PutModuleFinallyStartQuad (ModuleSym, NextQuad);
17302 : 15645 : GenQuadO (tok, M2Quads_FinallyStartOp, tok, SymbolTable_GetFileModule (), ModuleSym, false);
17303 : 15645 : M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
17304 : 15645 : M2Quads_PushT (name);
17305 : : /* CheckVariablesAt(ModuleSym) ; */
17306 : 15645 : CheckNeedPriorityBegin (tok, ModuleSym, ModuleSym);
17307 : 15645 : M2StackWord_PushWord (TryStack, NextQuad);
17308 : 15645 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
17309 : 15645 : if (SymbolTable_HasExceptionFinally (ModuleSym))
17310 : : {
17311 : 0 : GenQuadO (tok, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
17312 : : }
17313 : 15645 : }
17314 : :
17315 : :
17316 : : /*
17317 : : EndBuildFinally - Sets the end finalization code of a module.
17318 : : */
17319 : :
17320 : 15645 : extern "C" void M2Quads_EndBuildFinally (unsigned int tok)
17321 : : {
17322 : 15645 : if (SymbolTable_HasExceptionFinally (SymbolTable_GetCurrentModule ()))
17323 : : {
17324 : 0 : BuildRTExceptLeave (tok, true);
17325 : 0 : GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17326 : : }
17327 : 15645 : BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
17328 : 15645 : CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
17329 : 15645 : SymbolTable_PutModuleFinallyEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
17330 : 15645 : CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
17331 : 15645 : GenQuadO (tok, M2Quads_FinallyEndOp, tok, SymbolTable_GetFileModule (), SymbolTable_GetCurrentModule (), false);
17332 : 15645 : }
17333 : :
17334 : :
17335 : : /*
17336 : : BuildExceptInitial - adds an CatchBeginOp, CatchEndOp quadruple
17337 : : in the current block.
17338 : : */
17339 : :
17340 : 2690 : extern "C" void M2Quads_BuildExceptInitial (unsigned int tok)
17341 : : {
17342 : 2690 : unsigned int previous;
17343 : :
17344 : : /* we have finished the 'try' block, so now goto the return
17345 : : section which will tidy up (any) priorities before returning.
17346 : : */
17347 : 2690 : GenQuadO (tok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PopWord (ReturnStack), false);
17348 : 2690 : M2StackWord_PushWord (ReturnStack, NextQuad-1);
17349 : : /*
17350 : : this is the 'catch' block.
17351 : : */
17352 : 2690 : BackPatch (M2StackWord_PeepWord (TryStack, 1), NextQuad);
17353 : 2690 : GenQuadO (tok, M2Quads_CatchBeginOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17354 : 2690 : previous = static_cast<unsigned int> (M2StackWord_PopWord (CatchStack));
17355 : 2690 : if (previous != 0)
17356 : : {
17357 : 0 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}only allowed one EXCEPT statement in a procedure or module", 62);
17358 : : }
17359 : 2690 : M2StackWord_PushWord (CatchStack, NextQuad-1);
17360 : 2690 : BuildRTExceptEnter (tok);
17361 : 2690 : }
17362 : :
17363 : :
17364 : : /*
17365 : : BuildExceptFinally - adds an ExceptOp quadruple in a modules
17366 : : finally block.
17367 : : */
17368 : :
17369 : 0 : extern "C" void M2Quads_BuildExceptFinally (unsigned int tok)
17370 : : {
17371 : 0 : M2Quads_BuildExceptInitial (tok);
17372 : 0 : }
17373 : :
17374 : :
17375 : : /*
17376 : : BuildExceptProcedure - adds an ExceptOp quadruple in a procedure
17377 : : block.
17378 : : */
17379 : :
17380 : 132 : extern "C" void M2Quads_BuildExceptProcedure (unsigned int tok)
17381 : : {
17382 : 132 : M2Quads_BuildExceptInitial (tok);
17383 : 132 : }
17384 : :
17385 : :
17386 : : /*
17387 : : BuildRetry - adds an RetryOp quadruple.
17388 : : */
17389 : :
17390 : 120 : extern "C" void M2Quads_BuildRetry (unsigned int tok)
17391 : : {
17392 : 120 : if ((M2StackWord_PeepWord (CatchStack, 1)) == 0)
17393 : : {
17394 : 6 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}the {%kRETRY} statement must occur after an {%kEXCEPT} statement in the same module or procedure block", 106);
17395 : : }
17396 : : else
17397 : : {
17398 : 114 : BuildRTExceptLeave (tok, false);
17399 : 114 : GenQuadO (tok, M2Quads_RetryOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PeepWord (TryStack, 1), false);
17400 : : }
17401 : 120 : }
17402 : :
17403 : :
17404 : : /*
17405 : : BuildReThrow - creates a ThrowOp _ _ NulSym, indicating that
17406 : : the exception needs to be rethrown. The stack
17407 : : is unaltered.
17408 : : */
17409 : :
17410 : 180 : extern "C" void M2Quads_BuildReThrow (unsigned int tokenno)
17411 : : {
17412 : 180 : GenQuadO (tokenno, M2Quads_ThrowOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17413 : 180 : }
17414 : :
17415 : :
17416 : : /*
17417 : : StartBuildInnerInit - Sets the start of initialization code of the
17418 : : inner module to the next quadruple.
17419 : : */
17420 : :
17421 : 0 : extern "C" void M2Quads_StartBuildInnerInit (unsigned int tok)
17422 : : {
17423 : 0 : SymbolTable_PutModuleStartQuad (SymbolTable_GetCurrentModule (), NextQuad);
17424 : 0 : GenQuadO (tok, M2Quads_InitStartOp, tok, SymbolTable_NulSym, SymbolTable_GetCurrentModule (), false);
17425 : 0 : M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
17426 : 0 : CheckNeedPriorityBegin (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
17427 : 0 : M2StackWord_PushWord (TryStack, NextQuad);
17428 : 0 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
17429 : 0 : if (SymbolTable_HasExceptionFinally (SymbolTable_GetCurrentModule ()))
17430 : : {
17431 : 0 : GenQuadO (tok, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
17432 : : }
17433 : 0 : }
17434 : :
17435 : :
17436 : : /*
17437 : : EndBuildInnerInit - Sets the end initialization code of a module.
17438 : : */
17439 : :
17440 : 0 : extern "C" void M2Quads_EndBuildInnerInit (unsigned int tok)
17441 : : {
17442 : 0 : if (SymbolTable_HasExceptionBlock (SymbolTable_GetCurrentModule ()))
17443 : : {
17444 : 0 : BuildRTExceptLeave (tok, true);
17445 : 0 : GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17446 : : }
17447 : 0 : SymbolTable_PutModuleEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
17448 : 0 : CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
17449 : 0 : BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
17450 : 0 : CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
17451 : 0 : GenQuadO (tok, M2Quads_InitEndOp, tok, SymbolTable_NulSym, SymbolTable_GetCurrentModule (), false);
17452 : 0 : }
17453 : :
17454 : :
17455 : : /*
17456 : : BuildBuiltinConst - makes reference to a builtin constant within gm2.
17457 : :
17458 : : Entry Exit
17459 : :
17460 : : Ptr ->
17461 : : +------------+ +------------+
17462 : : | Ident | | Sym |
17463 : : |------------| |------------|
17464 : :
17465 : : Quadruple produced:
17466 : :
17467 : : q Sym BuiltinConstOp Ident
17468 : : */
17469 : :
17470 : 29602 : extern "C" void M2Quads_BuildBuiltinConst (void)
17471 : : {
17472 : 29602 : unsigned int idtok;
17473 : 29602 : unsigned int Id;
17474 : 29602 : unsigned int Sym;
17475 : :
17476 : 29602 : M2Quads_PopTtok (&Id, &idtok);
17477 : 29602 : Sym = SymbolTable_MakeTemporary (idtok, SymbolTable_ImmediateValue);
17478 : 29602 : SymbolTable_PutVar (Sym, M2Base_Integer);
17479 : : /*
17480 : : CASE GetBuiltinConstType(KeyToCharStar(Name(Id))) OF
17481 : :
17482 : : 0: ErrorFormat1(NewError(GetTokenNo()),
17483 : : '%a unrecognised builtin constant', Id) |
17484 : : 1: PutVar(Sym, Integer) |
17485 : : 2: PutVar(Sym, Real)
17486 : :
17487 : : ELSE
17488 : : InternalError ('unrecognised value')
17489 : : END ;
17490 : : */
17491 : 29602 : GenQuadO (idtok, M2Quads_BuiltinConstOp, Sym, SymbolTable_NulSym, Id, false);
17492 : 29602 : M2Quads_PushTtok (Sym, idtok);
17493 : 29602 : }
17494 : :
17495 : :
17496 : : /*
17497 : : BuildBuiltinTypeInfo - make reference to a builtin typeinfo function
17498 : : within gm2.
17499 : :
17500 : : Entry Exit
17501 : :
17502 : : Ptr ->
17503 : : +-------------+
17504 : : | Type |
17505 : : |-------------| +------------+
17506 : : | Ident | | Sym |
17507 : : |-------------| |------------|
17508 : :
17509 : : Quadruple produced:
17510 : :
17511 : : q Sym BuiltinTypeInfoOp Type Ident
17512 : : */
17513 : :
17514 : 360 : extern "C" void M2Quads_BuildBuiltinTypeInfo (void)
17515 : : {
17516 : 360 : unsigned int idtok;
17517 : 360 : unsigned int Ident;
17518 : 360 : unsigned int Type;
17519 : 360 : unsigned int Sym;
17520 : :
17521 : 360 : M2Quads_PopTtok (&Ident, &idtok);
17522 : 360 : M2Quads_PopT (&Type);
17523 : 360 : Sym = SymbolTable_MakeTemporary (M2LexBuf_BuiltinTokenNo, SymbolTable_ImmediateValue);
17524 : 360 : switch (m2builtins_GetBuiltinTypeInfoType (const_cast <const char * > (static_cast <char * > (NameKey_KeyToCharStar ((NameKey_Name) (Ident))))))
17525 : : {
17526 : 0 : case 0:
17527 : 0 : M2Error_ErrorFormat1 (M2Error_NewError (idtok), (const char *) "%a unrecognised builtin constant", 32, (const unsigned char *) &Ident, (sizeof (Ident)-1));
17528 : 0 : break;
17529 : :
17530 : 192 : case 1:
17531 : 192 : SymbolTable_PutVar (Sym, M2Base_Boolean);
17532 : 192 : break;
17533 : :
17534 : 120 : case 2:
17535 : 120 : SymbolTable_PutVar (Sym, M2Base_ZType);
17536 : 120 : break;
17537 : :
17538 : 48 : case 3:
17539 : 48 : SymbolTable_PutVar (Sym, M2Base_RType);
17540 : 48 : break;
17541 : :
17542 : :
17543 : 0 : default:
17544 : 0 : M2Error_InternalError ((const char *) "unrecognised value", 18);
17545 : 360 : break;
17546 : : }
17547 : 360 : GenQuadO (idtok, M2Quads_BuiltinTypeInfoOp, Sym, Type, Ident, false);
17548 : 360 : M2Quads_PushTtok (Sym, idtok);
17549 : 360 : }
17550 : :
17551 : :
17552 : : /*
17553 : : BuildAssignment - Builds an assignment from the values given on the
17554 : : quad stack. Either an assignment to an
17555 : : arithmetic expression or an assignment to a
17556 : : boolean expression. This procedure should not
17557 : : be called in CONST declarations.
17558 : : The Stack is expected to contain:
17559 : :
17560 : :
17561 : : Either
17562 : :
17563 : : Entry Exit
17564 : : ===== ====
17565 : :
17566 : : Ptr ->
17567 : : +------------+
17568 : : | Expression |
17569 : : |------------|
17570 : : | Designator |
17571 : : |------------| +------------+
17572 : : | | | | <- Ptr
17573 : : |------------| |------------|
17574 : :
17575 : :
17576 : : Quadruples Produced
17577 : :
17578 : : q BecomesOp Designator _ Expression
17579 : :
17580 : : OR
17581 : :
17582 : : Entry Exit
17583 : : ===== ====
17584 : :
17585 : : Ptr ->
17586 : : +------------+
17587 : : | True |False|
17588 : : |------------|
17589 : : | Designator |
17590 : : |------------| +------------+
17591 : : | | | | <- Ptr
17592 : : |------------| |------------|
17593 : :
17594 : :
17595 : : Quadruples Produced
17596 : :
17597 : : q BecomesOp Designator _ TRUE
17598 : : q+1 GotoOp q+3
17599 : : q+2 BecomesOp Designator _ FALSE
17600 : :
17601 : : */
17602 : :
17603 : 107495 : extern "C" void M2Quads_BuildAssignment (unsigned int becomesTokNo)
17604 : : {
17605 : 107495 : unsigned int des;
17606 : 107495 : unsigned int exp;
17607 : 107495 : unsigned int destok;
17608 : 107495 : unsigned int exptok;
17609 : 107495 : unsigned int combinedtok;
17610 : :
17611 : 107495 : des = static_cast<unsigned int> (M2Quads_OperandT (2));
17612 : 107495 : if (IsReadOnly (des))
17613 : : {
17614 : 36 : destok = static_cast<unsigned int> (M2Quads_OperandTok (2));
17615 : 36 : exptok = static_cast<unsigned int> (M2Quads_OperandTok (1));
17616 : 36 : exp = static_cast<unsigned int> (M2Quads_OperandT (1));
17617 : 36 : if (DebugTokPos)
17618 : : {
17619 : : M2MetaError_MetaErrorT1 (destok, (const char *) "destok {%1Ead}", 14, des);
17620 : : M2MetaError_MetaErrorT1 (exptok, (const char *) "exptok {%1Ead}", 14, exp);
17621 : : }
17622 : 36 : combinedtok = M2LexBuf_MakeVirtualTok (becomesTokNo, destok, exptok);
17623 : 36 : if (DebugTokPos)
17624 : : {
17625 : : M2MetaError_MetaErrorT1 (combinedtok, (const char *) "combined {%1Ead}", 16, des);
17626 : : }
17627 : 36 : if (IsBoolean (1))
17628 : : {
17629 : 0 : M2MetaError_MetaErrorT1 (combinedtok, (const char *) "cannot assign expression to a constant designator {%1Ead}", 57, des);
17630 : : }
17631 : : else
17632 : : {
17633 : 36 : exp = static_cast<unsigned int> (M2Quads_OperandT (1));
17634 : 36 : M2MetaError_MetaErrorT2 (combinedtok, (const char *) "cannot assign a constant designator {%1Ead} with an expression {%2Ead}", 70, des, exp);
17635 : : }
17636 : 36 : M2Quads_PopN (2); /* Remove both parameters. */
17637 : : }
17638 : 107459 : else if (SymbolTable_IsError (des))
17639 : : {
17640 : : /* avoid dangling else. */
17641 : 24 : M2Quads_PopN (2); /* Remove both parameters. */
17642 : : }
17643 : : else
17644 : : {
17645 : : /* avoid dangling else. */
17646 : 107435 : doBuildAssignment (becomesTokNo, true, true);
17647 : : }
17648 : 107495 : }
17649 : :
17650 : :
17651 : : /*
17652 : : BuildAssignConstant - used to create constant in the CONST declaration.
17653 : : The stack is expected to contain:
17654 : :
17655 : : Either
17656 : :
17657 : : Entry Exit
17658 : : ===== ====
17659 : :
17660 : : Ptr ->
17661 : : +------------+
17662 : : | Expression |
17663 : : |------------|
17664 : : | Designator |
17665 : : |------------| +------------+
17666 : : | | | | <- Ptr
17667 : : |------------| |------------|
17668 : :
17669 : :
17670 : : Quadruples Produced
17671 : :
17672 : : q BecomesOp Designator _ Expression
17673 : :
17674 : : OR
17675 : :
17676 : : Entry Exit
17677 : : ===== ====
17678 : :
17679 : : Ptr ->
17680 : : +------------+
17681 : : | True |False|
17682 : : |------------|
17683 : : | Designator |
17684 : : |------------| +------------+
17685 : : | | | | <- Ptr
17686 : : |------------| |------------|
17687 : :
17688 : :
17689 : : Quadruples Produced
17690 : :
17691 : : q BecomesOp Designator _ TRUE
17692 : : q+1 GotoOp q+3
17693 : : q+2 BecomesOp Designator _ FALSE
17694 : : */
17695 : :
17696 : 243995 : extern "C" void M2Quads_BuildAssignConstant (unsigned int equalsTokNo)
17697 : : {
17698 : 243995 : doBuildAssignment (equalsTokNo, true, true);
17699 : 243995 : }
17700 : :
17701 : :
17702 : : /*
17703 : : BuildAlignment - builds an assignment to an alignment constant.
17704 : :
17705 : : The Stack is expected to contain:
17706 : :
17707 : :
17708 : : Entry Exit
17709 : : ===== ====
17710 : :
17711 : : Ptr ->
17712 : : +---------------+
17713 : : | Expression |
17714 : : |---------------|
17715 : : | bytealignment |
17716 : : |---------------| empty
17717 : : */
17718 : :
17719 : 72 : extern "C" void M2Quads_BuildAlignment (unsigned int tokno)
17720 : : {
17721 : 72 : NameKey_Name name;
17722 : 72 : unsigned int expr;
17723 : 72 : unsigned int align;
17724 : :
17725 : 72 : M2Quads_PopT (&expr);
17726 : 72 : M2Quads_PopT (&name);
17727 : 72 : if (name != (NameKey_MakeKey ((const char *) "bytealignment", 13)))
17728 : : {
17729 : 0 : M2MetaError_MetaError1 ((const char *) "expecting bytealignment identifier, rather than {%1Ea}", 54, SymbolTable_MakeError (tokno, name));
17730 : : }
17731 : 72 : FifoQueue_GetConstFromFifoQueue (&align);
17732 : 72 : M2Quads_PushT (align);
17733 : 72 : M2Quads_PushT (expr);
17734 : 72 : M2Quads_BuildAssignConstant (tokno);
17735 : 72 : }
17736 : :
17737 : :
17738 : : /*
17739 : : BuildBitLength - builds an assignment to a bit length constant.
17740 : :
17741 : : The Stack is expected to contain:
17742 : :
17743 : :
17744 : : Entry Exit
17745 : : ===== ====
17746 : :
17747 : : Ptr ->
17748 : : +------------+
17749 : : | Expression |
17750 : : |------------| empty
17751 : : */
17752 : :
17753 : 0 : extern "C" void M2Quads_BuildBitLength (unsigned int tokno)
17754 : : {
17755 : 0 : unsigned int expr;
17756 : 0 : unsigned int length;
17757 : :
17758 : 0 : M2Quads_PopT (&expr);
17759 : 0 : FifoQueue_GetConstFromFifoQueue (&length);
17760 : 0 : M2Quads_PushT (length);
17761 : 0 : M2Quads_PushT (expr);
17762 : 0 : M2Quads_BuildAssignConstant (tokno);
17763 : 0 : }
17764 : :
17765 : :
17766 : : /*
17767 : : BuildPragmaField - builds an assignment to an alignment constant.
17768 : :
17769 : : The Stack is expected to contain:
17770 : :
17771 : :
17772 : : Entry Exit
17773 : : ===== ====
17774 : :
17775 : : Ptr ->
17776 : : +------------+
17777 : : | Expression |
17778 : : |------------| empty
17779 : : */
17780 : :
17781 : 12 : extern "C" void M2Quads_BuildPragmaField (void)
17782 : : {
17783 : 12 : unsigned int expr;
17784 : 12 : unsigned int const_;
17785 : 12 : NameKey_Name name;
17786 : :
17787 : 12 : M2Quads_PopT (&expr);
17788 : 12 : M2Quads_PopT (&name);
17789 : 12 : if ((name != (NameKey_MakeKey ((const char *) "unused", 6))) && (name != (NameKey_MakeKey ((const char *) "bytealignment", 13))))
17790 : : {
17791 : 0 : M2MetaError_MetaError0 ((const char *) "only allowed to use the attribute {%Ekbytealignment} in the default record field alignment pragma", 97);
17792 : : }
17793 : 12 : if (expr != SymbolTable_NulSym)
17794 : : {
17795 : 12 : FifoQueue_GetConstFromFifoQueue (&const_);
17796 : 12 : M2Quads_PushT (const_);
17797 : 12 : M2Quads_PushT (expr);
17798 : 12 : M2Quads_BuildAssignConstant (M2LexBuf_GetTokenNo ());
17799 : : }
17800 : 12 : }
17801 : :
17802 : :
17803 : : /*
17804 : : BuildDefaultFieldAlignment - builds an assignment to an alignment constant.
17805 : :
17806 : : The Stack is expected to contain:
17807 : :
17808 : :
17809 : : Entry Exit
17810 : : ===== ====
17811 : :
17812 : : Ptr ->
17813 : : +------------+
17814 : : | Expression |
17815 : : |------------| empty
17816 : : */
17817 : :
17818 : 36 : extern "C" void M2Quads_BuildDefaultFieldAlignment (void)
17819 : : {
17820 : 36 : unsigned int expr;
17821 : 36 : unsigned int align;
17822 : 36 : NameKey_Name name;
17823 : :
17824 : 36 : M2Quads_PopT (&expr);
17825 : 36 : M2Quads_PopT (&name);
17826 : 36 : if (name != (NameKey_MakeKey ((const char *) "bytealignment", 13)))
17827 : : {
17828 : 0 : M2MetaError_MetaError0 ((const char *) "{%E}only allowed to use the attribute {%kbytealignment} in the default record field alignment pragma", 100);
17829 : : }
17830 : 36 : FifoQueue_GetConstFromFifoQueue (&align);
17831 : 36 : M2Quads_PushT (align);
17832 : 36 : M2Quads_PushT (expr);
17833 : 36 : M2Quads_BuildAssignConstant (M2LexBuf_GetTokenNo ());
17834 : 36 : }
17835 : :
17836 : :
17837 : : /*
17838 : : BuildRepeat - Builds the repeat statement from the quad stack.
17839 : : The Stack is expected to contain:
17840 : :
17841 : :
17842 : : Entry Exit
17843 : : ===== ====
17844 : :
17845 : :
17846 : : Empty
17847 : : <- Ptr
17848 : : +------------+
17849 : : | RepeatQuad |
17850 : : |------------|
17851 : :
17852 : : */
17853 : :
17854 : 1356 : extern "C" void M2Quads_BuildRepeat (void)
17855 : : {
17856 : 1356 : M2Quads_PushT (NextQuad);
17857 : 1356 : }
17858 : :
17859 : :
17860 : : /*
17861 : : BuildUntil - Builds the until part of the repeat statement
17862 : : from the quad stack.
17863 : : The Stack is expected to contain:
17864 : :
17865 : :
17866 : : Entry Exit
17867 : : ===== ====
17868 : :
17869 : : Ptr ->
17870 : : +------------+
17871 : : | t | f |
17872 : : |------------|
17873 : : | RepeatQuad | Empty
17874 : : |------------|
17875 : : */
17876 : :
17877 : 1356 : extern "C" void M2Quads_BuildUntil (void)
17878 : : {
17879 : 1356 : unsigned int t;
17880 : 1356 : unsigned int f;
17881 : 1356 : unsigned int Repeat;
17882 : :
17883 : 1356 : CheckBooleanId ();
17884 : 1356 : PopBool (&t, &f);
17885 : 1356 : M2Quads_PopT (&Repeat);
17886 : 1356 : BackPatch (f, Repeat); /* If False then keep on repeating */
17887 : 1356 : BackPatch (t, NextQuad); /* If True then exit repeat */
17888 : 1356 : }
17889 : :
17890 : :
17891 : : /*
17892 : : BuildWhile - Builds the While part of the While statement
17893 : : from the quad stack.
17894 : : The Stack is expected to contain:
17895 : :
17896 : :
17897 : : Entry Exit
17898 : : ===== ====
17899 : :
17900 : : <- Ptr
17901 : : |------------|
17902 : : Empty | WhileQuad |
17903 : : |------------|
17904 : : */
17905 : :
17906 : 6456 : extern "C" void M2Quads_BuildWhile (void)
17907 : : {
17908 : 6456 : M2Quads_PushT (NextQuad);
17909 : 6456 : }
17910 : :
17911 : :
17912 : : /*
17913 : : BuildDoWhile - Builds the Do part of the while statement
17914 : : from the quad stack.
17915 : : The Stack is expected to contain:
17916 : :
17917 : :
17918 : : Entry Exit
17919 : : ===== ====
17920 : :
17921 : : Ptr ->
17922 : : +------------+ +------------+
17923 : : | t | f | | 0 | f |
17924 : : |------------| |------------|
17925 : : | WhileQuad | | WhileQuad |
17926 : : |------------| |------------|
17927 : :
17928 : : Quadruples
17929 : :
17930 : : BackPatch t exit to the NextQuad
17931 : : */
17932 : :
17933 : 6456 : extern "C" void M2Quads_BuildDoWhile (void)
17934 : : {
17935 : 6456 : unsigned int t;
17936 : 6456 : unsigned int f;
17937 : :
17938 : 6456 : CheckBooleanId ();
17939 : 6456 : PopBool (&t, &f);
17940 : 6456 : BackPatch (t, NextQuad);
17941 : 6456 : PushBool (0, f);
17942 : 6456 : }
17943 : :
17944 : :
17945 : : /*
17946 : : BuildEndWhile - Builds the end part of the while statement
17947 : : from the quad stack.
17948 : : The Stack is expected to contain:
17949 : :
17950 : :
17951 : : Entry Exit
17952 : : ===== ====
17953 : :
17954 : : Ptr ->
17955 : : +------------+
17956 : : | t | f |
17957 : : |------------|
17958 : : | WhileQuad | Empty
17959 : : |------------|
17960 : :
17961 : : Quadruples
17962 : :
17963 : : q GotoOp WhileQuad
17964 : : False exit is backpatched with q+1
17965 : : */
17966 : :
17967 : 6456 : extern "C" void M2Quads_BuildEndWhile (void)
17968 : : {
17969 : 6456 : unsigned int While;
17970 : 6456 : unsigned int t;
17971 : 6456 : unsigned int f;
17972 : :
17973 : 6456 : PopBool (&t, &f);
17974 : 6456 : M2Debug_Assert (t == 0);
17975 : 6456 : M2Quads_PopT (&While);
17976 : 6456 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, While);
17977 : 6456 : BackPatch (f, NextQuad);
17978 : 6456 : }
17979 : :
17980 : :
17981 : : /*
17982 : : BuildLoop - Builds the Loop part of the Loop statement
17983 : : from the quad stack.
17984 : : The Stack is expected to contain:
17985 : :
17986 : :
17987 : : Entry Exit
17988 : : ===== ====
17989 : :
17990 : : <- Ptr
17991 : : Empty +------------+
17992 : : | LoopQuad |
17993 : : |------------|
17994 : : */
17995 : :
17996 : 530 : extern "C" void M2Quads_BuildLoop (void)
17997 : : {
17998 : 530 : M2Quads_PushT (NextQuad);
17999 : 530 : PushExit (0); /* Seperate Exit Stack for loop end */
18000 : 530 : }
18001 : :
18002 : :
18003 : : /*
18004 : : BuildExit - Builds the Exit part of the Loop statement.
18005 : : */
18006 : :
18007 : 94 : extern "C" void M2Quads_BuildExit (void)
18008 : : {
18009 : 94 : if (M2StackWord_IsEmptyWord (ExitStack))
18010 : : {
18011 : 0 : M2MetaError_MetaError0 ((const char *) "{%EkEXIT} is only allowed in a {%kLOOP} statement", 49);
18012 : : }
18013 : : else
18014 : : {
18015 : 94 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18016 : 94 : PushExit (Merge (PopExit (), NextQuad-1));
18017 : : }
18018 : 94 : }
18019 : :
18020 : :
18021 : : /*
18022 : : BuildEndLoop - Builds the End part of the Loop statement
18023 : : from the quad stack.
18024 : : The Stack is expected to contain:
18025 : :
18026 : :
18027 : : Entry Exit
18028 : : ===== ====
18029 : :
18030 : : Ptr ->
18031 : : +------------+
18032 : : | LoopQuad | Empty
18033 : : |------------|
18034 : :
18035 : : Quadruples
18036 : :
18037 : : Goto _ _ LoopQuad
18038 : : */
18039 : :
18040 : 530 : extern "C" void M2Quads_BuildEndLoop (void)
18041 : : {
18042 : 530 : unsigned int Loop;
18043 : :
18044 : 530 : M2Quads_PopT (&Loop);
18045 : 530 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, Loop);
18046 : 530 : BackPatch (PopExit (), NextQuad);
18047 : 530 : }
18048 : :
18049 : :
18050 : : /*
18051 : : BuildThenIf - Builds the Then part of the If statement
18052 : : from the quad stack.
18053 : : The Stack is expected to contain:
18054 : :
18055 : :
18056 : : Entry Exit
18057 : : ===== ====
18058 : :
18059 : : Ptr -> <- Ptr
18060 : : +------------+ +------------+
18061 : : | t | f | | 0 | f |
18062 : : |------------| |------------|
18063 : :
18064 : : Quadruples
18065 : :
18066 : : The true exit is BackPatched to point to
18067 : : the NextQuad.
18068 : : */
18069 : :
18070 : 37392 : extern "C" void M2Quads_BuildThenIf (void)
18071 : : {
18072 : 37392 : unsigned int t;
18073 : 37392 : unsigned int f;
18074 : :
18075 : 37392 : CheckBooleanId ();
18076 : 37392 : PopBool (&t, &f);
18077 : 37392 : BackPatch (t, NextQuad);
18078 : 37392 : PushBool (0, f);
18079 : 37392 : }
18080 : :
18081 : :
18082 : : /*
18083 : : BuildElse - Builds the Else part of the If statement
18084 : : from the quad stack.
18085 : : The Stack is expected to contain:
18086 : :
18087 : :
18088 : : Entry Exit
18089 : : ===== ====
18090 : :
18091 : : Ptr ->
18092 : : +------------+ +------------+
18093 : : | t | f | | t+q | 0 |
18094 : : |------------| |------------|
18095 : :
18096 : : Quadruples
18097 : :
18098 : : q GotoOp _ _ 0
18099 : : q+1 <- BackPatched from f
18100 : : */
18101 : :
18102 : 12221 : extern "C" void M2Quads_BuildElse (void)
18103 : : {
18104 : 12221 : unsigned int t;
18105 : 12221 : unsigned int f;
18106 : :
18107 : 12221 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18108 : 12221 : PopBool (&t, &f);
18109 : 12221 : BackPatch (f, NextQuad);
18110 : 12221 : PushBool (Merge (t, NextQuad-1), 0); /* NextQuad-1 = Goto Quad */
18111 : 12221 : }
18112 : :
18113 : :
18114 : : /*
18115 : : BuildEndIf - Builds the End part of the If statement
18116 : : from the quad stack.
18117 : : The Stack is expected to contain:
18118 : :
18119 : :
18120 : : Entry Exit
18121 : : ===== ====
18122 : :
18123 : : Ptr ->
18124 : : +------------+
18125 : : | t | f | Empty
18126 : : |------------|
18127 : :
18128 : : Quadruples
18129 : :
18130 : : Both t and f are backpatched to point to the NextQuad
18131 : : */
18132 : :
18133 : 34388 : extern "C" void M2Quads_BuildEndIf (void)
18134 : : {
18135 : 34388 : unsigned int t;
18136 : 34388 : unsigned int f;
18137 : :
18138 : 34388 : PopBool (&t, &f);
18139 : 34388 : BackPatch (t, NextQuad);
18140 : 34388 : BackPatch (f, NextQuad);
18141 : 34388 : }
18142 : :
18143 : :
18144 : : /*
18145 : : BuildElsif1 - Builds the Elsif part of the If statement
18146 : : from the quad stack.
18147 : : The Stack is expected to contain:
18148 : :
18149 : :
18150 : : Entry Exit
18151 : : ===== ====
18152 : :
18153 : : Ptr ->
18154 : : +------------+ +------------+
18155 : : | t | f | | t+q | 0 |
18156 : : |------------| |------------|
18157 : :
18158 : : Quadruples
18159 : :
18160 : : q GotoOp _ _ 0
18161 : : q+1 <- BackPatched from f
18162 : : */
18163 : :
18164 : 3004 : extern "C" void M2Quads_BuildElsif1 (void)
18165 : : {
18166 : 3004 : unsigned int t;
18167 : 3004 : unsigned int f;
18168 : :
18169 : 3004 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18170 : 3004 : PopBool (&t, &f);
18171 : 3004 : BackPatch (f, NextQuad);
18172 : 3004 : PushBool (Merge (t, NextQuad-1), 0); /* NextQuad-1 = Goto Quad */
18173 : 3004 : }
18174 : :
18175 : :
18176 : : /*
18177 : : BuildElsif2 - Builds the Elsif until part of the If statement
18178 : : from the quad stack.
18179 : : The Stack is expected to contain:
18180 : :
18181 : :
18182 : : Entry Exit
18183 : : ===== ====
18184 : :
18185 : : Ptr ->
18186 : : +--------------+
18187 : : | 0 | f1 | <- Ptr
18188 : : |--------------| +---------------+
18189 : : | t2 | f2 | | t2 | f1+f2 |
18190 : : |--------------| |---------------|
18191 : : */
18192 : :
18193 : 3004 : extern "C" void M2Quads_BuildElsif2 (void)
18194 : : {
18195 : 3004 : unsigned int t1;
18196 : 3004 : unsigned int f1;
18197 : 3004 : unsigned int t2;
18198 : 3004 : unsigned int f2;
18199 : :
18200 : 3004 : PopBool (&t1, &f1);
18201 : 3004 : M2Debug_Assert (t1 == 0);
18202 : 3004 : PopBool (&t2, &f2);
18203 : 3004 : PushBool (t2, Merge (f1, f2));
18204 : 3004 : }
18205 : :
18206 : :
18207 : : /*
18208 : : BuildForToByDo - Builds the For To By Do part of the For statement
18209 : : from the quad stack.
18210 : : The Stack is expected to contain:
18211 : :
18212 : :
18213 : : Entry Exit
18214 : : ===== ====
18215 : :
18216 : : <- Ptr
18217 : : +----------------+
18218 : : Ptr -> | RangeId |
18219 : : +----------------+ |----------------|
18220 : : | BySym | ByType | | ForQuad |
18221 : : |----------------| |----------------|
18222 : : | e2 | | LastValue |
18223 : : |----------------| |----------------|
18224 : : | e1 | | BySym | ByType |
18225 : : |----------------| |----------------|
18226 : : | Ident | | IdentSym |
18227 : : |----------------| |----------------|
18228 : :
18229 : :
18230 : : x := e1 ;
18231 : : Note that LASTVALUE is calculated during M2GenGCC
18232 : : after all the types have been resolved.
18233 : : LASTVALUE := ((e2-e1) DIV BySym) * BySym + e1
18234 : : IF BySym<0
18235 : : THEN
18236 : : IF e1<e2
18237 : : THEN
18238 : : goto exit
18239 : : END
18240 : : ELSE
18241 : : IF e1>e2
18242 : : THEN
18243 : : goto exit
18244 : : END
18245 : : END ;
18246 : : LOOP
18247 : : body
18248 : : IF x=LASTVALUE
18249 : : THEN
18250 : : goto exit
18251 : : END ;
18252 : : INC(x, BySym)
18253 : : END
18254 : :
18255 : : Quadruples:
18256 : :
18257 : : q BecomesOp IdentSym _ e1
18258 : : q+ LastForIteratorOp LastValue := ((e1-e2) DIV by) * by + e1
18259 : : q+1 if >= by 0 q+..2
18260 : : q+2 GotoOp q+3
18261 : : q+3 If >= e1 e2 q+5
18262 : : q+4 GotoOp exit
18263 : : q+5 ..
18264 : : q+..1 Goto q+..5
18265 : : q+..2 If >= e2 e1 q+..4
18266 : : q+..3 GotoOp exit
18267 : : q+..4 ..
18268 : :
18269 : : The For Loop is regarded:
18270 : :
18271 : : For ident := e1 To e2 By by Do
18272 : :
18273 : : End
18274 : : */
18275 : :
18276 : 2154 : extern "C" void M2Quads_BuildForToByDo (void)
18277 : : {
18278 : 2154 : M2Quads_LineNote l1;
18279 : 2154 : M2Quads_LineNote l2;
18280 : 2154 : NameKey_Name e1;
18281 : 2154 : NameKey_Name e2;
18282 : 2154 : NameKey_Name Id;
18283 : 2154 : unsigned int e1tok;
18284 : 2154 : unsigned int e2tok;
18285 : 2154 : unsigned int idtok;
18286 : 2154 : unsigned int bytok;
18287 : 2154 : unsigned int LastIterator;
18288 : 2154 : unsigned int exit1;
18289 : 2154 : unsigned int IdSym;
18290 : 2154 : unsigned int BySym;
18291 : 2154 : unsigned int ByType;
18292 : 2154 : unsigned int ForLoop;
18293 : 2154 : unsigned int RangeId;
18294 : 2154 : unsigned int t;
18295 : 2154 : unsigned int f;
18296 : 2154 : unsigned int etype;
18297 : 2154 : unsigned int t1;
18298 : :
18299 : 2154 : l2 = PopLineNo ();
18300 : 2154 : l1 = PopLineNo ();
18301 : 2154 : UseLineNote (l1);
18302 : 2154 : PushFor (0);
18303 : 2154 : M2Quads_PopTFtok (&BySym, &ByType, &bytok);
18304 : 2154 : M2Quads_PopTtok (&e2, &e2tok);
18305 : 2154 : M2Quads_PopTtok (&e1, &e1tok);
18306 : 2154 : M2Quads_PopTtok (&Id, &idtok);
18307 : 2154 : IdSym = SymbolTable_RequestSym (idtok, Id);
18308 : 2154 : RangeId = M2Range_InitForLoopBeginRangeCheck (IdSym, idtok, e1, e1tok, e2, e2tok, BySym, bytok);
18309 : 2154 : BuildRange (RangeId);
18310 : 2154 : M2Quads_PushTtok (IdSym, idtok);
18311 : 2154 : M2Quads_PushTtok (e1, e1tok);
18312 : 2154 : BuildAssignmentWithoutBounds (idtok, true, true);
18313 : 2154 : UseLineNote (l2);
18314 : 2768 : LastIterator = SymbolTable_MakeTemporary (e2tok, AreConstant (((SymbolTable_IsConst (e1)) && (SymbolTable_IsConst (e2))) && (SymbolTable_IsConst (BySym))));
18315 : 2154 : SymbolTable_PutVar (LastIterator, SymbolTable_GetSType (IdSym));
18316 : 2154 : etype = M2Base_MixTypes (SymbolTable_GetSType (e1), SymbolTable_GetSType (e2), e2tok);
18317 : 2154 : e1 = doConvert (etype, e1);
18318 : 2154 : e2 = doConvert (etype, e2);
18319 : 2148 : ForLoopLastIterator (LastIterator, e1, e2, BySym, e1tok, e2tok, bytok);
18320 : : /* q+2 GotoOp q+3 */
18321 : 2148 : M2Quads_PushTFtok (BySym, ByType, bytok); /* BuildRelOp 1st parameter. */
18322 : 2148 : M2Quads_PushT (M2Reserved_GreaterEqualTok); /* 2nd parameter. */
18323 : : /* 3rd parameter. */
18324 : 2148 : PushZero (bytok, ByType);
18325 : 2148 : M2Quads_BuildRelOp (e2tok); /* Choose final expression position. */
18326 : 2148 : PopBool (&t, &f); /* Choose final expression position. */
18327 : 2148 : BackPatch (f, NextQuad);
18328 : : /* q+4 GotoOp Exit */
18329 : 2148 : M2Quads_PushTFtok (e1, SymbolTable_GetSType (e1), e1tok); /* BuildRelOp 1st parameter */
18330 : 2148 : M2Quads_PushT (M2Reserved_GreaterEqualTok); /* 2nd parameter */
18331 : 2148 : M2Quads_PushTFtok (e2, SymbolTable_GetSType (e2), e2tok); /* 3rd parameter */
18332 : 2148 : M2Quads_BuildRelOp (e2tok); /* Choose final expression position. */
18333 : 2148 : PopBool (&t1, &exit1); /* Choose final expression position. */
18334 : 2148 : BackPatch (t1, NextQuad);
18335 : 2148 : PushFor (Merge (PopFor (), exit1)); /* Merge exit1. */
18336 : 2148 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0); /* Merge exit1. */
18337 : 2148 : ForLoop = NextQuad-1;
18338 : : /* ELSE. */
18339 : 2148 : BackPatch (t, NextQuad);
18340 : 2148 : M2Quads_PushTFtok (e2, SymbolTable_GetSType (e2), e2tok); /* BuildRelOp 1st parameter */
18341 : 2148 : M2Quads_PushT (M2Reserved_GreaterEqualTok); /* 2nd parameter */
18342 : 2148 : M2Quads_PushTFtok (e1, SymbolTable_GetSType (e1), e1tok); /* 3rd parameter */
18343 : 2148 : M2Quads_BuildRelOp (e2tok); /* 3rd parameter */
18344 : 2148 : PopBool (&t1, &exit1);
18345 : 2148 : BackPatch (t1, NextQuad);
18346 : 2148 : PushFor (Merge (PopFor (), exit1)); /* Merge exit1. */
18347 : 2148 : BackPatch (ForLoop, NextQuad); /* Fixes the start of the for loop. */
18348 : 2148 : ForLoop = NextQuad;
18349 : : /* And set up the stack. */
18350 : 2148 : M2Quads_PushTFtok (IdSym, SymbolTable_GetSym (IdSym), idtok);
18351 : 2148 : M2Quads_PushTFtok (BySym, ByType, bytok);
18352 : 2148 : M2Quads_PushTFtok (LastIterator, SymbolTable_GetSType (LastIterator), e2tok);
18353 : 2148 : M2Quads_PushT (ForLoop);
18354 : 2148 : M2Quads_PushT (RangeId);
18355 : 2148 : }
18356 : :
18357 : :
18358 : : /*
18359 : : BuildPseudoBy - Builds the Non existant part of the By
18360 : : clause of the For statement
18361 : : from the quad stack.
18362 : : The Stack is expected to contain:
18363 : :
18364 : :
18365 : : Entry Exit
18366 : : ===== ====
18367 : :
18368 : : <- Ptr
18369 : : +------------+
18370 : : Ptr -> | BySym | t |
18371 : : +------------+ |------------|
18372 : : | e | t | | e | t |
18373 : : |------------| |------------|
18374 : : */
18375 : :
18376 : 1812 : extern "C" void M2Quads_BuildPseudoBy (void)
18377 : : {
18378 : 1812 : unsigned int expr;
18379 : 1812 : unsigned int type;
18380 : 1812 : unsigned int dotok;
18381 : :
18382 : : /* As there is no BY token this position is the DO at the end of the last expression. */
18383 : 1812 : M2Quads_PopTFtok (&expr, &type, &dotok);
18384 : 1812 : M2Quads_PushTFtok (expr, type, dotok);
18385 : 1812 : if (type == SymbolTable_NulSym)
18386 : : {} /* empty. */
18387 : : /* Use type. */
18388 : 1712 : else if ((SymbolTable_IsEnumeration (SymbolTable_SkipType (type))) || ((SymbolTable_SkipType (type)) == M2Base_Char))
18389 : : {
18390 : : /* avoid dangling else. */
18391 : : }
18392 : 1492 : else if (M2Base_IsOrdinalType (SymbolTable_SkipType (type)))
18393 : : {
18394 : : /* avoid dangling else. */
18395 : 1492 : type = M2Base_ZType;
18396 : : }
18397 : 1812 : PushOne (dotok, type, (const char *) "the implied {%kFOR} loop increment will cause an overflow {%1ad}", 64);
18398 : 1812 : }
18399 : :
18400 : :
18401 : : /*
18402 : : BuildEndFor - Builds the End part of the For statement
18403 : : from the quad stack.
18404 : : The Stack is expected to contain:
18405 : :
18406 : :
18407 : : Entry Exit
18408 : : ===== ====
18409 : :
18410 : : Ptr ->
18411 : : +----------------+
18412 : : | RangeId |
18413 : : |----------------|
18414 : : | ForQuad |
18415 : : |----------------|
18416 : : | LastValue |
18417 : : |----------------|
18418 : : | BySym | ByType |
18419 : : |----------------|
18420 : : | IdSym | Empty
18421 : : |----------------|
18422 : : */
18423 : :
18424 : 2148 : extern "C" void M2Quads_BuildEndFor (unsigned int endpostok)
18425 : : {
18426 : 2148 : unsigned int t;
18427 : 2148 : unsigned int f;
18428 : 2148 : unsigned int tsym;
18429 : 2148 : unsigned int RangeId;
18430 : 2148 : unsigned int IncQuad;
18431 : 2148 : unsigned int ForQuad;
18432 : 2148 : unsigned int LastSym;
18433 : 2148 : unsigned int ByType;
18434 : 2148 : unsigned int BySym;
18435 : 2148 : unsigned int bytok;
18436 : 2148 : unsigned int IdSym;
18437 : 2148 : unsigned int idtok;
18438 : :
18439 : 2148 : M2Quads_PopT (&RangeId);
18440 : 2148 : M2Quads_PopT (&ForQuad);
18441 : 2148 : M2Quads_PopT (&LastSym);
18442 : 2148 : M2Quads_PopTFtok (&BySym, &ByType, &bytok);
18443 : 2148 : M2Quads_PopTtok (&IdSym, &idtok);
18444 : : /* IF IdSym=LastSym THEN exit END */
18445 : 2148 : M2Quads_PushTF (IdSym, SymbolTable_GetSType (IdSym));
18446 : 2148 : M2Quads_PushT (M2Reserved_EqualTok);
18447 : 2148 : M2Quads_PushTF (LastSym, SymbolTable_GetSType (LastSym));
18448 : 2148 : M2Quads_BuildRelOp (endpostok);
18449 : 2148 : PopBool (&t, &f);
18450 : 2148 : BackPatch (t, NextQuad);
18451 : 2148 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18452 : 2148 : PushFor (Merge (PopFor (), NextQuad-1));
18453 : 2148 : BackPatch (f, NextQuad);
18454 : 2148 : if ((SymbolTable_GetMode (IdSym)) == SymbolTable_LeftValue)
18455 : : {
18456 : : /* index variable is a LeftValue, therefore we must dereference it */
18457 : 0 : tsym = SymbolTable_MakeTemporary (idtok, SymbolTable_RightValue);
18458 : 0 : SymbolTable_PutVar (tsym, SymbolTable_GetSType (IdSym));
18459 : 0 : CheckPointerThroughNil (idtok, IdSym);
18460 : 0 : doIndrX (endpostok, tsym, IdSym);
18461 : 0 : BuildRange (M2Range_InitForLoopEndRangeCheck (tsym, BySym)); /* --fixme-- pass endpostok. */
18462 : 0 : IncQuad = NextQuad;
18463 : : /* we have explicitly checked using the above and also
18464 : : this addition can legitimately overflow if a cardinal type
18465 : : is counting down. The above test will generate a more
18466 : : precise error message, so we suppress overflow detection
18467 : : here. */
18468 : 0 : GenQuadOTypetok (bytok, M2Quads_AddOp, tsym, tsym, BySym, false, false, idtok, idtok, bytok);
18469 : 0 : CheckPointerThroughNil (idtok, IdSym);
18470 : 0 : GenQuadOtok (idtok, M2Quads_XIndrOp, IdSym, SymbolTable_GetSType (IdSym), tsym, false, idtok, idtok, idtok);
18471 : : }
18472 : : else
18473 : : {
18474 : 2148 : BuildRange (M2Range_InitForLoopEndRangeCheck (IdSym, BySym));
18475 : 2148 : IncQuad = NextQuad;
18476 : : /* we have explicitly checked using the above and also
18477 : : this addition can legitimately overflow if a cardinal type
18478 : : is counting down. The above test will generate a more
18479 : : precise error message, so we suppress overflow detection
18480 : : here.
18481 : :
18482 : : This quadruple suppresses the generic binary op type
18483 : : check (performed in M2GenGCC.mod) as there
18484 : : will be a more informative/exhaustive check performed by the
18485 : : InitForLoopBeginRangeCheck setup in BuildForToByDo and
18486 : : performed by M2Range.mod. */
18487 : 2148 : GenQuadOTypetok (idtok, M2Quads_AddOp, IdSym, IdSym, BySym, false, false, idtok, idtok, bytok);
18488 : : }
18489 : 2148 : GenQuadO (endpostok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, ForQuad, false);
18490 : 2148 : BackPatch (PopFor (), NextQuad);
18491 : 2148 : AddForInfo (ForQuad, NextQuad-1, IncQuad, IdSym, idtok);
18492 : 2148 : M2Range_PutRangeForIncrement (RangeId, IncQuad);
18493 : 2148 : }
18494 : :
18495 : :
18496 : : /*
18497 : : BuildCaseStart - starts the case statement.
18498 : : It initializes a backpatch list on the compile
18499 : : time stack, the list is used to contain all
18500 : : case break points. The list is later backpatched
18501 : : and contains all positions of the case statement
18502 : : which jump to the end of the case statement.
18503 : : The stack also contains room for a boolean
18504 : : expression, this is needed to allow , operator
18505 : : in the CaseField alternatives.
18506 : :
18507 : : The Stack is expected to contain:
18508 : :
18509 : :
18510 : : Entry Exit
18511 : : ===== ====
18512 : :
18513 : : <- Ptr
18514 : : +------------+
18515 : : | 0 | 0 |
18516 : : |------------|
18517 : : | 0 | 0 |
18518 : : +-------------+ |------------|
18519 : : | Expr | | | Expr | |
18520 : : |-------------| |------------|
18521 : : */
18522 : :
18523 : 632 : extern "C" void M2Quads_BuildCaseStart (void)
18524 : : {
18525 : 632 : BuildRange (M2Range_InitCaseBounds (M2CaseList_PushCase (SymbolTable_NulSym, SymbolTable_NulSym, M2Quads_OperandT (1))));
18526 : 632 : PushBool (0, 0); /* BackPatch list initialized */
18527 : 632 : PushBool (0, 0); /* Room for a boolean expression */
18528 : 632 : }
18529 : :
18530 : :
18531 : : /*
18532 : : BuildCaseStartStatementSequence - starts the statement sequence
18533 : : inside a case clause.
18534 : : BackPatches the true exit to the
18535 : : NextQuad.
18536 : : The Stack:
18537 : :
18538 : : Entry Exit
18539 : :
18540 : : Ptr -> <- Ptr
18541 : : +-----------+ +------------+
18542 : : | t | f | | 0 | f |
18543 : : |-----------| |------------|
18544 : : */
18545 : :
18546 : 3054 : extern "C" void M2Quads_BuildCaseStartStatementSequence (void)
18547 : : {
18548 : 3054 : unsigned int t;
18549 : 3054 : unsigned int f;
18550 : :
18551 : 3054 : PopBool (&t, &f);
18552 : 3054 : BackPatch (t, NextQuad);
18553 : 3054 : PushBool (0, f);
18554 : 3054 : }
18555 : :
18556 : :
18557 : : /*
18558 : : BuildCaseEndStatementSequence - ends the statement sequence
18559 : : inside a case clause.
18560 : : BackPatches the false exit f1 to the
18561 : : NextQuad.
18562 : : Asserts that t1 and f2 is 0
18563 : : Pushes t2+q and 0
18564 : :
18565 : : Quadruples:
18566 : :
18567 : : q GotoOp _ _ 0
18568 : :
18569 : : The Stack:
18570 : :
18571 : : Entry Exit
18572 : :
18573 : : Ptr -> <- Ptr
18574 : : +-----------+ +------------+
18575 : : | t1 | f1 | | 0 | 0 |
18576 : : |-----------| |------------|
18577 : : | t2 | f2 | | t2+q | 0 |
18578 : : |-----------| |------------|
18579 : : */
18580 : :
18581 : 3054 : extern "C" void M2Quads_BuildCaseEndStatementSequence (void)
18582 : : {
18583 : 3054 : unsigned int t1;
18584 : 3054 : unsigned int f1;
18585 : 3054 : unsigned int t2;
18586 : 3054 : unsigned int f2;
18587 : :
18588 : 3054 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18589 : 3054 : PopBool (&t1, &f1);
18590 : 3054 : PopBool (&t2, &f2); /* t2 contains the break list for the case */
18591 : 3054 : BackPatch (f1, NextQuad); /* f1 no longer needed */
18592 : 3054 : M2Debug_Assert (t1 == 0); /* f1 no longer needed */
18593 : 3054 : M2Debug_Assert (f2 == 0);
18594 : 3054 : PushBool (Merge (t2, NextQuad-1), 0); /* NextQuad-1 = Goto Quad */
18595 : 3054 : PushBool (0, 0); /* Room for boolean expression */
18596 : 3054 : }
18597 : :
18598 : :
18599 : : /*
18600 : : BuildCaseRange - builds the range testing quaruples for
18601 : : a case clause.
18602 : :
18603 : : IF (e1>=ce1) AND (e1<=ce2)
18604 : : THEN
18605 : :
18606 : : ELS..
18607 : :
18608 : : The Stack:
18609 : :
18610 : : Entry Exit
18611 : :
18612 : : Ptr ->
18613 : : +-----------+
18614 : : | ce2 | <- Ptr
18615 : : |-----------| +-----------+
18616 : : | ce1 | | t | f |
18617 : : |-----------| |-----------|
18618 : : | t1 | f1 | | t1 | f1 |
18619 : : |-----------| |-----------|
18620 : : | t2 | f2 | | t2 | f2 |
18621 : : |-----------| |-----------|
18622 : : | e1 | | e1 |
18623 : : |-----------| |-----------|
18624 : : */
18625 : :
18626 : 176 : extern "C" void M2Quads_BuildCaseRange (void)
18627 : : {
18628 : 176 : unsigned int ce1;
18629 : 176 : unsigned int ce2;
18630 : 176 : unsigned int combinedtok;
18631 : 176 : unsigned int ce1tok;
18632 : 176 : unsigned int ce2tok;
18633 : 176 : unsigned int e1tok;
18634 : 176 : unsigned int e1;
18635 : 176 : unsigned int t2;
18636 : 176 : unsigned int f2;
18637 : 176 : unsigned int t1;
18638 : 176 : unsigned int f1;
18639 : :
18640 : 176 : M2Quads_PopTtok (&ce2, &ce2tok);
18641 : 176 : M2Quads_PopTtok (&ce1, &ce1tok);
18642 : 176 : combinedtok = M2LexBuf_MakeVirtualTok (ce2tok, ce2tok, ce1tok);
18643 : 176 : M2CaseList_AddRange (ce1, ce2, combinedtok);
18644 : 176 : PopBool (&t1, &f1);
18645 : 176 : PopBool (&t2, &f2);
18646 : 176 : M2Quads_PopTtok (&e1, &e1tok);
18647 : 176 : M2Quads_PushTtok (e1, e1tok); /* leave e1 on bottom of stack when exit procedure */
18648 : 176 : PushBool (t2, f2); /* leave e1 on bottom of stack when exit procedure */
18649 : 176 : PushBool (t1, f1); /* also leave t1 and f1 on the bottom of the stack */
18650 : 176 : M2Quads_PushTtok (e1, e1tok); /* also leave t1 and f1 on the bottom of the stack */
18651 : 176 : M2Quads_PushT (M2Reserved_GreaterEqualTok);
18652 : 176 : M2Quads_PushTtok (ce1, ce1tok);
18653 : 176 : M2Quads_BuildRelOp (combinedtok);
18654 : 176 : M2Quads_PushT (M2Reserved_AndTok);
18655 : 176 : M2Quads_RecordOp ();
18656 : 176 : M2Quads_PushTtok (e1, e1tok);
18657 : 176 : M2Quads_PushT (M2Reserved_LessEqualTok);
18658 : 176 : M2Quads_PushTtok (ce2, ce2tok);
18659 : 176 : M2Quads_BuildRelOp (combinedtok);
18660 : 176 : M2Quads_BuildBinaryOp ();
18661 : 176 : }
18662 : :
18663 : :
18664 : : /*
18665 : : BuildCaseEquality - builds the range testing quadruples for
18666 : : a case clause.
18667 : :
18668 : : IF e1=ce1
18669 : : THEN
18670 : :
18671 : : ELS..
18672 : :
18673 : : The Stack:
18674 : :
18675 : : Entry Exit
18676 : :
18677 : : Ptr ->
18678 : : +-----------+ +-----------+
18679 : : | ce1 | | t | f |
18680 : : |-----------| |-----------|
18681 : : | t1 | f1 | | t1 | f1 |
18682 : : |-----------| |-----------|
18683 : : | t2 | f2 | | t2 | f2 |
18684 : : |-----------| |-----------|
18685 : : | e1 | | e1 |
18686 : : |-----------| |-----------|
18687 : : */
18688 : :
18689 : 2928 : extern "C" void M2Quads_BuildCaseEquality (void)
18690 : : {
18691 : 2928 : unsigned int ce1tok;
18692 : 2928 : unsigned int e1tok;
18693 : 2928 : unsigned int ce1;
18694 : 2928 : unsigned int e1;
18695 : 2928 : unsigned int t2;
18696 : 2928 : unsigned int f2;
18697 : 2928 : unsigned int t1;
18698 : 2928 : unsigned int f1;
18699 : :
18700 : 2928 : M2Quads_PopTtok (&ce1, &ce1tok);
18701 : 2928 : M2CaseList_AddRange (ce1, SymbolTable_NulSym, ce1tok);
18702 : 2928 : PopBool (&t1, &f1);
18703 : 2928 : PopBool (&t2, &f2);
18704 : 2928 : M2Quads_PopTtok (&e1, &e1tok);
18705 : 2928 : M2Quads_PushTtok (e1, e1tok); /* leave e1 on bottom of stack when exit procedure */
18706 : 2928 : PushBool (t2, f2); /* also leave t2 and f2 on the bottom of the stack */
18707 : 2928 : PushBool (t1, f1); /* also leave t2 and f2 on the bottom of the stack */
18708 : 2928 : M2Quads_PushTtok (e1, e1tok);
18709 : 2928 : M2Quads_PushT (M2Reserved_EqualTok);
18710 : 2928 : M2Quads_PushTtok (ce1, ce1tok);
18711 : 2928 : M2Quads_BuildRelOp (ce1tok);
18712 : 2928 : }
18713 : :
18714 : :
18715 : : /*
18716 : : BuildCaseList - merges two case tests into one
18717 : :
18718 : : The Stack:
18719 : :
18720 : : Entry Exit
18721 : :
18722 : : Ptr ->
18723 : : +-----------+
18724 : : | t2 | f2 |
18725 : : |-----------| +-------------+
18726 : : | t1 | f1 | | t1+t2| f1+f2|
18727 : : |-----------| |-------------|
18728 : : */
18729 : :
18730 : 3104 : extern "C" void M2Quads_BuildCaseList (void)
18731 : : {
18732 : 3104 : unsigned int t2;
18733 : 3104 : unsigned int f2;
18734 : 3104 : unsigned int t1;
18735 : 3104 : unsigned int f1;
18736 : :
18737 : 3104 : PopBool (&t2, &f2);
18738 : 3104 : PopBool (&t1, &f1);
18739 : 3104 : PushBool (Merge (t1, t2), Merge (f1, f2));
18740 : 3104 : }
18741 : :
18742 : :
18743 : : /*
18744 : : BuildCaseOr - builds the , in the case clause.
18745 : :
18746 : : The Stack:
18747 : :
18748 : : Entry Exit
18749 : :
18750 : : Ptr -> <- Ptr
18751 : : +-----------+ +------------+
18752 : : | t | f | | t | 0 |
18753 : : |-----------| |------------|
18754 : : */
18755 : :
18756 : 50 : extern "C" void M2Quads_BuildCaseOr (void)
18757 : : {
18758 : 50 : unsigned int t;
18759 : 50 : unsigned int f;
18760 : :
18761 : 50 : PopBool (&t, &f);
18762 : 50 : BackPatch (f, NextQuad);
18763 : 50 : PushBool (t, 0);
18764 : 50 : }
18765 : :
18766 : :
18767 : : /*
18768 : : BuildCaseElse - builds the else of case clause.
18769 : :
18770 : : The Stack:
18771 : :
18772 : : Entry Exit
18773 : :
18774 : : Ptr -> <- Ptr
18775 : : +-----------+ +------------+
18776 : : | t | f | | t | 0 |
18777 : : |-----------| |------------|
18778 : : */
18779 : :
18780 : 632 : extern "C" void M2Quads_BuildCaseElse (void)
18781 : : {
18782 : 632 : unsigned int t;
18783 : 632 : unsigned int f;
18784 : :
18785 : 632 : PopBool (&t, &f);
18786 : 632 : BackPatch (f, NextQuad);
18787 : 632 : PushBool (t, 0);
18788 : 632 : }
18789 : :
18790 : :
18791 : : /*
18792 : : BuildCaseEnd - builds the end of case clause.
18793 : :
18794 : : The Stack:
18795 : :
18796 : : Entry Exit
18797 : :
18798 : : Ptr ->
18799 : : +-----------+
18800 : : | t1 | f1 |
18801 : : |-----------|
18802 : : | t2 | f2 |
18803 : : |-----------|
18804 : : | e1 |
18805 : : |-----------| Empty
18806 : : */
18807 : :
18808 : 632 : extern "C" void M2Quads_BuildCaseEnd (void)
18809 : : {
18810 : 632 : unsigned int e1;
18811 : 632 : unsigned int t;
18812 : 632 : unsigned int f;
18813 : :
18814 : 632 : PopBool (&t, &f);
18815 : 632 : BackPatch (f, NextQuad);
18816 : 632 : BackPatch (t, NextQuad);
18817 : 632 : PopBool (&t, &f);
18818 : 632 : BackPatch (f, NextQuad);
18819 : 632 : BackPatch (t, NextQuad);
18820 : 632 : M2Quads_PopT (&e1);
18821 : 632 : M2CaseList_PopCase ();
18822 : 632 : }
18823 : :
18824 : :
18825 : : /*
18826 : : BuildCaseCheck - builds the case checking code to ensure that
18827 : : the program does not need an else clause at runtime.
18828 : : The stack is unaltered.
18829 : : */
18830 : :
18831 : 348 : extern "C" void M2Quads_BuildCaseCheck (void)
18832 : : {
18833 : 348 : BuildError (M2Range_InitNoElseRangeCheck ());
18834 : 348 : }
18835 : :
18836 : :
18837 : : /*
18838 : : BuildNulParam - Builds a nul parameter on the stack.
18839 : : The Stack:
18840 : :
18841 : : Entry Exit
18842 : :
18843 : : <- Ptr
18844 : : Empty +------------+
18845 : : | 0 |
18846 : : |------------|
18847 : : */
18848 : :
18849 : 17895 : extern "C" void M2Quads_BuildNulParam (void)
18850 : : {
18851 : 17895 : M2Quads_PushT (static_cast<unsigned int> (0));
18852 : 17895 : }
18853 : :
18854 : :
18855 : : /*
18856 : : BuildProcedureCall - builds a procedure call.
18857 : : Although this procedure does not directly
18858 : : destroy the procedure parameters, it calls
18859 : : routine which will manipulate the stack and
18860 : : so the entry and exit states of the stack are shown.
18861 : :
18862 : : The Stack:
18863 : :
18864 : :
18865 : : Entry Exit
18866 : :
18867 : : Ptr ->
18868 : : +----------------+
18869 : : | NoOfParam |
18870 : : |----------------|
18871 : : | Param 1 |
18872 : : |----------------|
18873 : : | Param 2 |
18874 : : |----------------|
18875 : : . .
18876 : : . .
18877 : : . .
18878 : : |----------------|
18879 : : | Param # |
18880 : : |----------------|
18881 : : | ProcSym | Type | Empty
18882 : : |----------------|
18883 : : */
18884 : :
18885 : 167617 : extern "C" void M2Quads_BuildProcedureCall (unsigned int tokno)
18886 : : {
18887 : 167617 : unsigned int NoOfParam;
18888 : 167617 : unsigned int ProcSym;
18889 : :
18890 : 167617 : M2Quads_PopT (&NoOfParam);
18891 : 167617 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
18892 : 167617 : M2Quads_PushT (NoOfParam); /* Compile time stack restored to entry state */
18893 : 167617 : if ((M2Base_IsPseudoBaseProcedure (ProcSym)) || (M2System_IsPseudoSystemProcedure (ProcSym))) /* Compile time stack restored to entry state */
18894 : : {
18895 : 19204 : M2Quads_DisplayStack ();
18896 : 19204 : ManipulatePseudoCallParameters ();
18897 : 19204 : M2Quads_DisplayStack ();
18898 : 19204 : BuildPseudoProcedureCall (tokno);
18899 : 19204 : M2Quads_DisplayStack ();
18900 : : }
18901 : 148413 : else if (SymbolTable_IsUnknown (ProcSym))
18902 : : {
18903 : : /* avoid dangling else. */
18904 : 6 : M2MetaError_MetaError1 ((const char *) "{%1Ua} is not recognised as a procedure, check declaration or import", 68, ProcSym);
18905 : 6 : M2Quads_PopN (NoOfParam+2);
18906 : : }
18907 : : else
18908 : : {
18909 : : /* avoid dangling else. */
18910 : 148407 : M2Quads_DisplayStack ();
18911 : 148407 : BuildRealProcedureCall (tokno);
18912 : 148401 : M2Quads_DisplayStack ();
18913 : : }
18914 : 167611 : }
18915 : :
18916 : :
18917 : : /*
18918 : : CheckBuildFunction - checks to see whether ProcSym is a function
18919 : : and if so it adds a TempSym value which will
18920 : : hold the return value once the function finishes.
18921 : : This procedure also generates an error message
18922 : : if the user is calling a function and ignoring
18923 : : the return result. The additional TempSym
18924 : : is not created if ProcSym is a procedure
18925 : : and the stack is unaltered.
18926 : :
18927 : : The Stack:
18928 : :
18929 : :
18930 : : Entry Exit
18931 : :
18932 : : Ptr ->
18933 : :
18934 : : +----------------+
18935 : : | ProcSym | Type |
18936 : : +----------------+ |----------------|
18937 : : | ProcSym | Type | | TempSym | Type |
18938 : : |----------------| |----------------|
18939 : : */
18940 : :
18941 : 99015 : extern "C" bool M2Quads_CheckBuildFunction (void)
18942 : : {
18943 : 99015 : unsigned int tokpos;
18944 : 99015 : unsigned int TempSym;
18945 : 99015 : unsigned int ProcSym;
18946 : 99015 : unsigned int Type;
18947 : :
18948 : 99015 : M2Quads_PopTFtok (&ProcSym, &Type, &tokpos);
18949 : 99015 : if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (Type)))
18950 : : {
18951 : : /* avoid dangling else. */
18952 : 644 : if ((SymbolTable_GetSType (Type)) != SymbolTable_NulSym)
18953 : : {
18954 : 0 : TempSym = SymbolTable_MakeTemporary (tokpos, SymbolTable_RightValue);
18955 : 0 : SymbolTable_PutVar (TempSym, SymbolTable_GetSType (Type));
18956 : 0 : M2Quads_PushTFtok (TempSym, SymbolTable_GetSType (Type), tokpos);
18957 : 0 : M2Quads_PushTFtok (ProcSym, Type, tokpos);
18958 : 0 : if (! (SymbolTable_IsReturnOptionalAny (Type)))
18959 : : {
18960 : 0 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "function {%1Ea} is called but its return value is ignored", 57, ProcSym);
18961 : : }
18962 : 0 : return true;
18963 : : }
18964 : : }
18965 : 98371 : else if ((SymbolTable_IsProcedure (ProcSym)) && (Type != SymbolTable_NulSym))
18966 : : {
18967 : : /* avoid dangling else. */
18968 : 0 : TempSym = SymbolTable_MakeTemporary (tokpos, SymbolTable_RightValue);
18969 : 0 : SymbolTable_PutVar (TempSym, Type);
18970 : 0 : M2Quads_PushTFtok (TempSym, Type, tokpos);
18971 : 0 : M2Quads_PushTFtok (ProcSym, Type, tokpos);
18972 : 0 : if (! (SymbolTable_IsReturnOptionalAny (ProcSym)))
18973 : : {
18974 : 0 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "function {%1Ea} is called but its return value is ignored", 57, ProcSym);
18975 : : }
18976 : 0 : return true;
18977 : : }
18978 : 99015 : M2Quads_PushTFtok (ProcSym, Type, tokpos);
18979 : 99015 : return false;
18980 : : /* static analysis guarentees a RETURN statement will be used before here. */
18981 : : __builtin_unreachable ();
18982 : : }
18983 : :
18984 : :
18985 : : /*
18986 : : BuildFunctionCall - builds a function call.
18987 : : The Stack:
18988 : :
18989 : :
18990 : : Entry Exit
18991 : :
18992 : : Ptr ->
18993 : : +----------------+
18994 : : | NoOfParam |
18995 : : |----------------|
18996 : : | Param 1 |
18997 : : |----------------|
18998 : : | Param 2 |
18999 : : |----------------|
19000 : : . .
19001 : : . .
19002 : : . .
19003 : : |----------------|
19004 : : | Param # | <- Ptr
19005 : : |----------------| +------------+
19006 : : | ProcSym | Type | | ReturnVar |
19007 : : |----------------| |------------|
19008 : : */
19009 : :
19010 : 75880 : extern "C" void M2Quads_BuildFunctionCall (bool ConstExpr)
19011 : : {
19012 : 75880 : unsigned int paramtok;
19013 : 75880 : unsigned int combinedtok;
19014 : 75880 : unsigned int functok;
19015 : 75880 : unsigned int NoOfParam;
19016 : 75880 : unsigned int ProcSym;
19017 : :
19018 : 75880 : M2Quads_PopT (&NoOfParam);
19019 : 75880 : functok = OperandTtok (NoOfParam+1);
19020 : 75880 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
19021 : 75880 : ProcSym = PCSymBuild_SkipConst (ProcSym);
19022 : 75880 : M2Quads_PushT (NoOfParam);
19023 : : /* Compile time stack restored to entry state. */
19024 : 75880 : if (SymbolTable_IsUnknown (ProcSym))
19025 : : {
19026 : 6 : paramtok = OperandTtok (1);
19027 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, paramtok);
19028 : 6 : M2MetaError_MetaErrorT1 (functok, (const char *) "procedure function {%1Ea} is undefined", 38, ProcSym);
19029 : 6 : M2Quads_PopN (NoOfParam+2);
19030 : : /* Fake return value to continue compiling. */
19031 : 6 : M2Quads_PushT (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym));
19032 : : }
19033 : 75874 : else if (SymbolTable_IsAModula2Type (ProcSym))
19034 : : {
19035 : : /* avoid dangling else. */
19036 : 1454 : ManipulatePseudoCallParameters ();
19037 : 1448 : BuildTypeCoercion (ConstExpr);
19038 : : }
19039 : 74420 : else if ((M2System_IsPseudoSystemFunction (ProcSym)) || (M2Base_IsPseudoBaseFunction (ProcSym)))
19040 : : {
19041 : : /* avoid dangling else. */
19042 : 32664 : ManipulatePseudoCallParameters ();
19043 : 32664 : BuildPseudoFunctionCall (ConstExpr);
19044 : : }
19045 : : else
19046 : : {
19047 : : /* avoid dangling else. */
19048 : 41756 : BuildRealFunctionCall (functok, ConstExpr);
19049 : : }
19050 : 75856 : }
19051 : :
19052 : :
19053 : : /*
19054 : : BuildConstFunctionCall - builds a function call and checks that this function can be
19055 : : called inside a ConstExpression.
19056 : :
19057 : : The Stack:
19058 : :
19059 : :
19060 : : Entry Exit
19061 : :
19062 : : Ptr ->
19063 : : +----------------+
19064 : : | NoOfParam |
19065 : : |----------------|
19066 : : | Param 1 |
19067 : : |----------------|
19068 : : | Param 2 |
19069 : : |----------------|
19070 : : . .
19071 : : . .
19072 : : . .
19073 : : |----------------|
19074 : : | Param # | <- Ptr
19075 : : |----------------| +------------+
19076 : : | ProcSym | Type | | ReturnVar |
19077 : : |----------------| |------------|
19078 : :
19079 : : */
19080 : :
19081 : 4310 : extern "C" void M2Quads_BuildConstFunctionCall (void)
19082 : : {
19083 : 4310 : unsigned int functok;
19084 : 4310 : unsigned int combinedtok;
19085 : 4310 : unsigned int paramtok;
19086 : 4310 : unsigned int ConstExpression;
19087 : 4310 : unsigned int NoOfParam;
19088 : 4310 : unsigned int ProcSym;
19089 : :
19090 : 4310 : M2Quads_DisplayStack ();
19091 : 4310 : M2Quads_PopT (&NoOfParam);
19092 : 4310 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
19093 : 4310 : functok = OperandTtok (NoOfParam+1);
19094 : 4310 : if (M2Options_CompilerDebugging)
19095 : : {
19096 : 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));
19097 : : }
19098 : : /* ErrorStringAt (InitString ('constant function'), functok). */
19099 : 4310 : M2Quads_PushT (NoOfParam);
19100 : 4310 : if ((ProcSym != M2Base_Convert) && (((M2Base_IsPseudoBaseFunction (ProcSym)) || (M2System_IsPseudoSystemFunctionConstExpression (ProcSym))) || ((SymbolTable_IsProcedure (ProcSym)) && (SymbolTable_IsProcedureBuiltin (ProcSym)))))
19101 : : {
19102 : 4178 : M2Quads_BuildFunctionCall (true);
19103 : : }
19104 : : else
19105 : : {
19106 : 132 : if (SymbolTable_IsAModula2Type (ProcSym))
19107 : : {
19108 : : /* Type conversion. */
19109 : 132 : if (NoOfParam == 1)
19110 : : {
19111 : 132 : ConstExpression = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
19112 : 132 : paramtok = OperandTtok (NoOfParam+1);
19113 : 132 : M2Quads_PopN (NoOfParam+2);
19114 : : /* Build macro: CONVERT( ProcSym, ConstExpression ). */
19115 : 132 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
19116 : 132 : M2Quads_PushTtok (ProcSym, functok);
19117 : 132 : M2Quads_PushTtok (ConstExpression, paramtok);
19118 : 132 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters. */
19119 : 132 : BuildConvertFunction (M2Base_Convert, true); /* Two parameters. */
19120 : : }
19121 : : else
19122 : : {
19123 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}a constant type conversion can only have one argument", 57);
19124 : : }
19125 : : }
19126 : : else
19127 : : {
19128 : : /* Error issue message and fake return stack. */
19129 : 0 : if (M2Options_Iso)
19130 : : {
19131 : 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);
19132 : : }
19133 : : else
19134 : : {
19135 : 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);
19136 : : }
19137 : 0 : if (NoOfParam > 0)
19138 : : {
19139 : 0 : paramtok = OperandTtok (NoOfParam+1);
19140 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
19141 : : }
19142 : : else
19143 : : {
19144 : 0 : combinedtok = functok;
19145 : : }
19146 : 0 : M2Quads_PopN (NoOfParam+2);
19147 : 0 : M2Quads_PushT (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym)); /* Fake return value to continue compiling. */
19148 : : }
19149 : : }
19150 : 4310 : }
19151 : :
19152 : :
19153 : : /*
19154 : : BuildBooleanVariable - tests to see whether top of stack is a boolean
19155 : : conditional and if so it converts it into a boolean
19156 : : variable.
19157 : : */
19158 : :
19159 : 300570 : extern "C" void M2Quads_BuildBooleanVariable (void)
19160 : : {
19161 : 300570 : if (IsBoolean (1))
19162 : : {
19163 : 6438 : ConvertBooleanToVariable (OperandTtok (1), 1);
19164 : : }
19165 : 300570 : }
19166 : :
19167 : :
19168 : : /*
19169 : : BuildModuleStart - starts current module scope.
19170 : : */
19171 : :
19172 : 64669 : extern "C" void M2Quads_BuildModuleStart (unsigned int tok)
19173 : : {
19174 : 64669 : GenQuadO (tok, M2Quads_ModuleScopeOp, tok, (unsigned int ) (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()))), SymbolTable_GetCurrentModule (), false);
19175 : 64669 : }
19176 : :
19177 : :
19178 : : /*
19179 : : BuildProcedureStart - Builds start of the procedure. Generates a
19180 : : quadruple which indicated the start of
19181 : : this procedure declarations scope.
19182 : : The Stack is expected to contain:
19183 : :
19184 : :
19185 : : Entry Exit
19186 : : ===== ====
19187 : :
19188 : : Ptr -> <- Ptr
19189 : : +------------+ +-----------+
19190 : : | ProcSym | | ProcSym |
19191 : : |------------| |-----------|
19192 : : | Name | | Name |
19193 : : |------------| |-----------|
19194 : :
19195 : :
19196 : : Quadruples:
19197 : :
19198 : : q ProcedureScopeOp Line# Scope ProcSym
19199 : : */
19200 : :
19201 : 71787 : extern "C" void M2Quads_BuildProcedureStart (void)
19202 : : {
19203 : 71787 : unsigned int ProcSym;
19204 : :
19205 : 71787 : M2Quads_PopT (&ProcSym);
19206 : 71787 : M2Debug_Assert (SymbolTable_IsProcedure (ProcSym));
19207 : 71787 : SymbolTable_PutProcedureScopeQuad (ProcSym, NextQuad);
19208 : 71787 : GenQuad (M2Quads_ProcedureScopeOp, M2LexBuf_GetPreviousTokenLineNo (), SymbolTable_GetScope (ProcSym), ProcSym);
19209 : 71787 : M2Quads_PushT (ProcSym);
19210 : 71787 : }
19211 : :
19212 : :
19213 : : /*
19214 : : BuildProcedureBegin - determines the start of the BEGIN END block of
19215 : : the procedure.
19216 : : The Stack is expected to contain:
19217 : :
19218 : :
19219 : : Entry Exit
19220 : : ===== ====
19221 : :
19222 : : Ptr -> <- Ptr
19223 : : +------------+ +-----------+
19224 : : | ProcSym | | ProcSym |
19225 : : |------------| |-----------|
19226 : : | Name | | Name |
19227 : : |------------| |-----------|
19228 : :
19229 : :
19230 : : Quadruples:
19231 : :
19232 : : q NewLocalVarOp TokenNo(BEGIN) _ ProcSym
19233 : : */
19234 : :
19235 : 71775 : extern "C" void M2Quads_BuildProcedureBegin (void)
19236 : : {
19237 : 71775 : unsigned int ProcSym;
19238 : :
19239 : 71775 : M2Quads_PopT (&ProcSym);
19240 : 71775 : M2Debug_Assert (SymbolTable_IsProcedure (ProcSym));
19241 : 71775 : SymbolTable_PutProcedureStartQuad (ProcSym, NextQuad);
19242 : 71775 : SymbolTable_PutProcedureBegin (ProcSym, M2LexBuf_GetTokenNo ());
19243 : 71775 : GenQuad (M2Quads_NewLocalVarOp, M2LexBuf_GetTokenNo (), SymbolTable_GetScope (ProcSym), ProcSym);
19244 : 71775 : CurrentProc = ProcSym;
19245 : 71775 : M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
19246 : 71775 : M2Quads_PushT (ProcSym);
19247 : 71775 : CheckVariablesAt (ProcSym);
19248 : 71775 : CheckNeedPriorityBegin (M2LexBuf_GetTokenNo (), ProcSym, SymbolTable_GetCurrentModule ());
19249 : 71775 : M2StackWord_PushWord (TryStack, NextQuad);
19250 : 71775 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
19251 : 71775 : if (SymbolTable_HasExceptionBlock (ProcSym))
19252 : : {
19253 : 132 : GenQuad (M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
19254 : : }
19255 : 71775 : }
19256 : :
19257 : :
19258 : : /*
19259 : : BuildProcedureEnd - Builds end of the procedure. Destroys space for
19260 : : the local variables.
19261 : : The Stack is expected to contain:
19262 : :
19263 : :
19264 : : Entry Exit
19265 : : ===== ====
19266 : :
19267 : : Ptr -> <- Ptr
19268 : : +------------+ +-----------+
19269 : : | ProcSym | | ProcSym |
19270 : : |------------| |-----------|
19271 : : | Name | | Name |
19272 : : |------------| |-----------|
19273 : :
19274 : :
19275 : : Quadruples:
19276 : :
19277 : : q KillLocalVarOp TokenNo(END) _ ProcSym
19278 : : */
19279 : :
19280 : 71745 : extern "C" void M2Quads_BuildProcedureEnd (void)
19281 : : {
19282 : 71745 : unsigned int tok;
19283 : 71745 : unsigned int ProcSym;
19284 : :
19285 : 71745 : M2Quads_PopTtok (&ProcSym, &tok);
19286 : 71745 : if (SymbolTable_HasExceptionBlock (ProcSym))
19287 : : {
19288 : 132 : BuildRTExceptLeave (tok, true);
19289 : 132 : GenQuad (M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
19290 : : }
19291 : 71745 : if ((SymbolTable_GetSType (ProcSym)) != SymbolTable_NulSym)
19292 : : {
19293 : 12302 : BuildError (M2Range_InitNoReturnRangeCheck ());
19294 : : }
19295 : 71745 : BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
19296 : 71745 : CheckNeedPriorityEnd (tok, ProcSym, SymbolTable_GetCurrentModule ());
19297 : 71745 : CurrentProc = SymbolTable_NulSym;
19298 : 71745 : SymbolTable_PutProcedureEnd (ProcSym, (M2LexBuf_GetTokenNo ())-1); /* --fixme-- */
19299 : 71745 : GenQuad (M2Quads_KillLocalVarOp, (M2LexBuf_GetTokenNo ())-1, SymbolTable_NulSym, ProcSym); /* --fixme-- */
19300 : 71745 : SymbolTable_PutProcedureEndQuad (ProcSym, NextQuad);
19301 : 71745 : GenQuad (M2Quads_ReturnOp, SymbolTable_NulSym, SymbolTable_NulSym, ProcSym);
19302 : 71745 : CheckFunctionReturn (ProcSym);
19303 : 71745 : CheckVariablesInBlock (ProcSym);
19304 : : /* Call PutProcedureEndQuad so that any runtime procedure will be
19305 : : seen as defined even if it not seen during pass 2 (which will also
19306 : : call PutProcedureEndQuad). */
19307 : 71745 : SymbolTable_PutProcedureParametersDefined (ProcSym, SymbolTable_ProperProcedure);
19308 : 71745 : SymbolTable_PutProcedureDefined (ProcSym, SymbolTable_ProperProcedure);
19309 : 71745 : M2StackWord_RemoveTop (CatchStack);
19310 : 71745 : M2StackWord_RemoveTop (TryStack);
19311 : 71745 : M2Quads_PushT (ProcSym);
19312 : 71745 : }
19313 : :
19314 : :
19315 : : /*
19316 : : BuildReturn - Builds the Return part of the procedure.
19317 : : tokreturn is the location of the RETURN keyword.
19318 : : The Stack is expected to contain:
19319 : :
19320 : :
19321 : : Entry Exit
19322 : : ===== ====
19323 : :
19324 : : Ptr ->
19325 : : +------------+
19326 : : | e1 | Empty
19327 : : |------------|
19328 : : */
19329 : :
19330 : 19792 : extern "C" void M2Quads_BuildReturn (unsigned int tokreturn)
19331 : : {
19332 : 19792 : unsigned int tokcombined;
19333 : 19792 : unsigned int tokexpr;
19334 : 19792 : unsigned int e2;
19335 : 19792 : unsigned int t2;
19336 : 19792 : unsigned int e1;
19337 : 19792 : unsigned int t1;
19338 : 19792 : unsigned int t;
19339 : 19792 : unsigned int f;
19340 : 19792 : unsigned int Des;
19341 : :
19342 : 19792 : if (IsBoolean (1))
19343 : : {
19344 : 1612 : PopBooltok (&t, &f, &tokexpr);
19345 : : /* Des will be a boolean type */
19346 : 1612 : Des = SymbolTable_MakeTemporary (tokexpr, SymbolTable_RightValue);
19347 : 1612 : SymbolTable_PutVar (Des, M2Base_Boolean);
19348 : 1612 : M2Quads_PushTFtok (Des, M2Base_Boolean, tokexpr);
19349 : 1612 : PushBooltok (t, f, tokexpr);
19350 : 1612 : BuildAssignmentWithoutBounds (tokreturn, false, true);
19351 : 1612 : M2Quads_PushTFtok (Des, M2Base_Boolean, tokexpr);
19352 : : }
19353 : 19792 : M2Quads_PopTFtok (&e1, &t1, &tokexpr);
19354 : 19792 : tokcombined = M2LexBuf_MakeVirtualTok (tokreturn, tokreturn, tokexpr);
19355 : 19792 : if (e1 != SymbolTable_NulSym)
19356 : : {
19357 : : /* this will check that the type returned is compatible with
19358 : : the formal return type of the procedure. */
19359 : 19044 : CheckReturnType (tokcombined, CurrentProc, e1, t1);
19360 : : /* dereference LeftValue if necessary */
19361 : 19044 : if ((SymbolTable_GetMode (e1)) == SymbolTable_LeftValue)
19362 : : {
19363 : 108 : t2 = SymbolTable_GetSType (CurrentProc);
19364 : 108 : e2 = SymbolTable_MakeTemporary (tokexpr, SymbolTable_RightValue);
19365 : 108 : SymbolTable_PutVar (e2, t2);
19366 : 108 : CheckPointerThroughNil (tokexpr, e1);
19367 : 108 : doIndrX (tokexpr, e2, e1);
19368 : : /* here we check the data contents to ensure no overflow. */
19369 : 108 : BuildRange (M2Range_InitReturnRangeCheck (tokcombined, CurrentProc, e2));
19370 : 108 : GenQuadOtok (tokcombined, M2Quads_ReturnValueOp, e2, SymbolTable_NulSym, CurrentProc, false, tokcombined, M2LexBuf_UnknownTokenNo, SymbolTable_GetDeclaredMod (CurrentProc));
19371 : : }
19372 : : else
19373 : : {
19374 : : /* here we check the data contents to ensure no overflow. */
19375 : 18936 : BuildRange (M2Range_InitReturnRangeCheck (tokcombined, CurrentProc, e1));
19376 : 18936 : GenQuadOtok (tokcombined, M2Quads_ReturnValueOp, e1, SymbolTable_NulSym, CurrentProc, false, tokcombined, M2LexBuf_UnknownTokenNo, SymbolTable_GetDeclaredMod (CurrentProc));
19377 : : }
19378 : : }
19379 : 19792 : GenQuadO (tokcombined, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PopWord (ReturnStack), false);
19380 : 19792 : M2StackWord_PushWord (ReturnStack, NextQuad-1);
19381 : 19792 : }
19382 : :
19383 : :
19384 : : /*
19385 : : BuildModulePriority - assigns the current module with a priority
19386 : : from the top of stack.
19387 : :
19388 : : Entry Exit
19389 : : ===== ====
19390 : :
19391 : :
19392 : : Ptr -> Empty
19393 : : +------------+
19394 : : | Priority |
19395 : : |------------|
19396 : : */
19397 : :
19398 : 38 : extern "C" void M2Quads_BuildModulePriority (void)
19399 : : {
19400 : 38 : unsigned int Priority;
19401 : :
19402 : 38 : M2Quads_PopT (&Priority);
19403 : 38 : SymbolTable_PutPriority (SymbolTable_GetCurrentModule (), Priority);
19404 : 38 : }
19405 : :
19406 : :
19407 : : /*
19408 : : StartBuildWith - performs the with statement.
19409 : : The Stack:
19410 : :
19411 : : Entry Exit
19412 : :
19413 : : +------------+
19414 : : | Sym | Type | Empty
19415 : : |------------|
19416 : : */
19417 : :
19418 : 6036 : extern "C" void M2Quads_StartBuildWith (unsigned int withTok)
19419 : : {
19420 : 6036 : unsigned int tok;
19421 : 6036 : unsigned int Sym;
19422 : 6036 : unsigned int Type;
19423 : 6036 : unsigned int Ref;
19424 : :
19425 : 6036 : DebugLocation (static_cast<unsigned int> (M2Reserved_withtok), (const char *) "with", 4);
19426 : 6036 : BuildStmtNoteTok (withTok);
19427 : 6036 : M2Quads_DisplayStack ();
19428 : 6036 : M2Quads_PopTFtok (&Sym, &Type, &tok);
19429 : 6036 : DebugLocation (tok, (const char *) "expression", 10);
19430 : 6036 : Type = SymbolTable_SkipType (Type);
19431 : 6036 : if (Type == SymbolTable_NulSym)
19432 : : {
19433 : 6 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1Aa} {%1d} has a no type, the {%kWITH} statement requires a variable or parameter of a {%kRECORD} type", 104, Sym);
19434 : : }
19435 : : else
19436 : : {
19437 : 6030 : Ref = SymbolTable_MakeTemporary (tok, SymbolTable_LeftValue);
19438 : 6030 : SymbolTable_PutVar (Ref, Type);
19439 : 6030 : if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
19440 : : {
19441 : : /* Copy LeftValue. */
19442 : 5782 : GenQuadO (tok, M2Quads_BecomesOp, Ref, SymbolTable_NulSym, Sym, true);
19443 : : }
19444 : : else
19445 : : {
19446 : : /* Calculate the address of Sym. */
19447 : 248 : GenQuadO (tok, M2Quads_AddrOp, Ref, SymbolTable_NulSym, Sym, true);
19448 : : }
19449 : 6030 : PushWith (Sym, Type, Ref, tok);
19450 : 6030 : DebugLocation (tok, (const char *) "with ref", 8);
19451 : 6030 : if (! (SymbolTable_IsRecord (Type)))
19452 : : {
19453 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "the {%kWITH} statement requires that {%1Ea} {%1d} be of a {%kRECORD} {%1tsa:type rather than {%1tsa}}", 101, Sym);
19454 : : }
19455 : 6030 : SymbolTable_StartScope (Type);
19456 : : }
19457 : 6030 : M2Quads_DisplayStack ();
19458 : 6030 : }
19459 : :
19460 : :
19461 : : /*
19462 : : EndBuildWith - terminates the innermost with scope.
19463 : : */
19464 : :
19465 : 6030 : extern "C" void M2Quads_EndBuildWith (void)
19466 : : {
19467 : 6030 : M2Quads_DisplayStack ();
19468 : 6030 : SymbolTable_EndScope ();
19469 : 6030 : PopWith ();
19470 : 6030 : M2Quads_DisplayStack ();
19471 : 6030 : }
19472 : :
19473 : :
19474 : : /*
19475 : : CheckWithReference - performs the with statement.
19476 : : The Stack:
19477 : :
19478 : : Entry Exit
19479 : :
19480 : : +------------+ +------------+
19481 : : | Sym | Type | | Sym | Type |
19482 : : |------------| |------------|
19483 : : */
19484 : :
19485 : 589572 : extern "C" void M2Quads_CheckWithReference (void)
19486 : : {
19487 : 589572 : M2Quads_WithFrame f;
19488 : 589572 : unsigned int tokpos;
19489 : 589572 : unsigned int i;
19490 : 589572 : unsigned int n;
19491 : 589572 : unsigned int rw;
19492 : 589572 : unsigned int Sym;
19493 : 589572 : unsigned int Type;
19494 : :
19495 : 589572 : n = M2StackAddress_NoOfItemsInStackAddress (WithStack);
19496 : 589572 : if ((n > 0) && ! SuppressWith)
19497 : : {
19498 : 109554 : PopTFrwtok (&Sym, &Type, &rw, &tokpos);
19499 : 109554 : M2Debug_Assert (tokpos != M2LexBuf_UnknownTokenNo);
19500 : : /* inner WITH always has precidence */
19501 : 109554 : i = 1; /* top of stack */
19502 : : /* WriteString('Checking for a with') ; */
19503 : 342480 : while (i <= n)
19504 : : {
19505 : 123372 : f = static_cast<M2Quads_WithFrame> (M2StackAddress_PeepAddress (WithStack, i));
19506 : 123372 : if ((SymbolTable_IsRecordField (Sym)) && ((SymbolTable_GetRecord (SymbolTable_GetParent (Sym))) == f->RecordType))
19507 : : {
19508 : 30612 : if (SymbolTable_IsUnused (Sym))
19509 : : {
19510 : 0 : M2MetaError_MetaError1 ((const char *) "record field {%1Dad} was declared as unused by a pragma", 55, Sym);
19511 : : }
19512 : : /* Fake a RecordSym.op */
19513 : 30612 : PushTFrwtok (f->RecordRef, f->RecordType, f->rw, f->RecordTokPos);
19514 : 30612 : M2Quads_PushTFtok (Sym, Type, tokpos);
19515 : 30612 : BuildAccessWithField ();
19516 : 30612 : PopTFrw (&Sym, &Type, &f->rw);
19517 : 30612 : i = n+1; /* Finish loop. */
19518 : : }
19519 : : else
19520 : : {
19521 : 92760 : i += 1;
19522 : : }
19523 : : }
19524 : 109554 : PushTFrwtok (Sym, Type, rw, tokpos);
19525 : : }
19526 : 589572 : }
19527 : :
19528 : :
19529 : : /*
19530 : : BuildDesignatorRecord - Builds the record referencing.
19531 : : The Stack is expected to contain:
19532 : :
19533 : :
19534 : : Entry Exit
19535 : : ===== ====
19536 : :
19537 : : Ptr ->
19538 : : +--------------+
19539 : : | n |
19540 : : |--------------|
19541 : : | fld1 | type1 |
19542 : : |--------------|
19543 : : . .
19544 : : . .
19545 : : . .
19546 : : |--------------|
19547 : : | fldn | typen | <- Ptr
19548 : : |--------------| +-------------+
19549 : : | Sym | Type | | S | type1|
19550 : : |--------------| |-------------|
19551 : : */
19552 : :
19553 : 99874 : extern "C" void M2Quads_BuildDesignatorRecord (unsigned int dottok)
19554 : : {
19555 : 99874 : unsigned int RecordTok;
19556 : 99874 : unsigned int FieldTok;
19557 : 99874 : unsigned int combinedtok;
19558 : 99874 : unsigned int n;
19559 : 99874 : unsigned int rw;
19560 : 99874 : unsigned int Field;
19561 : 99874 : unsigned int FieldType;
19562 : 99874 : unsigned int RecordSym;
19563 : 99874 : unsigned int Res;
19564 : :
19565 : 99874 : M2Quads_PopT (&n);
19566 : 99874 : RecordSym = static_cast<unsigned int> (M2Quads_OperandT (n+1));
19567 : : /* RecordType could be found by: SkipType (OperandF (n+1)). */
19568 : 99874 : RecordTok = static_cast<unsigned int> (M2Quads_OperandTok (n+1));
19569 : 99874 : rw = static_cast<unsigned int> (OperandMergeRW (n+1));
19570 : 99874 : M2Debug_Assert (SymbolTable_IsLegal (rw));
19571 : 99874 : Field = static_cast<unsigned int> (M2Quads_OperandT (n));
19572 : 99874 : FieldType = SymbolTable_SkipType (M2Quads_OperandF (n));
19573 : 99874 : FieldTok = static_cast<unsigned int> (M2Quads_OperandTok (n));
19574 : 99874 : combinedtok = M2LexBuf_MakeVirtualTok (dottok, RecordTok, FieldTok);
19575 : 99874 : if (n > 1)
19576 : : {
19577 : 0 : M2Error_InternalError ((const char *) "not expecting to see n>1", 24);
19578 : : }
19579 : 99874 : if (SymbolTable_IsUnused (Field))
19580 : : {
19581 : 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);
19582 : : }
19583 : 99874 : Res = SymbolTable_MakeComponentRef (SymbolTable_MakeComponentRecord (combinedtok, SymbolTable_RightValue, RecordSym), Field);
19584 : 99874 : SymbolTable_PutVarConst (Res, IsReadOnly (RecordSym));
19585 : 99874 : GenQuadO (combinedtok, M2Quads_RecordFieldOp, Res, RecordSym, Field, false);
19586 : 99874 : M2Quads_PopN (n+1);
19587 : 99874 : PushTFrwtok (Res, FieldType, rw, combinedtok);
19588 : 99874 : }
19589 : :
19590 : :
19591 : : /*
19592 : : BuildDesignatorArray - Builds the array referencing.
19593 : : The purpose of this procedure is to work out
19594 : : whether the DesignatorArray is a static or
19595 : : dynamic array and to call the appropriate
19596 : : BuildRoutine.
19597 : :
19598 : : The Stack is expected to contain:
19599 : :
19600 : :
19601 : : Entry Exit
19602 : : ===== ====
19603 : :
19604 : : Ptr ->
19605 : : +--------------+
19606 : : | e | <- Ptr
19607 : : |--------------| +------------+
19608 : : | Sym | Type | | S | T |
19609 : : |--------------| |------------|
19610 : : */
19611 : :
19612 : 48896 : extern "C" void M2Quads_BuildDesignatorArray (void)
19613 : : {
19614 : 48896 : unsigned int combinedTok;
19615 : 48896 : unsigned int arrayTok;
19616 : 48896 : unsigned int exprTok;
19617 : 48896 : unsigned int e;
19618 : 48896 : unsigned int type;
19619 : 48896 : unsigned int dim;
19620 : 48896 : unsigned int result;
19621 : 48896 : unsigned int Sym;
19622 : 48896 : unsigned int Type;
19623 : :
19624 : 48896 : if (SymbolTable_IsConst (M2Quads_OperandT (2)))
19625 : : {
19626 : 174 : type = SymbolTable_GetDType (M2Quads_OperandT (2));
19627 : 174 : if (type == SymbolTable_NulSym)
19628 : : {
19629 : 0 : M2Error_InternalError ((const char *) "constant type should have been resolved", 39);
19630 : : }
19631 : 174 : else if (SymbolTable_IsArray (type))
19632 : : {
19633 : : /* avoid dangling else. */
19634 : 174 : M2Quads_PopTtok (&e, &exprTok);
19635 : 174 : PopTFDtok (&Sym, &Type, &dim, &arrayTok);
19636 : 174 : result = SymbolTable_MakeTemporary (exprTok, SymbolTable_RightValue);
19637 : 174 : SymbolTable_PutVar (result, Type);
19638 : 174 : M2Quads_PushTFtok (result, SymbolTable_GetSType (result), exprTok);
19639 : 174 : M2Quads_PushTtok (Sym, arrayTok);
19640 : 174 : combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, exprTok);
19641 : 174 : SymbolTable_PutVarConst (result, true);
19642 : 174 : M2Quads_BuildAssignConstant (combinedTok);
19643 : 174 : PushTFDtok (result, SymbolTable_GetDType (result), dim, arrayTok);
19644 : 174 : M2Quads_PushTtok (e, exprTok);
19645 : : }
19646 : : }
19647 : 48896 : if ((! (SymbolTable_IsVar (M2Quads_OperandT (2)))) && (! (SymbolTable_IsTemporary (M2Quads_OperandT (2)))))
19648 : : {
19649 : 18 : M2MetaError_MetaErrorT1 (OperandTtok (2), (const char *) "can only access arrays using variables or formal parameters not {%1Ead}", 71, M2Quads_OperandT (2));
19650 : 18 : BuildDesignatorError ((const char *) "bad array access", 16);
19651 : : }
19652 : 48896 : Sym = static_cast<unsigned int> (M2Quads_OperandT (2));
19653 : 48896 : Type = SymbolTable_GetDType (Sym);
19654 : 48896 : arrayTok = OperandTtok (2);
19655 : 48896 : if (Type == SymbolTable_NulSym)
19656 : : {
19657 : 6 : if ((arrayTok == M2LexBuf_UnknownTokenNo) || (arrayTok == M2LexBuf_BuiltinTokenNo))
19658 : : {
19659 : 6 : arrayTok = M2LexBuf_GetTokenNo ();
19660 : : }
19661 : 6 : M2MetaError_MetaErrorT0 (arrayTok, (const char *) "type of array is undefined", 26);
19662 : 6 : BuildDesignatorError ((const char *) "bad array access", 16);
19663 : : }
19664 : 48890 : else if (SymbolTable_IsUnbounded (Type))
19665 : : {
19666 : : /* avoid dangling else. */
19667 : 7662 : BuildDynamicArray ();
19668 : : }
19669 : 41228 : else if (SymbolTable_IsArray (Type))
19670 : : {
19671 : : /* avoid dangling else. */
19672 : 41204 : BuildStaticArray ();
19673 : : }
19674 : : else
19675 : : {
19676 : : /* avoid dangling else. */
19677 : 24 : M2MetaError_MetaErrorT1 (arrayTok, (const char *) "can only index static or dynamic arrays, {%1Ead} is not an array but a {%tad}", 77, Sym);
19678 : 24 : BuildDesignatorError ((const char *) "bad array access", 16);
19679 : : }
19680 : 48890 : }
19681 : :
19682 : :
19683 : : /*
19684 : : BuildDesignatorPointer - Builds a pointer reference.
19685 : : The Stack is expected to contain:
19686 : :
19687 : :
19688 : : Entry Exit
19689 : : ===== ====
19690 : :
19691 : : Ptr -> <- Ptr
19692 : : +--------------+ +--------------+
19693 : : | Sym1 | Type1| | Sym2 | Type2|
19694 : : |--------------| |--------------|
19695 : : */
19696 : :
19697 : 14166 : extern "C" void M2Quads_BuildDesignatorPointer (unsigned int ptrtok)
19698 : : {
19699 : 14166 : unsigned int combinedtok;
19700 : 14166 : unsigned int exprtok;
19701 : 14166 : unsigned int rw;
19702 : 14166 : unsigned int Sym1;
19703 : 14166 : unsigned int Type1;
19704 : 14166 : unsigned int Sym2;
19705 : 14166 : unsigned int Type2;
19706 : :
19707 : 14166 : PopTFrwtok (&Sym1, &Type1, &rw, &exprtok);
19708 : 14166 : DebugLocation (exprtok, (const char *) "expression", 10);
19709 : 14166 : Type1 = SymbolTable_SkipType (Type1);
19710 : 14166 : if (Type1 == SymbolTable_NulSym)
19711 : : {
19712 : 0 : M2MetaError_MetaErrorT1 (ptrtok, (const char *) "{%1ad} has no type and therefore cannot be dereferenced by ^", 60, Sym1);
19713 : : }
19714 : 14166 : else if (SymbolTable_IsUnknown (Sym1))
19715 : : {
19716 : : /* avoid dangling else. */
19717 : 0 : M2MetaError_MetaError1 ((const char *) "{%1EMad} is undefined and therefore {%1ad}^ cannot be resolved", 62, Sym1);
19718 : : }
19719 : 14166 : else if (SymbolTable_IsPointer (Type1))
19720 : : {
19721 : : /* avoid dangling else. */
19722 : 14166 : Type2 = SymbolTable_GetSType (Type1);
19723 : 14166 : Sym2 = SymbolTable_MakeTemporary (ptrtok, SymbolTable_LeftValue);
19724 : : /*
19725 : : Ok must reference by address
19726 : : - but we contain the type of the referenced entity
19727 : : */
19728 : 14166 : MarkAsRead (rw);
19729 : 14166 : SymbolTable_PutVarPointerCheck (Sym1, true);
19730 : 14166 : CheckPointerThroughNil (ptrtok, Sym1);
19731 : 14166 : if ((SymbolTable_GetMode (Sym1)) == SymbolTable_LeftValue)
19732 : : {
19733 : 498 : rw = SymbolTable_NulSym;
19734 : 498 : SymbolTable_PutLeftValueFrontBackType (Sym2, Type2, Type1);
19735 : 498 : GenQuadO (ptrtok, M2Quads_IndrXOp, Sym2, Type1, Sym1, false); /* Sym2 := *Sym1 */
19736 : : }
19737 : : else
19738 : : {
19739 : 13668 : SymbolTable_PutLeftValueFrontBackType (Sym2, Type2, SymbolTable_NulSym);
19740 : 13668 : GenQuadO (ptrtok, M2Quads_BecomesOp, Sym2, SymbolTable_NulSym, Sym1, false); /* Sym2 := Sym1 */
19741 : : }
19742 : 14166 : SymbolTable_PutVarPointerCheck (Sym2, true); /* we should check this for */
19743 : : /* Sym2 later on (pointer via NIL) */
19744 : 14166 : combinedtok = M2LexBuf_MakeVirtualTok (exprtok, exprtok, ptrtok);
19745 : 14166 : PushTFrwtok (Sym2, Type2, rw, combinedtok);
19746 : 14166 : DebugLocation (combinedtok, (const char *) "pointer expression", 18);
19747 : : }
19748 : : else
19749 : : {
19750 : : /* avoid dangling else. */
19751 : 0 : M2MetaError_MetaError2 ((const char *) "{%1ad} is not a pointer type but a {%2d}", 40, Sym1, Type1);
19752 : : }
19753 : 14166 : }
19754 : :
19755 : :
19756 : : /*
19757 : : BuildNulExpression - Builds a nul expression on the stack.
19758 : : The Stack:
19759 : :
19760 : : Entry Exit
19761 : :
19762 : : <- Ptr
19763 : : Empty +------------+
19764 : : | NulSym |
19765 : : |------------|
19766 : : tokpos is the position of the RETURN token.
19767 : : */
19768 : :
19769 : 748 : extern "C" void M2Quads_BuildNulExpression (unsigned int tokpos)
19770 : : {
19771 : 748 : M2Quads_PushTtok (static_cast<unsigned int> (SymbolTable_NulSym), tokpos);
19772 : 748 : }
19773 : :
19774 : :
19775 : : /*
19776 : : BuildSetStart - Pushes a Bitset type on the stack.
19777 : :
19778 : : The Stack:
19779 : :
19780 : : Entry Exit
19781 : :
19782 : : Ptr -> <- Ptr
19783 : :
19784 : : Empty +--------------+
19785 : : | Bitset |
19786 : : |--------------|
19787 : : */
19788 : :
19789 : 0 : extern "C" void M2Quads_BuildSetStart (unsigned int tokpos)
19790 : : {
19791 : 0 : M2Quads_PushTtok (M2Bitset_Bitset, tokpos);
19792 : 0 : }
19793 : :
19794 : :
19795 : : /*
19796 : : BuildSetEnd - pops the set value and type from the stack
19797 : : and pushes the value,type pair.
19798 : :
19799 : : Entry Exit
19800 : :
19801 : : Ptr ->
19802 : : +--------------+
19803 : : | Set Value | <- Ptr
19804 : : |--------------| +--------------+
19805 : : | Set Type | | Value | Type |
19806 : : |--------------| |--------------|
19807 : : */
19808 : :
19809 : 0 : extern "C" void M2Quads_BuildSetEnd (void)
19810 : : {
19811 : 0 : unsigned int valuepos;
19812 : 0 : unsigned int typepos;
19813 : 0 : unsigned int combined;
19814 : 0 : unsigned int value;
19815 : 0 : unsigned int type;
19816 : :
19817 : 0 : M2Quads_PopTtok (&value, &valuepos);
19818 : 0 : M2Quads_PopTtok (&type, &typepos);
19819 : 0 : combined = M2LexBuf_MakeVirtual2Tok (typepos, valuepos);
19820 : 0 : M2Quads_PushTFtok (value, type, combined);
19821 : 0 : M2Debug_Assert (SymbolTable_IsSet (type));
19822 : 0 : }
19823 : :
19824 : :
19825 : : /*
19826 : : BuildEmptySet - Builds an empty set on the stack.
19827 : : The Stack:
19828 : :
19829 : : Entry Exit
19830 : :
19831 : : <- Ptr
19832 : : +-------------+
19833 : : Ptr -> | Value |
19834 : : +-----------+ |-------------|
19835 : : | SetType | | SetType |
19836 : : |-----------| |-------------|
19837 : :
19838 : : tokpos points to the opening '{'.
19839 : : */
19840 : :
19841 : 0 : extern "C" void M2Quads_BuildEmptySet (unsigned int tokpos)
19842 : : {
19843 : 0 : NameKey_Name n;
19844 : 0 : unsigned int typepos;
19845 : 0 : unsigned int Type;
19846 : 0 : unsigned int NulSet;
19847 : :
19848 : 0 : M2Quads_PopTtok (&Type, &typepos); /* type of set we are building */
19849 : 0 : if ((Type == SymbolTable_NulSym) && M2Options_Pim)
19850 : : {
19851 : : /* allowed generic {} in PIM Modula-2 */
19852 : 0 : typepos = tokpos;
19853 : : }
19854 : 0 : else if (SymbolTable_IsUnknown (Type))
19855 : : {
19856 : : /* avoid dangling else. */
19857 : 0 : n = SymbolTable_GetSymName (Type);
19858 : 0 : M2Error_WriteFormat1 ((const char *) "set type %a is undefined", 24, (const unsigned char *) &n, (sizeof (n)-1));
19859 : 0 : Type = M2Bitset_Bitset;
19860 : : }
19861 : 0 : else if (! (SymbolTable_IsSet (SymbolTable_SkipType (Type))))
19862 : : {
19863 : : /* avoid dangling else. */
19864 : 0 : n = SymbolTable_GetSymName (Type);
19865 : 0 : M2Error_WriteFormat1 ((const char *) "expecting a set type %a", 23, (const unsigned char *) &n, (sizeof (n)-1));
19866 : 0 : Type = M2Bitset_Bitset;
19867 : : }
19868 : : else
19869 : : {
19870 : : /* avoid dangling else. */
19871 : 0 : Type = SymbolTable_SkipType (Type);
19872 : 0 : M2Debug_Assert (Type != SymbolTable_NulSym);
19873 : : }
19874 : 0 : NulSet = SymbolTable_MakeTemporary (typepos, SymbolTable_ImmediateValue);
19875 : 0 : SymbolTable_PutVar (NulSet, Type);
19876 : 0 : SymbolTable_PutConstSet (NulSet);
19877 : 0 : if (M2Options_CompilerDebugging)
19878 : : {
19879 : 0 : n = SymbolTable_GetSymName (Type);
19880 : 0 : M2Printf_printf1 ((const char *) "set type = %a\\n", 15, (const unsigned char *) &n, (sizeof (n)-1));
19881 : : }
19882 : 0 : M2ALU_PushNulSet (Type); /* onto the ALU stack */
19883 : 0 : SymbolTable_PopValue (NulSet); /* ALU -> symbol table */
19884 : : /* and now construct the M2Quads stack as defined by the comments above */
19885 : 0 : M2Quads_PushTtok (Type, typepos);
19886 : 0 : M2Quads_PushTtok (NulSet, typepos);
19887 : 0 : if (M2Options_CompilerDebugging)
19888 : : {
19889 : 0 : n = SymbolTable_GetSymName (Type);
19890 : 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));
19891 : 0 : M2Quads_DisplayStack (); /* Debugging info */
19892 : : }
19893 : 0 : }
19894 : :
19895 : :
19896 : : /*
19897 : : BuildInclRange - includes a set range with a set.
19898 : :
19899 : :
19900 : : Entry Exit
19901 : : ===== ====
19902 : :
19903 : :
19904 : : Ptr ->
19905 : : +------------+
19906 : : | El2 |
19907 : : |------------|
19908 : : | El1 | <- Ptr
19909 : : |------------| +-------------------+
19910 : : | Set Value | | Value + {El1..El2}|
19911 : : |------------| |-------------------|
19912 : :
19913 : : No quadruples produced as the range info is contained within
19914 : : the set value.
19915 : : */
19916 : :
19917 : 0 : extern "C" void M2Quads_BuildInclRange (void)
19918 : : {
19919 : 0 : NameKey_Name n;
19920 : 0 : unsigned int el1;
19921 : 0 : unsigned int el2;
19922 : 0 : unsigned int value;
19923 : :
19924 : 0 : M2Quads_PopT (&el2);
19925 : 0 : M2Quads_PopT (&el1);
19926 : 0 : M2Quads_PopT (&value);
19927 : 0 : if (! (SymbolTable_IsConstSet (value)))
19928 : : {
19929 : 0 : n = SymbolTable_GetSymName (el1);
19930 : 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));
19931 : : }
19932 : 0 : if ((SymbolTable_IsConst (el1)) && (SymbolTable_IsConst (el2)))
19933 : : {
19934 : 0 : SymbolTable_PushValue (value); /* onto ALU stack */
19935 : 0 : M2ALU_AddBitRange (M2LexBuf_GetTokenNo (), el1, el2); /* onto ALU stack */
19936 : 0 : SymbolTable_PopValue (value); /* ALU -> symboltable */
19937 : : }
19938 : : else
19939 : : {
19940 : 0 : if (! (SymbolTable_IsConst (el1)))
19941 : : {
19942 : 0 : n = SymbolTable_GetSymName (el1);
19943 : 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));
19944 : : }
19945 : 0 : if (! (SymbolTable_IsConst (el2)))
19946 : : {
19947 : 0 : n = SymbolTable_GetSymName (el2);
19948 : 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));
19949 : : }
19950 : : }
19951 : 0 : M2Quads_PushT (value);
19952 : 0 : }
19953 : :
19954 : :
19955 : : /*
19956 : : BuildInclBit - includes a bit into the set.
19957 : :
19958 : : Entry Exit
19959 : : ===== ====
19960 : :
19961 : :
19962 : : Ptr ->
19963 : : +------------+
19964 : : | Element | <- Ptr
19965 : : |------------| +------------+
19966 : : | Value | | Value |
19967 : : |------------| |------------|
19968 : :
19969 : : */
19970 : :
19971 : 10674 : extern "C" void M2Quads_BuildInclBit (void)
19972 : : {
19973 : 10674 : unsigned int tok;
19974 : 10674 : unsigned int el;
19975 : 10674 : unsigned int value;
19976 : 10674 : unsigned int t;
19977 : :
19978 : 10674 : M2Quads_PopT (&el);
19979 : 10674 : M2Quads_PopT (&value);
19980 : 10674 : tok = M2LexBuf_GetTokenNo ();
19981 : 10674 : if (SymbolTable_IsConst (el))
19982 : : {
19983 : 10622 : SymbolTable_PushValue (value); /* onto ALU stack */
19984 : 10622 : M2ALU_AddBit (tok, el); /* onto ALU stack */
19985 : 10622 : SymbolTable_PopValue (value); /* ALU -> symboltable */
19986 : : }
19987 : : else
19988 : : {
19989 : 52 : if ((SymbolTable_GetMode (el)) == SymbolTable_LeftValue)
19990 : : {
19991 : 0 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
19992 : 0 : SymbolTable_PutVar (t, SymbolTable_GetSType (el));
19993 : 0 : CheckPointerThroughNil (tok, el);
19994 : 0 : doIndrX (tok, t, el);
19995 : 0 : el = t;
19996 : : }
19997 : 52 : if (SymbolTable_IsConst (value))
19998 : : {
19999 : : /* move constant into a variable to achieve the include */
20000 : 52 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
20001 : 52 : SymbolTable_PutVar (t, SymbolTable_GetSType (value));
20002 : 52 : GenQuad (M2Quads_BecomesOp, t, SymbolTable_NulSym, value);
20003 : 52 : value = t;
20004 : : }
20005 : 52 : GenQuad (M2Quads_InclOp, value, SymbolTable_NulSym, el);
20006 : : }
20007 : 10674 : M2Quads_PushT (value);
20008 : 10674 : }
20009 : :
20010 : :
20011 : : /*
20012 : : SilentBuildConstructor - places NulSym into the constructor fifo queue.
20013 : : */
20014 : :
20015 : 0 : extern "C" void M2Quads_SilentBuildConstructor (void)
20016 : : {
20017 : 0 : FifoQueue_PutConstructorIntoFifoQueue (SymbolTable_NulSym);
20018 : 0 : }
20019 : :
20020 : :
20021 : : /*
20022 : : SilentBuildConstructorStart - removes an entry from the constructor fifo queue.
20023 : : */
20024 : :
20025 : 11248 : extern "C" void M2Quads_SilentBuildConstructorStart (void)
20026 : : {
20027 : 11248 : unsigned int constValue;
20028 : :
20029 : 11248 : FifoQueue_GetConstructorFromFifoQueue (&constValue);
20030 : 11248 : }
20031 : :
20032 : :
20033 : : /*
20034 : : BuildConstructor - builds a constructor.
20035 : : Stack
20036 : :
20037 : : Entry Exit
20038 : :
20039 : : Ptr ->
20040 : : +------------+
20041 : : | Type | <- Ptr
20042 : : |------------+
20043 : : */
20044 : :
20045 : 21488 : extern "C" void M2Quads_BuildConstructor (unsigned int tokcbrpos)
20046 : : {
20047 : 21488 : unsigned int tok;
20048 : 21488 : unsigned int constValue;
20049 : 21488 : unsigned int type;
20050 : :
20051 : 21488 : M2Quads_PopTtok (&type, &tok);
20052 : 21488 : constValue = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
20053 : 21488 : SymbolTable_PutVar (constValue, type);
20054 : 21488 : SymbolTable_PutConstructor (constValue);
20055 : 21488 : SymbolTable_PushValue (constValue);
20056 : 21488 : if (type == SymbolTable_NulSym)
20057 : : {
20058 : 6 : M2MetaError_MetaErrorT0 (tokcbrpos, (const char *) "{%E}constructor requires a type before the opening %{", 53);
20059 : : }
20060 : : else
20061 : : {
20062 : 21482 : M2ALU_ChangeToConstructor (tok, type);
20063 : 21482 : SymbolTable_PutConstructorFrom (constValue, type);
20064 : 21482 : SymbolTable_PopValue (constValue);
20065 : 21482 : FifoQueue_PutConstructorIntoFifoQueue (constValue);
20066 : : }
20067 : 21488 : PushConstructor (type);
20068 : 21488 : }
20069 : :
20070 : :
20071 : : /*
20072 : : BuildConstructorStart - builds a constructor.
20073 : : Stack
20074 : :
20075 : : Entry Exit
20076 : :
20077 : : Ptr -> <- Ptr
20078 : : +------------+ +----------------+
20079 : : | Type | | ConstructorSym |
20080 : : |------------+ |----------------|
20081 : : */
20082 : :
20083 : 10228 : extern "C" void M2Quads_BuildConstructorStart (unsigned int cbratokpos)
20084 : : {
20085 : 10228 : unsigned int typepos;
20086 : 10228 : unsigned int constValue;
20087 : 10228 : unsigned int type;
20088 : :
20089 : 10228 : M2Quads_PopTtok (&type, &typepos); /* we ignore the type as we already have the constructor symbol from pass C */
20090 : 10228 : FifoQueue_GetConstructorFromFifoQueue (&constValue); /* we ignore the type as we already have the constructor symbol from pass C */
20091 : 10228 : if (type != (SymbolTable_GetSType (constValue)))
20092 : : {
20093 : 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);
20094 : : }
20095 : 10228 : M2Quads_PushTtok (constValue, cbratokpos);
20096 : 10228 : PushConstructor (type);
20097 : 10228 : }
20098 : :
20099 : :
20100 : : /*
20101 : : BuildConstructorEnd - removes the current constructor frame from the
20102 : : constructor stack (it does not effect the quad
20103 : : stack)
20104 : :
20105 : : Entry Exit
20106 : :
20107 : : Ptr -> <- Ptr
20108 : : +------------+ +------------+
20109 : : | const | | const |
20110 : : |------------| |------------|
20111 : :
20112 : : startpos is the start of the constructor, either the typename or '{'
20113 : : cbratokpos is the '}'.
20114 : : */
20115 : :
20116 : 10228 : extern "C" void M2Quads_BuildConstructorEnd (unsigned int startpos, unsigned int cbratokpos)
20117 : : {
20118 : 10228 : unsigned int value;
20119 : 10228 : unsigned int valtok;
20120 : :
20121 : 10228 : if (DebugTokPos)
20122 : : {
20123 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "startpos", 8), startpos);
20124 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "cbratokpos", 10), cbratokpos);
20125 : : }
20126 : 10228 : M2Quads_PopTtok (&value, &valtok);
20127 : 10228 : if (DebugTokPos)
20128 : : {
20129 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "value valtok", 12), valtok);
20130 : : }
20131 : 10228 : valtok = M2LexBuf_MakeVirtual2Tok (startpos, cbratokpos);
20132 : 10228 : SymbolTable_PutDeclared (valtok, value);
20133 : 10228 : M2Quads_PushTtok (value, valtok); /* Use valtok as we now know it was a constructor. */
20134 : 10228 : M2Quads_PopConstructor (); /* Use valtok as we now know it was a constructor. */
20135 : 10228 : if (DebugTokPos)
20136 : : {
20137 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "aggregate constant", 18), valtok);
20138 : : }
20139 : 10228 : }
20140 : :
20141 : :
20142 : : /*
20143 : : NextConstructorField - increments the top of constructor stacks index by one.
20144 : : */
20145 : :
20146 : 33476 : extern "C" void M2Quads_NextConstructorField (void)
20147 : : {
20148 : 33476 : M2Quads_ConstructorFrame c;
20149 : :
20150 : 33476 : c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PeepAddress (ConstructorStack, 1));
20151 : 33476 : c->index += 1;
20152 : 33476 : }
20153 : :
20154 : :
20155 : : /*
20156 : : BuildTypeForConstructor - pushes the type implied by the current constructor.
20157 : : If no constructor is currently being built then
20158 : : it Pushes a Bitset type.
20159 : : */
20160 : :
20161 : 1756 : extern "C" void M2Quads_BuildTypeForConstructor (unsigned int tokpos)
20162 : : {
20163 : 1756 : M2Quads_ConstructorFrame c;
20164 : :
20165 : 1756 : if ((M2StackAddress_NoOfItemsInStackAddress (ConstructorStack)) == 0)
20166 : : {
20167 : 688 : M2Quads_PushTtok (M2Bitset_Bitset, tokpos);
20168 : : }
20169 : : else
20170 : : {
20171 : 1068 : c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PeepAddress (ConstructorStack, 1));
20172 : 1068 : if ((SymbolTable_IsArray (c->type)) || (SymbolTable_IsSet (c->type)))
20173 : : {
20174 : 972 : M2Quads_PushTtok (SymbolTable_GetSType (c->type), tokpos);
20175 : : }
20176 : 96 : else if (SymbolTable_IsRecord (c->type))
20177 : : {
20178 : : /* avoid dangling else. */
20179 : 96 : M2Quads_PushTtok (SymbolTable_GetSType (SymbolTable_GetNth (c->type, c->index)), tokpos);
20180 : : }
20181 : : else
20182 : : {
20183 : : /* avoid dangling else. */
20184 : 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);
20185 : : }
20186 : : }
20187 : 1756 : }
20188 : :
20189 : :
20190 : : /*
20191 : : BuildComponentValue - builds a component value.
20192 : :
20193 : : Entry Exit
20194 : :
20195 : : Ptr -> <- Ptr
20196 : :
20197 : :
20198 : : +------------+ +------------+
20199 : : | const | | const |
20200 : : |------------| |------------|
20201 : : */
20202 : :
20203 : 24550 : extern "C" void M2Quads_BuildComponentValue (void)
20204 : : {
20205 : 24550 : unsigned int const_;
20206 : 24550 : unsigned int e1;
20207 : 24550 : unsigned int e2;
20208 : 24550 : NameKey_Name nuldotdot;
20209 : 24550 : NameKey_Name nulby;
20210 : :
20211 : 24550 : M2Quads_PopT (&nulby);
20212 : 24550 : if (nulby == M2Reserved_NulTok)
20213 : : {
20214 : 24520 : M2Quads_PopT (&nuldotdot);
20215 : 24520 : if (nuldotdot == M2Reserved_NulTok)
20216 : : {
20217 : 24278 : M2Quads_PopT (&e1);
20218 : 24278 : M2Quads_PopT (&const_);
20219 : 24278 : M2Quads_PushT (AddFieldTo (const_, e1));
20220 : : }
20221 : : else
20222 : : {
20223 : 242 : M2Quads_PopT (&e2);
20224 : 242 : M2Quads_PopT (&e1);
20225 : 242 : M2Quads_PopT (&const_);
20226 : 242 : SymbolTable_PushValue (const_);
20227 : 242 : M2ALU_AddBitRange (M2LexBuf_GetTokenNo (), e1, e2);
20228 : 242 : SymbolTable_PopValue (const_);
20229 : 242 : M2Quads_PushT (const_);
20230 : : }
20231 : : }
20232 : : else
20233 : : {
20234 : 30 : M2Quads_PopT (&e1);
20235 : 30 : M2Quads_PopT (&nuldotdot);
20236 : 30 : if (nuldotdot == M2Reserved_NulTok)
20237 : : {
20238 : 30 : M2Quads_PopT (&e2);
20239 : 30 : M2Quads_PopT (&const_);
20240 : 30 : SymbolTable_PushValue (const_);
20241 : 30 : M2ALU_AddElements (M2LexBuf_GetTokenNo (), e2, e1);
20242 : 30 : SymbolTable_PopValue (const_);
20243 : 30 : M2Quads_PushT (const_);
20244 : : }
20245 : : else
20246 : : {
20247 : 0 : M2Quads_PopT (&e2);
20248 : 0 : M2Quads_PopT (&e1);
20249 : 0 : M2Quads_PopT (&const_);
20250 : 0 : M2Error_WriteFormat0 ((const char *) "the constant must be either an array constructor or a set constructor", 69);
20251 : 0 : M2Quads_PushT (const_);
20252 : : }
20253 : : }
20254 : 24550 : }
20255 : :
20256 : :
20257 : : /*
20258 : : PopConstructor - removes the top constructor from the top of stack.
20259 : : */
20260 : :
20261 : 31716 : extern "C" void M2Quads_PopConstructor (void)
20262 : : {
20263 : 31716 : M2Quads_ConstructorFrame c;
20264 : :
20265 : 31716 : c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PopAddress (ConstructorStack));
20266 : 31716 : Storage_DEALLOCATE ((void **) &c, sizeof (M2Quads__T1));
20267 : 31716 : }
20268 : :
20269 : :
20270 : : /*
20271 : : BuildNot - Builds a NOT operation from the quad stack.
20272 : : The Stack is expected to contain:
20273 : :
20274 : :
20275 : : Entry Exit
20276 : : ===== ====
20277 : :
20278 : : Ptr -> <- Ptr
20279 : : +------------+ +------------+
20280 : : | t | f | | f | t |
20281 : : |------------| |------------|
20282 : : */
20283 : :
20284 : 4418 : extern "C" void M2Quads_BuildNot (unsigned int notTokPos)
20285 : : {
20286 : 4418 : unsigned int combinedTok;
20287 : 4418 : unsigned int exprTokPos;
20288 : 4418 : unsigned int t;
20289 : 4418 : unsigned int f;
20290 : :
20291 : 4418 : CheckBooleanId ();
20292 : 4418 : PopBooltok (&t, &f, &exprTokPos);
20293 : 4418 : combinedTok = M2LexBuf_MakeVirtualTok (notTokPos, notTokPos, exprTokPos);
20294 : 4418 : PushBooltok (f, t, combinedTok);
20295 : 4418 : }
20296 : :
20297 : :
20298 : : /*
20299 : : RecordOp - Records the operator passed on the stack.
20300 : : This is called when a boolean operator is found in an
20301 : : expression. It is called just after the lhs has been built
20302 : : and pushed to the quad stack and prior to the rhs build.
20303 : : It checks to see if AND OR or equality tests are required.
20304 : : It will short circuit AND and OR expressions. It also
20305 : : converts a lhs to a boolean variable if an xor comparison
20306 : : is about to be performed.
20307 : :
20308 : : Checks for AND operator or OR operator
20309 : : if either of these operators are found then BackPatching
20310 : : takes place.
20311 : : The Expected Stack:
20312 : :
20313 : : Entry Exit
20314 : :
20315 : : Ptr -> <- Ptr
20316 : : +-------------+ +-------------+
20317 : : | OperatorTok | | OperatorTok |
20318 : : |-------------| |-------------|
20319 : : | t | f | | t | f |
20320 : : |-------------| |-------------|
20321 : :
20322 : :
20323 : : If OperatorTok=AndTok
20324 : : Then
20325 : : BackPatch(f, NextQuad)
20326 : : Elsif OperatorTok=OrTok
20327 : : Then
20328 : : BackPatch(t, NextQuad)
20329 : : End
20330 : : */
20331 : :
20332 : 81188 : extern "C" void M2Quads_RecordOp (void)
20333 : : {
20334 : 81188 : NameKey_Name Op;
20335 : 81188 : unsigned int tokno;
20336 : 81188 : unsigned int t;
20337 : 81188 : unsigned int f;
20338 : :
20339 : 81188 : M2Quads_PopTtok (&Op, &tokno);
20340 : 81188 : if ((Op == M2Reserved_AndTok) || (Op == M2Reserved_AmbersandTok))
20341 : : {
20342 : 8280 : CheckBooleanId ();
20343 : 8280 : PopBool (&t, &f);
20344 : 8280 : BackPatch (t, NextQuad);
20345 : 8280 : PushBool (0, f);
20346 : : }
20347 : 72908 : else if (Op == M2Reserved_OrTok)
20348 : : {
20349 : : /* avoid dangling else. */
20350 : 3394 : CheckBooleanId ();
20351 : 3394 : PopBool (&t, &f);
20352 : 3394 : BackPatch (f, NextQuad);
20353 : 3394 : PushBool (t, 0);
20354 : : }
20355 : 69514 : else if ((IsBoolean (1)) && ((((Op == M2Reserved_EqualTok) || (Op == M2Reserved_LessGreaterTok)) || (Op == M2Reserved_HashTok)) || (Op == M2Reserved_InTok)))
20356 : : {
20357 : : /* avoid dangling else. */
20358 : 24 : ConvertBooleanToVariable (tokno, 1);
20359 : : }
20360 : 81188 : M2Quads_PushTtok (Op, tokno);
20361 : 81188 : }
20362 : :
20363 : :
20364 : : /*
20365 : : BuildRelOp - Builds a relative operation from the quad stack.
20366 : : The Stack is expected to contain:
20367 : :
20368 : :
20369 : : Entry Exit
20370 : : ===== ====
20371 : :
20372 : : Ptr ->
20373 : : +------------+
20374 : : | e1 |
20375 : : |------------| <- Ptr
20376 : : | Operator |
20377 : : |------------| +------------+
20378 : : | e2 | | t | f |
20379 : : |------------| |------------|
20380 : :
20381 : :
20382 : : Quadruples Produced
20383 : :
20384 : : q IFOperator e2 e1 TrueExit ; e2 e1 since
20385 : : q+1 GotoOp FalseExit ; relation > etc
20386 : : ; requires order.
20387 : : */
20388 : :
20389 : 77352 : extern "C" void M2Quads_BuildRelOp (unsigned int optokpos)
20390 : : {
20391 : 77352 : unsigned int combinedTok;
20392 : 77352 : unsigned int rightpos;
20393 : 77352 : unsigned int leftpos;
20394 : 77352 : NameKey_Name Op;
20395 : 77352 : unsigned int t;
20396 : 77352 : unsigned int rightType;
20397 : 77352 : unsigned int leftType;
20398 : 77352 : unsigned int right;
20399 : 77352 : unsigned int left;
20400 : 77352 : DynamicStrings_String s;
20401 : :
20402 : 77352 : if (M2Options_CompilerDebugging)
20403 : : {
20404 : 0 : M2Quads_DisplayStack (); /* Debugging info */
20405 : : }
20406 : 77352 : if (((M2Quads_IsInConstExpression ()) && (IsBoolean (1))) && (IsBoolean (3)))
20407 : : {
20408 : : /*
20409 : : we allow # and = to be used with Boolean expressions.
20410 : : we do not allow > < >= <= though. We only examine
20411 : : this case if we are in a const expression as there will be
20412 : : no dereferencing of operands.
20413 : : */
20414 : 0 : BuildRelOpFromBoolean (optokpos);
20415 : : }
20416 : : else
20417 : : {
20418 : 77352 : if (IsBoolean (1))
20419 : : {
20420 : 36 : ConvertBooleanToVariable (OperandTtok (1), 1);
20421 : : }
20422 : 77352 : if (IsBoolean (3))
20423 : : {
20424 : 0 : ConvertBooleanToVariable (OperandTtok (3), 3);
20425 : : }
20426 : 77352 : M2Quads_PopTFtok (&right, &rightType, &rightpos);
20427 : 77352 : M2Quads_PopT (&Op);
20428 : 77352 : M2Quads_PopTFtok (&left, &leftType, &leftpos);
20429 : 77352 : CheckVariableOrConstantOrProcedure (rightpos, right);
20430 : 77352 : CheckVariableOrConstantOrProcedure (leftpos, left);
20431 : 77352 : combinedTok = M2LexBuf_MakeVirtualTok (optokpos, leftpos, rightpos);
20432 : 77352 : if ((left != SymbolTable_NulSym) && (right != SymbolTable_NulSym))
20433 : : {
20434 : : /* BuildRange will check the expression later on once gcc knows about all data types. */
20435 : 77352 : BuildRange (M2Range_InitTypesExpressionCheck (combinedTok, left, right, true, Op == M2Reserved_InTok));
20436 : : }
20437 : : /* Must dereference LeftValue operands. */
20438 : 77352 : if ((SymbolTable_GetMode (right)) == SymbolTable_LeftValue)
20439 : : {
20440 : 1398 : t = SymbolTable_MakeTemporary (rightpos, SymbolTable_RightValue);
20441 : 1398 : SymbolTable_PutVar (t, SymbolTable_GetSType (right));
20442 : 1398 : CheckPointerThroughNil (rightpos, right);
20443 : 1398 : doIndrX (rightpos, t, right);
20444 : 1398 : right = t;
20445 : : }
20446 : 77352 : if ((SymbolTable_GetMode (left)) == SymbolTable_LeftValue)
20447 : : {
20448 : 6465 : t = SymbolTable_MakeTemporary (leftpos, SymbolTable_RightValue);
20449 : 6465 : SymbolTable_PutVar (t, SymbolTable_GetSType (left));
20450 : 6465 : CheckPointerThroughNil (leftpos, left);
20451 : 6465 : doIndrX (leftpos, t, left);
20452 : 6465 : left = t;
20453 : : }
20454 : 77352 : if (DebugTokPos)
20455 : : {
20456 : : s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (M2LexBuf_GetTokenName (Op)));
20457 : : M2Error_WarnStringAt (s, optokpos);
20458 : : s = DynamicStrings_InitString ((const char *) "left", 4);
20459 : : M2Error_WarnStringAt (s, leftpos);
20460 : : s = DynamicStrings_InitString ((const char *) "right", 5);
20461 : : M2Error_WarnStringAt (s, rightpos);
20462 : : s = DynamicStrings_InitString ((const char *) "caret", 5);
20463 : : M2Error_WarnStringAt (s, optokpos);
20464 : : s = DynamicStrings_InitString ((const char *) "combined", 8);
20465 : : M2Error_WarnStringAt (s, combinedTok);
20466 : : }
20467 : 77352 : GenQuadOtok (combinedTok, MakeOp (Op), left, right, 0, false, leftpos, rightpos, M2LexBuf_UnknownTokenNo); /* True Exit */
20468 : 77352 : GenQuadO (combinedTok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false); /* False Exit */
20469 : 77352 : PushBooltok (NextQuad-2, NextQuad-1, combinedTok); /* False Exit */
20470 : : }
20471 : 77352 : }
20472 : :
20473 : :
20474 : : /*
20475 : : BuildBinaryOp - Builds a binary operation from the quad stack.
20476 : : Be aware that this procedure will check for
20477 : : the overloading of the bitset operators + - \ *.
20478 : : So do NOT call this procedure if you are building
20479 : : a reference to an array which has a bitset type or
20480 : : the address arithmetic will be wrongly coersed into
20481 : : logical ORs.
20482 : :
20483 : : The Stack is expected to contain:
20484 : :
20485 : :
20486 : : Entry Exit
20487 : : ===== ====
20488 : :
20489 : : Ptr ->
20490 : : +------------+
20491 : : | Sym1 |
20492 : : |------------|
20493 : : | Operator | <- Ptr
20494 : : |------------| +------------+
20495 : : | Sym2 | | Temporary |
20496 : : |------------| |------------|
20497 : :
20498 : :
20499 : : Quadruples Produced
20500 : :
20501 : : q Operator Temporary Sym1 Sym2
20502 : :
20503 : :
20504 : : OR
20505 : :
20506 : :
20507 : : Entry Exit
20508 : : ===== ====
20509 : :
20510 : : Ptr ->
20511 : : +------------+
20512 : : | T1 | F1 |
20513 : : |------------|
20514 : : | OrTok | <- Ptr
20515 : : |------------| +------------+
20516 : : | T2 | F2 | | T1+T2| F1 |
20517 : : |------------| |------------|
20518 : :
20519 : :
20520 : : Quadruples Produced
20521 : :
20522 : : */
20523 : :
20524 : 51743 : extern "C" void M2Quads_BuildBinaryOp (void)
20525 : : {
20526 : 51743 : doBuildBinaryOp (true, true);
20527 : 51635 : }
20528 : :
20529 : :
20530 : : /*
20531 : : BuildUnaryOp - Builds a unary operation from the quad stack.
20532 : : The Stack is expected to contain:
20533 : :
20534 : :
20535 : : Entry Exit
20536 : : ===== ====
20537 : :
20538 : : Ptr ->
20539 : : +------------+
20540 : : | Sym |
20541 : : |------------| +------------+
20542 : : | Operator | | Temporary | <- Ptr
20543 : : |------------| |------------|
20544 : :
20545 : :
20546 : : Quadruples Produced
20547 : :
20548 : : q Operator Temporary _ Sym
20549 : :
20550 : : */
20551 : :
20552 : 20567 : extern "C" void M2Quads_BuildUnaryOp (void)
20553 : : {
20554 : 20567 : unsigned int sympos;
20555 : 20567 : unsigned int tokpos;
20556 : 20567 : NameKey_Name Tok;
20557 : 20567 : unsigned int type;
20558 : 20567 : unsigned int Sym;
20559 : 20567 : unsigned int SymT;
20560 : 20567 : unsigned int r;
20561 : 20567 : unsigned int t;
20562 : :
20563 : 20567 : PopTrwtok (&Sym, &r, &sympos);
20564 : 20567 : M2Quads_PopTtok (&Tok, &tokpos);
20565 : 20567 : if (Tok == M2Reserved_MinusTok)
20566 : : {
20567 : 20423 : MarkAsRead (r);
20568 : 20423 : type = M2Base_NegateType (SymbolTable_GetSType (Sym)); /* , sympos */
20569 : 20423 : tokpos = M2LexBuf_MakeVirtualTok (tokpos, tokpos, sympos);
20570 : 40846 : t = SymbolTable_MakeTemporary (tokpos, AreConstant (SymbolTable_IsConst (Sym)));
20571 : 20423 : SymbolTable_PutVar (t, type);
20572 : : /*
20573 : : variables must have a type and REAL/LONGREAL constants must
20574 : : be typed
20575 : : */
20576 : 20423 : if (! (SymbolTable_IsConst (Sym)))
20577 : : {
20578 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
20579 : 840 : if ((type != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_SkipType (type))))
20580 : : {} /* empty. */
20581 : : /* do not dereference set variables */
20582 : 818 : else if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
20583 : : {
20584 : : /* avoid dangling else. */
20585 : : /* dereference symbols which are not sets and which are variables */
20586 : 0 : SymT = SymbolTable_MakeTemporary (sympos, SymbolTable_RightValue);
20587 : 0 : SymbolTable_PutVar (SymT, SymbolTable_GetSType (Sym));
20588 : 0 : CheckPointerThroughNil (sympos, Sym);
20589 : 0 : doIndrX (sympos, SymT, Sym);
20590 : 0 : Sym = SymT;
20591 : : }
20592 : : }
20593 : 20423 : GenQuadO (tokpos, M2Quads_NegateOp, t, SymbolTable_NulSym, Sym, true);
20594 : 20423 : M2Quads_PushTtok (t, tokpos);
20595 : : }
20596 : 144 : else if (Tok == M2Reserved_PlusTok)
20597 : : {
20598 : : /* avoid dangling else. */
20599 : 144 : tokpos = M2LexBuf_MakeVirtualTok (tokpos, tokpos, sympos);
20600 : 144 : PushTrwtok (Sym, r, tokpos);
20601 : : }
20602 : : else
20603 : : {
20604 : : /* avoid dangling else. */
20605 : 0 : M2MetaError_MetaErrorNT1 (tokpos, (const char *) "expecting an unary operator, seen {%Ek%a}", 41, Tok);
20606 : : }
20607 : 20567 : }
20608 : :
20609 : :
20610 : : /*
20611 : : OperandT - returns the ident operand stored in the true position on the boolean stack.
20612 : : */
20613 : :
20614 : 127632557 : extern "C" unsigned int M2Quads_OperandT (unsigned int pos)
20615 : : {
20616 : 127632557 : M2Debug_Assert (! (IsBoolean (pos)));
20617 : 127632557 : return OperandTno (pos);
20618 : : /* static analysis guarentees a RETURN statement will be used before here. */
20619 : : __builtin_unreachable ();
20620 : : }
20621 : :
20622 : :
20623 : : /*
20624 : : OperandF - returns the ident operand stored in the false position on the boolean stack.
20625 : : */
20626 : :
20627 : 152484 : extern "C" unsigned int M2Quads_OperandF (unsigned int pos)
20628 : : {
20629 : 152484 : M2Debug_Assert (! (IsBoolean (pos)));
20630 : 152484 : return OperandFno (pos);
20631 : : /* static analysis guarentees a RETURN statement will be used before here. */
20632 : : __builtin_unreachable ();
20633 : : }
20634 : :
20635 : :
20636 : : /*
20637 : : PushTF - Push a True and False numbers onto the True/False stack.
20638 : : True and False are assumed to contain Symbols or Ident etc.
20639 : : */
20640 : :
20641 : 8738317 : extern "C" void M2Quads_PushTF (unsigned int True, unsigned int False)
20642 : : {
20643 : 8738317 : M2Quads_BoolFrame f;
20644 : :
20645 : 8738317 : f = newBoolFrame ();
20646 : 8738317 : f->TrueExit = static_cast<unsigned int> (True);
20647 : 8738317 : f->FalseExit = static_cast<unsigned int> (False);
20648 : 8738317 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
20649 : 8738317 : }
20650 : :
20651 : :
20652 : : /*
20653 : : PopTF - Pop a True and False number from the True/False stack.
20654 : : True and False are assumed to contain Symbols or Ident etc.
20655 : : */
20656 : :
20657 : 6141155 : extern "C" void M2Quads_PopTF (unsigned int *True, unsigned int *False)
20658 : : {
20659 : 6141155 : M2Quads_BoolFrame f;
20660 : :
20661 : 6141155 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
20662 : 6141155 : (*True) = static_cast<unsigned int> (f->TrueExit);
20663 : 6141155 : (*False) = static_cast<unsigned int> (f->FalseExit);
20664 : 6141155 : M2Debug_Assert (! f->BooleanOp);
20665 : 6141155 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
20666 : 6141155 : }
20667 : :
20668 : :
20669 : : /*
20670 : : PushT - Push an item onto the stack in the T (true) position.
20671 : : */
20672 : :
20673 : 59077085 : extern "C" void M2Quads_PushT (unsigned int True)
20674 : : {
20675 : 59077085 : M2Quads_BoolFrame f;
20676 : :
20677 : 59077085 : f = newBoolFrame ();
20678 : 59077085 : f->TrueExit = static_cast<unsigned int> (True);
20679 : 59077085 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
20680 : 59077085 : }
20681 : :
20682 : :
20683 : : /*
20684 : : PopT - Pops the T value from the stack.
20685 : : */
20686 : :
20687 : 86668886 : extern "C" void M2Quads_PopT (unsigned int *True)
20688 : : {
20689 : 86668886 : M2Quads_BoolFrame f;
20690 : :
20691 : 86668886 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
20692 : 86668880 : (*True) = static_cast<unsigned int> (f->TrueExit);
20693 : 86668880 : M2Debug_Assert (! f->BooleanOp);
20694 : 86668880 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
20695 : 86668880 : }
20696 : :
20697 : :
20698 : : /*
20699 : : PushTtok - Push an item onto the stack in the T (true) position,
20700 : : it is assummed to be a token and its token location is recorded.
20701 : : */
20702 : :
20703 : 43790530 : extern "C" void M2Quads_PushTtok (unsigned int True, unsigned int tokno)
20704 : : {
20705 : 43790530 : M2Quads_BoolFrame f;
20706 : :
20707 : : /* PrintTokenNo (tokno) ; */
20708 : 43790530 : f = newBoolFrame ();
20709 : 43790530 : f->TrueExit = static_cast<unsigned int> (True);
20710 : 43790530 : f->tokenno = tokno;
20711 : 43790530 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
20712 : 43790530 : }
20713 : :
20714 : :
20715 : : /*
20716 : : PushTFtok - Push an item onto the stack in the T (true) position,
20717 : : it is assummed to be a token and its token location is recorded.
20718 : : */
20719 : :
20720 : 91342220 : extern "C" void M2Quads_PushTFtok (unsigned int True, unsigned int False, unsigned int tokno)
20721 : : {
20722 : 91342220 : M2Quads_BoolFrame f;
20723 : :
20724 : 91342220 : f = newBoolFrame ();
20725 : 91342220 : f->TrueExit = static_cast<unsigned int> (True);
20726 : 91342220 : f->FalseExit = static_cast<unsigned int> (False);
20727 : 91342220 : f->tokenno = tokno;
20728 : 91342220 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
20729 : 91342220 : }
20730 : :
20731 : :
20732 : : /*
20733 : : PopTFtok - Pop T/F/tok from the stack.
20734 : : */
20735 : :
20736 : 5939630 : extern "C" void M2Quads_PopTFtok (unsigned int *True, unsigned int *False, unsigned int *tokno)
20737 : : {
20738 : 5939630 : M2Quads_BoolFrame f;
20739 : :
20740 : 5939630 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
20741 : 5939630 : (*True) = static_cast<unsigned int> (f->TrueExit);
20742 : 5939630 : (*False) = static_cast<unsigned int> (f->FalseExit);
20743 : 5939630 : (*tokno) = f->tokenno;
20744 : 5939630 : }
20745 : :
20746 : :
20747 : : /*
20748 : : PushTFAtok - Push T/F/A/tok to the stack.
20749 : : */
20750 : :
20751 : 54 : extern "C" void M2Quads_PushTFAtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int tokno)
20752 : : {
20753 : 54 : M2Quads_BoolFrame f;
20754 : :
20755 : 54 : f = newBoolFrame ();
20756 : 54 : f->TrueExit = static_cast<unsigned int> (True);
20757 : 54 : f->FalseExit = static_cast<unsigned int> (False);
20758 : 54 : f->Unbounded = static_cast<unsigned int> (Array);
20759 : 54 : f->tokenno = tokno;
20760 : 54 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
20761 : 54 : }
20762 : :
20763 : :
20764 : : /*
20765 : : PopTtok - Pops the T value from the stack and token position.
20766 : : */
20767 : :
20768 : 63760757 : extern "C" void M2Quads_PopTtok (unsigned int *True, unsigned int *tok)
20769 : : {
20770 : 63760757 : M2Quads_BoolFrame f;
20771 : :
20772 : 63760757 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
20773 : 63760757 : (*True) = static_cast<unsigned int> (f->TrueExit);
20774 : 63760757 : (*tok) = f->tokenno;
20775 : 63760757 : M2Debug_Assert (! f->BooleanOp);
20776 : 63760757 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
20777 : 63760757 : }
20778 : :
20779 : :
20780 : : /*
20781 : : PushTFn - Push a True and False numbers onto the True/False stack.
20782 : : True and False are assumed to contain Symbols or Ident etc.
20783 : : */
20784 : :
20785 : 0 : extern "C" void M2Quads_PushTFn (unsigned int True, unsigned int False, unsigned int n)
20786 : : {
20787 : 0 : M2Quads_BoolFrame f;
20788 : :
20789 : 0 : f = newBoolFrame ();
20790 : 0 : f->TrueExit = static_cast<unsigned int> (True);
20791 : 0 : f->FalseExit = static_cast<unsigned int> (False);
20792 : 0 : f->name = static_cast<unsigned int> (n);
20793 : 0 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
20794 : 0 : }
20795 : :
20796 : :
20797 : : /*
20798 : : PushTFntok - Push a True and False numbers onto the True/False stack.
20799 : : True and False are assumed to contain Symbols or Ident etc.
20800 : : */
20801 : :
20802 : 534156 : extern "C" void M2Quads_PushTFntok (unsigned int True, unsigned int False, unsigned int n, unsigned int tokno)
20803 : : {
20804 : 534156 : M2Quads_BoolFrame f;
20805 : :
20806 : 534156 : f = newBoolFrame ();
20807 : 534156 : f->TrueExit = static_cast<unsigned int> (True);
20808 : 534156 : f->FalseExit = static_cast<unsigned int> (False);
20809 : 534156 : f->name = static_cast<unsigned int> (n);
20810 : 534156 : f->tokenno = tokno;
20811 : 534156 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
20812 : 534156 : }
20813 : :
20814 : :
20815 : : /*
20816 : : PopTFn - Pop a True and False number from the True/False stack.
20817 : : True and False are assumed to contain Symbols or Ident etc.
20818 : : */
20819 : :
20820 : 0 : extern "C" void M2Quads_PopTFn (unsigned int *True, unsigned int *False, unsigned int *n)
20821 : : {
20822 : 0 : M2Quads_BoolFrame f;
20823 : :
20824 : 0 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
20825 : 0 : (*True) = static_cast<unsigned int> (f->TrueExit);
20826 : 0 : (*False) = static_cast<unsigned int> (f->FalseExit);
20827 : 0 : (*n) = static_cast<unsigned int> (f->name);
20828 : 0 : M2Debug_Assert (! f->BooleanOp);
20829 : 0 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
20830 : 0 : }
20831 : :
20832 : :
20833 : : /*
20834 : : PopNothing - pops the top element on the boolean stack.
20835 : : */
20836 : :
20837 : 40101655 : extern "C" void M2Quads_PopNothing (void)
20838 : : {
20839 : 40101655 : M2Quads_BoolFrame f;
20840 : :
20841 : 40101655 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
20842 : 40101655 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
20843 : 40101655 : }
20844 : :
20845 : :
20846 : : /*
20847 : : PopN - pops multiple elements from the BoolStack.
20848 : : */
20849 : :
20850 : 7949036 : extern "C" void M2Quads_PopN (unsigned int n)
20851 : : {
20852 : 31357119 : while (n > 0)
20853 : : {
20854 : 23408083 : M2Quads_PopNothing ();
20855 : 23408083 : n -= 1;
20856 : : }
20857 : 7949036 : }
20858 : :
20859 : :
20860 : : /*
20861 : : PushTFA - Push True, False, Array, numbers onto the
20862 : : True/False stack. True and False are assumed to
20863 : : contain Symbols or Ident etc.
20864 : : */
20865 : :
20866 : 0 : extern "C" void M2Quads_PushTFA (unsigned int True, unsigned int False, unsigned int Array)
20867 : : {
20868 : 0 : M2Quads_BoolFrame f;
20869 : :
20870 : 0 : f = newBoolFrame ();
20871 : 0 : f->TrueExit = static_cast<unsigned int> (True);
20872 : 0 : f->FalseExit = static_cast<unsigned int> (False);
20873 : 0 : f->Unbounded = static_cast<unsigned int> (Array);
20874 : 0 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
20875 : 0 : }
20876 : :
20877 : :
20878 : : /*
20879 : : OperandTok - returns the token associated with pos, on the stack.
20880 : : */
20881 : :
20882 : 35481048 : extern "C" unsigned int M2Quads_OperandTok (unsigned int pos)
20883 : : {
20884 : 35481048 : M2Debug_Assert (! (IsBoolean (pos)));
20885 : 35481048 : return static_cast<unsigned int> (OperandTtok (pos));
20886 : : /* static analysis guarentees a RETURN statement will be used before here. */
20887 : : __builtin_unreachable ();
20888 : : }
20889 : :
20890 : :
20891 : : /*
20892 : : OperandA - returns possible array symbol associated with the ident
20893 : : operand stored on the boolean stack.
20894 : : */
20895 : :
20896 : 1385644 : extern "C" unsigned int M2Quads_OperandA (unsigned int pos)
20897 : : {
20898 : 1385644 : M2Quads_BoolFrame f;
20899 : :
20900 : 1385644 : M2Debug_Assert (pos > 0);
20901 : 1385644 : M2Debug_Assert (! (IsBoolean (pos)));
20902 : 1385644 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
20903 : 1385644 : return static_cast<unsigned int> (f->Unbounded);
20904 : : /* static analysis guarentees a RETURN statement will be used before here. */
20905 : : __builtin_unreachable ();
20906 : : }
20907 : :
20908 : :
20909 : : /*
20910 : : OperandAnno - returns the annotation string associated with the
20911 : : position, n, on the stack.
20912 : : */
20913 : :
20914 : 0 : extern "C" DynamicStrings_String M2Quads_OperandAnno (unsigned int n)
20915 : : {
20916 : 0 : M2Quads_BoolFrame f;
20917 : :
20918 : 0 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, n));
20919 : 0 : return f->Annotation;
20920 : : /* static analysis guarentees a RETURN statement will be used before here. */
20921 : : __builtin_unreachable ();
20922 : : }
20923 : :
20924 : :
20925 : : /*
20926 : : Annotate - annotate the top of stack.
20927 : : */
20928 : :
20929 : 68579509 : extern "C" void M2Quads_Annotate (const char *a_, unsigned int _a_high)
20930 : : {
20931 : 68579509 : M2Quads_BoolFrame f;
20932 : 68579509 : char a[_a_high+1];
20933 : :
20934 : : /* make a local copy of each unbounded array. */
20935 : 68579509 : memcpy (a, a_, _a_high+1);
20936 : :
20937 : 0 : if ((DebugStackOn && M2Options_CompilerDebugging) && ((M2StackAddress_NoOfItemsInStackAddress (BoolStack)) > 0))
20938 : : {
20939 : 0 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, 1)); /* top of stack */
20940 : 0 : if (f->Annotation != NULL) /* top of stack */
20941 : : {
20942 : 0 : f->Annotation = DynamicStrings_KillString (f->Annotation);
20943 : : }
20944 : 0 : f->Annotation = DynamicStrings_InitString ((const char *) a, _a_high);
20945 : : }
20946 : 68579509 : }
20947 : :
20948 : :
20949 : : /*
20950 : : DisplayStack - displays the compile time symbol stack.
20951 : : */
20952 : :
20953 : 12821496 : extern "C" void M2Quads_DisplayStack (void)
20954 : : {
20955 : 12821496 : if (DebugStackOn && M2Options_CompilerDebugging)
20956 : : {
20957 : 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});
20958 : : }
20959 : 12821496 : }
20960 : :
20961 : :
20962 : : /*
20963 : : Top - returns the no of items held in the stack.
20964 : : */
20965 : :
20966 : 50043924 : extern "C" unsigned int M2Quads_Top (void)
20967 : : {
20968 : 50043924 : return M2StackAddress_NoOfItemsInStackAddress (BoolStack);
20969 : : /* static analysis guarentees a RETURN statement will be used before here. */
20970 : : __builtin_unreachable ();
20971 : : }
20972 : :
20973 : :
20974 : : /*
20975 : : DupFrame - duplicate the top of stack and push the new frame.
20976 : : */
20977 : :
20978 : 0 : extern "C" void M2Quads_DupFrame (void)
20979 : : {
20980 : 0 : M2Quads_BoolFrame f;
20981 : 0 : M2Quads_BoolFrame newf;
20982 : :
20983 : 0 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
20984 : 0 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
20985 : 0 : newf = newBoolFrame ();
20986 : 0 : (*newf) = (*f);
20987 : 0 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (newf));
20988 : 0 : }
20989 : :
20990 : :
20991 : : /*
20992 : : WriteOperand - displays the operands name, symbol id and mode of addressing.
20993 : : */
20994 : :
20995 : 0 : extern "C" void M2Quads_WriteOperand (unsigned int Sym)
20996 : : {
20997 : 0 : NameKey_Name n;
20998 : :
20999 : 0 : if (Sym == SymbolTable_NulSym)
21000 : : {
21001 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "<nulsym>", 8);
21002 : : }
21003 : : else
21004 : : {
21005 : 0 : n = SymbolTable_GetSymName (Sym);
21006 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%a", 2, (const unsigned char *) &n, (sizeof (n)-1));
21007 : 0 : if ((SymbolTable_IsVar (Sym)) || (SymbolTable_IsConst (Sym)))
21008 : : {
21009 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "[", 1);
21010 : 0 : WriteMode (SymbolTable_GetMode (Sym));
21011 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "]", 1);
21012 : : }
21013 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "(%d)", 4, (const unsigned char *) &Sym, (sizeof (Sym)-1));
21014 : : }
21015 : 0 : }
21016 : :
21017 : :
21018 : : /*
21019 : : BeginVarient - begin a varient record.
21020 : : */
21021 : :
21022 : 276 : extern "C" void M2Quads_BeginVarient (void)
21023 : : {
21024 : 276 : unsigned int r;
21025 : 276 : unsigned int v;
21026 : :
21027 : 276 : r = GetRecordOrField ();
21028 : 552 : M2Debug_Assert ((SymbolTable_IsRecord (r)) || (SymbolTable_IsFieldVarient (r)));
21029 : 276 : v = GetRecordOrField ();
21030 : 276 : M2Debug_Assert (SymbolTable_IsVarient (v));
21031 : 276 : BuildRange (M2Range_InitCaseBounds (M2CaseList_PushCase (r, v, SymbolTable_NulSym)));
21032 : 276 : }
21033 : :
21034 : :
21035 : : /*
21036 : : EndVarient - end a varient record.
21037 : : */
21038 : :
21039 : 276 : extern "C" void M2Quads_EndVarient (void)
21040 : : {
21041 : 276 : M2CaseList_PopCase ();
21042 : 276 : }
21043 : :
21044 : :
21045 : : /*
21046 : : ElseVarient - associate an ELSE clause with a varient record.
21047 : : */
21048 : :
21049 : 114 : extern "C" void M2Quads_ElseVarient (void)
21050 : : {
21051 : 114 : unsigned int f;
21052 : :
21053 : 114 : f = GetRecordOrField ();
21054 : 114 : M2Debug_Assert (SymbolTable_IsFieldVarient (f));
21055 : 114 : M2CaseList_ElseCase (f);
21056 : 114 : }
21057 : :
21058 : :
21059 : : /*
21060 : : BeginVarientList - begin an ident list containing ranges belonging to a
21061 : : varient list.
21062 : : */
21063 : :
21064 : 552 : extern "C" void M2Quads_BeginVarientList (void)
21065 : : {
21066 : 552 : unsigned int f;
21067 : :
21068 : 552 : f = GetRecordOrField ();
21069 : 552 : M2Debug_Assert (SymbolTable_IsFieldVarient (f));
21070 : 552 : M2CaseList_BeginCaseList (f);
21071 : 552 : }
21072 : :
21073 : :
21074 : : /*
21075 : : EndVarientList - end a range list for a varient field.
21076 : : */
21077 : :
21078 : 552 : extern "C" void M2Quads_EndVarientList (void)
21079 : : {
21080 : 552 : M2CaseList_EndCaseList ();
21081 : 552 : }
21082 : :
21083 : :
21084 : : /*
21085 : : AddRecordToList - adds the record held on the top of stack to the
21086 : : list of records and varient fields.
21087 : : */
21088 : :
21089 : 276 : extern "C" void M2Quads_AddRecordToList (void)
21090 : : {
21091 : 276 : unsigned int r;
21092 : 276 : unsigned int n;
21093 : :
21094 : 276 : r = static_cast<unsigned int> (M2Quads_OperandT (1));
21095 : 552 : M2Debug_Assert ((SymbolTable_IsRecord (r)) || (SymbolTable_IsFieldVarient (r)));
21096 : : /*
21097 : : r might be a field varient if the declaration consists of nested
21098 : : varients. However ISO TSIZE can only utilise record types, we store
21099 : : a varient field anyway as the next pass would not know whether to
21100 : : ignore a varient field.
21101 : : */
21102 : 276 : Lists_PutItemIntoList (VarientFields, r);
21103 : 276 : if (DebugVarients)
21104 : : {
21105 : : n = Lists_NoOfItemsInList (VarientFields);
21106 : : if (SymbolTable_IsRecord (r))
21107 : : {
21108 : : 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));
21109 : : }
21110 : : else
21111 : : {
21112 : : 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));
21113 : : }
21114 : : }
21115 : 276 : }
21116 : :
21117 : :
21118 : : /*
21119 : : AddVarientToList - adds varient held on the top of stack to the list.
21120 : : */
21121 : :
21122 : 276 : extern "C" void M2Quads_AddVarientToList (void)
21123 : : {
21124 : 276 : unsigned int v;
21125 : 276 : unsigned int n;
21126 : :
21127 : 276 : v = static_cast<unsigned int> (M2Quads_OperandT (1));
21128 : 276 : M2Debug_Assert (SymbolTable_IsVarient (v));
21129 : 276 : Lists_PutItemIntoList (VarientFields, v);
21130 : 276 : if (DebugVarients)
21131 : : {
21132 : : n = Lists_NoOfItemsInList (VarientFields);
21133 : : 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));
21134 : : }
21135 : 276 : }
21136 : :
21137 : :
21138 : : /*
21139 : : AddVarientFieldToList - adds varient field, f, to the list of all varient
21140 : : fields created.
21141 : : */
21142 : :
21143 : 666 : extern "C" void M2Quads_AddVarientFieldToList (unsigned int f)
21144 : : {
21145 : 666 : unsigned int n;
21146 : :
21147 : 666 : M2Debug_Assert (SymbolTable_IsFieldVarient (f));
21148 : 666 : Lists_PutItemIntoList (VarientFields, f);
21149 : 666 : if (DebugVarients)
21150 : : {
21151 : : n = Lists_NoOfItemsInList (VarientFields);
21152 : : 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));
21153 : : }
21154 : 666 : }
21155 : :
21156 : :
21157 : : /*
21158 : : AddVarientRange - creates a range from the top two contant expressions
21159 : : on the stack which are recorded with the current
21160 : : varient field. The stack is unaltered.
21161 : : */
21162 : :
21163 : 0 : extern "C" void M2Quads_AddVarientRange (void)
21164 : : {
21165 : 0 : unsigned int r1;
21166 : 0 : unsigned int r2;
21167 : :
21168 : 0 : M2Quads_PopT (&r2);
21169 : 0 : M2Quads_PopT (&r1);
21170 : 0 : M2CaseList_AddRange (r1, r2, M2LexBuf_GetTokenNo ());
21171 : 0 : }
21172 : :
21173 : :
21174 : : /*
21175 : : AddVarientEquality - adds the contant expression on the top of the stack
21176 : : to the current varient field being recorded.
21177 : : The stack is unaltered.
21178 : : */
21179 : :
21180 : 594 : extern "C" void M2Quads_AddVarientEquality (void)
21181 : : {
21182 : 594 : unsigned int r1;
21183 : :
21184 : 594 : M2Quads_PopT (&r1);
21185 : 594 : M2CaseList_AddRange (r1, SymbolTable_NulSym, M2LexBuf_GetTokenNo ());
21186 : 594 : }
21187 : :
21188 : :
21189 : : /*
21190 : : BuildCodeOn - generates a quadruple declaring that code should be
21191 : : emmitted from henceforth.
21192 : :
21193 : : The Stack is unnaffected.
21194 : : */
21195 : :
21196 : 0 : extern "C" void M2Quads_BuildCodeOn (void)
21197 : : {
21198 : 0 : GenQuad (M2Quads_CodeOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21199 : 0 : }
21200 : :
21201 : :
21202 : : /*
21203 : : BuildCodeOff - generates a quadruple declaring that code should not be
21204 : : emmitted from henceforth.
21205 : :
21206 : : The Stack is unnaffected.
21207 : : */
21208 : :
21209 : 0 : extern "C" void M2Quads_BuildCodeOff (void)
21210 : : {
21211 : 0 : GenQuad (M2Quads_CodeOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21212 : 0 : }
21213 : :
21214 : :
21215 : : /*
21216 : : BuildProfileOn - generates a quadruple declaring that profile timings
21217 : : should be emmitted from henceforth.
21218 : :
21219 : : The Stack is unnaffected.
21220 : : */
21221 : :
21222 : 0 : extern "C" void M2Quads_BuildProfileOn (void)
21223 : : {
21224 : 0 : GenQuad (M2Quads_ProfileOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21225 : 0 : }
21226 : :
21227 : 0 : extern "C" void M2Quads_BuildProfileOff (void)
21228 : : {
21229 : : /*
21230 : : BuildProfileOn - generates a quadruple declaring that profile timings
21231 : : should be emmitted from henceforth.
21232 : :
21233 : : The Stack is unnaffected.
21234 : : */
21235 : 0 : GenQuad (M2Quads_ProfileOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21236 : 0 : }
21237 : :
21238 : :
21239 : : /*
21240 : : BuildOptimizeOn - generates a quadruple declaring that optimization
21241 : : should occur from henceforth.
21242 : :
21243 : : The Stack is unnaffected.
21244 : : */
21245 : :
21246 : 0 : extern "C" void M2Quads_BuildOptimizeOn (void)
21247 : : {
21248 : 0 : GenQuad (M2Quads_OptimizeOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21249 : 0 : }
21250 : :
21251 : :
21252 : : /*
21253 : : BuildOptimizeOff - generates a quadruple declaring that optimization
21254 : : should not occur from henceforth.
21255 : :
21256 : : The Stack is unnaffected.
21257 : : */
21258 : :
21259 : 0 : extern "C" void M2Quads_BuildOptimizeOff (void)
21260 : : {
21261 : 0 : GenQuad (M2Quads_OptimizeOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21262 : 0 : }
21263 : :
21264 : :
21265 : : /*
21266 : : BuildAsm - builds an Inline pseudo quadruple operator.
21267 : : The inline interface, Sym, is stored as the operand
21268 : : to the operator InlineOp.
21269 : :
21270 : : The stack is expected to contain:
21271 : :
21272 : :
21273 : : Entry Exit
21274 : : ===== ====
21275 : :
21276 : : Ptr ->
21277 : : +--------------+
21278 : : | Sym | Empty
21279 : : |--------------|
21280 : : */
21281 : :
21282 : 24 : extern "C" void M2Quads_BuildAsm (unsigned int tok)
21283 : : {
21284 : 24 : unsigned int Sym;
21285 : :
21286 : 24 : M2Quads_PopT (&Sym);
21287 : 24 : GenQuadO (tok, M2Quads_InlineOp, SymbolTable_NulSym, SymbolTable_NulSym, Sym, false);
21288 : 24 : }
21289 : :
21290 : :
21291 : : /*
21292 : : BuildLineNo - builds a LineNumberOp pseudo quadruple operator.
21293 : : This quadruple indicates which source line has been
21294 : : processed, these quadruples are only generated if we
21295 : : are producing runtime debugging information.
21296 : :
21297 : : The stack is not affected, read or altered in any way.
21298 : :
21299 : :
21300 : : Entry Exit
21301 : : ===== ====
21302 : :
21303 : : Ptr -> <- Ptr
21304 : : */
21305 : :
21306 : 0 : extern "C" void M2Quads_BuildLineNo (void)
21307 : : {
21308 : 0 : NameKey_Name filename;
21309 : 0 : M2Quads_QuadFrame f;
21310 : :
21311 : 0 : if (((NextQuad != Head) && (M2Options_GenerateLineDebug || M2Options_GenerateDebugging)) && false)
21312 : : {
21313 : : filename = NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()));
21314 : : f = GetQF (NextQuad-1);
21315 : : if (! ((f->Operator == M2Quads_LineNumberOp) && (f->Operand1 == ((unsigned int ) (filename)))))
21316 : : {
21317 : : GenQuad (M2Quads_LineNumberOp, (unsigned int ) (filename), SymbolTable_NulSym, (unsigned int ) (M2LexBuf_GetLineNo ()));
21318 : : }
21319 : : }
21320 : 0 : }
21321 : :
21322 : :
21323 : : /*
21324 : : PushLineNo - pushes the current file and line number to the stack.
21325 : : */
21326 : :
21327 : 4308 : extern "C" void M2Quads_PushLineNo (void)
21328 : : {
21329 : 4308 : PushLineNote (InitLineNote (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ())), M2LexBuf_GetLineNo ()));
21330 : 4308 : }
21331 : :
21332 : :
21333 : : /*
21334 : : BuildStmtNote - builds a StatementNoteOp pseudo quadruple operator.
21335 : : This quadruple indicates which source line has been
21336 : : processed and it represents the start of a statement
21337 : : sequence.
21338 : : It differs from LineNumberOp in that multiple successive
21339 : : LineNumberOps will be removed and the final one is attached to
21340 : : the next real GCC tree. Whereas a StatementNoteOp is always left
21341 : : alone. Depending upon the debugging level it will issue a nop
21342 : : instruction to ensure that the gdb single step will step into
21343 : : this line. Practically it allows pedalogical debugging to
21344 : : occur when there is syntax sugar such as:
21345 : :
21346 : :
21347 : : END step
21348 : : END step
21349 : : END ; step
21350 : : a := 1 ; step
21351 : :
21352 : : REPEAT step
21353 : : i := 1 step
21354 : :
21355 : : The stack is not affected, read or altered in any way.
21356 : :
21357 : :
21358 : : Entry Exit
21359 : : ===== ====
21360 : :
21361 : : Ptr -> <- Ptr
21362 : : */
21363 : :
21364 : 460102 : extern "C" void M2Quads_BuildStmtNote (int offset)
21365 : : {
21366 : 460102 : int tokenno;
21367 : :
21368 : 460102 : if (NextQuad != Head)
21369 : : {
21370 : 460102 : tokenno = offset;
21371 : 460102 : tokenno += M2LexBuf_GetTokenNo ();
21372 : 460102 : BuildStmtNoteTok ((unsigned int ) (tokenno));
21373 : : }
21374 : 460102 : }
21375 : :
21376 : :
21377 : : /*
21378 : : LoopAnalysis - checks whether an infinite loop exists.
21379 : : */
21380 : :
21381 : 316475 : extern "C" void M2Quads_LoopAnalysis (unsigned int Scope, unsigned int Current, unsigned int End)
21382 : : {
21383 : 316475 : M2Quads_QuadOperator op;
21384 : 316475 : unsigned int op1;
21385 : 316475 : unsigned int op2;
21386 : 316475 : unsigned int op3;
21387 : :
21388 : 316475 : if (M2Options_Pedantic)
21389 : : {
21390 : 10392 : while ((Current <= End) && (Current != 0))
21391 : : {
21392 : 9114 : M2Quads_GetQuad (Current, &op, &op1, &op2, &op3);
21393 : 9114 : if ((op == M2Quads_GotoOp) || (M2Quads_IsConditional (Current)))
21394 : : {
21395 : 114 : if (op3 <= Current)
21396 : : {
21397 : : /* found a loop - ie a branch which goes back in quadruple numbers */
21398 : 24 : if (IsInfiniteLoop (Current))
21399 : : {
21400 : 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);
21401 : 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);
21402 : : }
21403 : : /*
21404 : : WarnStringAt(InitString('it is very likely (although not absolutely certain) that the top of an infinite loop is here'),
21405 : : QuadToTokenNo(op3)) ;
21406 : : WarnStringAt(InitString('and the bottom of the infinite loop is ends here or alternatively a component of this loop is never executed'),
21407 : : QuadToTokenNo(Current))
21408 : : */
21409 : : }
21410 : : }
21411 : 9114 : Current = M2Quads_GetNextQuad (Current);
21412 : : }
21413 : : }
21414 : 316475 : }
21415 : :
21416 : :
21417 : : /*
21418 : : ForLoopAnalysis - checks all the FOR loops for index variable manipulation
21419 : : and dangerous usage outside the loop.
21420 : : */
21421 : :
21422 : 14505 : extern "C" void M2Quads_ForLoopAnalysis (void)
21423 : : {
21424 : 14505 : unsigned int i;
21425 : 14505 : unsigned int n;
21426 : 14505 : M2Quads_ForLoopInfo forDesc;
21427 : :
21428 : 14505 : if (M2Options_Pedantic)
21429 : : {
21430 : 96 : n = Indexing_HighIndice (ForInfo);
21431 : 96 : i = 1;
21432 : 192 : while (i <= n)
21433 : : {
21434 : 0 : forDesc = static_cast<M2Quads_ForLoopInfo> (Indexing_GetIndice (ForInfo, i));
21435 : 0 : CheckForIndex (forDesc);
21436 : 0 : i += 1;
21437 : : }
21438 : : }
21439 : 14505 : }
21440 : :
21441 : :
21442 : : /*
21443 : : BuildSizeCheckStart - switches off all quadruple generation if the function SIZE or HIGH
21444 : : is being "called". This should be done as SIZE only requires the
21445 : : actual type of the expression, not its value. Consider the problem of
21446 : : SIZE(UninitializedPointer^) which is quite legal and it must
21447 : : also be safe!
21448 : : ISO Modula-2 also allows HIGH(a[0]) for a two dimensional array
21449 : : and there is no need to compute a[0], we just need to follow the
21450 : : type and count dimensions. However if SIZE(a) or HIGH(a) occurs
21451 : : and, a, is an unbounded array then we turn on quadruple generation.
21452 : :
21453 : : The Stack is expected to contain:
21454 : :
21455 : :
21456 : : Entry Exit
21457 : : ===== ====
21458 : :
21459 : : Ptr -> <- Ptr
21460 : : +----------------------+ +----------------------+
21461 : : | ProcSym | Type | tok | | ProcSym | Type | tok |
21462 : : |----------------------| |----------------------|
21463 : : */
21464 : :
21465 : 154932 : extern "C" void M2Quads_BuildSizeCheckStart (void)
21466 : : {
21467 : 154932 : unsigned int ProcSym;
21468 : 154932 : unsigned int Type;
21469 : 154932 : unsigned int tok;
21470 : :
21471 : 154932 : M2Quads_PopTFtok (&ProcSym, &Type, &tok);
21472 : 154932 : if (((ProcSym == M2Size_Size) || (ProcSym == M2System_TSize)) || (ProcSym == M2System_TBitSize))
21473 : : {
21474 : 2772 : QuadrupleGeneration = false;
21475 : 2772 : BuildingSize = true;
21476 : : }
21477 : 152160 : else if (ProcSym == M2Base_High)
21478 : : {
21479 : : /* avoid dangling else. */
21480 : 2314 : QuadrupleGeneration = false;
21481 : 2314 : BuildingHigh = true;
21482 : : }
21483 : 154932 : M2Quads_PushTFtok (ProcSym, Type, tok);
21484 : 154932 : }
21485 : :
21486 : :
21487 : : /*
21488 : : BackPatchSubrangesAndOptParam - runs through all the quadruples and finds SubrangeLow or SubrangeHigh
21489 : : quadruples and replaces it by an assignment to the Low or High component
21490 : : of the subrange type.
21491 : :
21492 : : Input:
21493 : : SubrangeLow op1 op3 op3 is a subrange
21494 : :
21495 : : Output:
21496 : : Becomes op1 low
21497 : :
21498 : : Input:
21499 : : SubrangeHigh op1 op3 op3 is a subrange
21500 : :
21501 : : Output:
21502 : : Becomes op1 high
21503 : :
21504 : : Input:
21505 : : OptParam op1 op2 op3
21506 : :
21507 : : Output:
21508 : : Param op1 op2 GetOptArgInit(op3)
21509 : : */
21510 : :
21511 : 14505 : extern "C" void M2Quads_BackPatchSubrangesAndOptParam (void)
21512 : : {
21513 : 14505 : M2Quads_QuadFrame f;
21514 : 14505 : unsigned int q;
21515 : :
21516 : 14505 : q = M2Quads_GetFirstQuad ();
21517 : 14505 : if (q != 0)
21518 : : {
21519 : 4823934 : do {
21520 : 4823934 : f = GetQF (q);
21521 : 4823934 : switch (f->Operator)
21522 : : {
21523 : 234 : case M2Quads_SubrangeLowOp:
21524 : 234 : f->Operand3 = CollectLow (f->Operand3);
21525 : 234 : f->Operator = M2Quads_BecomesOp;
21526 : 234 : f->ConstExpr = false;
21527 : 234 : break;
21528 : :
21529 : 3034 : case M2Quads_SubrangeHighOp:
21530 : 3034 : f->Operand3 = CollectHigh (f->Operand3);
21531 : 3034 : f->Operator = M2Quads_BecomesOp;
21532 : 3034 : f->ConstExpr = false;
21533 : 3034 : break;
21534 : :
21535 : 3146 : case M2Quads_OptParamOp:
21536 : 3146 : f->Operand3 = SymbolTable_GetOptArgInit (f->Operand3);
21537 : 3146 : f->Operator = M2Quads_ParamOp;
21538 : 3146 : break;
21539 : :
21540 : :
21541 : : default:
21542 : : break;
21543 : : }
21544 : 4823934 : q = f->Next;
21545 : 4823934 : } while (! (q == 0));
21546 : : }
21547 : 14505 : }
21548 : :
21549 : :
21550 : : /*
21551 : : WriteOperator - writes the name of the quadruple operator.
21552 : : */
21553 : :
21554 : 0 : extern "C" void M2Quads_WriteOperator (M2Quads_QuadOperator Operator)
21555 : : {
21556 : 0 : switch (Operator)
21557 : : {
21558 : 0 : case M2Quads_ArithAddOp:
21559 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Arith + ", 18);
21560 : 0 : break;
21561 : :
21562 : 0 : case M2Quads_InitAddressOp:
21563 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitAddress ", 18);
21564 : 0 : break;
21565 : :
21566 : 0 : case M2Quads_LastForIteratorOp:
21567 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "LastForIterator ", 18);
21568 : 0 : break;
21569 : :
21570 : 0 : case M2Quads_LogicalOrOp:
21571 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Or ", 18);
21572 : 0 : break;
21573 : :
21574 : 0 : case M2Quads_LogicalAndOp:
21575 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "And ", 18);
21576 : 0 : break;
21577 : :
21578 : 0 : case M2Quads_LogicalXorOp:
21579 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Xor ", 18);
21580 : 0 : break;
21581 : :
21582 : 0 : case M2Quads_LogicalDiffOp:
21583 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Ldiff ", 18);
21584 : 0 : break;
21585 : :
21586 : 0 : case M2Quads_LogicalShiftOp:
21587 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Shift ", 18);
21588 : 0 : break;
21589 : :
21590 : 0 : case M2Quads_LogicalRotateOp:
21591 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Rotate ", 18);
21592 : 0 : break;
21593 : :
21594 : 0 : case M2Quads_BecomesOp:
21595 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Becomes ", 18);
21596 : 0 : break;
21597 : :
21598 : 0 : case M2Quads_IndrXOp:
21599 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "IndrX ", 18);
21600 : 0 : break;
21601 : :
21602 : 0 : case M2Quads_XIndrOp:
21603 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "XIndr ", 18);
21604 : 0 : break;
21605 : :
21606 : 0 : case M2Quads_ArrayOp:
21607 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Array ", 18);
21608 : 0 : break;
21609 : :
21610 : 0 : case M2Quads_ElementSizeOp:
21611 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ElementSize ", 18);
21612 : 0 : break;
21613 : :
21614 : 0 : case M2Quads_RecordFieldOp:
21615 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RecordField ", 18);
21616 : 0 : break;
21617 : :
21618 : 0 : case M2Quads_AddrOp:
21619 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Addr ", 18);
21620 : 0 : break;
21621 : :
21622 : 0 : case M2Quads_SizeOp:
21623 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Size ", 18);
21624 : 0 : break;
21625 : :
21626 : 0 : case M2Quads_IfInOp:
21627 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If IN ", 18);
21628 : 0 : break;
21629 : :
21630 : 0 : case M2Quads_IfNotInOp:
21631 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If NOT IN ", 18);
21632 : 0 : break;
21633 : :
21634 : 0 : case M2Quads_IfNotEquOp:
21635 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If <> ", 18);
21636 : 0 : break;
21637 : :
21638 : 0 : case M2Quads_IfEquOp:
21639 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If = ", 18);
21640 : 0 : break;
21641 : :
21642 : 0 : case M2Quads_IfLessEquOp:
21643 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If <= ", 18);
21644 : 0 : break;
21645 : :
21646 : 0 : case M2Quads_IfGreEquOp:
21647 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If >= ", 18);
21648 : 0 : break;
21649 : :
21650 : 0 : case M2Quads_IfGreOp:
21651 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If > ", 18);
21652 : 0 : break;
21653 : :
21654 : 0 : case M2Quads_IfLessOp:
21655 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If < ", 18);
21656 : 0 : break;
21657 : :
21658 : 0 : case M2Quads_GotoOp:
21659 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Goto ", 18);
21660 : 0 : break;
21661 : :
21662 : 0 : case M2Quads_DummyOp:
21663 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Dummy ", 18);
21664 : 0 : break;
21665 : :
21666 : 0 : case M2Quads_ModuleScopeOp:
21667 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ModuleScopeOp ", 18);
21668 : 0 : break;
21669 : :
21670 : 0 : case M2Quads_StartDefFileOp:
21671 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StartDefFile ", 18);
21672 : 0 : break;
21673 : :
21674 : 0 : case M2Quads_StartModFileOp:
21675 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StartModFile ", 18);
21676 : 0 : break;
21677 : :
21678 : 0 : case M2Quads_EndFileOp:
21679 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "EndFileOp ", 18);
21680 : 0 : break;
21681 : :
21682 : 0 : case M2Quads_InitStartOp:
21683 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitStart ", 18);
21684 : 0 : break;
21685 : :
21686 : 0 : case M2Quads_InitEndOp:
21687 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitEnd ", 18);
21688 : 0 : break;
21689 : :
21690 : 0 : case M2Quads_FinallyStartOp:
21691 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FinallyStart ", 18);
21692 : 0 : break;
21693 : :
21694 : 0 : case M2Quads_FinallyEndOp:
21695 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FinallyEnd ", 18);
21696 : 0 : break;
21697 : :
21698 : 0 : case M2Quads_RetryOp:
21699 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Retry ", 18);
21700 : 0 : break;
21701 : :
21702 : 0 : case M2Quads_TryOp:
21703 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Try ", 18);
21704 : 0 : break;
21705 : :
21706 : 0 : case M2Quads_ThrowOp:
21707 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Throw ", 18);
21708 : 0 : break;
21709 : :
21710 : 0 : case M2Quads_CatchBeginOp:
21711 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CatchBegin ", 18);
21712 : 0 : break;
21713 : :
21714 : 0 : case M2Quads_CatchEndOp:
21715 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CatchEnd ", 18);
21716 : 0 : break;
21717 : :
21718 : 0 : case M2Quads_AddOp:
21719 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "+ ", 18);
21720 : 0 : break;
21721 : :
21722 : 0 : case M2Quads_SubOp:
21723 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "- ", 18);
21724 : 0 : break;
21725 : :
21726 : 0 : case M2Quads_DivM2Op:
21727 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV M2 ", 18);
21728 : 0 : break;
21729 : :
21730 : 0 : case M2Quads_ModM2Op:
21731 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD M2 ", 18);
21732 : 0 : break;
21733 : :
21734 : 0 : case M2Quads_DivCeilOp:
21735 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV ceil ", 18);
21736 : 0 : break;
21737 : :
21738 : 0 : case M2Quads_ModCeilOp:
21739 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD ceil ", 18);
21740 : 0 : break;
21741 : :
21742 : 0 : case M2Quads_DivFloorOp:
21743 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV floor ", 18);
21744 : 0 : break;
21745 : :
21746 : 0 : case M2Quads_ModFloorOp:
21747 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD floor ", 18);
21748 : 0 : break;
21749 : :
21750 : 0 : case M2Quads_DivTruncOp:
21751 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV trunc ", 18);
21752 : 0 : break;
21753 : :
21754 : 0 : case M2Quads_ModTruncOp:
21755 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD trunc ", 18);
21756 : 0 : break;
21757 : :
21758 : 0 : case M2Quads_MultOp:
21759 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "* ", 18);
21760 : 0 : break;
21761 : :
21762 : 0 : case M2Quads_NegateOp:
21763 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Negate ", 18);
21764 : 0 : break;
21765 : :
21766 : 0 : case M2Quads_InclOp:
21767 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Incl ", 18);
21768 : 0 : break;
21769 : :
21770 : 0 : case M2Quads_ExclOp:
21771 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Excl ", 18);
21772 : 0 : break;
21773 : :
21774 : 0 : case M2Quads_ReturnOp:
21775 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Return ", 18);
21776 : 0 : break;
21777 : :
21778 : 0 : case M2Quads_ReturnValueOp:
21779 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ReturnValue ", 18);
21780 : 0 : break;
21781 : :
21782 : 0 : case M2Quads_FunctValueOp:
21783 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FunctValue ", 18);
21784 : 0 : break;
21785 : :
21786 : 0 : case M2Quads_CallOp:
21787 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Call ", 18);
21788 : 0 : break;
21789 : :
21790 : 0 : case M2Quads_ParamOp:
21791 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Param ", 18);
21792 : 0 : break;
21793 : :
21794 : 0 : case M2Quads_OptParamOp:
21795 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptParam ", 18);
21796 : 0 : break;
21797 : :
21798 : 0 : case M2Quads_NewLocalVarOp:
21799 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "NewLocalVar ", 18);
21800 : 0 : break;
21801 : :
21802 : 0 : case M2Quads_KillLocalVarOp:
21803 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "KillLocalVar ", 18);
21804 : 0 : break;
21805 : :
21806 : 0 : case M2Quads_ProcedureScopeOp:
21807 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProcedureScope ", 18);
21808 : 0 : break;
21809 : :
21810 : 0 : case M2Quads_UnboundedOp:
21811 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Unbounded ", 18);
21812 : 0 : break;
21813 : :
21814 : 0 : case M2Quads_CoerceOp:
21815 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Coerce ", 18);
21816 : 0 : break;
21817 : :
21818 : 0 : case M2Quads_ConvertOp:
21819 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Convert ", 18);
21820 : 0 : break;
21821 : :
21822 : 0 : case M2Quads_CastOp:
21823 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Cast ", 18);
21824 : 0 : break;
21825 : :
21826 : 0 : case M2Quads_HighOp:
21827 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "High ", 18);
21828 : 0 : break;
21829 : :
21830 : 0 : case M2Quads_CodeOnOp:
21831 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CodeOn ", 18);
21832 : 0 : break;
21833 : :
21834 : 0 : case M2Quads_CodeOffOp:
21835 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CodeOff ", 18);
21836 : 0 : break;
21837 : :
21838 : 0 : case M2Quads_ProfileOnOp:
21839 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProfileOn ", 18);
21840 : 0 : break;
21841 : :
21842 : 0 : case M2Quads_ProfileOffOp:
21843 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProfileOff ", 18);
21844 : 0 : break;
21845 : :
21846 : 0 : case M2Quads_OptimizeOnOp:
21847 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptimizeOn ", 18);
21848 : 0 : break;
21849 : :
21850 : 0 : case M2Quads_OptimizeOffOp:
21851 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptimizeOff ", 18);
21852 : 0 : break;
21853 : :
21854 : 0 : case M2Quads_InlineOp:
21855 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Inline ", 18);
21856 : 0 : break;
21857 : :
21858 : 0 : case M2Quads_StatementNoteOp:
21859 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StatementNote ", 18);
21860 : 0 : break;
21861 : :
21862 : 0 : case M2Quads_LineNumberOp:
21863 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "LineNumber ", 18);
21864 : 0 : break;
21865 : :
21866 : 0 : case M2Quads_BuiltinConstOp:
21867 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "BuiltinConst ", 18);
21868 : 0 : break;
21869 : :
21870 : 0 : case M2Quads_BuiltinTypeInfoOp:
21871 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "BuiltinTypeInfo ", 18);
21872 : 0 : break;
21873 : :
21874 : 0 : case M2Quads_StandardFunctionOp:
21875 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StandardFunction ", 18);
21876 : 0 : break;
21877 : :
21878 : 0 : case M2Quads_SavePriorityOp:
21879 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SavePriority ", 18);
21880 : 0 : break;
21881 : :
21882 : 0 : case M2Quads_RestorePriorityOp:
21883 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RestorePriority ", 18);
21884 : 0 : break;
21885 : :
21886 : 0 : case M2Quads_RangeCheckOp:
21887 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RangeCheck ", 18);
21888 : 0 : break;
21889 : :
21890 : 0 : case M2Quads_ErrorOp:
21891 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Error ", 18);
21892 : 0 : break;
21893 : :
21894 : 0 : case M2Quads_SaveExceptionOp:
21895 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SaveException ", 18);
21896 : 0 : break;
21897 : :
21898 : 0 : case M2Quads_RestoreExceptionOp:
21899 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RestoreException ", 18);
21900 : 0 : break;
21901 : :
21902 : 0 : case M2Quads_StringConvertCnulOp:
21903 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringConvertCnul ", 18);
21904 : 0 : break;
21905 : :
21906 : 0 : case M2Quads_StringConvertM2nulOp:
21907 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringConvertM2nul", 18);
21908 : 0 : break;
21909 : :
21910 : 0 : case M2Quads_StringLengthOp:
21911 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringLength ", 18);
21912 : 0 : break;
21913 : :
21914 : 0 : case M2Quads_SubrangeHighOp:
21915 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SubrangeHigh ", 18);
21916 : 0 : break;
21917 : :
21918 : 0 : case M2Quads_SubrangeLowOp:
21919 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SubrangeLow ", 18);
21920 : 0 : break;
21921 : :
21922 : :
21923 : 0 : default:
21924 : 0 : M2Error_InternalError ((const char *) "operator not expected", 21);
21925 : 0 : break;
21926 : : }
21927 : 0 : }
21928 : :
21929 : :
21930 : : /*
21931 : : PushAutoOn - push the auto flag and then set it to TRUE.
21932 : : Any call to ident in the parser will result in the token being pushed.
21933 : : */
21934 : :
21935 : 36037632 : extern "C" void M2Quads_PushAutoOn (void)
21936 : : {
21937 : 36037632 : M2StackWord_PushWord (AutoStack, static_cast<unsigned int> (IsAutoOn));
21938 : 36037632 : IsAutoOn = true;
21939 : 36037632 : }
21940 : :
21941 : :
21942 : : /*
21943 : : PushAutoOff - push the auto flag and then set it to FALSE.
21944 : : */
21945 : :
21946 : 64261436 : extern "C" void M2Quads_PushAutoOff (void)
21947 : : {
21948 : 64261436 : M2StackWord_PushWord (AutoStack, static_cast<unsigned int> (IsAutoOn));
21949 : 64261436 : IsAutoOn = false;
21950 : 64261436 : }
21951 : :
21952 : :
21953 : : /*
21954 : : IsAutoPushOn - returns the value of the current Auto ident push flag.
21955 : : */
21956 : :
21957 : 320195813 : extern "C" bool M2Quads_IsAutoPushOn (void)
21958 : : {
21959 : 320195813 : return IsAutoOn;
21960 : : /* static analysis guarentees a RETURN statement will be used before here. */
21961 : : __builtin_unreachable ();
21962 : : }
21963 : :
21964 : :
21965 : : /*
21966 : : PopAuto - restores the previous value of the Auto flag.
21967 : : */
21968 : :
21969 : 100275828 : extern "C" void M2Quads_PopAuto (void)
21970 : : {
21971 : 100275828 : IsAutoOn = static_cast<bool> (M2StackWord_PopWord (AutoStack));
21972 : 100275828 : }
21973 : :
21974 : :
21975 : : /*
21976 : : MustCheckOverflow - returns TRUE if the quadruple should test for overflow.
21977 : : */
21978 : :
21979 : 446289 : extern "C" bool M2Quads_MustCheckOverflow (unsigned int q)
21980 : : {
21981 : 446289 : M2Quads_QuadFrame f;
21982 : :
21983 : 446289 : f = GetQF (q);
21984 : 446289 : return f->CheckOverflow;
21985 : : /* static analysis guarentees a RETURN statement will be used before here. */
21986 : : __builtin_unreachable ();
21987 : : }
21988 : :
21989 : :
21990 : : /*
21991 : : PushInConstExpression - push the InConstExpression flag and then set it to TRUE.
21992 : : */
21993 : :
21994 : 931102 : extern "C" void M2Quads_PushInConstExpression (void)
21995 : : {
21996 : 931102 : M2StackWord_PushWord (ConstExprStack, static_cast<unsigned int> (InConstExpression));
21997 : 931102 : InConstExpression = true;
21998 : 931102 : }
21999 : :
22000 : :
22001 : : /*
22002 : : PopInConstExpression - restores the previous value of the InConstExpression.
22003 : : */
22004 : :
22005 : 931078 : extern "C" void M2Quads_PopInConstExpression (void)
22006 : : {
22007 : 931078 : InConstExpression = static_cast<bool> (M2StackWord_PopWord (ConstExprStack));
22008 : 931078 : }
22009 : :
22010 : :
22011 : : /*
22012 : : IsInConstExpression - returns the value of the InConstExpression.
22013 : : */
22014 : :
22015 : 83850 : extern "C" bool M2Quads_IsInConstExpression (void)
22016 : : {
22017 : 83850 : return InConstExpression;
22018 : : /* static analysis guarentees a RETURN statement will be used before here. */
22019 : : __builtin_unreachable ();
22020 : : }
22021 : :
22022 : :
22023 : : /*
22024 : : PushInConstParameters - push the InConstParameters flag and then set it to TRUE.
22025 : : */
22026 : :
22027 : 1626 : extern "C" void M2Quads_PushInConstParameters (void)
22028 : : {
22029 : 1626 : M2StackWord_PushWord (ConstParamStack, static_cast<unsigned int> (InConstParameters));
22030 : 1626 : InConstParameters = true;
22031 : 1626 : }
22032 : :
22033 : :
22034 : : /*
22035 : : PopInConstParameters - restores the previous value of the InConstParameters.
22036 : : */
22037 : :
22038 : 1626 : extern "C" void M2Quads_PopInConstParameters (void)
22039 : : {
22040 : 1626 : InConstParameters = static_cast<bool> (M2StackWord_PopWord (ConstParamStack));
22041 : 1626 : }
22042 : :
22043 : :
22044 : : /*
22045 : : IsInConstParameters - returns the value of the InConstParameters.
22046 : : */
22047 : :
22048 : 65794 : extern "C" bool M2Quads_IsInConstParameters (void)
22049 : : {
22050 : 65794 : return InConstParameters;
22051 : : /* static analysis guarentees a RETURN statement will be used before here. */
22052 : : __builtin_unreachable ();
22053 : : }
22054 : :
22055 : :
22056 : : /*
22057 : : BuildAsmElement - the stack is expected to contain:
22058 : :
22059 : :
22060 : : Entry Exit
22061 : : ===== ====
22062 : :
22063 : : Ptr ->
22064 : : +------------------+
22065 : : | expr | tokpos |
22066 : : |------------------|
22067 : : | str |
22068 : : |------------------|
22069 : : | name |
22070 : : |------------------| +------------------+
22071 : : | CurrentInterface | | CurrentInterface |
22072 : : |------------------| |------------------|
22073 : : | CurrentAsm | | CurrentAsm |
22074 : : |------------------| |------------------|
22075 : : | n | | n |
22076 : : |------------------| |------------------|
22077 : : */
22078 : :
22079 : 24 : extern "C" void M2Quads_BuildAsmElement (bool input, bool output)
22080 : : {
22081 : 24 : DynamicStrings_String s;
22082 : 24 : unsigned int n;
22083 : 24 : unsigned int str;
22084 : 24 : unsigned int expr;
22085 : 24 : unsigned int tokpos;
22086 : 24 : unsigned int CurrentInterface;
22087 : 24 : unsigned int CurrentAsm;
22088 : 24 : unsigned int name;
22089 : :
22090 : 24 : M2Quads_PopTtok (&expr, &tokpos);
22091 : 24 : M2Quads_PopT (&str);
22092 : 24 : M2Quads_PopT (&name);
22093 : 24 : M2Quads_PopT (&CurrentInterface);
22094 : 24 : M2Quads_PopT (&CurrentAsm);
22095 : 48 : M2Debug_Assert ((SymbolTable_IsGnuAsm (CurrentAsm)) || (SymbolTable_IsGnuAsmVolatile (CurrentAsm)));
22096 : 24 : M2Quads_PopT (&n);
22097 : 24 : n += 1;
22098 : 24 : if (CurrentInterface == SymbolTable_NulSym)
22099 : : {
22100 : 24 : CurrentInterface = SymbolTable_MakeRegInterface ();
22101 : : }
22102 : 24 : if (input)
22103 : : {
22104 : 12 : SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, name, str, expr, NextQuad, 0);
22105 : 12 : if (DebugAsmTokPos)
22106 : : {
22107 : : s = DynamicStrings_InitString ((const char *) "input expression", 16);
22108 : : M2Error_WarnStringAt (s, tokpos);
22109 : : }
22110 : : }
22111 : 24 : if (output)
22112 : : {
22113 : 12 : SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, name, str, expr, 0, NextQuad);
22114 : 12 : if (DebugAsmTokPos)
22115 : : {
22116 : : s = DynamicStrings_InitString ((const char *) "output expression", 17);
22117 : : M2Error_WarnStringAt (s, tokpos);
22118 : : }
22119 : : }
22120 : 24 : M2Quads_PushT (n);
22121 : 24 : M2Quads_PushT (CurrentAsm);
22122 : 24 : M2Quads_PushT (CurrentInterface);
22123 : 24 : }
22124 : :
22125 : :
22126 : : /*
22127 : : BuildAsmTrash - the stack is expected to contain:
22128 : :
22129 : :
22130 : : Entry Exit
22131 : : ===== ====
22132 : :
22133 : : Ptr ->
22134 : : +------------------+
22135 : : | expr | tokpos |
22136 : : |------------------| +------------------+
22137 : : | CurrentInterface | | CurrentInterface |
22138 : : |------------------| |------------------|
22139 : : | CurrentAsm | | CurrentAsm |
22140 : : |------------------| |------------------|
22141 : : | n | | n |
22142 : : |------------------| |------------------|
22143 : : */
22144 : :
22145 : 0 : extern "C" void M2Quads_BuildAsmTrash (void)
22146 : : {
22147 : 0 : unsigned int n;
22148 : 0 : unsigned int expr;
22149 : 0 : unsigned int tokpos;
22150 : 0 : unsigned int CurrentInterface;
22151 : 0 : unsigned int CurrentAsm;
22152 : :
22153 : 0 : M2Quads_PopTtok (&expr, &tokpos);
22154 : 0 : M2Quads_PopT (&CurrentInterface);
22155 : 0 : M2Quads_PopT (&CurrentAsm);
22156 : 0 : M2Debug_Assert ((SymbolTable_IsGnuAsm (CurrentAsm)) || (SymbolTable_IsGnuAsmVolatile (CurrentAsm)));
22157 : 0 : M2Quads_PopT (&n);
22158 : 0 : n += 1;
22159 : 0 : if (CurrentInterface == SymbolTable_NulSym)
22160 : : {
22161 : 0 : CurrentInterface = SymbolTable_MakeRegInterface ();
22162 : : }
22163 : 0 : SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, NameKey_NulName, SymbolTable_NulSym, expr, 0, NextQuad);
22164 : 0 : M2Quads_PushT (n);
22165 : 0 : M2Quads_PushT (CurrentAsm);
22166 : 0 : M2Quads_PushT (CurrentInterface);
22167 : 0 : }
22168 : :
22169 : :
22170 : : /*
22171 : : GetQuadTrash - return the symbol associated with the trashed operand.
22172 : : */
22173 : :
22174 : 120 : extern "C" unsigned int M2Quads_GetQuadTrash (unsigned int quad)
22175 : : {
22176 : 120 : M2Quads_QuadFrame f;
22177 : :
22178 : 120 : f = GetQF (quad);
22179 : 120 : LastQuadNo = quad;
22180 : 120 : return f->Trash;
22181 : : /* static analysis guarentees a RETURN statement will be used before here. */
22182 : : __builtin_unreachable ();
22183 : : }
22184 : :
22185 : 15392 : extern "C" void _M2_M2Quads_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
22186 : : {
22187 : 15392 : Init ();
22188 : 15392 : }
22189 : :
22190 : 0 : extern "C" void _M2_M2Quads_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
22191 : : {
22192 : 0 : }
|