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 : : #include "config.h"
24 : : #include "system.h"
25 : : #include "gcc-consolidation.h"
26 : :
27 : : #include <stdbool.h>
28 : : # if !defined (PROC_D)
29 : : # define PROC_D
30 : : typedef void (*PROC_t) (void);
31 : : typedef struct { PROC_t proc; } PROC;
32 : : # endif
33 : :
34 : : # if !defined (TRUE)
35 : : # define TRUE (1==1)
36 : : # endif
37 : :
38 : : # if !defined (FALSE)
39 : : # define FALSE (1==0)
40 : : # endif
41 : :
42 : : # include "GStorage.h"
43 : : # include "Gmcrts.h"
44 : : #if defined(__cplusplus)
45 : : # undef NULL
46 : : # define NULL 0
47 : : #endif
48 : : #define _M2Quads_C
49 : :
50 : : #include "GM2Quads.h"
51 : : # include "GStorage.h"
52 : : # include "GM2Debug.h"
53 : : # include "GNameKey.h"
54 : : # include "GFormatStrings.h"
55 : : # include "GM2DebugStack.h"
56 : : # include "GStrLib.h"
57 : : # include "GM2Scaffold.h"
58 : : # include "GM2MetaError.h"
59 : : # include "GDynamicStrings.h"
60 : : # include "GSymbolTable.h"
61 : : # include "GM2Batch.h"
62 : : # include "GM2GCCDeclare.h"
63 : : # include "GFifoQueue.h"
64 : : # include "GM2Comp.h"
65 : : # include "GM2LexBuf.h"
66 : : # include "GM2Error.h"
67 : : # include "GM2Printf.h"
68 : : # include "GM2Reserved.h"
69 : : # include "GM2Base.h"
70 : : # include "GM2System.h"
71 : : # include "GM2Size.h"
72 : : # include "GM2Bitset.h"
73 : : # include "GM2ALU.h"
74 : : # include "GLists.h"
75 : : # include "GM2Options.h"
76 : : # include "GM2LangDump.h"
77 : : # include "GM2Pass.h"
78 : : # include "GM2StackAddress.h"
79 : : # include "GM2StackWord.h"
80 : : # include "GIndexing.h"
81 : : # include "GM2Range.h"
82 : : # include "GM2CaseList.h"
83 : : # include "GPCSymBuild.h"
84 : : # include "Gm2builtins.h"
85 : : # include "GSymbolConversion.h"
86 : : # include "GM2Diagnostic.h"
87 : : # include "GFIO.h"
88 : : # include "GSFIO.h"
89 : : # include "GStdIO.h"
90 : : # include "GM2StackSpell.h"
91 : :
92 : : # define DebugStackOn true
93 : : # define DebugVarients false
94 : : # define DebugTokPos false
95 : : typedef struct M2Quads__T1_r M2Quads__T1;
96 : :
97 : : typedef M2Quads__T1 *M2Quads_ConstructorFrame;
98 : :
99 : : typedef struct M2Quads__T2_r M2Quads__T2;
100 : :
101 : : typedef M2Quads__T2 *M2Quads_BoolFrame;
102 : :
103 : : typedef struct M2Quads__T3_r M2Quads__T3;
104 : :
105 : : typedef M2Quads__T3 *M2Quads_QuadFrame;
106 : :
107 : : typedef struct M2Quads__T4_r M2Quads__T4;
108 : :
109 : : typedef M2Quads__T4 *M2Quads_WithFrame;
110 : :
111 : : typedef struct M2Quads__T5_r M2Quads__T5;
112 : :
113 : : typedef M2Quads__T5 *M2Quads_ForLoopInfo;
114 : :
115 : : typedef struct M2Quads__T6_r M2Quads__T6;
116 : :
117 : : typedef M2Quads__T6 *M2Quads_LineNote;
118 : :
119 : : # define DebugAsmTokPos false
120 : : struct M2Quads__T1_r {
121 : : unsigned int type;
122 : : unsigned int index;
123 : : };
124 : :
125 : : struct M2Quads__T2_r {
126 : : unsigned int TrueExit;
127 : : unsigned int FalseExit;
128 : : unsigned int Unbounded;
129 : : bool BooleanOp;
130 : : unsigned int Dimension;
131 : : unsigned int ReadWrite;
132 : : unsigned int name;
133 : : unsigned int RangeDep;
134 : : DynamicStrings_String Annotation;
135 : : unsigned int tokenno;
136 : : };
137 : :
138 : : struct M2Quads__T3_r {
139 : : M2Quads_QuadOperator Operator;
140 : : unsigned int Operand1;
141 : : unsigned int Operand2;
142 : : unsigned int Operand3;
143 : : unsigned int Trash;
144 : : unsigned int Next;
145 : : unsigned int LineNo;
146 : : unsigned int TokenNo;
147 : : unsigned int NoOfTimesReferenced;
148 : : bool ConstExpr;
149 : : bool CheckType;
150 : : bool CheckOverflow;
151 : : unsigned int op1pos;
152 : : unsigned int op2pos;
153 : : unsigned int op3pos;
154 : : };
155 : :
156 : : struct M2Quads__T4_r {
157 : : unsigned int RecordSym;
158 : : unsigned int RecordType;
159 : : unsigned int RecordRef;
160 : : unsigned int rw;
161 : : unsigned int RecordTokPos;
162 : : };
163 : :
164 : : struct M2Quads__T5_r {
165 : : unsigned int IncrementQuad;
166 : : unsigned int StartOfForLoop;
167 : : unsigned int EndOfForLoop;
168 : : unsigned int ForLoopIndex;
169 : : unsigned int IndexTok;
170 : : };
171 : :
172 : : struct M2Quads__T6_r {
173 : : unsigned int Line;
174 : : NameKey_Name File;
175 : : M2Quads_LineNote Next;
176 : : };
177 : :
178 : : static M2StackAddress_StackOfAddress ConstructorStack;
179 : : static M2StackAddress_StackOfAddress LineStack;
180 : : static M2StackAddress_StackOfAddress BoolStack;
181 : : static M2StackAddress_StackOfAddress WithStack;
182 : : static M2StackWord_StackOfWord TryStack;
183 : : static M2StackWord_StackOfWord CatchStack;
184 : : static M2StackWord_StackOfWord ExceptStack;
185 : : static M2StackWord_StackOfWord ConstExprStack;
186 : : static M2StackWord_StackOfWord ConstParamStack;
187 : : static M2StackWord_StackOfWord AutoStack;
188 : : static M2StackWord_StackOfWord RepeatStack;
189 : : static M2StackWord_StackOfWord WhileStack;
190 : : static M2StackWord_StackOfWord ForStack;
191 : : static M2StackWord_StackOfWord ExitStack;
192 : : static M2StackWord_StackOfWord ReturnStack;
193 : : static M2StackWord_StackOfWord PriorityStack;
194 : : static bool SuppressWith;
195 : : static Indexing_Index QuadArray;
196 : : static unsigned int NextQuad;
197 : : static unsigned int FreeList;
198 : : static unsigned int CurrentProc;
199 : : static unsigned int InitQuad;
200 : : static unsigned int LastQuadNo;
201 : : static NameKey_Name ArithPlusTok;
202 : : static NameKey_Name LogicalOrTok;
203 : : static NameKey_Name LogicalAndTok;
204 : : static NameKey_Name LogicalXorTok;
205 : : static NameKey_Name LogicalDifferenceTok;
206 : : static bool InConstExpression;
207 : : static bool InConstParameters;
208 : : static bool IsAutoOn;
209 : : static bool MustNotCheckBounds;
210 : : static Indexing_Index ForInfo;
211 : : static unsigned int GrowInitialization;
212 : : static bool BuildingHigh;
213 : : static bool BuildingSize;
214 : : static bool QuadrupleGeneration;
215 : : static M2Quads_LineNote FreeLineList;
216 : : static Lists_List VarientFields;
217 : : static unsigned int VarientFieldNo;
218 : : static unsigned int NoOfQuads;
219 : : static unsigned int Head;
220 : : static M2Diagnostic_Diagnostic QuadMemDiag;
221 : : static unsigned int BreakQuad;
222 : :
223 : : /*
224 : : SetOptionCoding - builds a code quadruple if the profiling
225 : : option was given to the compiler.
226 : : */
227 : :
228 : : extern "C" void M2Quads_SetOptionCoding (bool b);
229 : :
230 : : /*
231 : : SetOptionProfiling - builds a profile quadruple if the profiling
232 : : option was given to the compiler.
233 : : */
234 : :
235 : : extern "C" void M2Quads_SetOptionProfiling (bool b);
236 : :
237 : : /*
238 : : SetOptionOptimizing - builds a quadruple to say that the optimization option
239 : : has been found in a comment.
240 : : */
241 : :
242 : : extern "C" void M2Quads_SetOptionOptimizing (bool b);
243 : :
244 : : /*
245 : : Opposite - returns the opposite comparison operator.
246 : : */
247 : :
248 : : extern "C" M2Quads_QuadOperator M2Quads_Opposite (M2Quads_QuadOperator Operator);
249 : :
250 : : /*
251 : : IsReferenced - returns true if QuadNo is referenced by another quadruple.
252 : : */
253 : :
254 : : extern "C" bool M2Quads_IsReferenced (unsigned int QuadNo);
255 : :
256 : : /*
257 : : IsBackReference - returns TRUE if quadruple, q, is referenced from a quad further on.
258 : : */
259 : :
260 : : extern "C" bool M2Quads_IsBackReference (unsigned int q);
261 : :
262 : : /*
263 : : IsUnConditional - returns true if QuadNo is an unconditional jump.
264 : : */
265 : :
266 : : extern "C" bool M2Quads_IsUnConditional (unsigned int QuadNo);
267 : :
268 : : /*
269 : : IsConditional - returns true if QuadNo is a conditional jump.
270 : : */
271 : :
272 : : extern "C" bool M2Quads_IsConditional (unsigned int QuadNo);
273 : :
274 : : /*
275 : : IsBackReferenceConditional - returns TRUE if quadruple, q, is referenced from
276 : : a conditional quad further on.
277 : : */
278 : :
279 : : extern "C" bool M2Quads_IsBackReferenceConditional (unsigned int q);
280 : :
281 : : /*
282 : : IsGoto - returns true if QuadNo is a goto operation.
283 : : */
284 : :
285 : : extern "C" bool M2Quads_IsGoto (unsigned int QuadNo);
286 : :
287 : : /*
288 : : IsCall - returns true if QuadNo is a call operation.
289 : : */
290 : :
291 : : extern "C" bool M2Quads_IsCall (unsigned int QuadNo);
292 : :
293 : : /*
294 : : IsReturn - returns true if QuadNo is a return operation.
295 : : */
296 : :
297 : : extern "C" bool M2Quads_IsReturn (unsigned int QuadNo);
298 : :
299 : : /*
300 : : IsProcedureScope - returns true if QuadNo is a ProcedureScope operation.
301 : : */
302 : :
303 : : extern "C" bool M2Quads_IsProcedureScope (unsigned int QuadNo);
304 : :
305 : : /*
306 : : IsNewLocalVar - returns true if QuadNo is a NewLocalVar operation.
307 : : */
308 : :
309 : : extern "C" bool M2Quads_IsNewLocalVar (unsigned int QuadNo);
310 : :
311 : : /*
312 : : IsKillLocalVar - returns true if QuadNo is a KillLocalVar operation.
313 : : */
314 : :
315 : : extern "C" bool M2Quads_IsKillLocalVar (unsigned int QuadNo);
316 : :
317 : : /*
318 : : IsCatchBegin - returns true if QuadNo is a catch begin quad.
319 : : */
320 : :
321 : : extern "C" bool M2Quads_IsCatchBegin (unsigned int QuadNo);
322 : :
323 : : /*
324 : : IsCatchEnd - returns true if QuadNo is a catch end quad.
325 : : */
326 : :
327 : : extern "C" bool M2Quads_IsCatchEnd (unsigned int QuadNo);
328 : :
329 : : /*
330 : : IsInitStart - returns true if QuadNo is a init start quad.
331 : : */
332 : :
333 : : extern "C" bool M2Quads_IsInitStart (unsigned int QuadNo);
334 : :
335 : : /*
336 : : IsInitEnd - returns true if QuadNo is a init end quad.
337 : : */
338 : :
339 : : extern "C" bool M2Quads_IsInitEnd (unsigned int QuadNo);
340 : :
341 : : /*
342 : : IsFinallyStart - returns true if QuadNo is a finally start quad.
343 : : */
344 : :
345 : : extern "C" bool M2Quads_IsFinallyStart (unsigned int QuadNo);
346 : :
347 : : /*
348 : : IsFinallyEnd - returns true if QuadNo is a finally end quad.
349 : : */
350 : :
351 : : extern "C" bool M2Quads_IsFinallyEnd (unsigned int QuadNo);
352 : :
353 : : /*
354 : : IsBecomes - return TRUE if QuadNo is a BecomesOp.
355 : : */
356 : :
357 : : extern "C" bool M2Quads_IsBecomes (unsigned int QuadNo);
358 : :
359 : : /*
360 : : IsDummy - return TRUE if QuadNo is a DummyOp.
361 : : */
362 : :
363 : : extern "C" bool M2Quads_IsDummy (unsigned int QuadNo);
364 : :
365 : : /*
366 : : IsQuadConstExpr - returns TRUE if QuadNo is part of a constant expression.
367 : : */
368 : :
369 : : extern "C" bool M2Quads_IsQuadConstExpr (unsigned int QuadNo);
370 : :
371 : : /*
372 : : SetQuadConstExpr - sets the constexpr field to value.
373 : : */
374 : :
375 : : extern "C" void M2Quads_SetQuadConstExpr (unsigned int QuadNo, bool value);
376 : :
377 : : /*
378 : : GetQuadDest - returns the jump destination associated with quad.
379 : : */
380 : :
381 : : extern "C" unsigned int M2Quads_GetQuadDest (unsigned int QuadNo);
382 : :
383 : : /*
384 : : GetQuadOp1 - returns the 1st operand associated with quad.
385 : : */
386 : :
387 : : extern "C" unsigned int M2Quads_GetQuadOp1 (unsigned int QuadNo);
388 : :
389 : : /*
390 : : GetQuadOp2 - returns the 2nd operand associated with quad.
391 : : */
392 : :
393 : : extern "C" unsigned int M2Quads_GetQuadOp2 (unsigned int QuadNo);
394 : :
395 : : /*
396 : : GetQuadOp3 - returns the 3rd operand associated with quad.
397 : : */
398 : :
399 : : extern "C" unsigned int M2Quads_GetQuadOp3 (unsigned int QuadNo);
400 : :
401 : : /*
402 : : IsInitialisingConst - returns TRUE if the quadruple is setting
403 : : a const (op1) with a value.
404 : : */
405 : :
406 : : extern "C" bool M2Quads_IsInitialisingConst (unsigned int QuadNo);
407 : :
408 : : /*
409 : : IsConstQuad - return TRUE if the quadruple is marked as a constexpr.
410 : : */
411 : :
412 : : extern "C" bool M2Quads_IsConstQuad (unsigned int quad);
413 : :
414 : : /*
415 : : IsConditionalBooleanQuad - return TRUE if operand 1 is a boolean result.
416 : : */
417 : :
418 : : extern "C" bool M2Quads_IsConditionalBooleanQuad (unsigned int quad);
419 : :
420 : : /*
421 : : IsOptimizeOn - returns true if the Optimize flag was true at QuadNo.
422 : : */
423 : :
424 : : extern "C" bool M2Quads_IsOptimizeOn (unsigned int QuadNo);
425 : :
426 : : /*
427 : : IsProfileOn - returns true if the Profile flag was true at QuadNo.
428 : : */
429 : :
430 : : extern "C" bool M2Quads_IsProfileOn (unsigned int QuadNo);
431 : :
432 : : /*
433 : : IsCodeOn - returns true if the Code flag was true at QuadNo.
434 : : */
435 : :
436 : : extern "C" bool M2Quads_IsCodeOn (unsigned int QuadNo);
437 : :
438 : : /*
439 : : IsPseudoQuad - returns true if QuadNo is a compiler directive.
440 : : ie code, profile and optimize.
441 : : StartFile, EndFile,
442 : : */
443 : :
444 : : extern "C" bool M2Quads_IsPseudoQuad (unsigned int QuadNo);
445 : :
446 : : /*
447 : : IsDefOrModFile - returns TRUE if QuadNo is a start of Module or Def file
448 : : directive.
449 : : */
450 : :
451 : : extern "C" bool M2Quads_IsDefOrModFile (unsigned int QuadNo);
452 : :
453 : : /*
454 : : DumpQuadruples - dump all quadruples providing the -fq, -fdump-lang-quad,
455 : : -fdump-lang-quad= or -fdump-lang-all were issued to the
456 : : command line.
457 : : */
458 : :
459 : : extern "C" void M2Quads_DumpQuadruples (const char *title_, unsigned int _title_high);
460 : :
461 : : /*
462 : : DisplayQuadRange - displays all quads in list range, start..end.
463 : : */
464 : :
465 : : extern "C" void M2Quads_DisplayQuadRange (unsigned int scope, unsigned int start, unsigned int end);
466 : :
467 : : /*
468 : : DisplayQuad - displays a quadruple, QuadNo.
469 : : */
470 : :
471 : : extern "C" void M2Quads_DisplayQuad (unsigned int QuadNo);
472 : :
473 : : /*
474 : : GetLastFileQuad - returns the Quadruple number of the last StartDefFile or
475 : : StartModFile quadruple.
476 : : */
477 : :
478 : : extern "C" unsigned int M2Quads_GetLastFileQuad (unsigned int QuadNo);
479 : :
480 : : /*
481 : : GetLastQuadNo - returns the last quadruple number referenced
482 : : by a GetQuad.
483 : : */
484 : :
485 : : extern "C" unsigned int M2Quads_GetLastQuadNo (void);
486 : :
487 : : /*
488 : : QuadToTokenNo - Converts a QuadNo into the approprate token number of the
489 : : source file, the line number is returned.
490 : :
491 : : This may be used to yield an idea where abouts in the
492 : : source file the code generetion is
493 : : processing.
494 : : */
495 : :
496 : : extern "C" unsigned int M2Quads_QuadToTokenNo (unsigned int QuadNo);
497 : :
498 : : /*
499 : : QuadToLineNo - Converts a QuadNo into the approprate line number of the
500 : : source file, the line number is returned.
501 : :
502 : : This may be used to yield an idea where abouts in the
503 : : source file the code generetion is
504 : : processing.
505 : : */
506 : :
507 : : extern "C" unsigned int M2Quads_QuadToLineNo (unsigned int QuadNo);
508 : :
509 : : /*
510 : : GetQuad - returns the Quadruple QuadNo.
511 : : */
512 : :
513 : : extern "C" void M2Quads_GetQuad (unsigned int QuadNo, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3);
514 : :
515 : : /*
516 : : GetQuadOp - returns the operator for quad.
517 : : */
518 : :
519 : : extern "C" M2Quads_QuadOperator M2Quads_GetQuadOp (unsigned int quad);
520 : :
521 : : /*
522 : : GetM2OperatorDesc - returns the Modula-2 string associated with the quad operator
523 : : (if possible). It returns NIL if no there is not an obvious match
524 : : in Modula-2. It is assummed that the string will be used during
525 : : construction of error messages and therefore keywords are
526 : : wrapped with a format specifier.
527 : : */
528 : :
529 : : extern "C" DynamicStrings_String M2Quads_GetM2OperatorDesc (M2Quads_QuadOperator op);
530 : :
531 : : /*
532 : : GetQuadtok - returns the Quadruple QuadNo.
533 : : */
534 : :
535 : : extern "C" void M2Quads_GetQuadtok (unsigned int QuadNo, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3, unsigned int *Op1Pos, unsigned int *Op2Pos, unsigned int *Op3Pos);
536 : :
537 : : /*
538 : : GetQuadOtok - returns the Quadruple QuadNo.
539 : : */
540 : :
541 : : extern "C" void M2Quads_GetQuadOtok (unsigned int QuadNo, unsigned int *tok, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3, bool *overflowChecking, bool *constExpr, unsigned int *Op1Pos, unsigned int *Op2Pos, unsigned int *Op3Pos);
542 : :
543 : : /*
544 : : GetQuadOTypetok - returns the fields associated with quadruple QuadNo.
545 : : */
546 : :
547 : : extern "C" void M2Quads_GetQuadOTypetok (unsigned int QuadNo, unsigned int *tok, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3, bool *overflowChecking, bool *typeChecking, bool *constExpr, unsigned int *Op1Pos, unsigned int *Op2Pos, unsigned int *Op3Pos);
548 : :
549 : : /*
550 : : PutQuadOtok - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
551 : : sets a boolean to determinine whether overflow should be checked.
552 : : */
553 : :
554 : : extern "C" void M2Quads_PutQuadOtok (unsigned int QuadNo, unsigned int tok, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflowChecking, bool constExpr, unsigned int Op1Pos, unsigned int Op2Pos, unsigned int Op3Pos);
555 : :
556 : : /*
557 : : PutQuad - overwrites a quadruple QuadNo with Op, Oper1, Oper2, Oper3
558 : : */
559 : :
560 : : extern "C" void M2Quads_PutQuad (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3);
561 : :
562 : : /*
563 : : GetFirstQuad - returns the first quadruple.
564 : : */
565 : :
566 : : extern "C" unsigned int M2Quads_GetFirstQuad (void);
567 : :
568 : : /*
569 : : GetNextQuad - returns the Quadruple number following QuadNo.
570 : : */
571 : :
572 : : extern "C" unsigned int M2Quads_GetNextQuad (unsigned int QuadNo);
573 : :
574 : : /*
575 : : GetRealQuad - returns the Quadruple number of the real quadruple
576 : : at QuadNo or beyond.
577 : : */
578 : :
579 : : extern "C" unsigned int M2Quads_GetRealQuad (unsigned int QuadNo);
580 : :
581 : : /*
582 : : SubQuad - subtracts a quadruple QuadNo from a list Head.
583 : : */
584 : :
585 : : extern "C" void M2Quads_SubQuad (unsigned int QuadNo);
586 : :
587 : : /*
588 : : EraseQuad - erases a quadruple QuadNo, the quadruple is still in the list
589 : : but wiped clean.
590 : : */
591 : :
592 : : extern "C" void M2Quads_EraseQuad (unsigned int QuadNo);
593 : :
594 : : /*
595 : : CountQuads - returns the number of quadruples.
596 : : */
597 : :
598 : : extern "C" unsigned int M2Quads_CountQuads (void);
599 : :
600 : : /*
601 : : BuildScaffold - generate the main, init, finish functions if
602 : : no -c and this is the application module.
603 : : */
604 : :
605 : : extern "C" void M2Quads_BuildScaffold (unsigned int tok, unsigned int moduleSym);
606 : :
607 : : /*
608 : : StartBuildDefFile - generates a StartFileDefOp quadruple indicating the file
609 : : that has produced the subsequent quadruples.
610 : : The code generator uses the StartDefFileOp quadruples
611 : : to relate any error to the appropriate file.
612 : :
613 : :
614 : : Entry Exit
615 : : ===== ====
616 : :
617 : :
618 : : Ptr -> <- Ptr
619 : : +------------+ +------------+
620 : : | ModuleName | | ModuleName |
621 : : |------------| |------------|
622 : :
623 : :
624 : : Quadruples Produced
625 : :
626 : : q StartDefFileOp _ _ ModuleSym
627 : : */
628 : :
629 : : extern "C" void M2Quads_StartBuildDefFile (unsigned int tok);
630 : :
631 : : /*
632 : : StartBuildModFile - generates a StartModFileOp quadruple indicating the file
633 : : that has produced the subsequent quadruples.
634 : : The code generator uses the StartModFileOp quadruples
635 : : to relate any error to the appropriate file.
636 : :
637 : :
638 : : Entry Exit
639 : : ===== ====
640 : :
641 : :
642 : : Ptr -> <- Ptr
643 : : +------------+ +------------+
644 : : | ModuleName | | ModuleName |
645 : : |------------| |------------|
646 : :
647 : :
648 : : Quadruples Produced
649 : :
650 : : q StartModFileOp lineno filename ModuleSym
651 : : */
652 : :
653 : : extern "C" void M2Quads_StartBuildModFile (unsigned int tok);
654 : :
655 : : /*
656 : : EndBuildFile - generates an EndFileOp quadruple indicating the file
657 : : that has produced the previous quadruples has ended.
658 : :
659 : : Entry Exit
660 : : ===== ====
661 : :
662 : :
663 : : Ptr -> <- Ptr
664 : : +------------+ +------------+
665 : : | ModuleName | | ModuleName |
666 : : |------------| |------------|
667 : :
668 : :
669 : : Quadruples Produced
670 : :
671 : : q EndFileOp _ _ ModuleSym
672 : : */
673 : :
674 : : extern "C" void M2Quads_EndBuildFile (unsigned int tok);
675 : :
676 : : /*
677 : : StartBuildInit - Sets the start of initialization code of the
678 : : current module to the next quadruple.
679 : : */
680 : :
681 : : extern "C" void M2Quads_StartBuildInit (unsigned int tok);
682 : :
683 : : /*
684 : : EndBuildInit - Sets the end initialization code of a module.
685 : : */
686 : :
687 : : extern "C" void M2Quads_EndBuildInit (unsigned int tok);
688 : :
689 : : /*
690 : : StartBuildFinally - Sets the start of finalization code of the
691 : : current module to the next quadruple.
692 : : */
693 : :
694 : : extern "C" void M2Quads_StartBuildFinally (unsigned int tok);
695 : :
696 : : /*
697 : : EndBuildFinally - Sets the end finalization code of a module.
698 : : */
699 : :
700 : : extern "C" void M2Quads_EndBuildFinally (unsigned int tok);
701 : :
702 : : /*
703 : : BuildExceptInitial - adds an CatchBeginOp, CatchEndOp quadruple
704 : : in the current block.
705 : : */
706 : :
707 : : extern "C" void M2Quads_BuildExceptInitial (unsigned int tok);
708 : :
709 : : /*
710 : : BuildExceptFinally - adds an ExceptOp quadruple in a modules
711 : : finally block.
712 : : */
713 : :
714 : : extern "C" void M2Quads_BuildExceptFinally (unsigned int tok);
715 : :
716 : : /*
717 : : BuildExceptProcedure - adds an ExceptOp quadruple in a procedure
718 : : block.
719 : : */
720 : :
721 : : extern "C" void M2Quads_BuildExceptProcedure (unsigned int tok);
722 : :
723 : : /*
724 : : BuildRetry - adds an RetryOp quadruple.
725 : : */
726 : :
727 : : extern "C" void M2Quads_BuildRetry (unsigned int tok);
728 : :
729 : : /*
730 : : BuildReThrow - creates a ThrowOp _ _ NulSym, indicating that
731 : : the exception needs to be rethrown. The stack
732 : : is unaltered.
733 : : */
734 : :
735 : : extern "C" void M2Quads_BuildReThrow (unsigned int tokenno);
736 : :
737 : : /*
738 : : StartBuildInnerInit - Sets the start of initialization code of the
739 : : inner module to the next quadruple.
740 : : */
741 : :
742 : : extern "C" void M2Quads_StartBuildInnerInit (unsigned int tok);
743 : :
744 : : /*
745 : : EndBuildInnerInit - Sets the end initialization code of a module.
746 : : */
747 : :
748 : : extern "C" void M2Quads_EndBuildInnerInit (unsigned int tok);
749 : :
750 : : /*
751 : : BuildBuiltinConst - makes reference to a builtin constant within gm2.
752 : :
753 : : Entry Exit
754 : :
755 : : Ptr ->
756 : : +------------+ +------------+
757 : : | Ident | | Sym |
758 : : |------------| |------------|
759 : :
760 : : Quadruple produced:
761 : :
762 : : q Sym BuiltinConstOp Ident
763 : : */
764 : :
765 : : extern "C" void M2Quads_BuildBuiltinConst (void);
766 : :
767 : : /*
768 : : BuildBuiltinTypeInfo - make reference to a builtin typeinfo function
769 : : within gm2.
770 : :
771 : : Entry Exit
772 : :
773 : : Ptr ->
774 : : +-------------+
775 : : | Type |
776 : : |-------------| +------------+
777 : : | Ident | | Sym |
778 : : |-------------| |------------|
779 : :
780 : : Quadruple produced:
781 : :
782 : : q Sym BuiltinTypeInfoOp Type Ident
783 : : */
784 : :
785 : : extern "C" void M2Quads_BuildBuiltinTypeInfo (void);
786 : :
787 : : /*
788 : : BuildAssignment - Builds an assignment from the values given on the
789 : : quad stack. Either an assignment to an
790 : : arithmetic expression or an assignment to a
791 : : boolean expression. This procedure should not
792 : : be called in CONST declarations.
793 : : The Stack is expected to contain:
794 : :
795 : :
796 : : Either
797 : :
798 : : Entry Exit
799 : : ===== ====
800 : :
801 : : Ptr ->
802 : : +------------+
803 : : | Expression |
804 : : |------------|
805 : : | Designator |
806 : : |------------| +------------+
807 : : | | | | <- Ptr
808 : : |------------| |------------|
809 : :
810 : :
811 : : Quadruples Produced
812 : :
813 : : q BecomesOp Designator _ Expression
814 : :
815 : : OR
816 : :
817 : : Entry Exit
818 : : ===== ====
819 : :
820 : : Ptr ->
821 : : +------------+
822 : : | True |False|
823 : : |------------|
824 : : | Designator |
825 : : |------------| +------------+
826 : : | | | | <- Ptr
827 : : |------------| |------------|
828 : :
829 : :
830 : : Quadruples Produced
831 : :
832 : : q BecomesOp Designator _ TRUE
833 : : q+1 GotoOp q+3
834 : : q+2 BecomesOp Designator _ FALSE
835 : :
836 : : */
837 : :
838 : : extern "C" void M2Quads_BuildAssignment (unsigned int becomesTokNo);
839 : :
840 : : /*
841 : : BuildAssignConstant - used to create constant in the CONST declaration.
842 : : The stack is expected to contain:
843 : :
844 : : Either
845 : :
846 : : Entry Exit
847 : : ===== ====
848 : :
849 : : Ptr ->
850 : : +------------+
851 : : | Expression |
852 : : |------------|
853 : : | Designator |
854 : : |------------| +------------+
855 : : | | | | <- Ptr
856 : : |------------| |------------|
857 : :
858 : :
859 : : Quadruples Produced
860 : :
861 : : q BecomesOp Designator _ Expression
862 : :
863 : : OR
864 : :
865 : : Entry Exit
866 : : ===== ====
867 : :
868 : : Ptr ->
869 : : +------------+
870 : : | True |False|
871 : : |------------|
872 : : | Designator |
873 : : |------------| +------------+
874 : : | | | | <- Ptr
875 : : |------------| |------------|
876 : :
877 : :
878 : : Quadruples Produced
879 : :
880 : : q BecomesOp Designator _ TRUE
881 : : q+1 GotoOp q+3
882 : : q+2 BecomesOp Designator _ FALSE
883 : : */
884 : :
885 : : extern "C" void M2Quads_BuildAssignConstant (unsigned int equalsTokNo);
886 : :
887 : : /*
888 : : BuildAlignment - builds an assignment to an alignment constant.
889 : :
890 : : The Stack is expected to contain:
891 : :
892 : :
893 : : Entry Exit
894 : : ===== ====
895 : :
896 : : Ptr ->
897 : : +---------------+
898 : : | Expression |
899 : : |---------------|
900 : : | bytealignment |
901 : : |---------------| empty
902 : : */
903 : :
904 : : extern "C" void M2Quads_BuildAlignment (unsigned int tokno);
905 : :
906 : : /*
907 : : BuildBitLength - builds an assignment to a bit length constant.
908 : :
909 : : The Stack is expected to contain:
910 : :
911 : :
912 : : Entry Exit
913 : : ===== ====
914 : :
915 : : Ptr ->
916 : : +------------+
917 : : | Expression |
918 : : |------------| empty
919 : : */
920 : :
921 : : extern "C" void M2Quads_BuildBitLength (unsigned int tokno);
922 : :
923 : : /*
924 : : BuildPragmaField - builds an assignment to an alignment constant.
925 : :
926 : : The Stack is expected to contain:
927 : :
928 : :
929 : : Entry Exit
930 : : ===== ====
931 : :
932 : : Ptr ->
933 : : +------------+
934 : : | Expression |
935 : : |------------| empty
936 : : */
937 : :
938 : : extern "C" void M2Quads_BuildPragmaField (void);
939 : :
940 : : /*
941 : : BuildDefaultFieldAlignment - builds an assignment to an alignment constant.
942 : :
943 : : The Stack is expected to contain:
944 : :
945 : :
946 : : Entry Exit
947 : : ===== ====
948 : :
949 : : Ptr ->
950 : : +------------+
951 : : | Expression |
952 : : |------------| empty
953 : : */
954 : :
955 : : extern "C" void M2Quads_BuildDefaultFieldAlignment (void);
956 : :
957 : : /*
958 : : BuildRepeat - Builds the repeat statement from the quad stack.
959 : : The Stack is expected to contain:
960 : :
961 : :
962 : : Entry Exit
963 : : ===== ====
964 : :
965 : :
966 : : Empty
967 : : <- Ptr
968 : : +------------+
969 : : | RepeatQuad |
970 : : |------------|
971 : :
972 : : */
973 : :
974 : : extern "C" void M2Quads_BuildRepeat (void);
975 : :
976 : : /*
977 : : BuildUntil - Builds the until part of the repeat statement
978 : : from the quad stack.
979 : : The Stack is expected to contain:
980 : :
981 : :
982 : : Entry Exit
983 : : ===== ====
984 : :
985 : : Ptr ->
986 : : +------------+
987 : : | t | f |
988 : : |------------|
989 : : | RepeatQuad | Empty
990 : : |------------|
991 : : */
992 : :
993 : : extern "C" void M2Quads_BuildUntil (void);
994 : :
995 : : /*
996 : : BuildWhile - Builds the While part of the While statement
997 : : from the quad stack.
998 : : The Stack is expected to contain:
999 : :
1000 : :
1001 : : Entry Exit
1002 : : ===== ====
1003 : :
1004 : : <- Ptr
1005 : : |------------|
1006 : : Empty | WhileQuad |
1007 : : |------------|
1008 : : */
1009 : :
1010 : : extern "C" void M2Quads_BuildWhile (void);
1011 : :
1012 : : /*
1013 : : BuildDoWhile - Builds the Do part of the while statement
1014 : : from the quad stack.
1015 : : The Stack is expected to contain:
1016 : :
1017 : :
1018 : : Entry Exit
1019 : : ===== ====
1020 : :
1021 : : Ptr ->
1022 : : +------------+ +------------+
1023 : : | t | f | | 0 | f |
1024 : : |------------| |------------|
1025 : : | WhileQuad | | WhileQuad |
1026 : : |------------| |------------|
1027 : :
1028 : : Quadruples
1029 : :
1030 : : BackPatch t exit to the NextQuad
1031 : : */
1032 : :
1033 : : extern "C" void M2Quads_BuildDoWhile (void);
1034 : :
1035 : : /*
1036 : : BuildEndWhile - Builds the end part of the while statement
1037 : : from the quad stack.
1038 : : The Stack is expected to contain:
1039 : :
1040 : :
1041 : : Entry Exit
1042 : : ===== ====
1043 : :
1044 : : Ptr ->
1045 : : +------------+
1046 : : | t | f |
1047 : : |------------|
1048 : : | WhileQuad | Empty
1049 : : |------------|
1050 : :
1051 : : Quadruples
1052 : :
1053 : : q GotoOp WhileQuad
1054 : : False exit is backpatched with q+1
1055 : : */
1056 : :
1057 : : extern "C" void M2Quads_BuildEndWhile (int reltokpos);
1058 : :
1059 : : /*
1060 : : BuildLoop - Builds the Loop part of the Loop statement
1061 : : from the quad stack.
1062 : : The Stack is expected to contain:
1063 : :
1064 : :
1065 : : Entry Exit
1066 : : ===== ====
1067 : :
1068 : : <- Ptr
1069 : : Empty +------------+
1070 : : | LoopQuad |
1071 : : |------------|
1072 : : */
1073 : :
1074 : : extern "C" void M2Quads_BuildLoop (void);
1075 : :
1076 : : /*
1077 : : BuildExit - Builds the Exit part of the Loop statement.
1078 : : */
1079 : :
1080 : : extern "C" void M2Quads_BuildExit (void);
1081 : :
1082 : : /*
1083 : : BuildEndLoop - Builds the End part of the Loop statement
1084 : : from the quad stack.
1085 : : The Stack is expected to contain:
1086 : :
1087 : :
1088 : : Entry Exit
1089 : : ===== ====
1090 : :
1091 : : Ptr ->
1092 : : +------------+
1093 : : | LoopQuad | Empty
1094 : : |------------|
1095 : :
1096 : : Quadruples
1097 : :
1098 : : Goto _ _ LoopQuad
1099 : : */
1100 : :
1101 : : extern "C" void M2Quads_BuildEndLoop (void);
1102 : :
1103 : : /*
1104 : : BuildThenIf - Builds the Then part of the If statement
1105 : : from the quad stack.
1106 : : The Stack is expected to contain:
1107 : :
1108 : :
1109 : : Entry Exit
1110 : : ===== ====
1111 : :
1112 : : Ptr -> <- Ptr
1113 : : +------------+ +------------+
1114 : : | t | f | | 0 | f |
1115 : : |------------| |------------|
1116 : :
1117 : : Quadruples
1118 : :
1119 : : The true exit is BackPatched to point to
1120 : : the NextQuad.
1121 : : */
1122 : :
1123 : : extern "C" void M2Quads_BuildThenIf (void);
1124 : :
1125 : : /*
1126 : : BuildElse - Builds the Else part of the If statement
1127 : : from the quad stack.
1128 : : The Stack is expected to contain:
1129 : :
1130 : :
1131 : : Entry Exit
1132 : : ===== ====
1133 : :
1134 : : Ptr ->
1135 : : +------------+ +------------+
1136 : : | t | f | | t+q | 0 |
1137 : : |------------| |------------|
1138 : :
1139 : : Quadruples
1140 : :
1141 : : q GotoOp _ _ 0
1142 : : q+1 <- BackPatched from f
1143 : : */
1144 : :
1145 : : extern "C" void M2Quads_BuildElse (void);
1146 : :
1147 : : /*
1148 : : BuildEndIf - Builds the End part of the If statement
1149 : : from the quad stack.
1150 : : The Stack is expected to contain:
1151 : :
1152 : :
1153 : : Entry Exit
1154 : : ===== ====
1155 : :
1156 : : Ptr ->
1157 : : +------------+
1158 : : | t | f | Empty
1159 : : |------------|
1160 : :
1161 : : Quadruples
1162 : :
1163 : : Both t and f are backpatched to point to the NextQuad
1164 : : */
1165 : :
1166 : : extern "C" void M2Quads_BuildEndIf (void);
1167 : :
1168 : : /*
1169 : : BuildElsif1 - Builds the Elsif part of the If statement
1170 : : from the quad stack.
1171 : : The Stack is expected to contain:
1172 : :
1173 : :
1174 : : Entry Exit
1175 : : ===== ====
1176 : :
1177 : : Ptr ->
1178 : : +------------+ +------------+
1179 : : | t | f | | t+q | 0 |
1180 : : |------------| |------------|
1181 : :
1182 : : Quadruples
1183 : :
1184 : : q GotoOp _ _ 0
1185 : : q+1 <- BackPatched from f
1186 : : */
1187 : :
1188 : : extern "C" void M2Quads_BuildElsif1 (void);
1189 : :
1190 : : /*
1191 : : BuildElsif2 - Builds the Elsif until part of the If statement
1192 : : from the quad stack.
1193 : : The Stack is expected to contain:
1194 : :
1195 : :
1196 : : Entry Exit
1197 : : ===== ====
1198 : :
1199 : : Ptr ->
1200 : : +--------------+
1201 : : | 0 | f1 | <- Ptr
1202 : : |--------------| +---------------+
1203 : : | t2 | f2 | | t2 | f1+f2 |
1204 : : |--------------| |---------------|
1205 : : */
1206 : :
1207 : : extern "C" void M2Quads_BuildElsif2 (void);
1208 : :
1209 : : /*
1210 : : BuildForToByDo - Builds the For To By Do part of the For statement
1211 : : from the quad stack.
1212 : : The Stack is expected to contain:
1213 : :
1214 : :
1215 : : Entry Exit
1216 : : ===== ====
1217 : :
1218 : : <- Ptr
1219 : : +----------------+
1220 : : Ptr -> | RangeId |
1221 : : +----------------+ |----------------|
1222 : : | BySym | ByType | | ForQuad |
1223 : : |----------------| |----------------|
1224 : : | e2 | | LastValue |
1225 : : |----------------| |----------------|
1226 : : | e1 | | BySym | ByType |
1227 : : |----------------| |----------------|
1228 : : | Ident | | IdentSym |
1229 : : |----------------| |----------------|
1230 : :
1231 : :
1232 : : x := e1 ;
1233 : : Note that LASTVALUE is calculated during M2GenGCC
1234 : : after all the types have been resolved.
1235 : : LASTVALUE := ((e2-e1) DIV BySym) * BySym + e1
1236 : : IF BySym<0
1237 : : THEN
1238 : : IF e1<e2
1239 : : THEN
1240 : : goto exit
1241 : : END
1242 : : ELSE
1243 : : IF e1>e2
1244 : : THEN
1245 : : goto exit
1246 : : END
1247 : : END ;
1248 : : LOOP
1249 : : body
1250 : : IF x=LASTVALUE
1251 : : THEN
1252 : : goto exit
1253 : : END ;
1254 : : INC(x, BySym)
1255 : : END
1256 : :
1257 : : Quadruples:
1258 : :
1259 : : q BecomesOp IdentSym _ e1
1260 : : q+ LastForIteratorOp LastValue := ((e1-e2) DIV by) * by + e1
1261 : : q+1 if >= by 0 q+..2
1262 : : q+2 GotoOp q+3
1263 : : q+3 If >= e1 e2 q+5
1264 : : q+4 GotoOp exit
1265 : : q+5 ..
1266 : : q+..1 Goto q+..5
1267 : : q+..2 If >= e2 e1 q+..4
1268 : : q+..3 GotoOp exit
1269 : : q+..4 ..
1270 : :
1271 : : The For Loop is regarded:
1272 : :
1273 : : For ident := e1 To e2 By by Do
1274 : :
1275 : : End
1276 : : */
1277 : :
1278 : : extern "C" void M2Quads_BuildForToByDo (void);
1279 : :
1280 : : /*
1281 : : BuildPseudoBy - Builds the Non existant part of the By
1282 : : clause of the For statement
1283 : : from the quad stack.
1284 : : The Stack is expected to contain:
1285 : :
1286 : :
1287 : : Entry Exit
1288 : : ===== ====
1289 : :
1290 : : <- Ptr
1291 : : +------------+
1292 : : Ptr -> | BySym | t |
1293 : : +------------+ |------------|
1294 : : | e | t | | e | t |
1295 : : |------------| |------------|
1296 : : */
1297 : :
1298 : : extern "C" void M2Quads_BuildPseudoBy (void);
1299 : :
1300 : : /*
1301 : : BuildEndFor - Builds the End part of the For statement
1302 : : from the quad stack.
1303 : : The Stack is expected to contain:
1304 : :
1305 : :
1306 : : Entry Exit
1307 : : ===== ====
1308 : :
1309 : : Ptr ->
1310 : : +----------------+
1311 : : | RangeId |
1312 : : |----------------|
1313 : : | ForQuad |
1314 : : |----------------|
1315 : : | LastValue |
1316 : : |----------------|
1317 : : | BySym | ByType |
1318 : : |----------------|
1319 : : | IdSym | Empty
1320 : : |----------------|
1321 : : */
1322 : :
1323 : : extern "C" void M2Quads_BuildEndFor (unsigned int endpostok);
1324 : :
1325 : : /*
1326 : : BuildCaseStart - starts the case statement.
1327 : : It initializes a backpatch list on the compile
1328 : : time stack, the list is used to contain all
1329 : : case break points. The list is later backpatched
1330 : : and contains all positions of the case statement
1331 : : which jump to the end of the case statement.
1332 : : The stack also contains room for a boolean
1333 : : expression, this is needed to allow , operator
1334 : : in the CaseField alternatives.
1335 : :
1336 : : The Stack is expected to contain:
1337 : :
1338 : :
1339 : : Entry Exit
1340 : : ===== ====
1341 : :
1342 : : <- Ptr
1343 : : +------------+
1344 : : | 0 | 0 |
1345 : : |------------|
1346 : : | 0 | 0 |
1347 : : +-------------+ |------------|
1348 : : | Expr | | | Expr | |
1349 : : |-------------| |------------|
1350 : : */
1351 : :
1352 : : extern "C" void M2Quads_BuildCaseStart (void);
1353 : :
1354 : : /*
1355 : : BuildCaseStartStatementSequence - starts the statement sequence
1356 : : inside a case clause.
1357 : : BackPatches the true exit to the
1358 : : NextQuad.
1359 : : The Stack:
1360 : :
1361 : : Entry Exit
1362 : :
1363 : : Ptr -> <- Ptr
1364 : : +-----------+ +------------+
1365 : : | t | f | | 0 | f |
1366 : : |-----------| |------------|
1367 : : */
1368 : :
1369 : : extern "C" void M2Quads_BuildCaseStartStatementSequence (void);
1370 : :
1371 : : /*
1372 : : BuildCaseEndStatementSequence - ends the statement sequence
1373 : : inside a case clause.
1374 : : BackPatches the false exit f1 to the
1375 : : NextQuad.
1376 : : Asserts that t1 and f2 is 0
1377 : : Pushes t2+q and 0
1378 : :
1379 : : Quadruples:
1380 : :
1381 : : q GotoOp _ _ 0
1382 : :
1383 : : The Stack:
1384 : :
1385 : : Entry Exit
1386 : :
1387 : : Ptr -> <- Ptr
1388 : : +-----------+ +------------+
1389 : : | t1 | f1 | | 0 | 0 |
1390 : : |-----------| |------------|
1391 : : | t2 | f2 | | t2+q | 0 |
1392 : : |-----------| |------------|
1393 : : */
1394 : :
1395 : : extern "C" void M2Quads_BuildCaseEndStatementSequence (void);
1396 : :
1397 : : /*
1398 : : BuildCaseRange - builds the range testing quaruples for
1399 : : a case clause.
1400 : :
1401 : : IF (e1>=ce1) AND (e1<=ce2)
1402 : : THEN
1403 : :
1404 : : ELS..
1405 : :
1406 : : The Stack:
1407 : :
1408 : : Entry Exit
1409 : :
1410 : : Ptr ->
1411 : : +-----------+
1412 : : | ce2 | <- Ptr
1413 : : |-----------| +-----------+
1414 : : | ce1 | | t | f |
1415 : : |-----------| |-----------|
1416 : : | t1 | f1 | | t1 | f1 |
1417 : : |-----------| |-----------|
1418 : : | t2 | f2 | | t2 | f2 |
1419 : : |-----------| |-----------|
1420 : : | e1 | | e1 |
1421 : : |-----------| |-----------|
1422 : : */
1423 : :
1424 : : extern "C" void M2Quads_BuildCaseRange (void);
1425 : :
1426 : : /*
1427 : : BuildCaseEquality - builds the range testing quadruples for
1428 : : a case clause.
1429 : :
1430 : : IF e1=ce1
1431 : : THEN
1432 : :
1433 : : ELS..
1434 : :
1435 : : The Stack:
1436 : :
1437 : : Entry Exit
1438 : :
1439 : : Ptr ->
1440 : : +-----------+ +-----------+
1441 : : | ce1 | | t | f |
1442 : : |-----------| |-----------|
1443 : : | t1 | f1 | | t1 | f1 |
1444 : : |-----------| |-----------|
1445 : : | t2 | f2 | | t2 | f2 |
1446 : : |-----------| |-----------|
1447 : : | e1 | | e1 |
1448 : : |-----------| |-----------|
1449 : : */
1450 : :
1451 : : extern "C" void M2Quads_BuildCaseEquality (void);
1452 : :
1453 : : /*
1454 : : BuildCaseList - merges two case tests into one
1455 : :
1456 : : The Stack:
1457 : :
1458 : : Entry Exit
1459 : :
1460 : : Ptr ->
1461 : : +-----------+
1462 : : | t2 | f2 |
1463 : : |-----------| +-------------+
1464 : : | t1 | f1 | | t1+t2| f1+f2|
1465 : : |-----------| |-------------|
1466 : : */
1467 : :
1468 : : extern "C" void M2Quads_BuildCaseList (void);
1469 : :
1470 : : /*
1471 : : BuildCaseOr - builds the , in the case clause.
1472 : :
1473 : : The Stack:
1474 : :
1475 : : Entry Exit
1476 : :
1477 : : Ptr -> <- Ptr
1478 : : +-----------+ +------------+
1479 : : | t | f | | t | 0 |
1480 : : |-----------| |------------|
1481 : : */
1482 : :
1483 : : extern "C" void M2Quads_BuildCaseOr (void);
1484 : :
1485 : : /*
1486 : : BuildCaseElse - builds the else of case clause.
1487 : :
1488 : : The Stack:
1489 : :
1490 : : Entry Exit
1491 : :
1492 : : Ptr -> <- Ptr
1493 : : +-----------+ +------------+
1494 : : | t | f | | t | 0 |
1495 : : |-----------| |------------|
1496 : : */
1497 : :
1498 : : extern "C" void M2Quads_BuildCaseElse (void);
1499 : :
1500 : : /*
1501 : : BuildCaseEnd - builds the end of case clause.
1502 : :
1503 : : The Stack:
1504 : :
1505 : : Entry Exit
1506 : :
1507 : : Ptr ->
1508 : : +-----------+
1509 : : | t1 | f1 |
1510 : : |-----------|
1511 : : | t2 | f2 |
1512 : : |-----------|
1513 : : | e1 |
1514 : : |-----------| Empty
1515 : : */
1516 : :
1517 : : extern "C" void M2Quads_BuildCaseEnd (void);
1518 : :
1519 : : /*
1520 : : BuildCaseCheck - builds the case checking code to ensure that
1521 : : the program does not need an else clause at runtime.
1522 : : The stack is unaltered.
1523 : : */
1524 : :
1525 : : extern "C" void M2Quads_BuildCaseCheck (void);
1526 : :
1527 : : /*
1528 : : BuildNulParam - Builds a nul parameter on the stack.
1529 : : The Stack:
1530 : :
1531 : : Entry Exit
1532 : :
1533 : : <- Ptr
1534 : : Empty +------------+
1535 : : | 0 |
1536 : : |------------|
1537 : : */
1538 : :
1539 : : extern "C" void M2Quads_BuildNulParam (void);
1540 : :
1541 : : /*
1542 : : BuildProcedureCall - builds a procedure call.
1543 : : Although this procedure does not directly
1544 : : destroy the procedure parameters, it calls
1545 : : routine which will manipulate the stack and
1546 : : so the entry and exit states of the stack are shown.
1547 : :
1548 : : The Stack:
1549 : :
1550 : :
1551 : : Entry Exit
1552 : :
1553 : : Ptr ->
1554 : : +----------------+
1555 : : | NoOfParam |
1556 : : |----------------|
1557 : : | Param 1 |
1558 : : |----------------|
1559 : : | Param 2 |
1560 : : |----------------|
1561 : : . .
1562 : : . .
1563 : : . .
1564 : : |----------------|
1565 : : | Param # |
1566 : : |----------------|
1567 : : | ProcSym | Type | Empty
1568 : : |----------------|
1569 : : */
1570 : :
1571 : : extern "C" void M2Quads_BuildProcedureCall (unsigned int tokno);
1572 : :
1573 : : /*
1574 : : CheckBuildFunction - checks to see whether ProcSym is a function
1575 : : and if so it adds a TempSym value which will
1576 : : hold the return value once the function finishes.
1577 : : This procedure also generates an error message
1578 : : if the user is calling a function and ignoring
1579 : : the return result. The additional TempSym
1580 : : is not created if ProcSym is a procedure
1581 : : and the stack is unaltered.
1582 : :
1583 : : The Stack:
1584 : :
1585 : :
1586 : : Entry Exit
1587 : :
1588 : : Ptr ->
1589 : :
1590 : : +----------------+
1591 : : | ProcSym | Type |
1592 : : +----------------+ |----------------|
1593 : : | ProcSym | Type | | TempSym | Type |
1594 : : |----------------| |----------------|
1595 : : */
1596 : :
1597 : : extern "C" bool M2Quads_CheckBuildFunction (void);
1598 : :
1599 : : /*
1600 : : BuildFunctionCall - builds a function call.
1601 : : The Stack:
1602 : :
1603 : :
1604 : : Entry Exit
1605 : :
1606 : : Ptr ->
1607 : : +----------------+
1608 : : | NoOfParam |
1609 : : |----------------|
1610 : : | Param 1 |
1611 : : |----------------|
1612 : : | Param 2 |
1613 : : |----------------|
1614 : : . .
1615 : : . .
1616 : : . .
1617 : : |----------------|
1618 : : | Param # | <- Ptr
1619 : : |----------------| +------------+
1620 : : | ProcSym | Type | | ReturnVar |
1621 : : |----------------| |------------|
1622 : : */
1623 : :
1624 : : extern "C" void M2Quads_BuildFunctionCall (bool ConstExpr);
1625 : :
1626 : : /*
1627 : : BuildConstFunctionCall - builds a function call and checks that this function can be
1628 : : called inside a ConstExpression.
1629 : :
1630 : : The Stack:
1631 : :
1632 : :
1633 : : Entry Exit
1634 : :
1635 : : Ptr ->
1636 : : +----------------+
1637 : : | NoOfParam |
1638 : : |----------------|
1639 : : | Param 1 |
1640 : : |----------------|
1641 : : | Param 2 |
1642 : : |----------------|
1643 : : . .
1644 : : . .
1645 : : . .
1646 : : |----------------|
1647 : : | Param # | <- Ptr
1648 : : |----------------| +------------+
1649 : : | ProcSym | Type | | ReturnVar |
1650 : : |----------------| |------------|
1651 : :
1652 : : */
1653 : :
1654 : : extern "C" void M2Quads_BuildConstFunctionCall (void);
1655 : :
1656 : : /*
1657 : : BuildBooleanVariable - tests to see whether top of stack is a boolean
1658 : : conditional and if so it converts it into a boolean
1659 : : variable.
1660 : : */
1661 : :
1662 : : extern "C" void M2Quads_BuildBooleanVariable (void);
1663 : :
1664 : : /*
1665 : : BuildModuleStart - starts current module scope.
1666 : : */
1667 : :
1668 : : extern "C" void M2Quads_BuildModuleStart (unsigned int tok);
1669 : :
1670 : : /*
1671 : : BuildProcedureStart - Builds start of the procedure. Generates a
1672 : : quadruple which indicated the start of
1673 : : this procedure declarations scope.
1674 : : The Stack is expected to contain:
1675 : :
1676 : :
1677 : : Entry Exit
1678 : : ===== ====
1679 : :
1680 : : Ptr -> <- Ptr
1681 : : +------------+ +-----------+
1682 : : | ProcSym | | ProcSym |
1683 : : |------------| |-----------|
1684 : : | Name | | Name |
1685 : : |------------| |-----------|
1686 : :
1687 : :
1688 : : Quadruples:
1689 : :
1690 : : q ProcedureScopeOp Line# Scope ProcSym
1691 : : */
1692 : :
1693 : : extern "C" void M2Quads_BuildProcedureStart (void);
1694 : :
1695 : : /*
1696 : : BuildProcedureBegin - determines the start of the BEGIN END block of
1697 : : the procedure.
1698 : : The Stack is expected to contain:
1699 : :
1700 : :
1701 : : Entry Exit
1702 : : ===== ====
1703 : :
1704 : : Ptr -> <- Ptr
1705 : : +------------+ +-----------+
1706 : : | ProcSym | | ProcSym |
1707 : : |------------| |-----------|
1708 : : | Name | | Name |
1709 : : |------------| |-----------|
1710 : :
1711 : :
1712 : : Quadruples:
1713 : :
1714 : : q NewLocalVarOp TokenNo(BEGIN) _ ProcSym
1715 : : */
1716 : :
1717 : : extern "C" void M2Quads_BuildProcedureBegin (void);
1718 : :
1719 : : /*
1720 : : BuildProcedureEnd - Builds end of the procedure. Destroys space for
1721 : : the local variables.
1722 : : The Stack is expected to contain:
1723 : :
1724 : :
1725 : : Entry Exit
1726 : : ===== ====
1727 : :
1728 : : Ptr -> <- Ptr
1729 : : +------------+ +-----------+
1730 : : | ProcSym | | ProcSym |
1731 : : |------------| |-----------|
1732 : : | Name | | Name |
1733 : : |------------| |-----------|
1734 : :
1735 : :
1736 : : Quadruples:
1737 : :
1738 : : q KillLocalVarOp TokenNo(END) _ ProcSym
1739 : : */
1740 : :
1741 : : extern "C" void M2Quads_BuildProcedureEnd (void);
1742 : :
1743 : : /*
1744 : : BuildReturn - Builds the Return part of the procedure.
1745 : : tokreturn is the location of the RETURN keyword.
1746 : : The Stack is expected to contain:
1747 : :
1748 : :
1749 : : Entry Exit
1750 : : ===== ====
1751 : :
1752 : : Ptr ->
1753 : : +------------+
1754 : : | e1 | Empty
1755 : : |------------|
1756 : : */
1757 : :
1758 : : extern "C" void M2Quads_BuildReturn (unsigned int tokreturn);
1759 : :
1760 : : /*
1761 : : BuildModulePriority - assigns the current module with a priority
1762 : : from the top of stack.
1763 : :
1764 : : Entry Exit
1765 : : ===== ====
1766 : :
1767 : :
1768 : : Ptr -> Empty
1769 : : +------------+
1770 : : | Priority |
1771 : : |------------|
1772 : : */
1773 : :
1774 : : extern "C" void M2Quads_BuildModulePriority (void);
1775 : :
1776 : : /*
1777 : : StartBuildWith - performs the with statement.
1778 : : The Stack:
1779 : :
1780 : : Entry Exit
1781 : :
1782 : : +------------+
1783 : : | Sym | Type | Empty
1784 : : |------------|
1785 : : */
1786 : :
1787 : : extern "C" void M2Quads_StartBuildWith (unsigned int withTok);
1788 : :
1789 : : /*
1790 : : EndBuildWith - terminates the innermost with scope.
1791 : : */
1792 : :
1793 : : extern "C" void M2Quads_EndBuildWith (void);
1794 : :
1795 : : /*
1796 : : CheckWithReference - performs the with statement.
1797 : : The Stack:
1798 : :
1799 : : Entry Exit
1800 : :
1801 : : +------------+ +------------+
1802 : : | Sym | Type | | Sym | Type |
1803 : : |------------| |------------|
1804 : : */
1805 : :
1806 : : extern "C" void M2Quads_CheckWithReference (void);
1807 : :
1808 : : /*
1809 : : BuildDesignatorRecord - Builds the record referencing.
1810 : : The Stack is expected to contain:
1811 : :
1812 : :
1813 : : Entry Exit
1814 : : ===== ====
1815 : :
1816 : : Ptr ->
1817 : : +--------------+
1818 : : | n |
1819 : : |--------------|
1820 : : | fld1 | type1 |
1821 : : |--------------|
1822 : : . .
1823 : : . .
1824 : : . .
1825 : : |--------------|
1826 : : | fldn | typen | <- Ptr
1827 : : |--------------| +-------------+
1828 : : | Sym | Type | | S | type1|
1829 : : |--------------| |-------------|
1830 : : */
1831 : :
1832 : : extern "C" void M2Quads_BuildDesignatorRecord (unsigned int dottok);
1833 : :
1834 : : /*
1835 : : BuildDesignatorArray - Builds the array referencing.
1836 : : The purpose of this procedure is to work out
1837 : : whether the DesignatorArray is a constant string or
1838 : : dynamic array/static array and to call the appropriate
1839 : : BuildRoutine.
1840 : :
1841 : : The Stack is expected to contain:
1842 : :
1843 : : Entry Exit
1844 : : ===== ====
1845 : :
1846 : : Ptr ->
1847 : : +--------------+
1848 : : | e | <- Ptr
1849 : : |--------------| +------------+
1850 : : | Sym | Type | | S | T |
1851 : : |--------------| |------------|
1852 : : */
1853 : :
1854 : : extern "C" void M2Quads_BuildDesignatorArray (void);
1855 : :
1856 : : /*
1857 : : BuildDesignatorPointer - Builds a pointer reference.
1858 : : The Stack is expected to contain:
1859 : :
1860 : :
1861 : : Entry Exit
1862 : : ===== ====
1863 : :
1864 : : Ptr -> <- Ptr
1865 : : +--------------+ +--------------+
1866 : : | Sym1 | Type1| | Sym2 | Type2|
1867 : : |--------------| |--------------|
1868 : : */
1869 : :
1870 : : extern "C" void M2Quads_BuildDesignatorPointer (unsigned int ptrtok);
1871 : :
1872 : : /*
1873 : : BuildNulExpression - Builds a nul expression on the stack.
1874 : : The Stack:
1875 : :
1876 : : Entry Exit
1877 : :
1878 : : <- Ptr
1879 : : Empty +------------+
1880 : : | NulSym |
1881 : : |------------|
1882 : : tokpos is the position of the RETURN token.
1883 : : */
1884 : :
1885 : : extern "C" void M2Quads_BuildNulExpression (unsigned int tokpos);
1886 : :
1887 : : /*
1888 : : BuildSetStart - Pushes a Bitset type on the stack.
1889 : :
1890 : : The Stack:
1891 : :
1892 : : Entry Exit
1893 : :
1894 : : Ptr -> <- Ptr
1895 : :
1896 : : Empty +--------------+
1897 : : | Bitset |
1898 : : |--------------|
1899 : : */
1900 : :
1901 : : extern "C" void M2Quads_BuildSetStart (unsigned int tokpos);
1902 : :
1903 : : /*
1904 : : BuildSetEnd - pops the set value and type from the stack
1905 : : and pushes the value,type pair.
1906 : :
1907 : : Entry Exit
1908 : :
1909 : : Ptr ->
1910 : : +--------------+
1911 : : | Set Value | <- Ptr
1912 : : |--------------| +--------------+
1913 : : | Set Type | | Value | Type |
1914 : : |--------------| |--------------|
1915 : : */
1916 : :
1917 : : extern "C" void M2Quads_BuildSetEnd (void);
1918 : :
1919 : : /*
1920 : : BuildEmptySet - Builds an empty set on the stack.
1921 : : The Stack:
1922 : :
1923 : : Entry Exit
1924 : :
1925 : : <- Ptr
1926 : : +-------------+
1927 : : Ptr -> | Value |
1928 : : +-----------+ |-------------|
1929 : : | SetType | | SetType |
1930 : : |-----------| |-------------|
1931 : :
1932 : : tokpos points to the opening '{'.
1933 : : */
1934 : :
1935 : : extern "C" void M2Quads_BuildEmptySet (unsigned int tokpos);
1936 : :
1937 : : /*
1938 : : BuildInclRange - includes a set range with a set.
1939 : :
1940 : :
1941 : : Entry Exit
1942 : : ===== ====
1943 : :
1944 : :
1945 : : Ptr ->
1946 : : +------------+
1947 : : | El2 |
1948 : : |------------|
1949 : : | El1 | <- Ptr
1950 : : |------------| +-------------------+
1951 : : | Set Value | | Value + {El1..El2}|
1952 : : |------------| |-------------------|
1953 : :
1954 : : No quadruples produced as the range info is contained within
1955 : : the set value.
1956 : : */
1957 : :
1958 : : extern "C" void M2Quads_BuildInclRange (void);
1959 : :
1960 : : /*
1961 : : BuildInclBit - includes a bit into the set.
1962 : :
1963 : : Entry Exit
1964 : : ===== ====
1965 : :
1966 : :
1967 : : Ptr ->
1968 : : +------------+
1969 : : | Element | <- Ptr
1970 : : |------------| +------------+
1971 : : | Value | | Value |
1972 : : |------------| |------------|
1973 : :
1974 : : */
1975 : :
1976 : : extern "C" void M2Quads_BuildInclBit (void);
1977 : :
1978 : : /*
1979 : : SilentBuildConstructor - places NulSym into the constructor fifo queue.
1980 : : */
1981 : :
1982 : : extern "C" void M2Quads_SilentBuildConstructor (void);
1983 : :
1984 : : /*
1985 : : SilentBuildConstructorStart - removes an entry from the constructor fifo queue.
1986 : : */
1987 : :
1988 : : extern "C" void M2Quads_SilentBuildConstructorStart (void);
1989 : :
1990 : : /*
1991 : : BuildConstructor - builds a constructor.
1992 : : Stack
1993 : :
1994 : : Entry Exit
1995 : :
1996 : : Ptr ->
1997 : : +------------+
1998 : : | Type | <- Ptr
1999 : : |------------+
2000 : : */
2001 : :
2002 : : extern "C" void M2Quads_BuildConstructor (unsigned int tokcbrpos);
2003 : :
2004 : : /*
2005 : : BuildConstructorStart - builds a constructor.
2006 : : Stack
2007 : :
2008 : : Entry Exit
2009 : :
2010 : : Ptr -> <- Ptr
2011 : : +------------+ +----------------+
2012 : : | Type | | ConstructorSym |
2013 : : |------------+ |----------------|
2014 : : */
2015 : :
2016 : : extern "C" void M2Quads_BuildConstructorStart (unsigned int cbratokpos);
2017 : :
2018 : : /*
2019 : : BuildConstructorEnd - removes the current constructor frame from the
2020 : : constructor stack (it does not effect the quad
2021 : : stack)
2022 : :
2023 : : Entry Exit
2024 : :
2025 : : Ptr -> <- Ptr
2026 : : +------------+ +------------+
2027 : : | const | | const |
2028 : : |------------| |------------|
2029 : :
2030 : : startpos is the start of the constructor, either the typename or '{'
2031 : : cbratokpos is the '}'.
2032 : : */
2033 : :
2034 : : extern "C" void M2Quads_BuildConstructorEnd (unsigned int startpos, unsigned int cbratokpos);
2035 : :
2036 : : /*
2037 : : NextConstructorField - increments the top of constructor stacks index by one.
2038 : : */
2039 : :
2040 : : extern "C" void M2Quads_NextConstructorField (void);
2041 : :
2042 : : /*
2043 : : BuildTypeForConstructor - pushes the type implied by the current constructor.
2044 : : If no constructor is currently being built then
2045 : : it Pushes a Bitset type.
2046 : : */
2047 : :
2048 : : extern "C" void M2Quads_BuildTypeForConstructor (unsigned int tokpos);
2049 : :
2050 : : /*
2051 : : BuildComponentValue - builds a component value.
2052 : :
2053 : : Entry Exit
2054 : :
2055 : : Ptr -> <- Ptr
2056 : :
2057 : :
2058 : : +------------+ +------------+
2059 : : | const | | const |
2060 : : |------------| |------------|
2061 : : */
2062 : :
2063 : : extern "C" void M2Quads_BuildComponentValue (void);
2064 : :
2065 : : /*
2066 : : PopConstructor - removes the top constructor from the top of stack.
2067 : : */
2068 : :
2069 : : extern "C" void M2Quads_PopConstructor (void);
2070 : :
2071 : : /*
2072 : : BuildNot - Builds a NOT operation from the quad stack.
2073 : : The Stack is expected to contain:
2074 : :
2075 : :
2076 : : Entry Exit
2077 : : ===== ====
2078 : :
2079 : : Ptr -> <- Ptr
2080 : : +------------+ +------------+
2081 : : | t | f | | f | t |
2082 : : |------------| |------------|
2083 : : */
2084 : :
2085 : : extern "C" void M2Quads_BuildNot (unsigned int notTokPos);
2086 : :
2087 : : /*
2088 : : RecordOp - Records the operator passed on the stack.
2089 : : This is called when a boolean operator is found in an
2090 : : expression. It is called just after the lhs has been built
2091 : : and pushed to the quad stack and prior to the rhs build.
2092 : : It checks to see if AND OR or equality tests are required.
2093 : : It will short circuit AND and OR expressions. It also
2094 : : converts a lhs to a boolean variable if an xor comparison
2095 : : is about to be performed.
2096 : :
2097 : : Checks for AND operator or OR operator
2098 : : if either of these operators are found then BackPatching
2099 : : takes place.
2100 : : The Expected Stack:
2101 : :
2102 : : Entry Exit
2103 : :
2104 : : Ptr -> <- Ptr
2105 : : +-------------+ +-------------+
2106 : : | OperatorTok | | OperatorTok |
2107 : : |-------------| |-------------|
2108 : : | t | f | | t | f |
2109 : : |-------------| |-------------|
2110 : :
2111 : :
2112 : : If OperatorTok=AndTok
2113 : : Then
2114 : : BackPatch(f, NextQuad)
2115 : : Elsif OperatorTok=OrTok
2116 : : Then
2117 : : BackPatch(t, NextQuad)
2118 : : End
2119 : : */
2120 : :
2121 : : extern "C" void M2Quads_RecordOp (void);
2122 : :
2123 : : /*
2124 : : BuildRelOp - Builds a relative operation from the quad stack.
2125 : : The Stack is expected to contain:
2126 : :
2127 : :
2128 : : Entry Exit
2129 : : ===== ====
2130 : :
2131 : : Ptr ->
2132 : : +------------+
2133 : : | e1 |
2134 : : |------------| <- Ptr
2135 : : | Operator |
2136 : : |------------| +------------+
2137 : : | e2 | | t | f |
2138 : : |------------| |------------|
2139 : :
2140 : :
2141 : : Quadruples Produced
2142 : :
2143 : : q IFOperator e2 e1 TrueExit ; e2 e1 since
2144 : : q+1 GotoOp FalseExit ; relation > etc
2145 : : ; requires order.
2146 : : */
2147 : :
2148 : : extern "C" void M2Quads_BuildRelOp (unsigned int optokpos);
2149 : :
2150 : : /*
2151 : : BuildBinaryOp - Builds a binary operation from the quad stack.
2152 : : Be aware that this procedure will check for
2153 : : the overloading of the bitset operators + - \ *.
2154 : : So do NOT call this procedure if you are building
2155 : : a reference to an array which has a bitset type or
2156 : : the address arithmetic will be wrongly coersed into
2157 : : logical ORs.
2158 : :
2159 : : The Stack is expected to contain:
2160 : :
2161 : :
2162 : : Entry Exit
2163 : : ===== ====
2164 : :
2165 : : Ptr ->
2166 : : +------------+
2167 : : | Sym1 |
2168 : : |------------|
2169 : : | Operator | <- Ptr
2170 : : |------------| +------------+
2171 : : | Sym2 | | Temporary |
2172 : : |------------| |------------|
2173 : :
2174 : :
2175 : : Quadruples Produced
2176 : :
2177 : : q Operator Temporary Sym1 Sym2
2178 : :
2179 : :
2180 : : OR
2181 : :
2182 : :
2183 : : Entry Exit
2184 : : ===== ====
2185 : :
2186 : : Ptr ->
2187 : : +------------+
2188 : : | T1 | F1 |
2189 : : |------------|
2190 : : | OrTok | <- Ptr
2191 : : |------------| +------------+
2192 : : | T2 | F2 | | T1+T2| F1 |
2193 : : |------------| |------------|
2194 : :
2195 : :
2196 : : Quadruples Produced
2197 : :
2198 : : */
2199 : :
2200 : : extern "C" void M2Quads_BuildBinaryOp (void);
2201 : :
2202 : : /*
2203 : : BuildUnaryOp - Builds a unary operation from the quad stack.
2204 : : The Stack is expected to contain:
2205 : :
2206 : :
2207 : : Entry Exit
2208 : : ===== ====
2209 : :
2210 : : Ptr ->
2211 : : +------------+
2212 : : | Sym |
2213 : : |------------| +------------+
2214 : : | Operator | | Temporary | <- Ptr
2215 : : |------------| |------------|
2216 : :
2217 : :
2218 : : Quadruples Produced
2219 : :
2220 : : q Operator Temporary _ Sym
2221 : :
2222 : : */
2223 : :
2224 : : extern "C" void M2Quads_BuildUnaryOp (void);
2225 : :
2226 : : /*
2227 : : OperandT - returns the ident operand stored in the true position on the boolean stack.
2228 : : */
2229 : :
2230 : : extern "C" unsigned int M2Quads_OperandT (unsigned int pos);
2231 : :
2232 : : /*
2233 : : OperandF - returns the ident operand stored in the false position on the boolean stack.
2234 : : */
2235 : :
2236 : : extern "C" unsigned int M2Quads_OperandF (unsigned int pos);
2237 : :
2238 : : /*
2239 : : PushTF - Push a True and False numbers onto the True/False stack.
2240 : : True and False are assumed to contain Symbols or Ident etc.
2241 : : */
2242 : :
2243 : : extern "C" void M2Quads_PushTF (unsigned int True, unsigned int False);
2244 : :
2245 : : /*
2246 : : PopTF - Pop a True and False number from the True/False stack.
2247 : : True and False are assumed to contain Symbols or Ident etc.
2248 : : */
2249 : :
2250 : : extern "C" void M2Quads_PopTF (unsigned int *True, unsigned int *False);
2251 : :
2252 : : /*
2253 : : PushT - Push an item onto the stack in the T (true) position.
2254 : : */
2255 : :
2256 : : extern "C" void M2Quads_PushT (unsigned int True);
2257 : :
2258 : : /*
2259 : : PopT - Pops the T value from the stack.
2260 : : */
2261 : :
2262 : : extern "C" void M2Quads_PopT (unsigned int *True);
2263 : :
2264 : : /*
2265 : : PushTtok - Push an item onto the stack in the T (true) position,
2266 : : it is assummed to be a token and its token location is recorded.
2267 : : */
2268 : :
2269 : : extern "C" void M2Quads_PushTtok (unsigned int True, unsigned int tokno);
2270 : :
2271 : : /*
2272 : : PushTFtok - Push an item onto the stack in the T (true) position,
2273 : : it is assummed to be a token and its token location is recorded.
2274 : : */
2275 : :
2276 : : extern "C" void M2Quads_PushTFtok (unsigned int True, unsigned int False, unsigned int tokno);
2277 : :
2278 : : /*
2279 : : PopTFtok - Pop T/F/tok from the stack.
2280 : : */
2281 : :
2282 : : extern "C" void M2Quads_PopTFtok (unsigned int *True, unsigned int *False, unsigned int *tokno);
2283 : :
2284 : : /*
2285 : : PushTFAtok - Push T/F/A/tok to the stack.
2286 : : */
2287 : :
2288 : : extern "C" void M2Quads_PushTFAtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int tokno);
2289 : :
2290 : : /*
2291 : : PopTtok - Pops the T value from the stack and token position.
2292 : : */
2293 : :
2294 : : extern "C" void M2Quads_PopTtok (unsigned int *True, unsigned int *tok);
2295 : :
2296 : : /*
2297 : : PushTFn - Push a True and False numbers onto the True/False stack.
2298 : : True and False are assumed to contain Symbols or Ident etc.
2299 : : */
2300 : :
2301 : : extern "C" void M2Quads_PushTFn (unsigned int True, unsigned int False, unsigned int n);
2302 : :
2303 : : /*
2304 : : PushTFntok - Push a True and False numbers onto the True/False stack.
2305 : : True and False are assumed to contain Symbols or Ident etc.
2306 : : */
2307 : :
2308 : : extern "C" void M2Quads_PushTFntok (unsigned int True, unsigned int False, unsigned int n, unsigned int tokno);
2309 : :
2310 : : /*
2311 : : PopTFn - Pop a True and False number from the True/False stack.
2312 : : True and False are assumed to contain Symbols or Ident etc.
2313 : : */
2314 : :
2315 : : extern "C" void M2Quads_PopTFn (unsigned int *True, unsigned int *False, unsigned int *n);
2316 : :
2317 : : /*
2318 : : PopNothing - pops the top element on the boolean stack.
2319 : : */
2320 : :
2321 : : extern "C" void M2Quads_PopNothing (void);
2322 : :
2323 : : /*
2324 : : PopN - pops multiple elements from the BoolStack.
2325 : : */
2326 : :
2327 : : extern "C" void M2Quads_PopN (unsigned int n);
2328 : :
2329 : : /*
2330 : : PushTFA - Push True, False, Array, numbers onto the
2331 : : True/False stack. True and False are assumed to
2332 : : contain Symbols or Ident etc.
2333 : : */
2334 : :
2335 : : extern "C" void M2Quads_PushTFA (unsigned int True, unsigned int False, unsigned int Array);
2336 : :
2337 : : /*
2338 : : OperandTok - returns the token associated with pos, on the stack.
2339 : : */
2340 : :
2341 : : extern "C" unsigned int M2Quads_OperandTok (unsigned int pos);
2342 : :
2343 : : /*
2344 : : OperandA - returns possible array symbol associated with the ident
2345 : : operand stored on the boolean stack.
2346 : : */
2347 : :
2348 : : extern "C" unsigned int M2Quads_OperandA (unsigned int pos);
2349 : :
2350 : : /*
2351 : : OperandAnno - returns the annotation string associated with the
2352 : : position, n, on the stack.
2353 : : */
2354 : :
2355 : : extern "C" DynamicStrings_String M2Quads_OperandAnno (unsigned int n);
2356 : :
2357 : : /*
2358 : : Annotate - annotate the top of stack.
2359 : : */
2360 : :
2361 : : extern "C" void M2Quads_Annotate (const char *a_, unsigned int _a_high);
2362 : :
2363 : : /*
2364 : : DisplayStack - displays the compile time symbol stack.
2365 : : */
2366 : :
2367 : : extern "C" void M2Quads_DisplayStack (void);
2368 : :
2369 : : /*
2370 : : Top - returns the no of items held in the stack.
2371 : : */
2372 : :
2373 : : extern "C" unsigned int M2Quads_Top (void);
2374 : :
2375 : : /*
2376 : : DupFrame - duplicate the top of stack and push the new frame.
2377 : : */
2378 : :
2379 : : extern "C" void M2Quads_DupFrame (void);
2380 : :
2381 : : /*
2382 : : WriteOperand - displays the operands name, symbol id and mode of addressing.
2383 : : */
2384 : :
2385 : : extern "C" void M2Quads_WriteOperand (unsigned int Sym);
2386 : :
2387 : : /*
2388 : : BeginVarient - begin a varient record.
2389 : : */
2390 : :
2391 : : extern "C" void M2Quads_BeginVarient (void);
2392 : :
2393 : : /*
2394 : : EndVarient - end a varient record.
2395 : : */
2396 : :
2397 : : extern "C" void M2Quads_EndVarient (void);
2398 : :
2399 : : /*
2400 : : ElseVarient - associate an ELSE clause with a varient record.
2401 : : */
2402 : :
2403 : : extern "C" void M2Quads_ElseVarient (void);
2404 : :
2405 : : /*
2406 : : BeginVarientList - begin an ident list containing ranges belonging to a
2407 : : varient list.
2408 : : */
2409 : :
2410 : : extern "C" void M2Quads_BeginVarientList (void);
2411 : :
2412 : : /*
2413 : : EndVarientList - end a range list for a varient field.
2414 : : */
2415 : :
2416 : : extern "C" void M2Quads_EndVarientList (void);
2417 : :
2418 : : /*
2419 : : AddRecordToList - adds the record held on the top of stack to the
2420 : : list of records and varient fields.
2421 : : */
2422 : :
2423 : : extern "C" void M2Quads_AddRecordToList (void);
2424 : :
2425 : : /*
2426 : : AddVarientToList - adds varient held on the top of stack to the list.
2427 : : */
2428 : :
2429 : : extern "C" void M2Quads_AddVarientToList (void);
2430 : :
2431 : : /*
2432 : : AddVarientFieldToList - adds varient field, f, to the list of all varient
2433 : : fields created.
2434 : : */
2435 : :
2436 : : extern "C" void M2Quads_AddVarientFieldToList (unsigned int f);
2437 : :
2438 : : /*
2439 : : AddVarientRange - creates a range from the top two contant expressions
2440 : : on the stack which are recorded with the current
2441 : : varient field. The stack is unaltered.
2442 : : */
2443 : :
2444 : : extern "C" void M2Quads_AddVarientRange (void);
2445 : :
2446 : : /*
2447 : : AddVarientEquality - adds the contant expression on the top of the stack
2448 : : to the current varient field being recorded.
2449 : : The stack is unaltered.
2450 : : */
2451 : :
2452 : : extern "C" void M2Quads_AddVarientEquality (void);
2453 : :
2454 : : /*
2455 : : BuildCodeOn - generates a quadruple declaring that code should be
2456 : : emmitted from henceforth.
2457 : :
2458 : : The Stack is unnaffected.
2459 : : */
2460 : :
2461 : : extern "C" void M2Quads_BuildCodeOn (void);
2462 : :
2463 : : /*
2464 : : BuildCodeOff - generates a quadruple declaring that code should not be
2465 : : emmitted from henceforth.
2466 : :
2467 : : The Stack is unnaffected.
2468 : : */
2469 : :
2470 : : extern "C" void M2Quads_BuildCodeOff (void);
2471 : :
2472 : : /*
2473 : : BuildProfileOn - generates a quadruple declaring that profile timings
2474 : : should be emmitted from henceforth.
2475 : :
2476 : : The Stack is unnaffected.
2477 : : */
2478 : :
2479 : : extern "C" void M2Quads_BuildProfileOn (void);
2480 : : extern "C" void M2Quads_BuildProfileOff (void);
2481 : :
2482 : : /*
2483 : : BuildOptimizeOn - generates a quadruple declaring that optimization
2484 : : should occur from henceforth.
2485 : :
2486 : : The Stack is unnaffected.
2487 : : */
2488 : :
2489 : : extern "C" void M2Quads_BuildOptimizeOn (void);
2490 : :
2491 : : /*
2492 : : BuildOptimizeOff - generates a quadruple declaring that optimization
2493 : : should not occur from henceforth.
2494 : :
2495 : : The Stack is unnaffected.
2496 : : */
2497 : :
2498 : : extern "C" void M2Quads_BuildOptimizeOff (void);
2499 : :
2500 : : /*
2501 : : BuildAsm - builds an Inline pseudo quadruple operator.
2502 : : The inline interface, Sym, is stored as the operand
2503 : : to the operator InlineOp.
2504 : :
2505 : : The stack is expected to contain:
2506 : :
2507 : :
2508 : : Entry Exit
2509 : : ===== ====
2510 : :
2511 : : Ptr ->
2512 : : +--------------+
2513 : : | Sym | Empty
2514 : : |--------------|
2515 : : */
2516 : :
2517 : : extern "C" void M2Quads_BuildAsm (unsigned int tok);
2518 : :
2519 : : /*
2520 : : BuildLineNo - builds a LineNumberOp pseudo quadruple operator.
2521 : : This quadruple indicates which source line has been
2522 : : processed, these quadruples are only generated if we
2523 : : are producing runtime debugging information.
2524 : :
2525 : : The stack is not affected, read or altered in any way.
2526 : :
2527 : :
2528 : : Entry Exit
2529 : : ===== ====
2530 : :
2531 : : Ptr -> <- Ptr
2532 : : */
2533 : :
2534 : : extern "C" void M2Quads_BuildLineNo (void);
2535 : :
2536 : : /*
2537 : : PushLineNo - pushes the current file and line number to the stack.
2538 : : */
2539 : :
2540 : : extern "C" void M2Quads_PushLineNo (void);
2541 : :
2542 : : /*
2543 : : BuildStmtNote - builds a StatementNoteOp pseudo quadruple operator.
2544 : : This quadruple indicates which source line has been
2545 : : processed and it represents the start of a statement
2546 : : sequence.
2547 : : It differs from LineNumberOp in that multiple successive
2548 : : LineNumberOps will be removed and the final one is attached to
2549 : : the next real GCC tree. Whereas a StatementNoteOp is always left
2550 : : alone. Depending upon the debugging level it will issue a nop
2551 : : instruction to ensure that the gdb single step will step into
2552 : : this line. Practically it allows pedalogical debugging to
2553 : : occur when there is syntax sugar such as:
2554 : :
2555 : :
2556 : : END step
2557 : : END step
2558 : : END ; step
2559 : : a := 1 ; step
2560 : :
2561 : : REPEAT step
2562 : : i := 1 step
2563 : :
2564 : : The stack is not affected, read or altered in any way.
2565 : :
2566 : :
2567 : : Entry Exit
2568 : : ===== ====
2569 : :
2570 : : Ptr -> <- Ptr
2571 : : */
2572 : :
2573 : : extern "C" void M2Quads_BuildStmtNote (int offset);
2574 : :
2575 : : /*
2576 : : LoopAnalysis - checks whether an infinite loop exists.
2577 : : */
2578 : :
2579 : : extern "C" void M2Quads_LoopAnalysis (unsigned int Scope, unsigned int Current, unsigned int End);
2580 : :
2581 : : /*
2582 : : ForLoopAnalysis - checks all the FOR loops for index variable manipulation
2583 : : and dangerous usage outside the loop.
2584 : : */
2585 : :
2586 : : extern "C" void M2Quads_ForLoopAnalysis (void);
2587 : :
2588 : : /*
2589 : : BuildSizeCheckStart - switches off all quadruple generation if the function SIZE or HIGH
2590 : : is being "called". This should be done as SIZE only requires the
2591 : : actual type of the expression, not its value. Consider the problem of
2592 : : SIZE(UninitializedPointer^) which is quite legal and it must
2593 : : also be safe!
2594 : : ISO Modula-2 also allows HIGH(a[0]) for a two dimensional array
2595 : : and there is no need to compute a[0], we just need to follow the
2596 : : type and count dimensions. However if SIZE(a) or HIGH(a) occurs
2597 : : and, a, is an unbounded array then we turn on quadruple generation.
2598 : :
2599 : : The Stack is expected to contain:
2600 : :
2601 : :
2602 : : Entry Exit
2603 : : ===== ====
2604 : :
2605 : : Ptr -> <- Ptr
2606 : : +----------------------+ +----------------------+
2607 : : | ProcSym | Type | tok | | ProcSym | Type | tok |
2608 : : |----------------------| |----------------------|
2609 : : */
2610 : :
2611 : : extern "C" void M2Quads_BuildSizeCheckStart (void);
2612 : :
2613 : : /*
2614 : : BackPatchSubrangesAndOptParam - runs through all the quadruples and finds SubrangeLow or SubrangeHigh
2615 : : quadruples and replaces it by an assignment to the Low or High component
2616 : : of the subrange type.
2617 : :
2618 : : Input:
2619 : : SubrangeLow op1 op3 op3 is a subrange
2620 : :
2621 : : Output:
2622 : : Becomes op1 low
2623 : :
2624 : : Input:
2625 : : SubrangeHigh op1 op3 op3 is a subrange
2626 : :
2627 : : Output:
2628 : : Becomes op1 high
2629 : :
2630 : : Input:
2631 : : OptParam op1 op2 op3
2632 : :
2633 : : Output:
2634 : : Param op1 op2 GetOptArgInit(op3)
2635 : : */
2636 : :
2637 : : extern "C" void M2Quads_BackPatchSubrangesAndOptParam (void);
2638 : :
2639 : : /*
2640 : : WriteOperator - writes the name of the quadruple operator.
2641 : : */
2642 : :
2643 : : extern "C" void M2Quads_WriteOperator (M2Quads_QuadOperator Operator);
2644 : :
2645 : : /*
2646 : : PushAutoOn - push the auto flag and then set it to TRUE.
2647 : : Any call to ident in the parser will result in the token being pushed.
2648 : : */
2649 : :
2650 : : extern "C" void M2Quads_PushAutoOn (void);
2651 : :
2652 : : /*
2653 : : PushAutoOff - push the auto flag and then set it to FALSE.
2654 : : */
2655 : :
2656 : : extern "C" void M2Quads_PushAutoOff (void);
2657 : :
2658 : : /*
2659 : : IsAutoPushOn - returns the value of the current Auto ident push flag.
2660 : : */
2661 : :
2662 : : extern "C" bool M2Quads_IsAutoPushOn (void);
2663 : :
2664 : : /*
2665 : : PopAuto - restores the previous value of the Auto flag.
2666 : : */
2667 : :
2668 : : extern "C" void M2Quads_PopAuto (void);
2669 : :
2670 : : /*
2671 : : MustCheckOverflow - returns TRUE if the quadruple should test for overflow.
2672 : : */
2673 : :
2674 : : extern "C" bool M2Quads_MustCheckOverflow (unsigned int q);
2675 : :
2676 : : /*
2677 : : PushInConstExpression - push the InConstExpression flag and then set it to TRUE.
2678 : : */
2679 : :
2680 : : extern "C" void M2Quads_PushInConstExpression (void);
2681 : :
2682 : : /*
2683 : : PopInConstExpression - restores the previous value of the InConstExpression.
2684 : : */
2685 : :
2686 : : extern "C" void M2Quads_PopInConstExpression (void);
2687 : :
2688 : : /*
2689 : : IsInConstExpression - returns the value of the InConstExpression.
2690 : : */
2691 : :
2692 : : extern "C" bool M2Quads_IsInConstExpression (void);
2693 : :
2694 : : /*
2695 : : PushInConstParameters - push the InConstParameters flag and then set it to TRUE.
2696 : : */
2697 : :
2698 : : extern "C" void M2Quads_PushInConstParameters (void);
2699 : :
2700 : : /*
2701 : : PopInConstParameters - restores the previous value of the InConstParameters.
2702 : : */
2703 : :
2704 : : extern "C" void M2Quads_PopInConstParameters (void);
2705 : :
2706 : : /*
2707 : : IsInConstParameters - returns the value of the InConstParameters.
2708 : : */
2709 : :
2710 : : extern "C" bool M2Quads_IsInConstParameters (void);
2711 : :
2712 : : /*
2713 : : BuildAsmElement - the stack is expected to contain:
2714 : :
2715 : :
2716 : : Entry Exit
2717 : : ===== ====
2718 : :
2719 : : Ptr ->
2720 : : +------------------+
2721 : : | expr | tokpos |
2722 : : |------------------|
2723 : : | str |
2724 : : |------------------|
2725 : : | name |
2726 : : |------------------| +------------------+
2727 : : | CurrentInterface | | CurrentInterface |
2728 : : |------------------| |------------------|
2729 : : | CurrentAsm | | CurrentAsm |
2730 : : |------------------| |------------------|
2731 : : | n | | n |
2732 : : |------------------| |------------------|
2733 : : */
2734 : :
2735 : : extern "C" void M2Quads_BuildAsmElement (bool input, bool output);
2736 : :
2737 : : /*
2738 : : BuildAsmTrash - the stack is expected to contain:
2739 : :
2740 : :
2741 : : Entry Exit
2742 : : ===== ====
2743 : :
2744 : : Ptr ->
2745 : : +------------------+
2746 : : | expr | tokpos |
2747 : : |------------------| +------------------+
2748 : : | CurrentInterface | | CurrentInterface |
2749 : : |------------------| |------------------|
2750 : : | CurrentAsm | | CurrentAsm |
2751 : : |------------------| |------------------|
2752 : : | n | | n |
2753 : : |------------------| |------------------|
2754 : : */
2755 : :
2756 : : extern "C" void M2Quads_BuildAsmTrash (void);
2757 : :
2758 : : /*
2759 : : GetQuadTrash - return the symbol associated with the trashed operand.
2760 : : */
2761 : :
2762 : : extern "C" unsigned int M2Quads_GetQuadTrash (unsigned int quad);
2763 : :
2764 : : /*
2765 : : DSdbEnter -
2766 : : */
2767 : :
2768 : : static void DSdbEnter (void);
2769 : :
2770 : : /*
2771 : : DSdbExit -
2772 : : */
2773 : :
2774 : : static void DSdbExit (void);
2775 : :
2776 : : /*
2777 : : GetQF - returns the QuadFrame associated with, q.
2778 : : */
2779 : :
2780 : : static M2Quads_QuadFrame GetQF (unsigned int q);
2781 : :
2782 : : /*
2783 : : IsQuadA - returns true if QuadNo is a op.
2784 : : */
2785 : :
2786 : : static bool IsQuadA (unsigned int QuadNo, M2Quads_QuadOperator op);
2787 : :
2788 : : /*
2789 : : OpUsesOp1 - return TRUE if op allows op1.
2790 : : */
2791 : :
2792 : : static bool OpUsesOp1 (M2Quads_QuadOperator op);
2793 : :
2794 : : /*
2795 : : AddQuadInformation - adds variable analysis and jump analysis to the new quadruple.
2796 : : */
2797 : :
2798 : : static void AddQuadInformation (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3);
2799 : :
2800 : : /*
2801 : : PutQuadO - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
2802 : : sets a boolean to determinine whether overflow should be checked.
2803 : : */
2804 : :
2805 : : static void PutQuadO (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow);
2806 : :
2807 : : /*
2808 : : PutQuadOType -
2809 : : */
2810 : :
2811 : : static void PutQuadOType (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow, bool checktype);
2812 : :
2813 : : /*
2814 : : UndoReadWriteInfo -
2815 : : */
2816 : :
2817 : : static void UndoReadWriteInfo (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3);
2818 : :
2819 : : /*
2820 : : CheckAddTuple2Read - checks to see whether symbol tuple contains variables or
2821 : : parameters and if so it then adds them to the quadruple
2822 : : variable list.
2823 : : */
2824 : :
2825 : : static void CheckAddTuple2Read (unsigned int tuple, bool canDereference, unsigned int Quad);
2826 : :
2827 : : /*
2828 : : CheckAddVariableRead - checks to see whether symbol, Sym, is a variable or
2829 : : a parameter and if so it then adds this quadruple
2830 : : to the variable list.
2831 : : */
2832 : :
2833 : : static void CheckAddVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad);
2834 : :
2835 : : /*
2836 : : CheckRemoveVariableRead - checks to see whether, Sym, is a variable or
2837 : : a parameter and if so then it removes the
2838 : : quadruple from the variable list.
2839 : : */
2840 : :
2841 : : static void CheckRemoveVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad);
2842 : :
2843 : : /*
2844 : : CheckAddVariableWrite - checks to see whether symbol, Sym, is a variable and
2845 : : if so it then adds this quadruple to the variable list.
2846 : : */
2847 : :
2848 : : static void CheckAddVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad);
2849 : :
2850 : : /*
2851 : : CheckRemoveVariableWrite - checks to see whether, Sym, is a variable and
2852 : : if so then it removes the quadruple from the
2853 : : variable list.
2854 : : */
2855 : :
2856 : : static void CheckRemoveVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad);
2857 : :
2858 : : /*
2859 : : CheckConst -
2860 : : */
2861 : :
2862 : : static void CheckConst (unsigned int sym);
2863 : :
2864 : : /*
2865 : : AlterReference - alters all references from OldQuad, to NewQuad in a
2866 : : quadruple list Head.
2867 : : */
2868 : :
2869 : : static void AlterReference (unsigned int Head, unsigned int OldQuad, unsigned int NewQuad);
2870 : :
2871 : : /*
2872 : : GrowQuads - grows the list of quadruples to the quadruple, to.
2873 : : */
2874 : :
2875 : : static void GrowQuads (unsigned int to);
2876 : :
2877 : : /*
2878 : : ManipulateReference - manipulates the quadruple, q, so that it now points to quad, to.
2879 : : */
2880 : :
2881 : : static void ManipulateReference (unsigned int q, unsigned int to);
2882 : :
2883 : : /*
2884 : : RemoveReference - remove the reference by quadruple q to wherever
2885 : : it was pointing.
2886 : : */
2887 : :
2888 : : static void RemoveReference (unsigned int q);
2889 : :
2890 : : /*
2891 : : NewQuad - sets QuadNo to a new quadruple.
2892 : : */
2893 : :
2894 : : static void NewQuad (unsigned int *QuadNo);
2895 : :
2896 : : /*
2897 : : CheckVariableAt - checks to see whether, sym, was declared at a particular address.
2898 : : */
2899 : :
2900 : : static void CheckVariableAt (unsigned int sym);
2901 : :
2902 : : /*
2903 : : CheckVariablesAt - checks to see whether we need to initialize any pointers
2904 : : which point to variable declared at addresses.
2905 : : */
2906 : :
2907 : : static void CheckVariablesAt (unsigned int scope);
2908 : :
2909 : : /*
2910 : : GetTurnInterrupts - returns the TurnInterrupts procedure function.
2911 : : */
2912 : :
2913 : : static unsigned int GetTurnInterrupts (unsigned int tok);
2914 : :
2915 : : /*
2916 : : GetProtection - returns the PROTECTION data type.
2917 : : */
2918 : :
2919 : : static unsigned int GetProtection (unsigned int tok);
2920 : :
2921 : : /*
2922 : : CheckNeedPriorityBegin - checks to see whether we need to save the old
2923 : : module priority and change to another module
2924 : : priority.
2925 : : The current module initialization or procedure
2926 : : being built is defined by, scope. The module whose
2927 : : priority will be used is defined by, module.
2928 : : */
2929 : :
2930 : : static void CheckNeedPriorityBegin (unsigned int tok, unsigned int scope, unsigned int module);
2931 : :
2932 : : /*
2933 : : CheckNeedPriorityEnd - checks to see whether we need to restore the old
2934 : : module priority.
2935 : : The current module initialization or procedure
2936 : : being built is defined by, scope.
2937 : : */
2938 : :
2939 : : static void CheckNeedPriorityEnd (unsigned int tok, unsigned int scope, unsigned int module);
2940 : :
2941 : : /*
2942 : : BuildRTExceptEnter - informs RTExceptions that we are about to enter the except state.
2943 : : */
2944 : :
2945 : : static void BuildRTExceptEnter (unsigned int tok);
2946 : :
2947 : : /*
2948 : : BuildRTExceptLeave - informs RTExceptions that we are about to leave the except state.
2949 : : If, destroy, is TRUE then pop the ExceptStack.
2950 : : */
2951 : :
2952 : : static void BuildRTExceptLeave (unsigned int tok, bool destroy);
2953 : :
2954 : : /*
2955 : : SafeRequestSym - only used during scaffold to get argc, argv, envp.
2956 : : It attempts to get symbol name from the current scope(s) and if
2957 : : it fails then it falls back onto default constants.
2958 : : */
2959 : :
2960 : : static unsigned int SafeRequestSym (unsigned int tok, NameKey_Name name);
2961 : :
2962 : : /*
2963 : : callRequestDependant - create a call:
2964 : : RequestDependant (GetSymName (modulesym), GetLibName (modulesym),
2965 : : GetSymName (depModuleSym), GetLibName (depModuleSym));
2966 : : */
2967 : :
2968 : : static void callRequestDependant (unsigned int tokno, unsigned int moduleSym, unsigned int depModuleSym, unsigned int requestDep);
2969 : :
2970 : : /*
2971 : : ForeachImportInDepDo -
2972 : : */
2973 : :
2974 : : static void ForeachImportInDepDo (Lists_List importStatements, unsigned int moduleSym, unsigned int requestDep);
2975 : :
2976 : : /*
2977 : : ForeachImportedModuleDo -
2978 : : */
2979 : :
2980 : : static void ForeachImportedModuleDo (unsigned int moduleSym, unsigned int requestDep);
2981 : :
2982 : : /*
2983 : : BuildM2DepFunction - creates the dependency graph procedure using IR:
2984 : : static void
2985 : : dependencies (void)
2986 : : {
2987 : : M2RTS_RequestDependant (module_name, libname, "b", "b libname");
2988 : : M2RTS_RequestDependant (module_name, libname, NULL, NULL);
2989 : : }
2990 : : */
2991 : :
2992 : : static void BuildM2DepFunction (unsigned int tokno, unsigned int moduleSym);
2993 : :
2994 : : /*
2995 : : BuildM2LinkFunction - creates the _M2_link procedure which will
2996 : : cause the linker to pull in all the module ctors.
2997 : : */
2998 : :
2999 : : static void BuildM2LinkFunction (unsigned int tokno);
3000 : :
3001 : : /*
3002 : : BuildTry - build the try statement for main.
3003 : : */
3004 : :
3005 : : static void BuildTry (unsigned int tokno);
3006 : :
3007 : : /*
3008 : : BuildExcept - build the except block for main.
3009 : : */
3010 : :
3011 : : static void BuildExcept (unsigned int tokno);
3012 : :
3013 : : /*
3014 : : BuildM2MainFunction - creates the main function with appropriate calls to the scaffold.
3015 : : */
3016 : :
3017 : : static void BuildM2MainFunction (unsigned int tokno);
3018 : :
3019 : : /*
3020 : : DeferMakeConstStringCnul - return a C const string which will be nul terminated.
3021 : : */
3022 : :
3023 : : static unsigned int DeferMakeConstStringCnul (unsigned int tok, unsigned int sym);
3024 : :
3025 : : /*
3026 : : DeferMakeConstStringM2nul - return a const string which will be nul terminated.
3027 : : */
3028 : :
3029 : : static unsigned int DeferMakeConstStringM2nul (unsigned int tok, unsigned int sym);
3030 : :
3031 : : /*
3032 : : BuildStringAdrParam - push the address of a nul terminated string onto the quad stack.
3033 : : */
3034 : :
3035 : : static void BuildStringAdrParam (unsigned int tok, NameKey_Name name);
3036 : :
3037 : : /*
3038 : : BuildM2InitFunction -
3039 : : */
3040 : :
3041 : : static void BuildM2InitFunction (unsigned int tok, unsigned int moduleSym);
3042 : :
3043 : : /*
3044 : : BuildM2FiniFunction -
3045 : : */
3046 : :
3047 : : static void BuildM2FiniFunction (unsigned int tok, unsigned int moduleSym);
3048 : :
3049 : : /*
3050 : : BuildM2CtorFunction - create a constructor function associated with moduleSym.
3051 : :
3052 : : void
3053 : : ctorFunction ()
3054 : : {
3055 : : M2RTS_RegisterModule (GetSymName (moduleSym), GetLibName (moduleSym),
3056 : : init, fini, dependencies);
3057 : : }
3058 : : */
3059 : :
3060 : : static void BuildM2CtorFunction (unsigned int tok, unsigned int moduleSym);
3061 : :
3062 : : /*
3063 : : AddForInfo - adds the description of the FOR loop into the record list.
3064 : : This is used if -pedantic is turned on to check index variable
3065 : : usage.
3066 : : */
3067 : :
3068 : : static void AddForInfo (unsigned int Start, unsigned int End, unsigned int IncQuad, unsigned int Sym, unsigned int idtok);
3069 : :
3070 : : /*
3071 : : CheckForIndex - checks the quadruples: Start..End to see whether a
3072 : : for loop index is manipulated by the programmer.
3073 : : It generates a warning if this is the case.
3074 : : It also checks to see whether the IndexSym is read
3075 : : immediately outside the loop in which case a warning
3076 : : is issued.
3077 : : */
3078 : :
3079 : : static void CheckForIndex (M2Quads_ForLoopInfo forDesc);
3080 : :
3081 : : /*
3082 : : BuildRange - generates a RangeCheckOp quad with, r, as its operand.
3083 : : */
3084 : :
3085 : : static void BuildRange (unsigned int r);
3086 : :
3087 : : /*
3088 : : BuildError - generates a ErrorOp quad, indicating that if this
3089 : : quadruple is reachable, then a runtime error would
3090 : : occur.
3091 : : */
3092 : :
3093 : : static void BuildError (unsigned int r);
3094 : :
3095 : : /*
3096 : : CheckPointerThroughNil - builds a range quadruple, providing, sym, is
3097 : : a candidate for checking against NIL.
3098 : : This range quadruple is only expanded into
3099 : : code during the code generation phase
3100 : : thus allowing limited compile time checking.
3101 : : */
3102 : :
3103 : : static void CheckPointerThroughNil (unsigned int tokpos, unsigned int sym);
3104 : :
3105 : : /*
3106 : : CollectLow - returns the low of the subrange value.
3107 : : */
3108 : :
3109 : : static unsigned int CollectLow (unsigned int sym);
3110 : :
3111 : : /*
3112 : : CollectHigh - returns the high of the subrange value, sym.
3113 : : */
3114 : :
3115 : : static unsigned int CollectHigh (unsigned int sym);
3116 : :
3117 : : /*
3118 : : CheckCompatibleWithBecomes - checks to see that symbol, sym, is
3119 : : compatible with the := operator.
3120 : : */
3121 : :
3122 : : static void CheckCompatibleWithBecomes (unsigned int des, unsigned int expr, unsigned int destok, unsigned int exprtok);
3123 : :
3124 : : /*
3125 : : BuildAssignmentWithoutBounds - calls BuildAssignment but makes sure we do not
3126 : : check bounds.
3127 : : */
3128 : :
3129 : : static void BuildAssignmentWithoutBounds (unsigned int tok, bool checkTypes, bool checkOverflow);
3130 : :
3131 : : /*
3132 : : MarkArrayWritten - marks, Array, as being written.
3133 : : */
3134 : :
3135 : : static void MarkArrayWritten (unsigned int Array);
3136 : :
3137 : : /*
3138 : : MarkAsReadWrite - marks the variable or parameter as being
3139 : : read/write.
3140 : : */
3141 : :
3142 : : static void MarkAsReadWrite (unsigned int sym);
3143 : :
3144 : : /*
3145 : : MarkAsRead - marks the variable or parameter as being read.
3146 : : */
3147 : :
3148 : : static void MarkAsRead (unsigned int sym);
3149 : :
3150 : : /*
3151 : : MarkAsWrite - marks the variable or parameter as being written.
3152 : : */
3153 : :
3154 : : static void MarkAsWrite (unsigned int sym);
3155 : :
3156 : : /*
3157 : : doVal - return an expression which is VAL(type, expr). If
3158 : : expr is a constant then return expr.
3159 : : */
3160 : :
3161 : : static unsigned int doVal (unsigned int type, unsigned int expr);
3162 : :
3163 : : /*
3164 : : MoveWithMode -
3165 : : */
3166 : :
3167 : : static void MoveWithMode (unsigned int tokno, unsigned int Des, unsigned int Exp, unsigned int Array, unsigned int destok, unsigned int exptok, bool checkOverflow);
3168 : :
3169 : : /*
3170 : : CheckBecomesMeta - checks to make sure that we are not
3171 : : assigning a variable to a constant.
3172 : : Also check we are not assigning to an
3173 : : unbounded array.
3174 : : */
3175 : :
3176 : : static void CheckBecomesMeta (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok);
3177 : :
3178 : : /*
3179 : : BuildAssignmentBoolean - build the quadruples for a boolean variable or constant
3180 : : which will be assigned to the result of a boolean expression.
3181 : : For example:
3182 : :
3183 : : foo := a = b ;
3184 : : foo := a IN b ;
3185 : :
3186 : : The boolean result is contained in the control flow
3187 : : the true value will emerge from the quad path t.
3188 : : The false value will emerge from the quad path f.
3189 : : This procedure terminates both paths by backpatching
3190 : : and assigns TRUE or FALSE to the variable/constant.
3191 : : A variable maybe an L value so it will require dereferencing.
3192 : : */
3193 : :
3194 : : static void BuildAssignmentBoolean (unsigned int becomesTokNo, bool checkOverflow, unsigned int t, unsigned int f, unsigned int Des, unsigned int destok);
3195 : :
3196 : : /*
3197 : : doBuildAssignment - subsiduary procedure of BuildAssignment.
3198 : : It builds the assignment and optionally
3199 : : checks the types are compatible.
3200 : : */
3201 : :
3202 : : static void doBuildAssignment (unsigned int becomesTokNo, bool checkTypes, bool checkOverflow);
3203 : :
3204 : : /*
3205 : : CheckAssignCompatible - checks to see that an assignment is compatible.
3206 : : It performs limited checking - thorough checking
3207 : : is done in pass 3. But we do what we can here
3208 : : given knowledge so far.
3209 : : */
3210 : :
3211 : : static void CheckAssignCompatible (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok);
3212 : :
3213 : : /*
3214 : : CheckBooleanId - Checks to see if the top operand is a boolean.
3215 : : If the operand is not a boolean then it is tested
3216 : : with true and a boolean is generated.
3217 : : The Stack:
3218 : :
3219 : :
3220 : : Entry Exit
3221 : : Ptr -> <- Ptr
3222 : : +------------+ +------------+
3223 : : | Sym | | t | f |
3224 : : |------------| |------------|
3225 : :
3226 : : Quadruples
3227 : :
3228 : : q If= Sym True _
3229 : : q+1 GotoOp _ _ _
3230 : : */
3231 : :
3232 : : static void CheckBooleanId (void);
3233 : :
3234 : : /*
3235 : : PushOne - pushes the value one to the stack.
3236 : : The Stack is changed:
3237 : :
3238 : :
3239 : : Entry Exit
3240 : : ===== ====
3241 : :
3242 : : <- Ptr
3243 : : +------------+
3244 : : Ptr -> | 1 | type |
3245 : : |------------|
3246 : : */
3247 : :
3248 : : static void PushOne (unsigned int tok, unsigned int type, const char *message_, unsigned int _message_high);
3249 : :
3250 : : /*
3251 : : PushZero - pushes the value zero to the stack.
3252 : : The Stack is changed:
3253 : :
3254 : :
3255 : : Entry Exit
3256 : : ===== ====
3257 : :
3258 : : <- Ptr
3259 : : +------------+
3260 : : Ptr -> | 0 | type |
3261 : : |------------|
3262 : : */
3263 : :
3264 : : static void PushZero (unsigned int tok, unsigned int type);
3265 : :
3266 : : /*
3267 : : ForLoopLastIterator - calculate the last iterator value but avoid setting
3268 : : LastIterator twice if it is a constant (in the quads).
3269 : : In the ForLoopLastIteratorVariable case only one
3270 : : path will be chosen but at the time of quadruple
3271 : : generation we do not know the value of BySym.
3272 : : */
3273 : :
3274 : : static void ForLoopLastIterator (unsigned int LastIterator, unsigned int e1, unsigned int e2, unsigned int BySym, unsigned int e1tok, unsigned int e2tok, unsigned int bytok);
3275 : :
3276 : : /*
3277 : : BuildSizeCheckEnd - checks to see whether the function "called" was in fact SIZE.
3278 : : If so then we restore quadruple generation.
3279 : : */
3280 : :
3281 : : static void BuildSizeCheckEnd (unsigned int ProcSym);
3282 : :
3283 : : /*
3284 : : BuildRealProcedureCall - builds a real procedure call.
3285 : : The Stack:
3286 : :
3287 : :
3288 : : Entry Exit
3289 : :
3290 : : Ptr ->
3291 : : +----------------+
3292 : : | NoOfParam |
3293 : : |----------------|
3294 : : | Param 1 |
3295 : : |----------------|
3296 : : | Param 2 |
3297 : : |----------------|
3298 : : . .
3299 : : . .
3300 : : . .
3301 : : |----------------|
3302 : : | Param # |
3303 : : |----------------|
3304 : : | ProcSym | Type | Empty
3305 : : |----------------|
3306 : : */
3307 : :
3308 : : static void BuildRealProcedureCall (unsigned int tokno);
3309 : :
3310 : : /*
3311 : : BuildRealFuncProcCall - builds a real procedure or function call.
3312 : : The Stack:
3313 : :
3314 : :
3315 : : Entry Exit
3316 : :
3317 : : Ptr ->
3318 : : +----------------+
3319 : : | NoOfParam |
3320 : : |----------------|
3321 : : | Param 1 |
3322 : : |----------------|
3323 : : | Param 2 |
3324 : : |----------------|
3325 : : . .
3326 : : . .
3327 : : . .
3328 : : |----------------|
3329 : : | Param # |
3330 : : |----------------|
3331 : : | ProcSym | Type | Empty
3332 : : |----------------|
3333 : : */
3334 : :
3335 : : static void BuildRealFuncProcCall (unsigned int tokno, bool IsFunc, bool IsForC, bool ConstExpr);
3336 : :
3337 : : /*
3338 : : CheckProcedureParameters - Checks the parameters which are being passed to
3339 : : procedure ProcSym.
3340 : :
3341 : : The Stack:
3342 : :
3343 : :
3344 : : Entry Exit
3345 : :
3346 : : Ptr -> <- Ptr
3347 : : +----------------+ +----------------+
3348 : : | NoOfParam | | NoOfParam |
3349 : : |----------------| |----------------|
3350 : : | Param 1 | | Param 1 |
3351 : : |----------------| |----------------|
3352 : : | Param 2 | | Param 2 |
3353 : : |----------------| |----------------|
3354 : : . . . .
3355 : : . . . .
3356 : : . . . .
3357 : : |----------------| |----------------|
3358 : : | Param # | | Param # |
3359 : : |----------------| |----------------|
3360 : : | ProcSym | Type | | ProcSym | Type |
3361 : : |----------------| |----------------|
3362 : :
3363 : : */
3364 : :
3365 : : static void CheckProcedureParameters (bool IsForC);
3366 : :
3367 : : /*
3368 : : CheckProcTypeAndProcedure - checks the ProcType with the call.
3369 : : */
3370 : :
3371 : : static void CheckProcTypeAndProcedure (unsigned int tokno, unsigned int ProcType, unsigned int call, unsigned int ParamCheckId);
3372 : :
3373 : : /*
3374 : : IsReallyPointer - returns TRUE is sym is a pointer, address or a type declared
3375 : : as a pointer or address.
3376 : : */
3377 : :
3378 : : static bool IsReallyPointer (unsigned int Sym);
3379 : :
3380 : : /*
3381 : : LegalUnboundedParam - returns TRUE if the parameter, Actual, can legitimately be
3382 : : passed to ProcSym, i, the, Formal, parameter.
3383 : : */
3384 : :
3385 : : static bool LegalUnboundedParam (unsigned int tokpos, unsigned int ProcSym, unsigned int i, unsigned int ActualType, unsigned int Actual, unsigned int Dimension, unsigned int Formal);
3386 : :
3387 : : /*
3388 : : CheckParameter - checks that types ActualType and FormalType are compatible for parameter
3389 : : passing. ProcSym is the procedure and i is the parameter number.
3390 : :
3391 : : We obey the following rules:
3392 : :
3393 : : (1) we allow WORD, BYTE, LOC to be compitable with any like sized
3394 : : type.
3395 : : (2) we allow ADDRESS to be compatible with any pointer type.
3396 : : (3) we relax INTEGER and CARDINAL checking for Temporary variables.
3397 : :
3398 : : Note that type sizes are checked during the code generation pass.
3399 : : */
3400 : :
3401 : : static void CheckParameter (unsigned int tokpos, unsigned int Actual, unsigned int Dimension, unsigned int Formal, unsigned int ProcSym, unsigned int i, Lists_List TypeList, unsigned int ParamCheckId);
3402 : :
3403 : : /*
3404 : : DescribeType - returns a String describing a symbol, Sym, name and its type.
3405 : : */
3406 : :
3407 : : static DynamicStrings_String DescribeType (unsigned int Sym);
3408 : :
3409 : : /*
3410 : : FailParameter - generates an error message indicating that a parameter
3411 : : declaration has failed.
3412 : :
3413 : : The parameters are:
3414 : :
3415 : : CurrentState - string describing the current failing state.
3416 : : Actual - actual parameter.
3417 : : ParameterNo - parameter number that has failed.
3418 : : ProcedureSym - procedure symbol where parameter has failed.
3419 : :
3420 : : If any parameter is Nul then it is ignored.
3421 : : */
3422 : :
3423 : : static void FailParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo);
3424 : :
3425 : : /*
3426 : : WarnParameter - generates a warning message indicating that a parameter
3427 : : use might cause problems on another target.
3428 : :
3429 : : CurrentState - string describing the current failing state.
3430 : : Actual - actual parameter.
3431 : : ParameterNo - parameter number that has failed.
3432 : : ProcedureSym - procedure symbol where parameter has failed.
3433 : :
3434 : : If any parameter is Nul then it is ignored.
3435 : : */
3436 : :
3437 : : static void WarnParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo);
3438 : :
3439 : : /*
3440 : : doIndrX - perform des = *exp with a conversion if necessary.
3441 : : */
3442 : :
3443 : : static void doIndrX (unsigned int tok, unsigned int des, unsigned int exp);
3444 : :
3445 : : /*
3446 : : MakeRightValue - returns a temporary which will have the RightValue of symbol, Sym.
3447 : : If Sym is a right value and has type, type, then no quadruples are
3448 : : generated and Sym is returned. Otherwise a new temporary is created
3449 : : and an IndrX quadruple is generated.
3450 : : */
3451 : :
3452 : : static unsigned int MakeRightValue (unsigned int tok, unsigned int Sym, unsigned int type);
3453 : :
3454 : : /*
3455 : : MakeLeftValue - returns a temporary coresponding to the LeftValue of
3456 : : symbol, Sym. No quadruple is generated if Sym is already
3457 : : a LeftValue and has the same type.
3458 : : */
3459 : :
3460 : : static unsigned int MakeLeftValue (unsigned int tok, unsigned int Sym, SymbolTable_ModeOfAddr with, unsigned int type);
3461 : :
3462 : : /*
3463 : : ManipulatePseudoCallParameters - manipulates the parameters to a pseudo function or
3464 : : procedure. It dereferences all LeftValue parameters
3465 : : and Boolean parameters.
3466 : : The Stack:
3467 : :
3468 : :
3469 : : Entry Exit
3470 : :
3471 : : Ptr -> exactly the same
3472 : : +----------------+
3473 : : | NoOfParameters |
3474 : : |----------------|
3475 : : | Param 1 |
3476 : : |----------------|
3477 : : | Param 2 |
3478 : : |----------------|
3479 : : . .
3480 : : . .
3481 : : . .
3482 : : |----------------|
3483 : : | Param # |
3484 : : |----------------|
3485 : : | ProcSym | Type |
3486 : : |----------------|
3487 : :
3488 : : */
3489 : :
3490 : : static void ManipulatePseudoCallParameters (void);
3491 : :
3492 : : /*
3493 : : ManipulateParameters - manipulates the procedure parameters in
3494 : : preparation for a procedure call.
3495 : : Prepares Boolean, Unbounded and VAR parameters.
3496 : : The Stack:
3497 : :
3498 : :
3499 : : Entry Exit
3500 : :
3501 : : Ptr -> exactly the same
3502 : : +----------------+
3503 : : | NoOfParameters |
3504 : : |----------------|
3505 : : | Param 1 |
3506 : : |----------------|
3507 : : | Param 2 |
3508 : : |----------------|
3509 : : . .
3510 : : . .
3511 : : . .
3512 : : |----------------|
3513 : : | Param # |
3514 : : |----------------|
3515 : : | ProcSym | Type |
3516 : : |----------------|
3517 : : */
3518 : :
3519 : : static void ManipulateParameters (bool IsForC);
3520 : :
3521 : : /*
3522 : : CheckParameterOrdinals - check that ordinal values are within type range.
3523 : : */
3524 : :
3525 : : static void CheckParameterOrdinals (void);
3526 : :
3527 : : /*
3528 : : IsSameUnbounded - returns TRUE if unbounded types, t1, and, t2,
3529 : : are compatible.
3530 : : */
3531 : :
3532 : : static bool IsSameUnbounded (unsigned int t1, unsigned int t2);
3533 : :
3534 : : /*
3535 : : AssignUnboundedVar - assigns an Unbounded symbol fields,
3536 : : ArrayAddress and ArrayHigh, from an array symbol.
3537 : : UnboundedSym is not a VAR parameter and therefore
3538 : : this procedure can complete both of the fields.
3539 : : Sym can be a Variable with type Unbounded.
3540 : : Sym can be a Variable with type Array.
3541 : : Sym can be a String Constant.
3542 : :
3543 : : ParamType is the TYPE of the parameter
3544 : : */
3545 : :
3546 : : static void AssignUnboundedVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3547 : :
3548 : : /*
3549 : : AssignUnboundedNonVar - assigns an Unbounded symbol fields,
3550 : : The difference between this procedure and
3551 : : AssignUnboundedVar is that this procedure cannot
3552 : : set the Unbounded.Address since the data from
3553 : : Sym will be copied because parameter is NOT a VAR
3554 : : parameter.
3555 : : UnboundedSym is not a VAR parameter and therefore
3556 : : this procedure can only complete the HIGH field
3557 : : and not the ADDRESS field.
3558 : : Sym can be a Variable with type Unbounded.
3559 : : Sym can be a Variable with type Array.
3560 : : Sym can be a String Constant.
3561 : :
3562 : : ParamType is the TYPE of the paramater
3563 : : */
3564 : :
3565 : : static void AssignUnboundedNonVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3566 : :
3567 : : /*
3568 : : GenHigh - generates a HighOp but it checks if op3 is a
3569 : : L value and if so it dereferences it. This
3570 : : is inefficient, however it is clean and we let the gcc
3571 : : backend detect these as common subexpressions.
3572 : : It will also detect that a R value -> L value -> R value
3573 : : via indirection and eleminate these.
3574 : : */
3575 : :
3576 : : static void GenHigh (unsigned int tok, unsigned int op1, unsigned int op2, unsigned int op3);
3577 : :
3578 : : /*
3579 : : AssignHighField -
3580 : : */
3581 : :
3582 : : static void AssignHighField (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int actuali, unsigned int formali);
3583 : :
3584 : : /*
3585 : : AssignHighFields -
3586 : : */
3587 : :
3588 : : static void AssignHighFields (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3589 : :
3590 : : /*
3591 : : UnboundedNonVarLinkToArray - links an array, ArraySym, to an unbounded
3592 : : array, UnboundedSym. The parameter is a
3593 : : NON VAR variety.
3594 : : */
3595 : :
3596 : : static void UnboundedNonVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3597 : :
3598 : : /*
3599 : : UnboundedVarLinkToArray - links an array, ArraySym, to an unbounded array,
3600 : : UnboundedSym. The parameter is a VAR variety.
3601 : : */
3602 : :
3603 : : static void UnboundedVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3604 : :
3605 : : /*
3606 : : BuildPseudoProcedureCall - builds a pseudo procedure call.
3607 : : This procedure does not directly alter the
3608 : : stack, but by calling routines the stack
3609 : : will change in the following way when this
3610 : : procedure returns.
3611 : :
3612 : : The Stack:
3613 : :
3614 : :
3615 : : Entry Exit
3616 : :
3617 : : Ptr ->
3618 : : +----------------+
3619 : : | NoOfParam |
3620 : : |----------------|
3621 : : | Param 1 |
3622 : : |----------------|
3623 : : | Param 2 |
3624 : : |----------------|
3625 : : . .
3626 : : . .
3627 : : . .
3628 : : |----------------|
3629 : : | Param # |
3630 : : |----------------|
3631 : : | ProcSym | Type | Empty
3632 : : |----------------|
3633 : : */
3634 : :
3635 : : static void BuildPseudoProcedureCall (unsigned int tokno);
3636 : :
3637 : : /*
3638 : : GetItemPointedTo - returns the symbol type that is being pointed to
3639 : : by Sym.
3640 : : */
3641 : :
3642 : : static unsigned int GetItemPointedTo (unsigned int Sym);
3643 : :
3644 : : /*
3645 : : BuildThrowProcedure - builds the pseudo procedure call M2RTS.Throw.
3646 : : The Stack:
3647 : :
3648 : :
3649 : : Entry Exit
3650 : :
3651 : : Ptr ->
3652 : : +----------------+
3653 : : | NoOfParam |
3654 : : |----------------|
3655 : : | Param 1 |
3656 : : |----------------|
3657 : : | Param 2 |
3658 : : |----------------|
3659 : : . .
3660 : : . .
3661 : : . .
3662 : : |----------------|
3663 : : | Param # |
3664 : : |----------------|
3665 : : | ProcSym | Type | Empty
3666 : : |----------------|
3667 : : */
3668 : :
3669 : : static void BuildThrowProcedure (unsigned int functok);
3670 : :
3671 : : /*
3672 : : BuildNewProcedure - builds the pseudo procedure call NEW.
3673 : : This procedure is traditionally a "macro" for
3674 : : NEW(x, ...) --> ALLOCATE(x, TSIZE(x^, ...))
3675 : : One method of implementation is to emulate a "macro"
3676 : : processor by pushing the relevant input tokens
3677 : : back onto the input stack.
3678 : : However this causes two problems:
3679 : :
3680 : : (i) Unnecessary code is produced for x^
3681 : : (ii) SIZE must be imported from SYSTEM
3682 : : Therefore we chose an alternative method of
3683 : : implementation;
3684 : : generate quadruples for ALLOCATE(x, TSIZE(x^, ...))
3685 : : this, although slightly more efficient,
3686 : : is more complex and circumvents problems (i) and (ii).
3687 : :
3688 : : The Stack:
3689 : :
3690 : :
3691 : : Entry Exit
3692 : :
3693 : : Ptr ->
3694 : : +----------------+
3695 : : | NoOfParam |
3696 : : |----------------|
3697 : : | Param 1 |
3698 : : |----------------|
3699 : : | Param 2 |
3700 : : |----------------|
3701 : : . .
3702 : : . .
3703 : : . .
3704 : : |----------------|
3705 : : | Param # |
3706 : : |----------------|
3707 : : | ProcSym | Type | Empty
3708 : : |----------------|
3709 : : */
3710 : :
3711 : : static void BuildNewProcedure (unsigned int functok);
3712 : :
3713 : : /*
3714 : : BuildDisposeProcedure - builds the pseudo procedure call DISPOSE.
3715 : : This procedure is traditionally a "macro" for
3716 : : DISPOSE(x) --> DEALLOCATE(x, TSIZE(x^))
3717 : : One method of implementation is to emulate a "macro"
3718 : : processor by pushing the relevant input tokens
3719 : : back onto the input stack.
3720 : : However this causes two problems:
3721 : :
3722 : : (i) Unnecessary code is produced for x^
3723 : : (ii) TSIZE must be imported from SYSTEM
3724 : : Therefore we chose an alternative method of
3725 : : implementation;
3726 : : generate quadruples for DEALLOCATE(x, TSIZE(x^))
3727 : : this, although slightly more efficient,
3728 : : is more complex and circumvents problems (i)
3729 : : and (ii).
3730 : :
3731 : : The Stack:
3732 : :
3733 : :
3734 : : Entry Exit
3735 : :
3736 : : Ptr ->
3737 : : +----------------+
3738 : : | NoOfParam |
3739 : : |----------------|
3740 : : | Param 1 |
3741 : : |----------------|
3742 : : | Param 2 |
3743 : : |----------------|
3744 : : . .
3745 : : . .
3746 : : . .
3747 : : |----------------|
3748 : : | Param # |
3749 : : |----------------|
3750 : : | ProcSym | Type | Empty
3751 : : |----------------|
3752 : : */
3753 : :
3754 : : static void BuildDisposeProcedure (unsigned int functok);
3755 : :
3756 : : /*
3757 : : CheckRangeIncDec - performs des := des <tok> expr
3758 : : with range checking (if enabled).
3759 : :
3760 : : Stack
3761 : : Entry Exit
3762 : :
3763 : : +------------+
3764 : : empty | des + expr |
3765 : : |------------|
3766 : : */
3767 : :
3768 : : static void CheckRangeIncDec (unsigned int tokenpos, unsigned int des, unsigned int expr, NameKey_Name tok);
3769 : :
3770 : : /*
3771 : : BuildIncProcedure - builds the pseudo procedure call INC.
3772 : : INC is a procedure which increments a variable.
3773 : : It takes one or two parameters:
3774 : : INC(a, b) or INC(a)
3775 : : a := a+b or a := a+1
3776 : :
3777 : : The Stack:
3778 : :
3779 : :
3780 : : Entry Exit
3781 : :
3782 : : Ptr ->
3783 : : +----------------+
3784 : : | NoOfParam |
3785 : : |----------------|
3786 : : | Param 1 |
3787 : : |----------------|
3788 : : | Param 2 |
3789 : : |----------------|
3790 : : . .
3791 : : . .
3792 : : . .
3793 : : |----------------|
3794 : : | Param # |
3795 : : |----------------|
3796 : : | ProcSym | Type | Empty
3797 : : |----------------|
3798 : : */
3799 : :
3800 : : static void BuildIncProcedure (unsigned int proctok);
3801 : :
3802 : : /*
3803 : : BuildDecProcedure - builds the pseudo procedure call DEC.
3804 : : DEC is a procedure which decrements a variable.
3805 : : It takes one or two parameters:
3806 : : DEC(a, b) or DEC(a)
3807 : : a := a-b or a := a-1
3808 : :
3809 : : The Stack:
3810 : :
3811 : :
3812 : : Entry Exit
3813 : :
3814 : : Ptr ->
3815 : : +----------------+
3816 : : | NoOfParam |
3817 : : |----------------|
3818 : : | Param 1 |
3819 : : |----------------|
3820 : : | Param 2 |
3821 : : |----------------|
3822 : : . .
3823 : : . .
3824 : : . .
3825 : : |----------------|
3826 : : | Param # |
3827 : : |----------------|
3828 : : | ProcSym | Type | Empty
3829 : : |----------------|
3830 : : */
3831 : :
3832 : : static void BuildDecProcedure (unsigned int proctok);
3833 : :
3834 : : /*
3835 : : DereferenceLValue - checks to see whether, operand, is declare as an LValue
3836 : : and if so it dereferences it.
3837 : : */
3838 : :
3839 : : static unsigned int DereferenceLValue (unsigned int tok, unsigned int operand);
3840 : :
3841 : : /*
3842 : : BuildInclProcedure - builds the pseudo procedure call INCL.
3843 : : INCL is a procedure which adds bit b into a BITSET a.
3844 : : It takes two parameters:
3845 : : INCL(a, b)
3846 : :
3847 : : a := a + {b}
3848 : :
3849 : : The Stack:
3850 : :
3851 : :
3852 : : Entry Exit
3853 : :
3854 : : Ptr ->
3855 : : +----------------+
3856 : : | NoOfParam |
3857 : : |----------------|
3858 : : | Param 1 |
3859 : : |----------------|
3860 : : | Param 2 |
3861 : : |----------------|
3862 : : | ProcSym | Type | Empty
3863 : : |----------------|
3864 : : */
3865 : :
3866 : : static void BuildInclProcedure (unsigned int proctok);
3867 : :
3868 : : /*
3869 : : BuildExclProcedure - builds the pseudo procedure call EXCL.
3870 : : INCL is a procedure which removes bit b from SET a.
3871 : : It takes two parameters:
3872 : : EXCL(a, b)
3873 : :
3874 : : a := a - {b}
3875 : :
3876 : : The Stack:
3877 : :
3878 : :
3879 : : Entry Exit
3880 : :
3881 : : Ptr ->
3882 : : +----------------+
3883 : : | NoOfParam |
3884 : : |----------------|
3885 : : | Param 1 |
3886 : : |----------------|
3887 : : | Param 2 |
3888 : : |----------------|
3889 : : | ProcSym | Type | Empty
3890 : : |----------------|
3891 : : */
3892 : :
3893 : : static void BuildExclProcedure (unsigned int proctok);
3894 : :
3895 : : /*
3896 : : BuildTypeCoercion - builds the type coersion.
3897 : : Modula-2 allows types to be coersed with no runtime
3898 : : penility.
3899 : : It insists that the TSIZE(t1)=TSIZE(t2) where
3900 : : t2 variable := t2(variable of type t1).
3901 : : The ReturnVar on the stack is of type t2.
3902 : :
3903 : : The Stack:
3904 : :
3905 : :
3906 : : Entry Exit
3907 : :
3908 : : Ptr ->
3909 : : +----------------+
3910 : : | NoOfParam |
3911 : : |----------------|
3912 : : | Param 1 |
3913 : : |----------------|
3914 : : | Param 2 |
3915 : : |----------------|
3916 : : . .
3917 : : . .
3918 : : . .
3919 : : |----------------|
3920 : : | Param # | <- Ptr
3921 : : |----------------| +------------+
3922 : : | ProcSym | Type | | ReturnVar |
3923 : : |----------------| |------------|
3924 : :
3925 : : Quadruples:
3926 : :
3927 : : CoerceOp ReturnVar Type Param1
3928 : :
3929 : : A type coercion will only be legal if the different
3930 : : types have exactly the same size.
3931 : : Since we can only decide this after M2Eval has processed
3932 : : the symbol table then we create a quadruple explaining
3933 : : the coercion taking place, the code generator can test
3934 : : this assertion and report an error if the type sizes
3935 : : differ.
3936 : : */
3937 : :
3938 : : static void BuildTypeCoercion (bool ConstExpr);
3939 : :
3940 : : /*
3941 : : BuildRealFunctionCall - builds a function call.
3942 : : The Stack:
3943 : :
3944 : :
3945 : : Entry Exit
3946 : :
3947 : : Ptr ->
3948 : : +----------------+
3949 : : | NoOfParam |
3950 : : |----------------|
3951 : : | Param 1 |
3952 : : |----------------|
3953 : : | Param 2 |
3954 : : |----------------|
3955 : : . .
3956 : : . .
3957 : : . .
3958 : : |----------------|
3959 : : | Param # | <- Ptr
3960 : : |----------------| +------------+
3961 : : | ProcSym | Type | | ReturnVar |
3962 : : |----------------| |------------|
3963 : : */
3964 : :
3965 : : static void BuildRealFunctionCall (unsigned int tokno, bool ConstExpr);
3966 : :
3967 : : /*
3968 : : BuildPseudoFunctionCall - builds the pseudo function
3969 : : The Stack:
3970 : :
3971 : :
3972 : : Entry Exit
3973 : :
3974 : : Ptr ->
3975 : : +----------------+
3976 : : | NoOfParam |
3977 : : |----------------|
3978 : : | Param 1 |
3979 : : |----------------|
3980 : : | Param 2 |
3981 : : |----------------|
3982 : : . .
3983 : : . .
3984 : : . .
3985 : : |----------------|
3986 : : | Param # | <- Ptr
3987 : : |----------------| +------------+
3988 : : | ProcSym | Type | | ReturnVar |
3989 : : |----------------| |------------|
3990 : :
3991 : : */
3992 : :
3993 : : static void BuildPseudoFunctionCall (bool ConstExpr);
3994 : :
3995 : : /*
3996 : : BuildAddAdrFunction - builds the pseudo procedure call ADDADR.
3997 : :
3998 : : PROCEDURE ADDADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
3999 : :
4000 : : Which returns address given by (addr + offset),
4001 : : [ the standard says that it _may_
4002 : : "raise an exception if this address is not valid."
4003 : : currently we do not generate any exception code ]
4004 : :
4005 : : The Stack:
4006 : :
4007 : : Entry Exit
4008 : :
4009 : : Ptr ->
4010 : : +----------------+
4011 : : | NoOfParam |
4012 : : |----------------|
4013 : : | Param 1 |
4014 : : |----------------|
4015 : : | Param 2 | <- Ptr
4016 : : |----------------| +------------+
4017 : : | ProcSym | Type | | ReturnVar |
4018 : : |----------------| |------------|
4019 : : */
4020 : :
4021 : : static void BuildAddAdrFunction (unsigned int ProcSym, bool ConstExpr);
4022 : :
4023 : : /*
4024 : : BuildSubAdrFunction - builds the pseudo procedure call ADDADR.
4025 : :
4026 : : PROCEDURE SUBADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
4027 : :
4028 : : Which returns address given by (addr - offset),
4029 : : [ the standard says that it _may_
4030 : : "raise an exception if this address is not valid."
4031 : : currently we do not generate any exception code ]
4032 : :
4033 : : The Stack:
4034 : :
4035 : : Entry Exit
4036 : :
4037 : : Ptr ->
4038 : : +----------------+
4039 : : | NoOfParam |
4040 : : |----------------|
4041 : : | Param 1 |
4042 : : |----------------|
4043 : : | Param 2 | <- Ptr
4044 : : |----------------| +------------+
4045 : : | ProcSym | Type | | ReturnVar |
4046 : : |----------------| |------------|
4047 : : */
4048 : :
4049 : : static void BuildSubAdrFunction (unsigned int ProcSym, bool ConstExpr);
4050 : :
4051 : : /*
4052 : : BuildDifAdrFunction - builds the pseudo procedure call DIFADR.
4053 : :
4054 : : PROCEDURE DIFADR (addr1, addr2: ADDRESS): INTEGER ;
4055 : :
4056 : : Which returns address given by (addr1 - addr2),
4057 : : [ the standard says that it _may_
4058 : : "raise an exception if this address is invalid or
4059 : : address space is non-contiguous."
4060 : : currently we do not generate any exception code ]
4061 : :
4062 : : The Stack:
4063 : :
4064 : : Entry Exit
4065 : :
4066 : : Ptr ->
4067 : : +----------------+
4068 : : | NoOfParam |
4069 : : |----------------|
4070 : : | Param 1 |
4071 : : |----------------|
4072 : : | Param 2 | <- Ptr
4073 : : |----------------| +------------+
4074 : : | ProcSym | Type | | ReturnVar |
4075 : : |----------------| |------------|
4076 : : */
4077 : :
4078 : : static void BuildDifAdrFunction (unsigned int ProcSym, bool ConstExpr);
4079 : :
4080 : : /*
4081 : : BuildHighFunction - checks the stack in preparation for generating
4082 : : quadruples which perform HIGH.
4083 : : This procedure does not alter the stack but
4084 : : determines whether, a, in HIGH(a) is an ArraySym
4085 : : or UnboundedSym.
4086 : : Both cases are different and appropriate quadruple
4087 : : generating routines are called.
4088 : :
4089 : : The Stack:
4090 : :
4091 : :
4092 : : Entry Exit
4093 : :
4094 : : Ptr ->
4095 : : +----------------+
4096 : : | NoOfParam |
4097 : : |----------------|
4098 : : | Param 1 |
4099 : : |----------------|
4100 : : | Param 2 |
4101 : : |----------------|
4102 : : . .
4103 : : . .
4104 : : . .
4105 : : |----------------|
4106 : : | Param # | <- Ptr
4107 : : |----------------| +------------+
4108 : : | ProcSym | Type | | ReturnVar |
4109 : : |----------------| |------------|
4110 : :
4111 : : */
4112 : :
4113 : : static void BuildHighFunction (void);
4114 : :
4115 : : /*
4116 : : BuildConstHighFromSym - builds the pseudo function HIGH from an Sym.
4117 : : Sym is a constant or an array which has constant bounds
4118 : : and therefore it can be calculated at compile time.
4119 : :
4120 : : The Stack:
4121 : :
4122 : :
4123 : : Entry Exit
4124 : :
4125 : : Ptr ->
4126 : : +----------------+
4127 : : | NoOfParam |
4128 : : |----------------|
4129 : : | Param 1 |
4130 : : |----------------|
4131 : : | Param 2 |
4132 : : |----------------|
4133 : : . .
4134 : : . .
4135 : : . .
4136 : : |----------------|
4137 : : | Param # | <- Ptr
4138 : : |----------------| +------------+
4139 : : | ProcSym | Type | | ReturnVar |
4140 : : |----------------| |------------|
4141 : : */
4142 : :
4143 : : static void BuildConstHighFromSym (unsigned int tok);
4144 : :
4145 : : /*
4146 : : BuildHighFromUnbounded - builds the pseudo function HIGH from an
4147 : : UnboundedSym.
4148 : :
4149 : : The Stack:
4150 : :
4151 : :
4152 : : Entry Exit
4153 : :
4154 : : Ptr ->
4155 : : +----------------+
4156 : : | NoOfParam |
4157 : : |----------------|
4158 : : | Param # | <- Ptr
4159 : : |----------------| +------------+
4160 : : | ProcSym | Type | | ReturnVar |
4161 : : |----------------| |------------|
4162 : :
4163 : : */
4164 : :
4165 : : static void BuildHighFromUnbounded (unsigned int tok);
4166 : :
4167 : : /*
4168 : : GetQualidentImport - returns the symbol as if it were qualified from, module.n.
4169 : : This is used to reference runtime support procedures and an
4170 : : error is generated if the symbol cannot be obtained.
4171 : : */
4172 : :
4173 : : static unsigned int GetQualidentImport (unsigned int tokno, NameKey_Name n, NameKey_Name module);
4174 : :
4175 : : /*
4176 : : ConstExprError - return TRUE if a constant expression is being built and Var is a variable.
4177 : : */
4178 : :
4179 : : static bool ConstExprError (unsigned int Func, unsigned int Var, unsigned int optok, bool ConstExpr);
4180 : :
4181 : : /*
4182 : : DeferMakeLengthConst - creates a constant which contains the length of string, sym.
4183 : : */
4184 : :
4185 : : static unsigned int DeferMakeLengthConst (unsigned int tok, unsigned int sym);
4186 : :
4187 : : /*
4188 : : BuildLengthFunction - builds the inline standard function LENGTH.
4189 : :
4190 : : The Stack:
4191 : :
4192 : :
4193 : : Entry Exit
4194 : :
4195 : : Ptr ->
4196 : : +----------------+
4197 : : | NoOfParam |
4198 : : |----------------|
4199 : : | Param 1 | <- Ptr
4200 : : |----------------| +------------+
4201 : : | ProcSym | Type | | ReturnVar |
4202 : : |----------------| |------------|
4203 : :
4204 : : */
4205 : :
4206 : : static void BuildLengthFunction (unsigned int Function, bool ConstExpr);
4207 : :
4208 : : /*
4209 : : BuildOddFunction - builds the pseudo procedure call ODD.
4210 : : This procedure is actually a "macro" for
4211 : : ORD(x) --> VAL(BOOLEAN, x MOD 2)
4212 : : However we cannot push tokens back onto the input stack
4213 : : because the compiler is currently building a function
4214 : : call and expecting a ReturnVar on the stack.
4215 : : Hence we manipulate the stack and call
4216 : : BuildConvertFunction.
4217 : :
4218 : : The Stack:
4219 : :
4220 : :
4221 : : Entry Exit
4222 : :
4223 : : Ptr ->
4224 : : +----------------+
4225 : : | NoOfParam |
4226 : : |----------------|
4227 : : | Param 1 |
4228 : : |----------------|
4229 : : | Param 2 |
4230 : : |----------------|
4231 : : . .
4232 : : . .
4233 : : . .
4234 : : |----------------|
4235 : : | Param # |
4236 : : |----------------|
4237 : : | ProcSym | Type | Empty
4238 : : |----------------|
4239 : : */
4240 : :
4241 : : static void BuildOddFunction (unsigned int ProcSym, bool ConstExpr);
4242 : :
4243 : : /*
4244 : : BuildAbsFunction - builds a call to the standard function ABS.
4245 : :
4246 : : We cannot implement it as a macro or inline an
4247 : : IF THEN statement as the IF THEN ELSE requires
4248 : : we write the value to the same variable (or constant)
4249 : : twice. The macro implementation will fail as
4250 : : the compiler maybe building a function
4251 : : call and expecting a ReturnVar on the stack.
4252 : : The only method to implement this is to pass it to the
4253 : : gcc backend.
4254 : :
4255 : : The Stack:
4256 : :
4257 : :
4258 : : Entry Exit
4259 : :
4260 : : Ptr ->
4261 : : +----------------+
4262 : : | NoOfParam |
4263 : : |----------------|
4264 : : | Param 1 |
4265 : : |----------------|
4266 : : | Param 2 |
4267 : : |----------------|
4268 : : . .
4269 : : . .
4270 : : . .
4271 : : |----------------|
4272 : : | Param # |
4273 : : |----------------|
4274 : : | ProcSym | Type | Empty
4275 : : |----------------|
4276 : : */
4277 : :
4278 : : static void BuildAbsFunction (unsigned int ProcSym, bool ConstExpr);
4279 : :
4280 : : /*
4281 : : BuildCapFunction - builds the pseudo procedure call CAP.
4282 : : We generate a the following quad:
4283 : :
4284 : :
4285 : : StandardFunctionOp ReturnVal Cap Param1
4286 : :
4287 : : The Stack:
4288 : :
4289 : :
4290 : : Entry Exit
4291 : :
4292 : : Ptr ->
4293 : : +----------------+
4294 : : | NoOfParam = 1 |
4295 : : |----------------|
4296 : : | Param 1 |
4297 : : |----------------| +-------------+
4298 : : | ProcSym | Type | | ReturnVal |
4299 : : |----------------| |-------------|
4300 : : */
4301 : :
4302 : : static void BuildCapFunction (unsigned int ProcSym, bool ConstExpr);
4303 : :
4304 : : /*
4305 : : BuildChrFunction - builds the pseudo procedure call CHR.
4306 : : This procedure is actually a "macro" for
4307 : : CHR(x) --> CONVERT(CHAR, x)
4308 : : However we cannot push tokens back onto the input stack
4309 : : because the compiler is currently building a function
4310 : : call and expecting a ReturnVar on the stack.
4311 : : Hence we manipulate the stack and call
4312 : : BuildConvertFunction.
4313 : :
4314 : : The Stack:
4315 : :
4316 : :
4317 : : Entry Exit
4318 : :
4319 : : Ptr ->
4320 : : +----------------+
4321 : : | NoOfParam |
4322 : : |----------------|
4323 : : | Param 1 |
4324 : : |----------------|
4325 : : | Param 2 |
4326 : : |----------------|
4327 : : . .
4328 : : . .
4329 : : . .
4330 : : |----------------|
4331 : : | Param # |
4332 : : |----------------|
4333 : : | ProcSym | Type | Empty
4334 : : |----------------|
4335 : : */
4336 : :
4337 : : static void BuildChrFunction (unsigned int ProcSym, bool ConstExpr);
4338 : :
4339 : : /*
4340 : : BuildOrdFunction - builds the pseudo procedure call ORD.
4341 : : This procedure is actually a "macro" for
4342 : : ORD(x) --> CONVERT(GetSType(sym), x)
4343 : : However we cannot push tokens back onto the input stack
4344 : : because the compiler is currently building a function
4345 : : call and expecting a ReturnVar on the stack.
4346 : : Hence we manipulate the stack and call
4347 : : BuildConvertFunction.
4348 : :
4349 : : The Stack:
4350 : :
4351 : :
4352 : : Entry Exit
4353 : :
4354 : : Ptr ->
4355 : : +----------------+
4356 : : | NoOfParam |
4357 : : |----------------|
4358 : : | Param 1 |
4359 : : |----------------|
4360 : : | Param 2 |
4361 : : |----------------|
4362 : : . .
4363 : : . .
4364 : : . .
4365 : : |----------------|
4366 : : | Param # |
4367 : : |----------------|
4368 : : | ProcSym | Type | Empty
4369 : : |----------------|
4370 : : */
4371 : :
4372 : : static void BuildOrdFunction (unsigned int Sym, bool ConstExpr);
4373 : :
4374 : : /*
4375 : : BuildIntFunction - builds the pseudo procedure call INT.
4376 : : This procedure is actually a "macro" for
4377 : : INT(x) --> CONVERT(INTEGER, x)
4378 : : However we cannot push tokens back onto the input stack
4379 : : because the compiler is currently building a function
4380 : : call and expecting a ReturnVar on the stack.
4381 : : Hence we manipulate the stack and call
4382 : : BuildConvertFunction.
4383 : :
4384 : : The Stack:
4385 : :
4386 : :
4387 : : Entry Exit
4388 : :
4389 : : Ptr ->
4390 : : +----------------+
4391 : : | NoOfParam |
4392 : : |----------------|
4393 : : | Param 1 |
4394 : : |----------------|
4395 : : | Param 2 |
4396 : : |----------------|
4397 : : . .
4398 : : . .
4399 : : . .
4400 : : |----------------|
4401 : : | Param # |
4402 : : |----------------|
4403 : : | ProcSym | Type | Empty
4404 : : |----------------|
4405 : : */
4406 : :
4407 : : static void BuildIntFunction (unsigned int Sym, bool ConstExpr);
4408 : :
4409 : : /*
4410 : : BuildMakeAdrFunction - builds the pseudo procedure call MAKEADR.
4411 : :
4412 : : The Stack:
4413 : :
4414 : :
4415 : : Entry Exit
4416 : :
4417 : : Ptr ->
4418 : : +----------------+
4419 : : | NoOfParam |
4420 : : |----------------|
4421 : : | Param 1 |
4422 : : |----------------|
4423 : : | Param 2 |
4424 : : |----------------|
4425 : : . .
4426 : : . .
4427 : : . .
4428 : : |----------------|
4429 : : | Param # |
4430 : : |----------------|
4431 : : | ProcSym | Type | Empty
4432 : : |----------------|
4433 : : */
4434 : :
4435 : : static void BuildMakeAdrFunction (void);
4436 : :
4437 : : /*
4438 : : BuildShiftFunction - builds the pseudo procedure call SHIFT.
4439 : :
4440 : : PROCEDURE SHIFT (val: <any type>;
4441 : : num: INTEGER): <any type> ;
4442 : :
4443 : : "Returns a bit sequence obtained from val by
4444 : : shifting up or down (left or right) by the
4445 : : absolute value of num, introducing
4446 : : zeros as necessary. The direction is down if
4447 : : the sign of num is negative, otherwise the
4448 : : direction is up."
4449 : :
4450 : : The Stack:
4451 : :
4452 : : Entry Exit
4453 : :
4454 : : Ptr ->
4455 : : +----------------+
4456 : : | NoOfParam |
4457 : : |----------------|
4458 : : | Param 1 |
4459 : : |----------------|
4460 : : | Param 2 | <- Ptr
4461 : : |----------------| +------------+
4462 : : | ProcSym | Type | | ReturnVar |
4463 : : |----------------| |------------|
4464 : : */
4465 : :
4466 : : static void BuildShiftFunction (void);
4467 : :
4468 : : /*
4469 : : BuildRotateFunction - builds the pseudo procedure call ROTATE.
4470 : :
4471 : : PROCEDURE ROTATE (val: <any type>;
4472 : : num: INTEGER): <any type> ;
4473 : :
4474 : : "Returns a bit sequence obtained from val
4475 : : by rotating up or down (left or right) by
4476 : : the absolute value of num. The direction is
4477 : : down if the sign of num is negative, otherwise
4478 : : the direction is up."
4479 : :
4480 : : The Stack:
4481 : :
4482 : : Entry Exit
4483 : :
4484 : : Ptr ->
4485 : : +----------------+
4486 : : | NoOfParam |
4487 : : |----------------|
4488 : : | Param 1 |
4489 : : |----------------|
4490 : : | Param 2 | <- Ptr
4491 : : |----------------| +------------+
4492 : : | ProcSym | Type | | ReturnVar |
4493 : : |----------------| |------------|
4494 : : */
4495 : :
4496 : : static void BuildRotateFunction (void);
4497 : :
4498 : : /*
4499 : : BuildValFunction - builds the pseudo procedure call VAL.
4500 : : This procedure is actually a "macro" for
4501 : : VAL(Type, x) --> CONVERT(Type, x)
4502 : : However we cannot push tokens back onto the input stack
4503 : : because the compiler is currently building a function
4504 : : call and expecting a ReturnVar on the stack.
4505 : : Hence we manipulate the stack and call
4506 : : BuildConvertFunction.
4507 : :
4508 : : The Stack:
4509 : :
4510 : :
4511 : : Entry Exit
4512 : :
4513 : : Ptr ->
4514 : : +----------------+
4515 : : | NoOfParam |
4516 : : |----------------|
4517 : : | Param 1 |
4518 : : |----------------|
4519 : : | Param 2 |
4520 : : |----------------|
4521 : : . .
4522 : : . .
4523 : : . .
4524 : : |----------------|
4525 : : | Param # |
4526 : : |----------------|
4527 : : | ProcSym | Type | Empty
4528 : : |----------------|
4529 : : */
4530 : :
4531 : : static void BuildValFunction (unsigned int ProcSym, bool ConstExpr);
4532 : :
4533 : : /*
4534 : : BuildCastFunction - builds the pseudo procedure call CAST.
4535 : : This procedure is actually a "macro" for
4536 : : CAST(Type, x) --> Type(x)
4537 : : However we cannot push tokens back onto the input stack
4538 : : because the compiler is currently building a function
4539 : : call and expecting a ReturnVar on the stack.
4540 : : Hence we manipulate the stack and call
4541 : : BuildConvertFunction.
4542 : :
4543 : : The Stack:
4544 : :
4545 : :
4546 : : Entry Exit
4547 : :
4548 : : Ptr ->
4549 : : +----------------+
4550 : : | NoOfParam |
4551 : : |----------------|
4552 : : | Param 1 |
4553 : : |----------------|
4554 : : | Param 2 |
4555 : : |----------------|
4556 : : . .
4557 : : . .
4558 : : . .
4559 : : |----------------|
4560 : : | Param # |
4561 : : |----------------|
4562 : : | ProcSym | Type | Empty
4563 : : |----------------|
4564 : : */
4565 : :
4566 : : static void BuildCastFunction (unsigned int ProcSym, bool ConstExpr);
4567 : :
4568 : : /*
4569 : : BuildConvertFunction - builds the pseudo function CONVERT.
4570 : : CONVERT( Type, Variable ) ;
4571 : :
4572 : : The Stack:
4573 : :
4574 : :
4575 : : Entry Exit
4576 : :
4577 : : Ptr ->
4578 : : +----------------+
4579 : : | NoOfParam |
4580 : : |----------------|
4581 : : | Param 1 |
4582 : : |----------------|
4583 : : | Param 2 |
4584 : : |----------------|
4585 : : . .
4586 : : . .
4587 : : . .
4588 : : |----------------|
4589 : : | Param # | <- Ptr
4590 : : |----------------| +---------------------+
4591 : : | ProcSym | Type | | ReturnVar | Param1 |
4592 : : |----------------| |---------------------|
4593 : :
4594 : : Quadruples:
4595 : :
4596 : : ConvertOp ReturnVar Param1 Param2
4597 : :
4598 : : Converts variable Param2 into a variable Param1
4599 : : with a type Param1.
4600 : : */
4601 : :
4602 : : static void BuildConvertFunction (unsigned int ProcSym, bool ConstExpr);
4603 : :
4604 : : /*
4605 : : CheckBaseTypeValue - checks to see whether the value, min, really exists.
4606 : : */
4607 : :
4608 : : static unsigned int CheckBaseTypeValue (unsigned int tok, unsigned int type, unsigned int min, unsigned int func);
4609 : :
4610 : : /*
4611 : : GetTypeMin - returns the minimium value of type and generate an error
4612 : : if this is unavailable.
4613 : : */
4614 : :
4615 : : static unsigned int GetTypeMin (unsigned int tok, unsigned int func, unsigned int type);
4616 : :
4617 : : /*
4618 : : GetTypeMinLower - obtain the maximum value for type.
4619 : : */
4620 : :
4621 : : static unsigned int GetTypeMinLower (unsigned int tok, unsigned int func, unsigned int type);
4622 : :
4623 : : /*
4624 : : GetTypeMax - returns the maximum value of type and generate an error
4625 : : if this is unavailable.
4626 : : */
4627 : :
4628 : : static unsigned int GetTypeMax (unsigned int tok, unsigned int func, unsigned int type);
4629 : :
4630 : : /*
4631 : : GetTypeMaxLower - obtain the maximum value for type.
4632 : : */
4633 : :
4634 : : static unsigned int GetTypeMaxLower (unsigned int tok, unsigned int func, unsigned int type);
4635 : :
4636 : : /*
4637 : : BuildMinFunction - builds the pseudo function call Min.
4638 : :
4639 : : The Stack:
4640 : :
4641 : : Entry Exit
4642 : :
4643 : : Ptr ->
4644 : : +----------------+
4645 : : | NoOfParam=1 |
4646 : : |----------------|
4647 : : | Param 1 |
4648 : : |----------------|
4649 : : | ProcSym | Type | Empty
4650 : : |----------------|
4651 : : */
4652 : :
4653 : : static void BuildMinFunction (void);
4654 : :
4655 : : /*
4656 : : BuildMaxFunction - builds the pseudo function call Max.
4657 : :
4658 : : The Stack:
4659 : :
4660 : : Entry Exit
4661 : :
4662 : : Ptr ->
4663 : : +----------------+
4664 : : | NoOfParam=1 |
4665 : : |----------------|
4666 : : | Param 1 |
4667 : : |----------------|
4668 : : | ProcSym | Type | Empty
4669 : : |----------------|
4670 : : */
4671 : :
4672 : : static void BuildMaxFunction (void);
4673 : :
4674 : : /*
4675 : : BuildTruncFunction - builds the pseudo procedure call TRUNC.
4676 : : This procedure is actually a "macro" for
4677 : : TRUNC(x) --> CONVERT(INTEGER, x)
4678 : : However we cannot push tokens back onto the input stack
4679 : : because the compiler is currently building a function
4680 : : call and expecting a ReturnVar on the stack.
4681 : : Hence we manipulate the stack and call
4682 : : BuildConvertFunction.
4683 : :
4684 : : The Stack:
4685 : :
4686 : :
4687 : : Entry Exit
4688 : :
4689 : : Ptr ->
4690 : : +----------------+
4691 : : | NoOfParam |
4692 : : |----------------|
4693 : : | Param 1 |
4694 : : |----------------|
4695 : : | Param 2 |
4696 : : |----------------|
4697 : : . .
4698 : : . .
4699 : : . .
4700 : : |----------------|
4701 : : | Param # |
4702 : : |----------------|
4703 : : | ProcSym | Type | Empty
4704 : : |----------------|
4705 : : */
4706 : :
4707 : : static void BuildTruncFunction (unsigned int Sym, bool ConstExpr);
4708 : :
4709 : : /*
4710 : : BuildFloatFunction - builds the pseudo procedure call FLOAT.
4711 : : This procedure is actually a "macro" for
4712 : : FLOAT(x) --> CONVERT(REAL, x)
4713 : : However we cannot push tokens back onto the input stack
4714 : : because the compiler is currently building a function
4715 : : call and expecting a ReturnVar on the stack.
4716 : : Hence we manipulate the stack and call
4717 : : BuildConvertFunction.
4718 : :
4719 : : The Stack:
4720 : :
4721 : :
4722 : : Entry Exit
4723 : :
4724 : : Ptr ->
4725 : : +----------------+
4726 : : | NoOfParam |
4727 : : |----------------|
4728 : : | Param 1 |
4729 : : |----------------|
4730 : : | Param 2 |
4731 : : |----------------|
4732 : : . .
4733 : : . .
4734 : : . .
4735 : : |----------------|
4736 : : | Param # |
4737 : : |----------------|
4738 : : | ProcSym | Type | Empty
4739 : : |----------------|
4740 : : */
4741 : :
4742 : : static void BuildFloatFunction (unsigned int Sym, bool ConstExpr);
4743 : :
4744 : : /*
4745 : : BuildReFunction - builds the pseudo procedure call RE.
4746 : :
4747 : : The Stack:
4748 : :
4749 : :
4750 : : Entry Exit
4751 : :
4752 : : Ptr ->
4753 : : +----------------+
4754 : : | NoOfParam |
4755 : : |----------------|
4756 : : | Param 1 |
4757 : : |----------------|
4758 : : | Param 2 |
4759 : : |----------------|
4760 : : . .
4761 : : . .
4762 : : . .
4763 : : |----------------|
4764 : : | Param # |
4765 : : |----------------|
4766 : : | ProcSym | Type | Empty
4767 : : |----------------|
4768 : : */
4769 : :
4770 : : static void BuildReFunction (unsigned int Sym, bool ConstExpr);
4771 : :
4772 : : /*
4773 : : BuildImFunction - builds the pseudo procedure call IM.
4774 : :
4775 : : The Stack:
4776 : :
4777 : :
4778 : : Entry Exit
4779 : :
4780 : : Ptr ->
4781 : : +----------------+
4782 : : | NoOfParam |
4783 : : |----------------|
4784 : : | Param 1 |
4785 : : |----------------|
4786 : : | Param 2 |
4787 : : |----------------|
4788 : : . .
4789 : : . .
4790 : : . .
4791 : : |----------------|
4792 : : | Param # |
4793 : : |----------------|
4794 : : | ProcSym | Type | Empty
4795 : : |----------------|
4796 : : */
4797 : :
4798 : : static void BuildImFunction (unsigned int Sym, bool ConstExpr);
4799 : :
4800 : : /*
4801 : : BuildCmplxFunction - builds the pseudo procedure call CMPLX.
4802 : :
4803 : : The Stack:
4804 : :
4805 : :
4806 : : Entry Exit
4807 : :
4808 : : Ptr ->
4809 : : +----------------+
4810 : : | NoOfParam |
4811 : : |----------------|
4812 : : | Param 1 |
4813 : : |----------------|
4814 : : | Param 2 |
4815 : : |----------------|
4816 : : . .
4817 : : . .
4818 : : . .
4819 : : |----------------|
4820 : : | Param # |
4821 : : |----------------|
4822 : : | ProcSym | Type | Empty
4823 : : |----------------|
4824 : : */
4825 : :
4826 : : static void BuildCmplxFunction (unsigned int func, bool ConstExpr);
4827 : :
4828 : : /*
4829 : : BuildAdrFunction - builds the pseudo function ADR
4830 : : The Stack:
4831 : :
4832 : :
4833 : : Entry Exit
4834 : :
4835 : : Ptr ->
4836 : : +----------------+
4837 : : | NoOfParam |
4838 : : |----------------|
4839 : : | Param 1 |
4840 : : |----------------|
4841 : : | Param 2 |
4842 : : |----------------|
4843 : : . .
4844 : : . .
4845 : : . .
4846 : : |----------------|
4847 : : | Param # | <- Ptr
4848 : : |----------------| +------------+
4849 : : | ProcSym | Type | | ReturnVar |
4850 : : |----------------| |------------|
4851 : :
4852 : : */
4853 : :
4854 : : static void BuildAdrFunction (void);
4855 : :
4856 : : /*
4857 : : BuildSizeFunction - builds the pseudo function SIZE
4858 : : The Stack:
4859 : :
4860 : :
4861 : : Entry Exit
4862 : :
4863 : : Ptr ->
4864 : : +----------------+
4865 : : | NoOfParam |
4866 : : |----------------|
4867 : : | Param 1 |
4868 : : |----------------|
4869 : : | Param 2 |
4870 : : |----------------|
4871 : : . .
4872 : : . .
4873 : : . .
4874 : : |----------------|
4875 : : | Param # | <- Ptr
4876 : : |----------------| +------------+
4877 : : | ProcSym | Type | | ReturnVar |
4878 : : |----------------| |------------|
4879 : : */
4880 : :
4881 : : static void BuildSizeFunction (void);
4882 : :
4883 : : /*
4884 : : BuildTSizeFunction - builds the pseudo function TSIZE
4885 : : The Stack:
4886 : :
4887 : :
4888 : : Entry Exit
4889 : :
4890 : : Ptr ->
4891 : : +----------------+
4892 : : | NoOfParam |
4893 : : |----------------|
4894 : : | Param 1 |
4895 : : |----------------|
4896 : : | Param 2 |
4897 : : |----------------|
4898 : : . .
4899 : : . .
4900 : : . .
4901 : : |----------------|
4902 : : | Param # | <- Ptr
4903 : : |----------------| +------------+
4904 : : | ProcSym | Type | | ReturnVar |
4905 : : |----------------| |------------|
4906 : :
4907 : : */
4908 : :
4909 : : static void BuildTSizeFunction (void);
4910 : :
4911 : : /*
4912 : : BuildTBitSizeFunction - builds the pseudo function TBITSIZE
4913 : : The Stack:
4914 : :
4915 : :
4916 : : Entry Exit
4917 : :
4918 : : Ptr ->
4919 : : +----------------+
4920 : : | NoOfParam |
4921 : : |----------------|
4922 : : | Param 1 |
4923 : : |----------------|
4924 : : | Param 2 |
4925 : : |----------------|
4926 : : . .
4927 : : . .
4928 : : . .
4929 : : |----------------|
4930 : : | Param # | <- Ptr
4931 : : |----------------| +------------+
4932 : : | ProcSym | Type | | ReturnVar |
4933 : : |----------------| |------------|
4934 : :
4935 : : */
4936 : :
4937 : : static void BuildTBitSizeFunction (void);
4938 : :
4939 : : /*
4940 : : ExpectingParameterType -
4941 : : */
4942 : :
4943 : : static void ExpectingParameterType (unsigned int BlockSym, unsigned int Type);
4944 : :
4945 : : /*
4946 : : ExpectingVariableType -
4947 : : */
4948 : :
4949 : : static void ExpectingVariableType (unsigned int BlockSym, unsigned int Type);
4950 : :
4951 : : /*
4952 : : CheckVariablesAndParameterTypesInBlock - checks to make sure that block, BlockSym, has
4953 : : parameters types and variable types which are legal.
4954 : : */
4955 : :
4956 : : static void CheckVariablesAndParameterTypesInBlock (unsigned int BlockSym);
4957 : :
4958 : : /*
4959 : : IsNeverAltered - returns TRUE if variable, sym, is never altered
4960 : : between quadruples: Start..End
4961 : : */
4962 : :
4963 : : static bool IsNeverAltered (unsigned int sym, unsigned int Start, unsigned int End);
4964 : :
4965 : : /*
4966 : : IsConditionVariable - returns TRUE if the condition at quadruple, q, is variable.
4967 : : */
4968 : :
4969 : : static bool IsConditionVariable (unsigned int q, unsigned int Start, unsigned int End);
4970 : :
4971 : : /*
4972 : : IsInfiniteLoop - returns TRUE if an infinite loop is found.
4973 : : Given a backwards jump at, End, it returns a BOOLEAN which depends on
4974 : : whether a jump is found to jump beyond, End. If a conditonal jump is found
4975 : : to pass over, End, the condition is tested for global variables, procedure variables and
4976 : : constants.
4977 : :
4978 : : constant - ignored
4979 : : variables - tested to see whether they are altered inside the loop
4980 : : global variable - the procedure tests to see whether it is altered as above
4981 : : but will also test to see whether this loop calls a procedure
4982 : : in which case it believes the loop NOT to be infinite
4983 : : (as this procedure call might alter the global variable)
4984 : :
4985 : : Note that this procedure can easily be fooled by the user altering variables
4986 : : with pointers.
4987 : : */
4988 : :
4989 : : static bool IsInfiniteLoop (unsigned int End);
4990 : :
4991 : : /*
4992 : : CheckVariablesInBlock - given a block, BlockSym, check whether all variables are used.
4993 : : */
4994 : :
4995 : : static void CheckVariablesInBlock (unsigned int BlockSym);
4996 : :
4997 : : /*
4998 : : CheckFunctionReturn - checks to see that a RETURN statement was present in a function.
4999 : : */
5000 : :
5001 : : static void CheckFunctionReturn (unsigned int ProcSym);
5002 : :
5003 : : /*
5004 : : CheckReturnType - checks to see that the return type from currentProc is
5005 : : assignment compatible with actualType.
5006 : : */
5007 : :
5008 : : static void CheckReturnType (unsigned int tokno, unsigned int currentProc, unsigned int actualVal, unsigned int actualType);
5009 : :
5010 : : /*
5011 : : BuildReturnLower - check the return type and value to ensure type
5012 : : compatibility and no range overflow will occur.
5013 : : */
5014 : :
5015 : : static void BuildReturnLower (unsigned int tokcombined, unsigned int tokexpr, unsigned int e1, unsigned int t1);
5016 : :
5017 : : /*
5018 : : IsReadOnly - a helper procedure function to detect constants.
5019 : : */
5020 : :
5021 : : static bool IsReadOnly (unsigned int sym);
5022 : :
5023 : : /*
5024 : : BuildDesignatorError - removes the designator from the stack and replaces
5025 : : it with an error symbol.
5026 : : */
5027 : :
5028 : : static void BuildDesignatorError (const char *message_, unsigned int _message_high);
5029 : :
5030 : : /*
5031 : : BuildDesignatorPointerError - removes the designator from the stack and replaces
5032 : : it with an error symbol.
5033 : : */
5034 : :
5035 : : static void BuildDesignatorPointerError (unsigned int type, unsigned int rw, unsigned int tokpos, const char *message_, unsigned int _message_high);
5036 : :
5037 : : /*
5038 : : BuildDesignatorArrayStaticDynamic - Builds the array referencing.
5039 : : The purpose of this procedure is to work out
5040 : : whether the DesignatorArray is a static or
5041 : : dynamic array and to call the appropriate
5042 : : BuildRoutine.
5043 : :
5044 : : The Stack is expected to contain:
5045 : :
5046 : :
5047 : : Entry Exit
5048 : : ===== ====
5049 : :
5050 : : Ptr ->
5051 : : +--------------+
5052 : : | e | <- Ptr
5053 : : |--------------| +------------+
5054 : : | Sym | Type | | S | T |
5055 : : |--------------| |------------|
5056 : : */
5057 : :
5058 : : static void BuildDesignatorArrayStaticDynamic (void);
5059 : :
5060 : : /*
5061 : : BuildStaticArray - Builds the array referencing for static arrays.
5062 : : The Stack is expected to contain:
5063 : :
5064 : :
5065 : : Entry Exit
5066 : : ===== ====
5067 : :
5068 : : Ptr ->
5069 : : +--------------+
5070 : : | e | <- Ptr
5071 : : |--------------| +------------+
5072 : : | Sym | Type | | S | T |
5073 : : |--------------| |------------|
5074 : : */
5075 : :
5076 : : static void BuildStaticArray (void);
5077 : :
5078 : : /*
5079 : : calculateMultipicand - generates quadruples which calculate the
5080 : : multiplicand for the array at dimension, dim.
5081 : : */
5082 : :
5083 : : static unsigned int calculateMultipicand (unsigned int tok, unsigned int arraySym, unsigned int arrayType, unsigned int dim);
5084 : :
5085 : : /*
5086 : : ConvertToAddress - convert sym to an address.
5087 : : */
5088 : :
5089 : : static unsigned int ConvertToAddress (unsigned int tokpos, unsigned int sym);
5090 : :
5091 : : /*
5092 : : BuildDynamicArray - Builds the array referencing for dynamic arrays.
5093 : : The Stack is expected to contain:
5094 : :
5095 : :
5096 : : Entry Exit
5097 : : ===== ====
5098 : :
5099 : : Ptr ->
5100 : : +-----------------------+
5101 : : | Index | <- Ptr
5102 : : |-----------------------| +---------------------------+
5103 : : | ArraySym | Type | Dim | | S | T | ArraySym | Dim+1 |
5104 : : |-----------------------| |---------------------------|
5105 : :
5106 : :
5107 : : if Dim=1
5108 : : then
5109 : : S := base of ArraySym + TSIZE(Type)*Index
5110 : : else
5111 : : S := S + TSIZE(Type)*Index
5112 : : fi
5113 : : */
5114 : :
5115 : : static void BuildDynamicArray (void);
5116 : :
5117 : : /*
5118 : : DebugLocation -
5119 : : */
5120 : :
5121 : : static void DebugLocation (unsigned int tok, const char *message_, unsigned int _message_high);
5122 : :
5123 : : /*
5124 : : PushWith - pushes sym and type onto the with stack. It checks for
5125 : : previous declaration of this record type.
5126 : : */
5127 : :
5128 : : static void PushWith (unsigned int Sym, unsigned int Type, unsigned int Ref, unsigned int Tok);
5129 : : static void PopWith (void);
5130 : :
5131 : : /*
5132 : : BuildAccessWithField - similar to BuildDesignatorRecord except it
5133 : : does not perform the address operation.
5134 : : The address will have been computed at the
5135 : : beginning of the WITH statement.
5136 : : It also stops the GenQuad procedure from examining the
5137 : : with stack.
5138 : :
5139 : : The Stack
5140 : :
5141 : : Entry
5142 : :
5143 : : Ptr ->
5144 : : +--------------+
5145 : : | Field | Type1| <- Ptr
5146 : : |-------|------| +-------------+
5147 : : | Adr | Type2| | Sym | Type1|
5148 : : |--------------| |-------------|
5149 : : */
5150 : :
5151 : : static void BuildAccessWithField (void);
5152 : :
5153 : : /*
5154 : : PushConstructor -
5155 : : */
5156 : :
5157 : : static void PushConstructor (unsigned int sym);
5158 : :
5159 : : /*
5160 : : AddFieldTo - adds field, e, to, value.
5161 : : */
5162 : :
5163 : : static unsigned int AddFieldTo (unsigned int value, unsigned int e);
5164 : :
5165 : : /*
5166 : : CheckLogicalOperator - returns a logical operator if the operands imply
5167 : : a logical operation should be performed.
5168 : : */
5169 : :
5170 : : static NameKey_Name CheckLogicalOperator (NameKey_Name Tok, unsigned int left, unsigned int lefttype);
5171 : :
5172 : : /*
5173 : : CheckDivModRem - initiates calls to check the divisor for DIV, MOD, REM
5174 : : expressions.
5175 : : */
5176 : :
5177 : : static void CheckDivModRem (unsigned int TokPos, NameKey_Name tok, unsigned int d, unsigned int e);
5178 : :
5179 : : /*
5180 : : doConvert - convert, sym, to a new symbol with, type.
5181 : : Return the new symbol.
5182 : : */
5183 : :
5184 : : static unsigned int doConvert (unsigned int type, unsigned int sym);
5185 : :
5186 : : /*
5187 : : doBuildBinaryOp - build the binary op, with or without type
5188 : : checking.
5189 : : */
5190 : :
5191 : : static void doBuildBinaryOp (bool checkTypes, bool checkOverflow);
5192 : :
5193 : : /*
5194 : : AreConstant - returns immediate addressing mode if b is true else
5195 : : offset mode is returned. b determines whether the
5196 : : operands are all constant - in which case we can use
5197 : : a constant temporary variable.
5198 : : */
5199 : :
5200 : : static SymbolTable_ModeOfAddr AreConstant (bool b);
5201 : :
5202 : : /*
5203 : : ConvertBooleanToVariable - converts a BoolStack(i) from a Boolean True|False
5204 : : exit pair into a variable containing the value TRUE or
5205 : : FALSE. The parameter i is relative to the top
5206 : : of the stack.
5207 : : */
5208 : :
5209 : : static void ConvertBooleanToVariable (unsigned int tok, unsigned int i);
5210 : :
5211 : : /*
5212 : : DumpQuadSummary -
5213 : : */
5214 : :
5215 : : static void DumpQuadSummary (unsigned int quad);
5216 : :
5217 : : /*
5218 : : BuildRelOpFromBoolean - builds a relational operator sequence of quadruples
5219 : : instead of using a temporary boolean variable.
5220 : : This function can only be used when we perform
5221 : : the following translation:
5222 : :
5223 : : (a=b) # (c=d) alternatively (a=b) = (c=d)
5224 : : ^ ^
5225 : :
5226 : : it only allows # = to be used as >= <= > < all
5227 : : assume a particular value for TRUE and FALSE.
5228 : : (In which case the user should specify ORD)
5229 : :
5230 : :
5231 : : before
5232 : :
5233 : : q if r1 op1 op2 t2
5234 : : q+1 Goto f2
5235 : : ...
5236 : : q+n if r2 op3 op4 t1
5237 : : q+n+1 Goto f1
5238 : :
5239 : : after (in case of =)
5240 : :
5241 : : q if r1 op1 op2 q+2
5242 : : q+1 Goto q+4
5243 : : q+2 if r2 op3 op4 t
5244 : : q+3 Goto f
5245 : : q+4 if r2 op3 op4 f
5246 : : q+5 Goto t
5247 : :
5248 : : after (in case of #)
5249 : :
5250 : : q if r1 op1 op2 q+2
5251 : : q+1 Goto q+n+2
5252 : : q+2 ...
5253 : : ... ...
5254 : : q+n if r2 op3 op4 f
5255 : : q+n+1 Goto t
5256 : : q+n+2 if r2 op3 op4 t
5257 : : q+n+3 Goto f
5258 : :
5259 : : The Stack is expected to contain:
5260 : :
5261 : :
5262 : : Entry Exit
5263 : : ===== ====
5264 : :
5265 : : Ptr ->
5266 : : +------------+
5267 : : | t1 | f1 |
5268 : : |------------|
5269 : : | Operator | <- Ptr
5270 : : |------------| +------------+
5271 : : | t2 | f2 | | t | f |
5272 : : |------------| |------------|
5273 : :
5274 : :
5275 : : */
5276 : :
5277 : : static void BuildRelOpFromBoolean (unsigned int tokpos);
5278 : :
5279 : : /*
5280 : : CheckVariableOrConstantOrProcedure - checks to make sure sym is a variable, constant or procedure.
5281 : : */
5282 : :
5283 : : static void CheckVariableOrConstantOrProcedure (unsigned int tokpos, unsigned int sym);
5284 : :
5285 : : /*
5286 : : MakeOp - returns the equalent quadruple operator to a token, t.
5287 : : */
5288 : :
5289 : : static M2Quads_QuadOperator MakeOp (NameKey_Name t);
5290 : :
5291 : : /*
5292 : : GenQuadO - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
5293 : : */
5294 : :
5295 : : static void GenQuadO (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow);
5296 : :
5297 : : /*
5298 : : GenQuadOTrash - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
5299 : : */
5300 : :
5301 : : static void GenQuadOTrash (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow, unsigned int trash);
5302 : :
5303 : : /*
5304 : : GenQuad - Generate a quadruple with Operation, Op1, Op2, Op3.
5305 : : */
5306 : :
5307 : : static void GenQuad (M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3);
5308 : :
5309 : : /*
5310 : : GenQuadOtok - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
5311 : : */
5312 : :
5313 : : 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);
5314 : :
5315 : : /*
5316 : : GenQuadOTypetok - assigns the fields of the quadruple with
5317 : : the parameters.
5318 : : */
5319 : :
5320 : : 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);
5321 : :
5322 : : /*
5323 : : DumpUntil - dump all quadruples until we seen the ending quadruple
5324 : : with procsym in the third operand.
5325 : : Return the quad number containing the match.
5326 : : */
5327 : :
5328 : : static unsigned int DumpUntil (M2Quads_QuadOperator ending, unsigned int procsym, unsigned int quad);
5329 : :
5330 : : /*
5331 : : GetCtorInit - return the init procedure for the module.
5332 : : */
5333 : :
5334 : : static unsigned int GetCtorInit (unsigned int sym);
5335 : :
5336 : : /*
5337 : : GetCtorFini - return the fini procedure for the module.
5338 : : */
5339 : :
5340 : : static unsigned int GetCtorFini (unsigned int sym);
5341 : :
5342 : : /*
5343 : : DumpQuadrupleFilter -
5344 : : */
5345 : :
5346 : : static void DumpQuadrupleFilter (void);
5347 : :
5348 : : /*
5349 : : DumpQuadrupleAll - dump all quadruples.
5350 : : */
5351 : :
5352 : : static void DumpQuadrupleAll (void);
5353 : :
5354 : : /*
5355 : : BackPatch - Makes each of the quadruples on the list pointed to by
5356 : : QuadNo take quadruple Value as a target.
5357 : : */
5358 : :
5359 : : static void BackPatch (unsigned int QuadNo, unsigned int Value);
5360 : :
5361 : : /*
5362 : : Merge - joins two quad lists, QuadList2 to the end of QuadList1.
5363 : : A QuadList of value zero is a nul list.
5364 : : */
5365 : :
5366 : : static unsigned int Merge (unsigned int QuadList1, unsigned int QuadList2);
5367 : :
5368 : : /*
5369 : : DisplayProcedureAttributes -
5370 : : */
5371 : :
5372 : : static void DisplayProcedureAttributes (unsigned int proc);
5373 : :
5374 : : /*
5375 : : WriteQuad - Writes out the Quad BufferQuad.
5376 : : */
5377 : :
5378 : : static void WriteQuad (unsigned int BufferQuad);
5379 : :
5380 : : /*
5381 : : WriteOperand - displays the operands name, symbol id and mode of addressing.
5382 : : */
5383 : :
5384 : : static void WriteMode (SymbolTable_ModeOfAddr Mode);
5385 : :
5386 : : /*
5387 : : PushExit - pushes the exit value onto the EXIT stack.
5388 : : */
5389 : :
5390 : : static void PushExit (unsigned int Exit);
5391 : :
5392 : : /*
5393 : : PopExit - pops the exit value from the EXIT stack.
5394 : : */
5395 : :
5396 : : static unsigned int PopExit (void);
5397 : :
5398 : : /*
5399 : : PushFor - pushes the exit value onto the FOR stack.
5400 : : */
5401 : :
5402 : : static void PushFor (unsigned int Exit);
5403 : :
5404 : : /*
5405 : : PopFor - pops the exit value from the FOR stack.
5406 : : */
5407 : :
5408 : : static unsigned int PopFor (void);
5409 : :
5410 : : /*
5411 : : OperandTno - returns the ident operand stored in the true position
5412 : : on the boolean stack. This is exactly the same as
5413 : : OperandT but it has no IsBoolean checking.
5414 : : */
5415 : :
5416 : : static unsigned int OperandTno (unsigned int pos);
5417 : :
5418 : : /*
5419 : : OperandFno - returns the ident operand stored in the false position
5420 : : on the boolean stack. This is exactly the same as
5421 : : OperandF but it has no IsBoolean checking.
5422 : : */
5423 : :
5424 : : static unsigned int OperandFno (unsigned int pos);
5425 : :
5426 : : /*
5427 : : OperandTtok - returns the token associated with the position, pos
5428 : : on the boolean stack.
5429 : : */
5430 : :
5431 : : static unsigned int OperandTtok (unsigned int pos);
5432 : :
5433 : : /*
5434 : : PopBooltok - Pops a True and a False exit quad number from the True/False
5435 : : stack.
5436 : : */
5437 : :
5438 : : static void PopBooltok (unsigned int *True, unsigned int *False, unsigned int *tokno);
5439 : :
5440 : : /*
5441 : : PushBooltok - Push a True and a False exit quad numbers onto the
5442 : : True/False stack.
5443 : : */
5444 : :
5445 : : static void PushBooltok (unsigned int True, unsigned int False, unsigned int tokno);
5446 : :
5447 : : /*
5448 : : PopBool - Pops a True and a False exit quad number from the True/False
5449 : : stack.
5450 : : */
5451 : :
5452 : : static void PopBool (unsigned int *True, unsigned int *False);
5453 : :
5454 : : /*
5455 : : PushBool - Push a True and a False exit quad numbers onto the
5456 : : True/False stack.
5457 : : */
5458 : :
5459 : : static void PushBool (unsigned int True, unsigned int False);
5460 : :
5461 : : /*
5462 : : IsBoolean - returns true is the Stack position pos contains a Boolean
5463 : : Exit. False is returned if an Ident is stored.
5464 : : */
5465 : :
5466 : : static bool IsBoolean (unsigned int pos);
5467 : :
5468 : : /*
5469 : : OperandD - returns possible array dimension associated with the ident
5470 : : operand stored on the boolean stack.
5471 : : */
5472 : :
5473 : : static unsigned int OperandD (unsigned int pos);
5474 : :
5475 : : /*
5476 : : OperandRW - returns the rw operand stored on the boolean stack.
5477 : : */
5478 : :
5479 : : static unsigned int OperandRW (unsigned int pos);
5480 : :
5481 : : /*
5482 : : OperandMergeRW - returns the rw operand if not NulSym else it
5483 : : returns True.
5484 : : */
5485 : :
5486 : : static unsigned int OperandMergeRW (unsigned int pos);
5487 : :
5488 : : /*
5489 : : OperandRangeDep - return the range dependant associated with the quad stack.
5490 : : */
5491 : :
5492 : : static unsigned int OperandRangeDep (unsigned int pos);
5493 : :
5494 : : /*
5495 : : PutRangeDep - assigns the quad stack pos RangeDep to dep.
5496 : : */
5497 : :
5498 : : static void PutRangeDep (unsigned int pos, unsigned int dep);
5499 : :
5500 : : /*
5501 : : UseLineNote - uses the line note and returns it to the free list.
5502 : : */
5503 : :
5504 : : static void UseLineNote (M2Quads_LineNote l);
5505 : :
5506 : : /*
5507 : : PopLineNo - pops a line note from the line stack.
5508 : : */
5509 : :
5510 : : static M2Quads_LineNote PopLineNo (void);
5511 : :
5512 : : /*
5513 : : InitLineNote - creates a line note and initializes it to
5514 : : contain, file, line.
5515 : : */
5516 : :
5517 : : static M2Quads_LineNote InitLineNote (NameKey_Name file, unsigned int line);
5518 : :
5519 : : /*
5520 : : PushLineNote -
5521 : : */
5522 : :
5523 : : static void PushLineNote (M2Quads_LineNote l);
5524 : :
5525 : : /*
5526 : : BuildStmtNoteTok - adds a nop (with an assigned tokenno location) to the code.
5527 : : */
5528 : :
5529 : : static void BuildStmtNoteTok (unsigned int tokenno);
5530 : :
5531 : : /*
5532 : : GetRecordOrField -
5533 : : */
5534 : :
5535 : : static unsigned int GetRecordOrField (void);
5536 : :
5537 : : /*
5538 : : PushTFAD - Push True, False, Array, Dim, numbers onto the
5539 : : True/False stack. True and False are assumed to
5540 : : contain Symbols or Ident etc.
5541 : : */
5542 : :
5543 : : static void PushTFAD (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim);
5544 : :
5545 : : /*
5546 : : PushTFADtok - Push True, False, Array, Dim, numbers onto the
5547 : : True/False stack. True and False are assumed to
5548 : : contain Symbols or Ident etc.
5549 : : */
5550 : :
5551 : : static void PushTFADtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int tokno);
5552 : :
5553 : : /*
5554 : : PushTFADrwtok - Push True, False, Array, Dim, rw, numbers onto the
5555 : : True/False stack. True and False are assumed to
5556 : : contain Symbols or Ident etc.
5557 : : */
5558 : :
5559 : : static void PushTFADrwtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int rw, unsigned int Tok);
5560 : :
5561 : : /*
5562 : : PopTFrwtok - Pop a True and False number from the True/False stack.
5563 : : True and False are assumed to contain Symbols or Ident etc.
5564 : : */
5565 : :
5566 : : static void PopTFrwtok (unsigned int *True, unsigned int *False, unsigned int *rw, unsigned int *tokno);
5567 : :
5568 : : /*
5569 : : PushTFrwtok - Push an item onto the stack in the T (true) position,
5570 : : it is assummed to be a token and its token location is recorded.
5571 : : */
5572 : :
5573 : : static void PushTFrwtok (unsigned int True, unsigned int False, unsigned int rw, unsigned int tokno);
5574 : :
5575 : : /*
5576 : : PushTFDtok - Push True, False, Dim, numbers onto the
5577 : : True/False stack. True and False are assumed to
5578 : : contain Symbols or Ident etc.
5579 : : */
5580 : :
5581 : : static void PushTFDtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int Tok);
5582 : :
5583 : : /*
5584 : : PopTFDtok - Pop a True, False, Dim number from the True/False stack.
5585 : : True and False are assumed to contain Symbols or Ident etc.
5586 : : */
5587 : :
5588 : : static void PopTFDtok (unsigned int *True, unsigned int *False, unsigned int *Dim, unsigned int *Tok);
5589 : :
5590 : : /*
5591 : : PushTFDrwtok - Push True, False, Dim, numbers onto the
5592 : : True/False stack. True and False are assumed to
5593 : : contain Symbols or Ident etc.
5594 : : */
5595 : :
5596 : : static void PushTFDrwtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int rw, unsigned int Tok);
5597 : :
5598 : : /*
5599 : : PushTFrw - Push a True and False numbers onto the True/False stack.
5600 : : True and False are assumed to contain Symbols or Ident etc.
5601 : : It also pushes the higher level symbol which is associated
5602 : : with the True symbol. Eg record variable or array variable.
5603 : : */
5604 : :
5605 : : static void PushTFrw (unsigned int True, unsigned int False, unsigned int rw);
5606 : :
5607 : : /*
5608 : : PopTFrw - Pop a True and False number from the True/False stack.
5609 : : True and False are assumed to contain Symbols or Ident etc.
5610 : : */
5611 : :
5612 : : static void PopTFrw (unsigned int *True, unsigned int *False, unsigned int *rw);
5613 : :
5614 : : /*
5615 : : newBoolFrame - creates a new BoolFrame with all fields initialised to their defaults.
5616 : : */
5617 : :
5618 : : static M2Quads_BoolFrame newBoolFrame (void);
5619 : :
5620 : : /*
5621 : : PushTrwtok - Push an item onto the True/False stack. The False value will be zero.
5622 : : */
5623 : :
5624 : : static void PushTrwtok (unsigned int True, unsigned int rw, unsigned int tok);
5625 : :
5626 : : /*
5627 : : PopTrw - Pop a True field and rw symbol from the stack.
5628 : : */
5629 : :
5630 : : static void PopTrw (unsigned int *True, unsigned int *rw);
5631 : :
5632 : : /*
5633 : : PopTrwtok - Pop a True field and rw symbol from the stack.
5634 : : */
5635 : :
5636 : : static void PopTrwtok (unsigned int *True, unsigned int *rw, unsigned int *tok);
5637 : :
5638 : : /*
5639 : : gdbhook - a debugger convenience hook.
5640 : : */
5641 : :
5642 : : static void gdbhook (void);
5643 : :
5644 : : /*
5645 : : BreakWhenQuadCreated - to be called interactively by gdb.
5646 : : */
5647 : :
5648 : : static void BreakWhenQuadCreated (unsigned int quad);
5649 : :
5650 : : /*
5651 : : CheckBreak - if quad = BreakQuad then call gdbhook.
5652 : : */
5653 : :
5654 : : static void CheckBreak (unsigned int quad);
5655 : :
5656 : : /*
5657 : : Init - initialize the M2Quads module, all the stacks, all the lists
5658 : : and the quads list.
5659 : : */
5660 : :
5661 : : static void Init (void);
5662 : :
5663 : :
5664 : : /*
5665 : : DSdbEnter -
5666 : : */
5667 : :
5668 : 0 : static void DSdbEnter (void)
5669 : : {
5670 : 0 : }
5671 : :
5672 : :
5673 : : /*
5674 : : DSdbExit -
5675 : : */
5676 : :
5677 : 0 : static void DSdbExit (void)
5678 : : {
5679 : 0 : }
5680 : :
5681 : :
5682 : : /*
5683 : : GetQF - returns the QuadFrame associated with, q.
5684 : : */
5685 : :
5686 : 14196558887 : static M2Quads_QuadFrame GetQF (unsigned int q)
5687 : : {
5688 : 0 : return (M2Quads_QuadFrame) (Indexing_GetIndice (QuadArray, q));
5689 : : /* static analysis guarentees a RETURN statement will be used before here. */
5690 : : __builtin_unreachable ();
5691 : : }
5692 : :
5693 : :
5694 : : /*
5695 : : IsQuadA - returns true if QuadNo is a op.
5696 : : */
5697 : :
5698 : 1042581266 : static bool IsQuadA (unsigned int QuadNo, M2Quads_QuadOperator op)
5699 : : {
5700 : 1042581266 : M2Quads_QuadFrame f;
5701 : :
5702 : 0 : f = GetQF (QuadNo);
5703 : 1042581266 : return f->Operator == op;
5704 : : /* static analysis guarentees a RETURN statement will be used before here. */
5705 : : __builtin_unreachable ();
5706 : : }
5707 : :
5708 : :
5709 : : /*
5710 : : OpUsesOp1 - return TRUE if op allows op1.
5711 : : */
5712 : :
5713 : 419698 : static bool OpUsesOp1 (M2Quads_QuadOperator op)
5714 : : {
5715 : 419698 : switch (op)
5716 : : {
5717 : : case M2Quads_StringConvertCnulOp:
5718 : : case M2Quads_StringConvertM2nulOp:
5719 : : case M2Quads_StringLengthOp:
5720 : : case M2Quads_InclOp:
5721 : : case M2Quads_ExclOp:
5722 : : case M2Quads_UnboundedOp:
5723 : : case M2Quads_FunctValueOp:
5724 : : case M2Quads_NegateOp:
5725 : : case M2Quads_BecomesOp:
5726 : : case M2Quads_HighOp:
5727 : : case M2Quads_SizeOp:
5728 : : case M2Quads_AddrOp:
5729 : : case M2Quads_RecordFieldOp:
5730 : : case M2Quads_ArrayOp:
5731 : : case M2Quads_LogicalShiftOp:
5732 : : case M2Quads_LogicalRotateOp:
5733 : : case M2Quads_LogicalOrOp:
5734 : : case M2Quads_LogicalAndOp:
5735 : : case M2Quads_LogicalXorOp:
5736 : : case M2Quads_CoerceOp:
5737 : : case M2Quads_ConvertOp:
5738 : : case M2Quads_CastOp:
5739 : : case M2Quads_AddOp:
5740 : : case M2Quads_SubOp:
5741 : : case M2Quads_MultOp:
5742 : : case M2Quads_ModFloorOp:
5743 : : case M2Quads_DivCeilOp:
5744 : : case M2Quads_ModCeilOp:
5745 : : case M2Quads_DivFloorOp:
5746 : : case M2Quads_ModTruncOp:
5747 : : case M2Quads_DivTruncOp:
5748 : : case M2Quads_DivM2Op:
5749 : : case M2Quads_ModM2Op:
5750 : : case M2Quads_XIndrOp:
5751 : : case M2Quads_IndrXOp:
5752 : : case M2Quads_SaveExceptionOp:
5753 : : case M2Quads_RestoreExceptionOp:
5754 : : return true;
5755 : 100204 : break;
5756 : :
5757 : :
5758 : 100204 : default:
5759 : 100204 : return false;
5760 : : break;
5761 : : }
5762 : : /* static analysis guarentees a RETURN statement will be used before here. */
5763 : : __builtin_unreachable ();
5764 : : }
5765 : :
5766 : :
5767 : : /*
5768 : : AddQuadInformation - adds variable analysis and jump analysis to the new quadruple.
5769 : : */
5770 : :
5771 : 6349408 : static void AddQuadInformation (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
5772 : : {
5773 : 6349408 : switch (Op)
5774 : : {
5775 : 177343 : case M2Quads_IfInOp:
5776 : 177343 : case M2Quads_IfNotInOp:
5777 : 177343 : case M2Quads_IfEquOp:
5778 : 177343 : case M2Quads_IfNotEquOp:
5779 : 177343 : case M2Quads_IfLessOp:
5780 : 177343 : case M2Quads_IfLessEquOp:
5781 : 177343 : case M2Quads_IfGreOp:
5782 : 177343 : case M2Quads_IfGreEquOp:
5783 : 177343 : ManipulateReference (QuadNo, Oper3);
5784 : 177343 : CheckAddVariableRead (Oper1, false, QuadNo);
5785 : 177343 : CheckAddVariableRead (Oper2, false, QuadNo);
5786 : 177343 : break;
5787 : :
5788 : 2586 : case M2Quads_LastForIteratorOp:
5789 : 2586 : CheckAddVariableWrite (Oper1, false, QuadNo);
5790 : 2586 : CheckAddTuple2Read (Oper2, false, QuadNo);
5791 : 2586 : CheckAddVariableRead (Oper3, false, QuadNo);
5792 : 2586 : break;
5793 : :
5794 : 186072 : case M2Quads_TryOp:
5795 : 186072 : case M2Quads_RetryOp:
5796 : 186072 : case M2Quads_GotoOp:
5797 : 186072 : ManipulateReference (QuadNo, Oper3);
5798 : 186072 : break;
5799 : :
5800 : 1960 : case M2Quads_InclOp:
5801 : 1960 : case M2Quads_ExclOp:
5802 : : /* variable references */
5803 : 1960 : CheckConst (Oper1);
5804 : 1960 : CheckAddVariableRead (Oper3, false, QuadNo);
5805 : 1960 : CheckAddVariableWrite (Oper1, true, QuadNo);
5806 : 1960 : break;
5807 : :
5808 : 672030 : case M2Quads_UnboundedOp:
5809 : 672030 : case M2Quads_FunctValueOp:
5810 : 672030 : case M2Quads_NegateOp:
5811 : 672030 : case M2Quads_BecomesOp:
5812 : 672030 : case M2Quads_HighOp:
5813 : 672030 : case M2Quads_SizeOp:
5814 : 672030 : CheckConst (Oper1);
5815 : 672030 : CheckAddVariableWrite (Oper1, false, QuadNo);
5816 : 672030 : CheckAddVariableRead (Oper3, false, QuadNo);
5817 : 672030 : break;
5818 : :
5819 : 196669 : case M2Quads_AddrOp:
5820 : 196669 : CheckConst (Oper1);
5821 : 196669 : CheckAddVariableWrite (Oper1, false, QuadNo);
5822 : : /* the next line is a kludge and assumes we _will_
5823 : : write to the variable as we have taken its address */
5824 : 196669 : CheckRemoveVariableWrite (Oper1, true, QuadNo);
5825 : 196669 : break;
5826 : :
5827 : 27679 : case M2Quads_ReturnValueOp:
5828 : 27679 : CheckAddVariableRead (Oper1, false, QuadNo);
5829 : 27679 : break;
5830 : :
5831 : : case M2Quads_ReturnOp:
5832 : : case M2Quads_NewLocalVarOp:
5833 : : case M2Quads_KillLocalVarOp:
5834 : : break;
5835 : :
5836 : 219126 : case M2Quads_CallOp:
5837 : 219126 : CheckAddVariableRead (Oper3, true, QuadNo);
5838 : 219126 : break;
5839 : :
5840 : 613775 : case M2Quads_ParamOp:
5841 : 613775 : CheckAddVariableRead (Oper2, false, QuadNo);
5842 : 613775 : CheckAddVariableRead (Oper3, false, QuadNo);
5843 : 613775 : if (((Oper1 > 0) && (Oper1 <= (SymbolTable_NoOfParamAny (Oper2)))) && (SymbolTable_IsVarParamAny (Oper2, Oper1)))
5844 : : {
5845 : : /* _may_ also write to a var parameter, although we dont know */
5846 : 20470 : CheckAddVariableWrite (Oper3, true, QuadNo);
5847 : : }
5848 : : break;
5849 : :
5850 : 359304 : case M2Quads_RecordFieldOp:
5851 : 359304 : case M2Quads_ArrayOp:
5852 : 359304 : case M2Quads_LogicalShiftOp:
5853 : 359304 : case M2Quads_LogicalRotateOp:
5854 : 359304 : case M2Quads_LogicalOrOp:
5855 : 359304 : case M2Quads_LogicalAndOp:
5856 : 359304 : case M2Quads_LogicalXorOp:
5857 : 359304 : case M2Quads_CoerceOp:
5858 : 359304 : case M2Quads_ConvertOp:
5859 : 359304 : case M2Quads_CastOp:
5860 : 359304 : case M2Quads_AddOp:
5861 : 359304 : case M2Quads_SubOp:
5862 : 359304 : case M2Quads_MultOp:
5863 : 359304 : case M2Quads_DivM2Op:
5864 : 359304 : case M2Quads_ModM2Op:
5865 : 359304 : case M2Quads_ModFloorOp:
5866 : 359304 : case M2Quads_DivCeilOp:
5867 : 359304 : case M2Quads_ModCeilOp:
5868 : 359304 : case M2Quads_DivFloorOp:
5869 : 359304 : case M2Quads_ModTruncOp:
5870 : 359304 : case M2Quads_DivTruncOp:
5871 : 359304 : CheckConst (Oper1);
5872 : 359304 : CheckAddVariableWrite (Oper1, false, QuadNo);
5873 : 359304 : CheckAddVariableRead (Oper2, false, QuadNo);
5874 : 359304 : CheckAddVariableRead (Oper3, false, QuadNo);
5875 : 359304 : break;
5876 : :
5877 : 43372 : case M2Quads_XIndrOp:
5878 : 43372 : CheckConst (Oper1);
5879 : 43372 : CheckAddVariableWrite (Oper1, true, QuadNo);
5880 : 43372 : CheckAddVariableRead (Oper3, false, QuadNo);
5881 : 43372 : break;
5882 : :
5883 : 17445 : case M2Quads_IndrXOp:
5884 : 17445 : CheckConst (Oper1);
5885 : 17445 : CheckAddVariableWrite (Oper1, false, QuadNo);
5886 : 17445 : CheckAddVariableRead (Oper3, true, QuadNo);
5887 : 17445 : break;
5888 : :
5889 : 2892 : case M2Quads_SaveExceptionOp:
5890 : : /* RangeCheckOp : CheckRangeAddVariableRead(Oper3, QuadNo) | */
5891 : 2892 : CheckConst (Oper1);
5892 : 2892 : CheckAddVariableWrite (Oper1, false, QuadNo);
5893 : 2892 : break;
5894 : :
5895 : 3054 : case M2Quads_RestoreExceptionOp:
5896 : 3054 : CheckAddVariableRead (Oper1, false, QuadNo);
5897 : 3054 : break;
5898 : :
5899 : :
5900 : : default:
5901 : : break;
5902 : : }
5903 : 6349408 : }
5904 : :
5905 : :
5906 : : /*
5907 : : PutQuadO - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
5908 : : sets a boolean to determinine whether overflow should be checked.
5909 : : */
5910 : :
5911 : 5395064 : static void PutQuadO (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow)
5912 : : {
5913 : 0 : PutQuadOType (QuadNo, Op, Oper1, Oper2, Oper3, overflow, true);
5914 : 0 : }
5915 : :
5916 : :
5917 : : /*
5918 : : PutQuadOType -
5919 : : */
5920 : :
5921 : 6267511 : static void PutQuadOType (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow, bool checktype)
5922 : : {
5923 : 6267511 : M2Quads_QuadFrame f;
5924 : :
5925 : 6267511 : if (QuadrupleGeneration)
5926 : : {
5927 : 6267511 : M2Quads_EraseQuad (QuadNo);
5928 : 6267511 : AddQuadInformation (QuadNo, Op, Oper1, Oper2, Oper3);
5929 : 6267511 : f = GetQF (QuadNo);
5930 : 6267511 : f->Operator = Op;
5931 : 6267511 : f->Operand1 = Oper1;
5932 : 6267511 : f->Operand2 = Oper2;
5933 : 6267511 : f->Operand3 = Oper3;
5934 : 6267511 : f->CheckOverflow = overflow;
5935 : 6267511 : f->CheckType = checktype;
5936 : 6267511 : f->ConstExpr = false; /* IsInConstExpression () */
5937 : : }
5938 : : /* IsInConstExpression () */
5939 : 6267511 : }
5940 : :
5941 : :
5942 : : /*
5943 : : UndoReadWriteInfo -
5944 : : */
5945 : :
5946 : 8253602 : static void UndoReadWriteInfo (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
5947 : : {
5948 : 8253602 : switch (Op)
5949 : : {
5950 : 97750 : case M2Quads_IfInOp:
5951 : 97750 : case M2Quads_IfNotInOp:
5952 : 97750 : case M2Quads_IfEquOp:
5953 : 97750 : case M2Quads_IfNotEquOp:
5954 : 97750 : case M2Quads_IfLessOp:
5955 : 97750 : case M2Quads_IfLessEquOp:
5956 : 97750 : case M2Quads_IfGreOp:
5957 : 97750 : case M2Quads_IfGreEquOp:
5958 : : /* jumps, calls and branches */
5959 : 97750 : RemoveReference (QuadNo);
5960 : 97750 : CheckRemoveVariableRead (Oper1, false, QuadNo);
5961 : 97750 : CheckRemoveVariableRead (Oper2, false, QuadNo);
5962 : 97750 : break;
5963 : :
5964 : 136545 : case M2Quads_TryOp:
5965 : 136545 : case M2Quads_RetryOp:
5966 : 136545 : case M2Quads_GotoOp:
5967 : 136545 : RemoveReference (QuadNo);
5968 : 136545 : break;
5969 : :
5970 : 0 : case M2Quads_InclOp:
5971 : 0 : case M2Quads_ExclOp:
5972 : : /* variable references */
5973 : 0 : CheckRemoveVariableRead (Oper1, false, QuadNo);
5974 : 0 : CheckRemoveVariableWrite (Oper1, true, QuadNo);
5975 : 0 : break;
5976 : :
5977 : 331120 : case M2Quads_UnboundedOp:
5978 : 331120 : case M2Quads_FunctValueOp:
5979 : 331120 : case M2Quads_NegateOp:
5980 : 331120 : case M2Quads_BecomesOp:
5981 : 331120 : case M2Quads_HighOp:
5982 : 331120 : case M2Quads_SizeOp:
5983 : 331120 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
5984 : 331120 : CheckRemoveVariableRead (Oper3, false, QuadNo);
5985 : 331120 : break;
5986 : :
5987 : 1630 : case M2Quads_AddrOp:
5988 : 1630 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
5989 : : /* the next line is a kludge and assumes we _will_
5990 : : write to the variable as we have taken its address */
5991 : 1630 : CheckRemoveVariableWrite (Oper1, true, QuadNo);
5992 : 1630 : break;
5993 : :
5994 : 184 : case M2Quads_ReturnValueOp:
5995 : 184 : CheckRemoveVariableRead (Oper1, false, QuadNo);
5996 : 184 : break;
5997 : :
5998 : : case M2Quads_ReturnOp:
5999 : : case M2Quads_CallOp:
6000 : : case M2Quads_NewLocalVarOp:
6001 : : case M2Quads_KillLocalVarOp:
6002 : : break;
6003 : :
6004 : 11254 : case M2Quads_ParamOp:
6005 : 11254 : CheckRemoveVariableRead (Oper2, false, QuadNo);
6006 : 11254 : CheckRemoveVariableRead (Oper3, false, QuadNo);
6007 : 11254 : if (((Oper1 > 0) && (Oper1 <= (SymbolTable_NoOfParamAny (Oper2)))) && (SymbolTable_IsVarParamAny (Oper2, Oper1)))
6008 : : {
6009 : : /* _may_ also write to a var parameter, although we dont know */
6010 : 112 : CheckRemoveVariableWrite (Oper3, true, QuadNo);
6011 : : }
6012 : : break;
6013 : :
6014 : 50030 : case M2Quads_RecordFieldOp:
6015 : 50030 : case M2Quads_ArrayOp:
6016 : 50030 : case M2Quads_LogicalShiftOp:
6017 : 50030 : case M2Quads_LogicalRotateOp:
6018 : 50030 : case M2Quads_LogicalOrOp:
6019 : 50030 : case M2Quads_LogicalAndOp:
6020 : 50030 : case M2Quads_LogicalXorOp:
6021 : 50030 : case M2Quads_CoerceOp:
6022 : 50030 : case M2Quads_ConvertOp:
6023 : 50030 : case M2Quads_CastOp:
6024 : 50030 : case M2Quads_AddOp:
6025 : 50030 : case M2Quads_SubOp:
6026 : 50030 : case M2Quads_MultOp:
6027 : 50030 : case M2Quads_DivM2Op:
6028 : 50030 : case M2Quads_ModM2Op:
6029 : 50030 : case M2Quads_ModFloorOp:
6030 : 50030 : case M2Quads_DivCeilOp:
6031 : 50030 : case M2Quads_ModCeilOp:
6032 : 50030 : case M2Quads_DivFloorOp:
6033 : 50030 : case M2Quads_ModTruncOp:
6034 : 50030 : case M2Quads_DivTruncOp:
6035 : 50030 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
6036 : 50030 : CheckRemoveVariableRead (Oper2, false, QuadNo);
6037 : 50030 : CheckRemoveVariableRead (Oper3, false, QuadNo);
6038 : 50030 : break;
6039 : :
6040 : 4 : case M2Quads_XIndrOp:
6041 : 4 : CheckRemoveVariableWrite (Oper1, true, QuadNo);
6042 : 4 : CheckRemoveVariableRead (Oper3, false, QuadNo);
6043 : 4 : break;
6044 : :
6045 : 450 : case M2Quads_IndrXOp:
6046 : 450 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
6047 : 450 : CheckRemoveVariableRead (Oper3, true, QuadNo);
6048 : 450 : break;
6049 : :
6050 : 0 : case M2Quads_SaveExceptionOp:
6051 : : /* RangeCheckOp : CheckRangeRemoveVariableRead(Oper3, QuadNo) | */
6052 : 0 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
6053 : 0 : break;
6054 : :
6055 : 216 : case M2Quads_RestoreExceptionOp:
6056 : 216 : CheckRemoveVariableRead (Oper1, false, QuadNo);
6057 : 216 : break;
6058 : :
6059 : :
6060 : : default:
6061 : : break;
6062 : : }
6063 : 8253602 : }
6064 : :
6065 : :
6066 : : /*
6067 : : CheckAddTuple2Read - checks to see whether symbol tuple contains variables or
6068 : : parameters and if so it then adds them to the quadruple
6069 : : variable list.
6070 : : */
6071 : :
6072 : 2586 : static void CheckAddTuple2Read (unsigned int tuple, bool canDereference, unsigned int Quad)
6073 : : {
6074 : 2586 : if (SymbolTable_IsTuple (tuple))
6075 : : {
6076 : 2586 : CheckAddVariableRead (SymbolTable_GetNth (tuple, 1), canDereference, Quad);
6077 : 2586 : CheckAddVariableRead (SymbolTable_GetNth (tuple, 2), canDereference, Quad);
6078 : : }
6079 : 2586 : }
6080 : :
6081 : :
6082 : : /*
6083 : : CheckAddVariableRead - checks to see whether symbol, Sym, is a variable or
6084 : : a parameter and if so it then adds this quadruple
6085 : : to the variable list.
6086 : : */
6087 : :
6088 : 3293268 : static void CheckAddVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad)
6089 : : {
6090 : 3293268 : if (SymbolTable_IsVar (Sym))
6091 : : {
6092 : 1175717 : SymbolTable_PutReadQuad (Sym, SymbolTable_GetMode (Sym), Quad);
6093 : 1175717 : if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
6094 : : {
6095 : 17513 : SymbolTable_PutReadQuad (Sym, SymbolTable_RightValue, Quad);
6096 : : }
6097 : : }
6098 : 3293268 : }
6099 : :
6100 : :
6101 : : /*
6102 : : CheckRemoveVariableRead - checks to see whether, Sym, is a variable or
6103 : : a parameter and if so then it removes the
6104 : : quadruple from the variable list.
6105 : : */
6106 : :
6107 : 650042 : static void CheckRemoveVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad)
6108 : : {
6109 : 650042 : if (SymbolTable_IsVar (Sym))
6110 : : {
6111 : 123764 : SymbolTable_RemoveReadQuad (Sym, SymbolTable_GetMode (Sym), Quad);
6112 : 123764 : if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
6113 : : {
6114 : 450 : SymbolTable_RemoveReadQuad (Sym, SymbolTable_RightValue, Quad);
6115 : : }
6116 : : }
6117 : 650042 : }
6118 : :
6119 : :
6120 : : /*
6121 : : CheckAddVariableWrite - checks to see whether symbol, Sym, is a variable and
6122 : : if so it then adds this quadruple to the variable list.
6123 : : */
6124 : :
6125 : 1316728 : static void CheckAddVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad)
6126 : : {
6127 : 1316728 : if (SymbolTable_IsVar (Sym))
6128 : : {
6129 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
6130 : 949030 : if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
6131 : : {
6132 : 59738 : SymbolTable_PutReadQuad (Sym, SymbolTable_LeftValue, Quad);
6133 : 59738 : SymbolTable_PutWriteQuad (Sym, SymbolTable_RightValue, Quad);
6134 : : }
6135 : : else
6136 : : {
6137 : 889292 : SymbolTable_PutWriteQuad (Sym, SymbolTable_GetMode (Sym), Quad);
6138 : : }
6139 : : }
6140 : 1316728 : }
6141 : :
6142 : :
6143 : : /*
6144 : : CheckRemoveVariableWrite - checks to see whether, Sym, is a variable and
6145 : : if so then it removes the quadruple from the
6146 : : variable list.
6147 : : */
6148 : :
6149 : 581645 : static void CheckRemoveVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad)
6150 : : {
6151 : 581645 : if (SymbolTable_IsVar (Sym))
6152 : : {
6153 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
6154 : 218047 : if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
6155 : : {
6156 : 11338 : SymbolTable_RemoveReadQuad (Sym, SymbolTable_LeftValue, Quad);
6157 : 11338 : SymbolTable_RemoveWriteQuad (Sym, SymbolTable_RightValue, Quad);
6158 : : }
6159 : : else
6160 : : {
6161 : 206709 : SymbolTable_RemoveWriteQuad (Sym, SymbolTable_GetMode (Sym), Quad);
6162 : : }
6163 : : }
6164 : 581645 : }
6165 : :
6166 : :
6167 : : /*
6168 : : CheckConst -
6169 : : */
6170 : :
6171 : 1293672 : static void CheckConst (unsigned int sym)
6172 : : {
6173 : 1293672 : if (SymbolTable_IsConst (sym))
6174 : : {
6175 : 365916 : M2GCCDeclare_PutToBeSolvedByQuads (sym);
6176 : : }
6177 : 1293672 : }
6178 : :
6179 : :
6180 : : /*
6181 : : AlterReference - alters all references from OldQuad, to NewQuad in a
6182 : : quadruple list Head.
6183 : : */
6184 : :
6185 : 1904194 : static void AlterReference (unsigned int Head, unsigned int OldQuad, unsigned int NewQuad)
6186 : : {
6187 : 1904194 : M2Quads_QuadFrame f;
6188 : 1904194 : M2Quads_QuadFrame g;
6189 : 1904194 : unsigned int i;
6190 : :
6191 : 1904194 : f = GetQF (OldQuad);
6192 : 12839564 : while ((f->NoOfTimesReferenced > 0) && (Head != 0))
6193 : : {
6194 : 9031176 : g = GetQF (Head);
6195 : 9031176 : switch (g->Operator)
6196 : : {
6197 : 398994 : case M2Quads_IfInOp:
6198 : 398994 : case M2Quads_IfNotInOp:
6199 : 398994 : case M2Quads_IfEquOp:
6200 : 398994 : case M2Quads_IfNotEquOp:
6201 : 398994 : case M2Quads_IfLessOp:
6202 : 398994 : case M2Quads_IfLessEquOp:
6203 : 398994 : case M2Quads_IfGreOp:
6204 : 398994 : case M2Quads_IfGreEquOp:
6205 : 398994 : case M2Quads_TryOp:
6206 : 398994 : case M2Quads_RetryOp:
6207 : 398994 : case M2Quads_GotoOp:
6208 : 398994 : if (g->Operand3 == OldQuad)
6209 : : {
6210 : 8970 : ManipulateReference (Head, NewQuad);
6211 : : }
6212 : : break;
6213 : :
6214 : :
6215 : : default:
6216 : : break;
6217 : : }
6218 : 9031176 : i = g->Next;
6219 : 9031176 : Head = i;
6220 : : }
6221 : 1904194 : }
6222 : :
6223 : :
6224 : : /*
6225 : : GrowQuads - grows the list of quadruples to the quadruple, to.
6226 : : */
6227 : :
6228 : 641770 : static void GrowQuads (unsigned int to)
6229 : : {
6230 : 641770 : unsigned int i;
6231 : 641770 : M2Quads_QuadFrame f;
6232 : :
6233 : 641770 : if ((to != 0) && (to > GrowInitialization))
6234 : : {
6235 : 9980 : i = GrowInitialization+1;
6236 : 19960 : while (i <= to)
6237 : : {
6238 : 9980 : if (Indexing_InBounds (QuadArray, i))
6239 : : {
6240 : 0 : M2Debug_Assert ((Indexing_GetIndice (QuadArray, i)) != NULL);
6241 : : }
6242 : : else
6243 : : {
6244 : 9980 : Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T3));
6245 : 9980 : if (f == NULL)
6246 : : {
6247 : 0 : M2Error_InternalError ((const char *) "out of memory error when trying to allocate a quadruple", 55);
6248 : : }
6249 : 9980 : Indexing_PutIndice (QuadArray, i, reinterpret_cast <void *> (f));
6250 : 9980 : f->NoOfTimesReferenced = 0;
6251 : : }
6252 : 9980 : i += 1;
6253 : : }
6254 : 9980 : GrowInitialization = to;
6255 : : }
6256 : 641770 : }
6257 : :
6258 : :
6259 : : /*
6260 : : ManipulateReference - manipulates the quadruple, q, so that it now points to quad, to.
6261 : : */
6262 : :
6263 : 641770 : static void ManipulateReference (unsigned int q, unsigned int to)
6264 : : {
6265 : 641770 : M2Quads_QuadFrame f;
6266 : :
6267 : 1283540 : M2Debug_Assert ((GrowInitialization >= q) || (to == 0));
6268 : 641770 : GrowQuads (to);
6269 : 641770 : RemoveReference (q);
6270 : 641770 : f = GetQF (q);
6271 : 641770 : f->Operand3 = to;
6272 : 641770 : if (to != 0)
6273 : : {
6274 : 407627 : f = GetQF (to);
6275 : 407627 : f->NoOfTimesReferenced += 1;
6276 : : }
6277 : 641770 : }
6278 : :
6279 : :
6280 : : /*
6281 : : RemoveReference - remove the reference by quadruple q to wherever
6282 : : it was pointing.
6283 : : */
6284 : :
6285 : 876065 : static void RemoveReference (unsigned int q)
6286 : : {
6287 : 876065 : M2Quads_QuadFrame f;
6288 : 876065 : M2Quads_QuadFrame g;
6289 : :
6290 : 876065 : f = GetQF (q);
6291 : 876065 : if ((f->Operand3 != 0) && (f->Operand3 < NextQuad))
6292 : : {
6293 : 278507 : CheckBreak (f->Operand3);
6294 : 278507 : g = GetQF (f->Operand3);
6295 : 278507 : M2Debug_Assert (g->NoOfTimesReferenced != 0);
6296 : 278507 : g->NoOfTimesReferenced -= 1;
6297 : : }
6298 : 876065 : }
6299 : :
6300 : :
6301 : : /*
6302 : : NewQuad - sets QuadNo to a new quadruple.
6303 : : */
6304 : :
6305 : 6268308 : static void NewQuad (unsigned int *QuadNo)
6306 : : {
6307 : 6268308 : M2Quads_QuadFrame f;
6308 : :
6309 : 6268308 : (*QuadNo) = FreeList;
6310 : 6268308 : if ((Indexing_InBounds (QuadArray, (*QuadNo))) && ((Indexing_GetIndice (QuadArray, (*QuadNo))) != NULL))
6311 : : {
6312 : 9980 : f = static_cast<M2Quads_QuadFrame> (Indexing_GetIndice (QuadArray, (*QuadNo)));
6313 : : }
6314 : : else
6315 : : {
6316 : 6258328 : Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T3));
6317 : 6258328 : if (f == NULL)
6318 : : {
6319 : 0 : M2Error_InternalError ((const char *) "out of memory error trying to allocate a quadruple", 50);
6320 : : }
6321 : : else
6322 : : {
6323 : 6258328 : NoOfQuads += 1;
6324 : 6258328 : Indexing_PutIndice (QuadArray, (*QuadNo), reinterpret_cast <void *> (f));
6325 : 6258328 : f->NoOfTimesReferenced = 0;
6326 : 6258328 : M2Diagnostic_MemSet (QuadMemDiag, 1, NoOfQuads);
6327 : 6258328 : M2Diagnostic_MemIncr (QuadMemDiag, 2, sizeof ((*f)));
6328 : : }
6329 : : }
6330 : 6268308 : f->Operator = M2Quads_DummyOp;
6331 : 6268308 : f->Operand3 = 0;
6332 : 6268308 : f->Next = 0;
6333 : 6268308 : FreeList += 1;
6334 : 6268308 : if (GrowInitialization < FreeList)
6335 : : {
6336 : 6258328 : GrowInitialization = FreeList;
6337 : : }
6338 : 6268308 : }
6339 : :
6340 : :
6341 : : /*
6342 : : CheckVariableAt - checks to see whether, sym, was declared at a particular address.
6343 : : */
6344 : :
6345 : 4048162 : static void CheckVariableAt (unsigned int sym)
6346 : : {
6347 : 4048162 : if ((SymbolTable_IsVar (sym)) && (SymbolTable_IsVariableAtAddress (sym)))
6348 : : {
6349 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
6350 : 54 : if ((SymbolTable_GetMode (sym)) == SymbolTable_LeftValue)
6351 : : {
6352 : 54 : GenQuad (M2Quads_InitAddressOp, sym, SymbolTable_NulSym, SymbolTable_GetVariableAtAddress (sym));
6353 : : }
6354 : : else
6355 : : {
6356 : 0 : M2Error_InternalError ((const char *) "expecting lvalue for this variable which is declared at an explicit address", 75);
6357 : : }
6358 : : }
6359 : 4048162 : }
6360 : :
6361 : :
6362 : : /*
6363 : : CheckVariablesAt - checks to see whether we need to initialize any pointers
6364 : : which point to variable declared at addresses.
6365 : : */
6366 : :
6367 : 164055 : static void CheckVariablesAt (unsigned int scope)
6368 : : {
6369 : 0 : SymbolTable_ForeachLocalSymDo (scope, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) CheckVariableAt});
6370 : 0 : }
6371 : :
6372 : :
6373 : : /*
6374 : : GetTurnInterrupts - returns the TurnInterrupts procedure function.
6375 : : */
6376 : :
6377 : 840 : static unsigned int GetTurnInterrupts (unsigned int tok)
6378 : : {
6379 : 840 : if (M2Options_Iso)
6380 : : {
6381 : 0 : return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "TurnInterrupts", 14), NameKey_MakeKey ((const char *) "COROUTINES", 10));
6382 : : }
6383 : : else
6384 : : {
6385 : 840 : return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "TurnInterrupts", 14), NameKey_MakeKey ((const char *) "SYSTEM", 6));
6386 : : }
6387 : : /* static analysis guarentees a RETURN statement will be used before here. */
6388 : : __builtin_unreachable ();
6389 : : }
6390 : :
6391 : :
6392 : : /*
6393 : : GetProtection - returns the PROTECTION data type.
6394 : : */
6395 : :
6396 : 420 : static unsigned int GetProtection (unsigned int tok)
6397 : : {
6398 : 420 : if (M2Options_Iso)
6399 : : {
6400 : 0 : return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "PROTECTION", 10), NameKey_MakeKey ((const char *) "COROUTINES", 10));
6401 : : }
6402 : : else
6403 : : {
6404 : 420 : return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "PROTECTION", 10), NameKey_MakeKey ((const char *) "SYSTEM", 6));
6405 : : }
6406 : : /* static analysis guarentees a RETURN statement will be used before here. */
6407 : : __builtin_unreachable ();
6408 : : }
6409 : :
6410 : :
6411 : : /*
6412 : : CheckNeedPriorityBegin - checks to see whether we need to save the old
6413 : : module priority and change to another module
6414 : : priority.
6415 : : The current module initialization or procedure
6416 : : being built is defined by, scope. The module whose
6417 : : priority will be used is defined by, module.
6418 : : */
6419 : :
6420 : 179927 : static void CheckNeedPriorityBegin (unsigned int tok, unsigned int scope, unsigned int module)
6421 : : {
6422 : 179927 : unsigned int ProcSym;
6423 : 179927 : unsigned int old;
6424 : :
6425 : 179927 : if ((SymbolTable_GetPriority (module)) != SymbolTable_NulSym)
6426 : : {
6427 : : /* module has been given a priority */
6428 : 420 : ProcSym = GetTurnInterrupts (tok);
6429 : 420 : if (ProcSym != SymbolTable_NulSym)
6430 : : {
6431 : 420 : old = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
6432 : 420 : SymbolTable_PutVar (old, GetProtection (tok));
6433 : 840 : GenQuadO (tok, M2Quads_SavePriorityOp, old, scope, ProcSym, false);
6434 : 420 : M2StackWord_PushWord (PriorityStack, old);
6435 : : }
6436 : : }
6437 : 179927 : }
6438 : :
6439 : :
6440 : : /*
6441 : : CheckNeedPriorityEnd - checks to see whether we need to restore the old
6442 : : module priority.
6443 : : The current module initialization or procedure
6444 : : being built is defined by, scope.
6445 : : */
6446 : :
6447 : 179752 : static void CheckNeedPriorityEnd (unsigned int tok, unsigned int scope, unsigned int module)
6448 : : {
6449 : 179752 : unsigned int ProcSym;
6450 : 179752 : unsigned int old;
6451 : :
6452 : 179752 : if ((SymbolTable_GetPriority (module)) != SymbolTable_NulSym)
6453 : : {
6454 : : /* module has been given a priority */
6455 : 420 : ProcSym = GetTurnInterrupts (tok);
6456 : 420 : if (ProcSym != SymbolTable_NulSym)
6457 : : {
6458 : 420 : old = static_cast<unsigned int> (M2StackWord_PopWord (PriorityStack));
6459 : 420 : GenQuad (M2Quads_RestorePriorityOp, old, scope, ProcSym);
6460 : : }
6461 : : }
6462 : 179752 : }
6463 : :
6464 : :
6465 : : /*
6466 : : BuildRTExceptEnter - informs RTExceptions that we are about to enter the except state.
6467 : : */
6468 : :
6469 : 2892 : static void BuildRTExceptEnter (unsigned int tok)
6470 : : {
6471 : 2892 : unsigned int old;
6472 : 2892 : unsigned int ProcSym;
6473 : :
6474 : 2892 : if (M2Options_Exceptions)
6475 : : {
6476 : : /* now inform the Modula-2 runtime we are in the exception state */
6477 : 2892 : ProcSym = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "SetExceptionState", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
6478 : 2892 : if (ProcSym == SymbolTable_NulSym)
6479 : : {
6480 : 0 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%W}no procedure SetExceptionState found in RTExceptions which is needed to implement exception handling", 104);
6481 : : }
6482 : : else
6483 : : {
6484 : 2892 : old = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
6485 : 2892 : SymbolTable_PutVar (old, M2Base_Boolean);
6486 : 5784 : GenQuadO (tok, M2Quads_SaveExceptionOp, old, SymbolTable_NulSym, ProcSym, false);
6487 : 2892 : M2StackWord_PushWord (ExceptStack, old);
6488 : : }
6489 : : }
6490 : : else
6491 : : {
6492 : 0 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}cannot use {%kEXCEPT} blocks with the -fno-exceptions flag", 62);
6493 : : }
6494 : 2892 : }
6495 : :
6496 : :
6497 : : /*
6498 : : BuildRTExceptLeave - informs RTExceptions that we are about to leave the except state.
6499 : : If, destroy, is TRUE then pop the ExceptStack.
6500 : : */
6501 : :
6502 : 3054 : static void BuildRTExceptLeave (unsigned int tok, bool destroy)
6503 : : {
6504 : 3054 : unsigned int old;
6505 : 3054 : unsigned int ProcSym;
6506 : :
6507 : 3054 : if (M2Options_Exceptions)
6508 : : {
6509 : : /* avoid dangling else. */
6510 : : /* now inform the Modula-2 runtime we are in the exception state */
6511 : 3054 : ProcSym = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "SetExceptionState", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
6512 : 3054 : if (ProcSym != SymbolTable_NulSym)
6513 : : {
6514 : 3054 : if (destroy)
6515 : : {
6516 : 2892 : old = static_cast<unsigned int> (M2StackWord_PopWord (ExceptStack));
6517 : : }
6518 : : else
6519 : : {
6520 : 162 : old = static_cast<unsigned int> (M2StackWord_PeepWord (ExceptStack, 1));
6521 : : }
6522 : 3054 : GenQuadO (tok, M2Quads_RestoreExceptionOp, old, SymbolTable_NulSym, ProcSym, false);
6523 : : }
6524 : : }
6525 : : /* no need for an error message here as it will be generated in the Enter procedure above */
6526 : 3054 : }
6527 : :
6528 : :
6529 : : /*
6530 : : SafeRequestSym - only used during scaffold to get argc, argv, envp.
6531 : : It attempts to get symbol name from the current scope(s) and if
6532 : : it fails then it falls back onto default constants.
6533 : : */
6534 : :
6535 : 16020 : static unsigned int SafeRequestSym (unsigned int tok, NameKey_Name name)
6536 : : {
6537 : 16020 : unsigned int sym;
6538 : :
6539 : 16020 : sym = SymbolTable_GetSym (name);
6540 : 16020 : if (sym == SymbolTable_NulSym)
6541 : : {
6542 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
6543 : 0 : if (name == (NameKey_MakeKey ((const char *) "argc", 4)))
6544 : : {
6545 : 0 : return SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType);
6546 : : }
6547 : 0 : else if ((name == (NameKey_MakeKey ((const char *) "argv", 4))) || (name == (NameKey_MakeKey ((const char *) "envp", 4))))
6548 : : {
6549 : : /* avoid dangling else. */
6550 : 0 : return M2Base_Nil;
6551 : : }
6552 : : else
6553 : : {
6554 : : /* avoid dangling else. */
6555 : 0 : M2Error_InternalError ((const char *) "not expecting this parameter name", 33);
6556 : : return M2Base_Nil;
6557 : : }
6558 : : }
6559 : : return sym;
6560 : : /* static analysis guarentees a RETURN statement will be used before here. */
6561 : : __builtin_unreachable ();
6562 : : }
6563 : :
6564 : :
6565 : : /*
6566 : : callRequestDependant - create a call:
6567 : : RequestDependant (GetSymName (modulesym), GetLibName (modulesym),
6568 : : GetSymName (depModuleSym), GetLibName (depModuleSym));
6569 : : */
6570 : :
6571 : 38768 : static void callRequestDependant (unsigned int tokno, unsigned int moduleSym, unsigned int depModuleSym, unsigned int requestDep)
6572 : : {
6573 : 38768 : M2Debug_Assert (requestDep != SymbolTable_NulSym);
6574 : 38768 : M2Quads_PushTtok (requestDep, tokno);
6575 : 38768 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
6576 : 38768 : M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetSymName (moduleSym)), tokno);
6577 : 38768 : M2Quads_PushT (static_cast<unsigned int> (1));
6578 : 38768 : BuildAdrFunction ();
6579 : 38768 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
6580 : 38768 : M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetLibName (moduleSym)), tokno);
6581 : 38768 : M2Quads_PushT (static_cast<unsigned int> (1));
6582 : 38768 : BuildAdrFunction ();
6583 : 38768 : if (depModuleSym == SymbolTable_NulSym)
6584 : : {
6585 : 15619 : M2Quads_PushTF (M2Base_Nil, M2System_Address);
6586 : 15619 : M2Quads_PushTF (M2Base_Nil, M2System_Address);
6587 : : }
6588 : : else
6589 : : {
6590 : 23149 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
6591 : 23149 : M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetSymName (depModuleSym)), tokno);
6592 : 23149 : M2Quads_PushT (static_cast<unsigned int> (1));
6593 : 23149 : BuildAdrFunction ();
6594 : 23149 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
6595 : 23149 : M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetLibName (depModuleSym)), tokno);
6596 : 23149 : M2Quads_PushT (static_cast<unsigned int> (1));
6597 : 23149 : BuildAdrFunction ();
6598 : : }
6599 : 38768 : M2Quads_PushT (static_cast<unsigned int> (4));
6600 : 38768 : M2Quads_BuildProcedureCall (tokno);
6601 : 38768 : }
6602 : :
6603 : :
6604 : : /*
6605 : : ForeachImportInDepDo -
6606 : : */
6607 : :
6608 : 31238 : static void ForeachImportInDepDo (Lists_List importStatements, unsigned int moduleSym, unsigned int requestDep)
6609 : : {
6610 : 31238 : unsigned int i;
6611 : 31238 : unsigned int j;
6612 : 31238 : unsigned int m;
6613 : 31238 : unsigned int n;
6614 : 31238 : unsigned int imported;
6615 : 31238 : unsigned int stmt;
6616 : 31238 : Lists_List l;
6617 : :
6618 : 31238 : if (importStatements != NULL)
6619 : : {
6620 : 19690 : i = 1;
6621 : 19690 : n = Lists_NoOfItemsInList (importStatements);
6622 : 61779 : while (i <= n)
6623 : : {
6624 : 22399 : stmt = static_cast<unsigned int> (Lists_GetItemFromList (importStatements, i));
6625 : 22399 : M2Debug_Assert (SymbolTable_IsImportStatement (stmt));
6626 : 22399 : l = SymbolTable_GetImportStatementList (stmt);
6627 : 22399 : j = 1;
6628 : 22399 : m = Lists_NoOfItemsInList (l);
6629 : 67947 : while (j <= m)
6630 : : {
6631 : 23149 : imported = static_cast<unsigned int> (Lists_GetItemFromList (l, j));
6632 : 23149 : M2Debug_Assert (SymbolTable_IsImport (imported));
6633 : 23149 : callRequestDependant (SymbolTable_GetImportDeclared (imported), moduleSym, SymbolTable_GetImportModule (imported), requestDep);
6634 : 23149 : j += 1;
6635 : : }
6636 : 22399 : i += 1;
6637 : : }
6638 : : }
6639 : 31238 : }
6640 : :
6641 : :
6642 : : /*
6643 : : ForeachImportedModuleDo -
6644 : : */
6645 : :
6646 : 15619 : static void ForeachImportedModuleDo (unsigned int moduleSym, unsigned int requestDep)
6647 : : {
6648 : 15619 : Lists_List importStatements;
6649 : :
6650 : 15619 : importStatements = SymbolTable_GetModuleModImportStatementList (moduleSym);
6651 : 15619 : ForeachImportInDepDo (importStatements, moduleSym, requestDep);
6652 : 15619 : importStatements = SymbolTable_GetModuleDefImportStatementList (moduleSym);
6653 : 15619 : ForeachImportInDepDo (importStatements, moduleSym, requestDep);
6654 : 15619 : }
6655 : :
6656 : :
6657 : : /*
6658 : : BuildM2DepFunction - creates the dependency graph procedure using IR:
6659 : : static void
6660 : : dependencies (void)
6661 : : {
6662 : : M2RTS_RequestDependant (module_name, libname, "b", "b libname");
6663 : : M2RTS_RequestDependant (module_name, libname, NULL, NULL);
6664 : : }
6665 : : */
6666 : :
6667 : 15663 : static void BuildM2DepFunction (unsigned int tokno, unsigned int moduleSym)
6668 : : {
6669 : 15663 : unsigned int requestDep;
6670 : 15663 : unsigned int ctor;
6671 : 15663 : unsigned int init;
6672 : 15663 : unsigned int fini;
6673 : 15663 : unsigned int dep;
6674 : :
6675 : 15663 : if (M2Options_ScaffoldDynamic)
6676 : : {
6677 : : /* Scaffold required and dynamic dependency graph should be produced. */
6678 : 15619 : SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
6679 : 15619 : M2Quads_PushT (dep);
6680 : 15619 : M2Quads_BuildProcedureStart ();
6681 : 15619 : M2Quads_BuildProcedureBegin ();
6682 : 15619 : SymbolTable_StartScope (dep);
6683 : 15619 : requestDep = GetQualidentImport (tokno, NameKey_MakeKey ((const char *) "RequestDependant", 16), NameKey_MakeKey ((const char *) "M2RTS", 5));
6684 : 15619 : if (requestDep != SymbolTable_NulSym)
6685 : : {
6686 : 15619 : ForeachImportedModuleDo (moduleSym, requestDep);
6687 : 15619 : callRequestDependant (tokno, moduleSym, SymbolTable_NulSym, requestDep);
6688 : : }
6689 : 15619 : SymbolTable_EndScope ();
6690 : 15619 : M2Quads_BuildProcedureEnd ();
6691 : 15619 : M2Quads_PopN (1);
6692 : : }
6693 : 15663 : }
6694 : :
6695 : :
6696 : : /*
6697 : : BuildM2LinkFunction - creates the _M2_link procedure which will
6698 : : cause the linker to pull in all the module ctors.
6699 : : */
6700 : :
6701 : 2706 : static void BuildM2LinkFunction (unsigned int tokno)
6702 : : {
6703 : 2706 : if (M2Options_ScaffoldDynamic)
6704 : : {
6705 : 2670 : if (M2Scaffold_linkFunction != SymbolTable_NulSym)
6706 : : {
6707 : : /* void
6708 : : _M2_link (void)
6709 : : {
6710 : : for each module in uselist do
6711 : : PROC foo_%d = _M2_module_ctor
6712 : : done
6713 : : }. */
6714 : 2666 : M2Quads_PushT (M2Scaffold_linkFunction);
6715 : 2666 : M2Quads_BuildProcedureStart ();
6716 : 2666 : M2Quads_BuildProcedureBegin ();
6717 : 2666 : SymbolTable_StartScope (M2Scaffold_linkFunction);
6718 : 2666 : M2Scaffold_PopulateCtorArray (tokno);
6719 : 2666 : SymbolTable_EndScope ();
6720 : 2666 : M2Quads_BuildProcedureEnd ();
6721 : 2666 : M2Quads_PopN (1);
6722 : : }
6723 : : }
6724 : 2706 : }
6725 : :
6726 : :
6727 : : /*
6728 : : BuildTry - build the try statement for main.
6729 : : */
6730 : :
6731 : 2670 : static void BuildTry (unsigned int tokno)
6732 : : {
6733 : 2670 : if (M2Options_Exceptions)
6734 : : {
6735 : 2670 : M2StackWord_PushWord (TryStack, NextQuad);
6736 : 2670 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
6737 : 2670 : GenQuadO (tokno, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
6738 : : }
6739 : 2670 : }
6740 : :
6741 : :
6742 : : /*
6743 : : BuildExcept - build the except block for main.
6744 : : */
6745 : :
6746 : 2670 : static void BuildExcept (unsigned int tokno)
6747 : : {
6748 : 2670 : unsigned int catchProcedure;
6749 : :
6750 : 2670 : if (M2Options_Exceptions)
6751 : : {
6752 : 2670 : M2Quads_BuildExceptInitial (tokno);
6753 : 2670 : catchProcedure = GetQualidentImport (tokno, NameKey_MakeKey ((const char *) "DefaultErrorCatch", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
6754 : 2670 : if (catchProcedure != SymbolTable_NulSym)
6755 : : {
6756 : 2670 : M2Quads_PushTtok (catchProcedure, tokno);
6757 : 2670 : M2Quads_PushT (static_cast<unsigned int> (0));
6758 : 2670 : M2Quads_BuildProcedureCall (tokno);
6759 : : }
6760 : 2670 : BuildRTExceptLeave (tokno, true);
6761 : 2670 : GenQuadO (tokno, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
6762 : : }
6763 : 2670 : }
6764 : :
6765 : :
6766 : : /*
6767 : : BuildM2MainFunction - creates the main function with appropriate calls to the scaffold.
6768 : : */
6769 : :
6770 : 2706 : static void BuildM2MainFunction (unsigned int tokno)
6771 : : {
6772 : 2706 : if ((M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic) && ! M2Options_SharedFlag)
6773 : : {
6774 : : /*
6775 : : int
6776 : : main (int argc, char *argv[], char *envp[])
6777 : : {
6778 : : try {
6779 : : _M2_init (argc, argv, envp);
6780 : : _M2_fini (argc, argv, envp);
6781 : : return 0;
6782 : : }
6783 : : catch (...) {
6784 : : RTExceptions_DefaultErrorCatch ();
6785 : : return 0;
6786 : : }
6787 : : }
6788 : : */
6789 : 2670 : M2Quads_PushT (M2Scaffold_mainFunction);
6790 : 2670 : M2Quads_BuildProcedureStart ();
6791 : 2670 : M2Quads_BuildProcedureBegin ();
6792 : 2670 : SymbolTable_StartScope (M2Scaffold_mainFunction);
6793 : 2670 : BuildTry (tokno);
6794 : : /* _M2_init (argc, argv, envp); */
6795 : 2670 : M2Quads_PushTtok (M2Scaffold_initFunction, tokno);
6796 : 2670 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argc", 4)), tokno);
6797 : 2670 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argv", 4)), tokno);
6798 : 2670 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "envp", 4)), tokno);
6799 : 2670 : M2Quads_PushT (static_cast<unsigned int> (3));
6800 : 2670 : M2Quads_BuildProcedureCall (tokno);
6801 : : /* _M2_fini (argc, argv, envp); */
6802 : 2670 : M2Quads_PushTtok (M2Scaffold_finiFunction, tokno);
6803 : 2670 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argc", 4)), tokno);
6804 : 2670 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argv", 4)), tokno);
6805 : 2670 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "envp", 4)), tokno);
6806 : 2670 : M2Quads_PushT (static_cast<unsigned int> (3));
6807 : 2670 : M2Quads_BuildProcedureCall (tokno);
6808 : 2670 : PushZero (tokno, M2Base_Integer);
6809 : 2670 : M2Quads_BuildReturn (tokno);
6810 : 2670 : BuildExcept (tokno);
6811 : 2670 : PushZero (tokno, M2Base_Integer);
6812 : 2670 : M2Quads_BuildReturn (tokno);
6813 : 2670 : SymbolTable_EndScope ();
6814 : 2670 : M2Quads_BuildProcedureEnd ();
6815 : 2670 : M2Quads_PopN (1);
6816 : : }
6817 : 2706 : }
6818 : :
6819 : :
6820 : : /*
6821 : : DeferMakeConstStringCnul - return a C const string which will be nul terminated.
6822 : : */
6823 : :
6824 : 9613 : static unsigned int DeferMakeConstStringCnul (unsigned int tok, unsigned int sym)
6825 : : {
6826 : 9613 : unsigned int const_;
6827 : :
6828 : 9613 : const_ = SymbolTable_MakeConstStringCnul (tok, NameKey_NulName, false);
6829 : 19226 : GenQuadO (tok, M2Quads_StringConvertCnulOp, const_, 0, sym, false);
6830 : 9613 : return const_;
6831 : : /* static analysis guarentees a RETURN statement will be used before here. */
6832 : : __builtin_unreachable ();
6833 : : }
6834 : :
6835 : :
6836 : : /*
6837 : : DeferMakeConstStringM2nul - return a const string which will be nul terminated.
6838 : : */
6839 : :
6840 : 34697 : static unsigned int DeferMakeConstStringM2nul (unsigned int tok, unsigned int sym)
6841 : : {
6842 : 34697 : unsigned int const_;
6843 : :
6844 : 34697 : const_ = SymbolTable_MakeConstStringM2nul (tok, NameKey_NulName, false);
6845 : 69394 : GenQuadO (tok, M2Quads_StringConvertM2nulOp, const_, 0, sym, false);
6846 : 34697 : return const_;
6847 : : /* static analysis guarentees a RETURN statement will be used before here. */
6848 : : __builtin_unreachable ();
6849 : : }
6850 : :
6851 : :
6852 : : /*
6853 : : BuildStringAdrParam - push the address of a nul terminated string onto the quad stack.
6854 : : */
6855 : :
6856 : 8010 : static void BuildStringAdrParam (unsigned int tok, NameKey_Name name)
6857 : : {
6858 : 8010 : unsigned int str;
6859 : 8010 : unsigned int m2strnul;
6860 : :
6861 : 8010 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6862 : 8010 : str = SymbolTable_MakeConstString (tok, name);
6863 : 8010 : SymbolTable_PutConstStringKnown (tok, str, name, false, true);
6864 : 8010 : m2strnul = DeferMakeConstStringM2nul (tok, str);
6865 : 8010 : M2Quads_PushTtok (m2strnul, tok);
6866 : 8010 : M2Quads_PushT (static_cast<unsigned int> (1));
6867 : 8010 : BuildAdrFunction ();
6868 : 8010 : }
6869 : :
6870 : :
6871 : : /*
6872 : : BuildM2InitFunction -
6873 : : */
6874 : :
6875 : 2706 : static void BuildM2InitFunction (unsigned int tok, unsigned int moduleSym)
6876 : : {
6877 : 2706 : unsigned int constructModules;
6878 : :
6879 : 2706 : if (M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic)
6880 : : {
6881 : : /* int
6882 : : _M2_init (int argc, char *argv[], char *envp[])
6883 : : {
6884 : : M2RTS_ConstructModules (module_name, libname,
6885 : : overrideliborder, argc, argv, envp);
6886 : : } */
6887 : 2670 : M2Quads_PushT (M2Scaffold_initFunction);
6888 : 2670 : M2Quads_BuildProcedureStart ();
6889 : 2670 : M2Quads_BuildProcedureBegin ();
6890 : 2670 : SymbolTable_StartScope (M2Scaffold_initFunction);
6891 : 2670 : if (M2Options_ScaffoldDynamic)
6892 : : {
6893 : : /* avoid dangling else. */
6894 : 2670 : if (M2Scaffold_linkFunction != SymbolTable_NulSym)
6895 : : {
6896 : : /* _M2_link (); */
6897 : 2666 : M2Quads_PushTtok (M2Scaffold_linkFunction, tok);
6898 : 2666 : M2Quads_PushT (static_cast<unsigned int> (0));
6899 : 2666 : M2Quads_BuildProcedureCall (tok);
6900 : : }
6901 : : /* Lookup ConstructModules and call it. */
6902 : 2670 : constructModules = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "ConstructModules", 16), NameKey_MakeKey ((const char *) "M2RTS", 5));
6903 : 2670 : if (constructModules != SymbolTable_NulSym)
6904 : : {
6905 : : /* ConstructModules (module_name, argc, argv, envp); */
6906 : 2670 : M2Quads_PushTtok (constructModules, tok);
6907 : 2670 : BuildStringAdrParam (tok, SymbolTable_GetSymName (moduleSym));
6908 : 2670 : BuildStringAdrParam (tok, SymbolTable_GetLibName (moduleSym));
6909 : 2670 : BuildStringAdrParam (tok, NameKey_makekey (M2Options_GetRuntimeModuleOverride ()));
6910 : 2670 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argc", 4)), tok);
6911 : 2670 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argv", 4)), tok);
6912 : 2670 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "envp", 4)), tok);
6913 : 2670 : M2Quads_PushT (static_cast<unsigned int> (6));
6914 : 2670 : M2Quads_BuildProcedureCall (tok);
6915 : : }
6916 : : }
6917 : 0 : else if (M2Options_ScaffoldStatic)
6918 : : {
6919 : : /* avoid dangling else. */
6920 : 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)));
6921 : : }
6922 : 2670 : SymbolTable_EndScope ();
6923 : 2670 : M2Quads_BuildProcedureEnd ();
6924 : 2670 : M2Quads_PopN (1);
6925 : : }
6926 : 2706 : }
6927 : :
6928 : :
6929 : : /*
6930 : : BuildM2FiniFunction -
6931 : : */
6932 : :
6933 : 2706 : static void BuildM2FiniFunction (unsigned int tok, unsigned int moduleSym)
6934 : : {
6935 : 2706 : unsigned int deconstructModules;
6936 : :
6937 : 2706 : if (M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic)
6938 : : {
6939 : : /* Scaffold required and main should be produced. */
6940 : 2670 : M2Quads_PushT (M2Scaffold_finiFunction);
6941 : 2670 : M2Quads_BuildProcedureStart ();
6942 : 2670 : M2Quads_BuildProcedureBegin ();
6943 : 2670 : SymbolTable_StartScope (M2Scaffold_finiFunction);
6944 : 2670 : if (M2Options_ScaffoldDynamic)
6945 : : {
6946 : : /* avoid dangling else. */
6947 : : /* static void
6948 : : _M2_finish (int argc, char *argv[], char *envp[])
6949 : : {
6950 : : M2RTS_DeconstructModules (module_name, argc, argv, envp);
6951 : : } */
6952 : 2670 : deconstructModules = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "DeconstructModules", 18), NameKey_MakeKey ((const char *) "M2RTS", 5));
6953 : 2670 : if (deconstructModules != SymbolTable_NulSym)
6954 : : {
6955 : : /* DeconstructModules (module_name, argc, argv, envp); */
6956 : 2670 : M2Quads_PushTtok (deconstructModules, tok);
6957 : 2670 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6958 : 2670 : M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetSymName (moduleSym)), tok);
6959 : 2670 : M2Quads_PushT (static_cast<unsigned int> (1));
6960 : 2670 : BuildAdrFunction ();
6961 : 2670 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6962 : 2670 : M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetLibName (moduleSym)), tok);
6963 : 2670 : M2Quads_PushT (static_cast<unsigned int> (1));
6964 : 2670 : BuildAdrFunction ();
6965 : 2670 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argc", 4)), tok);
6966 : 2670 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argv", 4)), tok);
6967 : 2670 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "envp", 4)), tok);
6968 : 2670 : M2Quads_PushT (static_cast<unsigned int> (5));
6969 : 2670 : M2Quads_BuildProcedureCall (tok);
6970 : : }
6971 : : }
6972 : 0 : else if (M2Options_ScaffoldStatic)
6973 : : {
6974 : : /* avoid dangling else. */
6975 : 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)));
6976 : : }
6977 : 2670 : SymbolTable_EndScope ();
6978 : 2670 : M2Quads_BuildProcedureEnd ();
6979 : 2670 : M2Quads_PopN (1);
6980 : : }
6981 : 2706 : }
6982 : :
6983 : :
6984 : : /*
6985 : : BuildM2CtorFunction - create a constructor function associated with moduleSym.
6986 : :
6987 : : void
6988 : : ctorFunction ()
6989 : : {
6990 : : M2RTS_RegisterModule (GetSymName (moduleSym), GetLibName (moduleSym),
6991 : : init, fini, dependencies);
6992 : : }
6993 : : */
6994 : :
6995 : 15663 : static void BuildM2CtorFunction (unsigned int tok, unsigned int moduleSym)
6996 : : {
6997 : 15663 : unsigned int RegisterModule;
6998 : 15663 : unsigned int ctor;
6999 : 15663 : unsigned int init;
7000 : 15663 : unsigned int fini;
7001 : 15663 : unsigned int dep;
7002 : :
7003 : 15663 : if (M2Options_ScaffoldDynamic)
7004 : : {
7005 : 15619 : SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
7006 : 15619 : if (ctor != SymbolTable_NulSym)
7007 : : {
7008 : 15619 : M2Debug_Assert (SymbolTable_IsProcedure (ctor));
7009 : 15619 : M2Quads_PushT (ctor);
7010 : 15619 : M2Quads_BuildProcedureStart ();
7011 : 15619 : M2Quads_BuildProcedureBegin ();
7012 : 15619 : SymbolTable_StartScope (ctor);
7013 : 15619 : RegisterModule = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "RegisterModule", 14), NameKey_MakeKey ((const char *) "M2RTS", 5));
7014 : 15619 : if (RegisterModule != SymbolTable_NulSym)
7015 : : {
7016 : : /* RegisterModule (module_name, init, fini, dependencies); */
7017 : 15619 : M2Quads_PushTtok (RegisterModule, tok);
7018 : 15619 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
7019 : 15619 : M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetSymName (moduleSym)), tok);
7020 : 15619 : M2Quads_PushT (static_cast<unsigned int> (1));
7021 : 15619 : BuildAdrFunction ();
7022 : 15619 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
7023 : 15619 : M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetLibName (moduleSym)), tok);
7024 : 15619 : M2Quads_PushT (static_cast<unsigned int> (1));
7025 : 15619 : BuildAdrFunction ();
7026 : 15619 : M2Quads_PushTtok (init, tok);
7027 : 15619 : M2Quads_PushTtok (fini, tok);
7028 : 15619 : M2Quads_PushTtok (dep, tok);
7029 : 15619 : M2Quads_PushT (static_cast<unsigned int> (5));
7030 : 15619 : M2Quads_BuildProcedureCall (tok);
7031 : : }
7032 : 15619 : SymbolTable_EndScope ();
7033 : 15619 : M2Quads_BuildProcedureEnd ();
7034 : 15619 : M2Quads_PopN (1);
7035 : : }
7036 : : }
7037 : 15663 : }
7038 : :
7039 : :
7040 : : /*
7041 : : AddForInfo - adds the description of the FOR loop into the record list.
7042 : : This is used if -pedantic is turned on to check index variable
7043 : : usage.
7044 : : */
7045 : :
7046 : 2604 : static void AddForInfo (unsigned int Start, unsigned int End, unsigned int IncQuad, unsigned int Sym, unsigned int idtok)
7047 : : {
7048 : 2604 : M2Quads_ForLoopInfo forDesc;
7049 : :
7050 : 2604 : if (M2Options_Pedantic)
7051 : : {
7052 : 0 : Storage_ALLOCATE ((void **) &forDesc, sizeof (M2Quads__T5));
7053 : 0 : forDesc->IncrementQuad = IncQuad;
7054 : 0 : forDesc->StartOfForLoop = Start;
7055 : 0 : forDesc->EndOfForLoop = End;
7056 : 0 : forDesc->ForLoopIndex = Sym;
7057 : 0 : forDesc->IndexTok = idtok;
7058 : 0 : Indexing_IncludeIndiceIntoIndex (ForInfo, reinterpret_cast <void *> (forDesc));
7059 : : }
7060 : 2604 : }
7061 : :
7062 : :
7063 : : /*
7064 : : CheckForIndex - checks the quadruples: Start..End to see whether a
7065 : : for loop index is manipulated by the programmer.
7066 : : It generates a warning if this is the case.
7067 : : It also checks to see whether the IndexSym is read
7068 : : immediately outside the loop in which case a warning
7069 : : is issued.
7070 : : */
7071 : :
7072 : 0 : static void CheckForIndex (M2Quads_ForLoopInfo forDesc)
7073 : : {
7074 : 0 : unsigned int ReadStart;
7075 : 0 : unsigned int ReadEnd;
7076 : 0 : unsigned int WriteStart;
7077 : 0 : unsigned int WriteEnd;
7078 : :
7079 : 0 : SymbolTable_GetWriteLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->StartOfForLoop, forDesc->EndOfForLoop, &WriteStart, &WriteEnd);
7080 : 0 : if ((WriteStart < forDesc->IncrementQuad) && (WriteStart > forDesc->StartOfForLoop))
7081 : : {
7082 : 0 : M2MetaError_MetaErrorT1 (forDesc->IndexTok, (const char *) "{%kFOR} loop index variable {%1Wad} is being manipulated inside the loop", 72, forDesc->ForLoopIndex);
7083 : 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);
7084 : : }
7085 : 0 : SymbolTable_GetWriteLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->EndOfForLoop, 0, &WriteStart, &WriteEnd);
7086 : 0 : SymbolTable_GetReadLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->EndOfForLoop, 0, &ReadStart, &ReadEnd);
7087 : 0 : if ((ReadStart != 0) && ((ReadStart < WriteStart) || (WriteStart == 0)))
7088 : : {
7089 : 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);
7090 : 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);
7091 : : }
7092 : 0 : }
7093 : :
7094 : :
7095 : : /*
7096 : : BuildRange - generates a RangeCheckOp quad with, r, as its operand.
7097 : : */
7098 : :
7099 : 2065556 : static void BuildRange (unsigned int r)
7100 : : {
7101 : 2065556 : GenQuad (M2Quads_RangeCheckOp, (unsigned int ) (M2LexBuf_GetLineNo ()), SymbolTable_NulSym, r);
7102 : 2065556 : }
7103 : :
7104 : :
7105 : : /*
7106 : : BuildError - generates a ErrorOp quad, indicating that if this
7107 : : quadruple is reachable, then a runtime error would
7108 : : occur.
7109 : : */
7110 : :
7111 : 19445 : static void BuildError (unsigned int r)
7112 : : {
7113 : 19445 : GenQuad (M2Quads_ErrorOp, (unsigned int ) (M2LexBuf_GetLineNo ()), SymbolTable_NulSym, r);
7114 : 19445 : }
7115 : :
7116 : :
7117 : : /*
7118 : : CheckPointerThroughNil - builds a range quadruple, providing, sym, is
7119 : : a candidate for checking against NIL.
7120 : : This range quadruple is only expanded into
7121 : : code during the code generation phase
7122 : : thus allowing limited compile time checking.
7123 : : */
7124 : :
7125 : 80147 : static void CheckPointerThroughNil (unsigned int tokpos, unsigned int sym)
7126 : : {
7127 : 80147 : if ((SymbolTable_IsVar (sym)) && (SymbolTable_GetVarPointerCheck (sym)))
7128 : : {
7129 : : /* PutVarPointerCheck(sym, FALSE) ; so we do not detect this again */
7130 : 23438 : BuildRange (M2Range_InitPointerRangeCheck (tokpos, sym, (SymbolTable_GetMode (sym)) == SymbolTable_LeftValue));
7131 : : }
7132 : 80147 : }
7133 : :
7134 : :
7135 : : /*
7136 : : CollectLow - returns the low of the subrange value.
7137 : : */
7138 : :
7139 : 282 : static unsigned int CollectLow (unsigned int sym)
7140 : : {
7141 : 282 : unsigned int low;
7142 : 282 : unsigned int high;
7143 : :
7144 : 282 : if (SymbolTable_IsSubrange (sym))
7145 : : {
7146 : 282 : SymbolTable_GetSubrange (sym, &high, &low);
7147 : 282 : return low;
7148 : : }
7149 : : else
7150 : : {
7151 : 0 : M2Error_InternalError ((const char *) "expecting Subrange symbol", 25);
7152 : : }
7153 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
7154 : : __builtin_unreachable ();
7155 : : }
7156 : :
7157 : :
7158 : : /*
7159 : : CollectHigh - returns the high of the subrange value, sym.
7160 : : */
7161 : :
7162 : 562 : static unsigned int CollectHigh (unsigned int sym)
7163 : : {
7164 : 562 : unsigned int low;
7165 : 562 : unsigned int high;
7166 : :
7167 : 562 : if (SymbolTable_IsSubrange (sym))
7168 : : {
7169 : 562 : SymbolTable_GetSubrange (sym, &high, &low);
7170 : 562 : return high;
7171 : : }
7172 : : else
7173 : : {
7174 : 0 : M2Error_InternalError ((const char *) "expecting Subrange symbol", 25);
7175 : : }
7176 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
7177 : : __builtin_unreachable ();
7178 : : }
7179 : :
7180 : :
7181 : : /*
7182 : : CheckCompatibleWithBecomes - checks to see that symbol, sym, is
7183 : : compatible with the := operator.
7184 : : */
7185 : :
7186 : 496133 : static void CheckCompatibleWithBecomes (unsigned int des, unsigned int expr, unsigned int destok, unsigned int exprtok)
7187 : : {
7188 : 496133 : if (SymbolTable_IsType (des))
7189 : : {
7190 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to a type {%1a}", 51, des);
7191 : : }
7192 : 496133 : else if (SymbolTable_IsProcedure (des))
7193 : : {
7194 : : /* avoid dangling else. */
7195 : 6 : M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to a procedure {%1a}", 56, des);
7196 : : }
7197 : 496127 : else if (SymbolTable_IsFieldEnumeration (des))
7198 : : {
7199 : : /* avoid dangling else. */
7200 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to an enumeration field {%1a}", 65, des);
7201 : : }
7202 : 496133 : if ((M2Base_IsPseudoBaseProcedure (expr)) || (M2Base_IsPseudoBaseFunction (expr)))
7203 : : {
7204 : 6 : M2MetaError_MetaErrorT1 (exprtok, (const char *) "an assignment cannot assign a {%1dv} {%1a}", 42, expr);
7205 : : }
7206 : 496133 : }
7207 : :
7208 : :
7209 : : /*
7210 : : BuildAssignmentWithoutBounds - calls BuildAssignment but makes sure we do not
7211 : : check bounds.
7212 : : */
7213 : :
7214 : 83743 : static void BuildAssignmentWithoutBounds (unsigned int tok, bool checkTypes, bool checkOverflow)
7215 : : {
7216 : 83743 : bool old;
7217 : :
7218 : 83743 : old = MustNotCheckBounds;
7219 : 83743 : MustNotCheckBounds = true;
7220 : 0 : doBuildAssignment (tok, checkTypes, checkOverflow);
7221 : 83743 : MustNotCheckBounds = old;
7222 : 19736 : }
7223 : :
7224 : :
7225 : : /*
7226 : : MarkArrayWritten - marks, Array, as being written.
7227 : : */
7228 : :
7229 : 101624 : static void MarkArrayWritten (unsigned int Array)
7230 : : {
7231 : 101624 : if ((Array != SymbolTable_NulSym) && (SymbolTable_IsVarAParam (Array)))
7232 : : {
7233 : 12610 : SymbolTable_PutVarWritten (Array, true);
7234 : : }
7235 : 101624 : }
7236 : :
7237 : :
7238 : : /*
7239 : : MarkAsReadWrite - marks the variable or parameter as being
7240 : : read/write.
7241 : : */
7242 : :
7243 : 31111 : static void MarkAsReadWrite (unsigned int sym)
7244 : : {
7245 : 31111 : if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
7246 : : {
7247 : 21498 : SymbolTable_PutReadQuad (sym, SymbolTable_RightValue, NextQuad);
7248 : 21498 : SymbolTable_PutWriteQuad (sym, SymbolTable_RightValue, NextQuad);
7249 : : }
7250 : 31111 : }
7251 : :
7252 : :
7253 : : /*
7254 : : MarkAsRead - marks the variable or parameter as being read.
7255 : : */
7256 : :
7257 : 1263506 : static void MarkAsRead (unsigned int sym)
7258 : : {
7259 : 1263506 : if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
7260 : : {
7261 : 358290 : SymbolTable_PutReadQuad (sym, SymbolTable_RightValue, NextQuad);
7262 : : }
7263 : 1263506 : }
7264 : :
7265 : :
7266 : : /*
7267 : : MarkAsWrite - marks the variable or parameter as being written.
7268 : : */
7269 : :
7270 : 496133 : static void MarkAsWrite (unsigned int sym)
7271 : : {
7272 : 496133 : if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
7273 : : {
7274 : 85807 : SymbolTable_PutWriteQuad (sym, SymbolTable_RightValue, NextQuad);
7275 : : }
7276 : 496133 : }
7277 : :
7278 : :
7279 : : /*
7280 : : doVal - return an expression which is VAL(type, expr). If
7281 : : expr is a constant then return expr.
7282 : : */
7283 : :
7284 : 43762 : static unsigned int doVal (unsigned int type, unsigned int expr)
7285 : : {
7286 : 43762 : if ((! (SymbolTable_IsConst (expr))) && ((SymbolTable_SkipType (type)) != (SymbolTable_GetDType (expr))))
7287 : : {
7288 : 33022 : M2Quads_PushTF (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym));
7289 : 33022 : M2Quads_PushT (SymbolTable_SkipType (type));
7290 : 33022 : M2Quads_PushT (expr);
7291 : 33022 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
7292 : 33022 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
7293 : 33022 : M2Quads_PopT (&expr);
7294 : : }
7295 : 43762 : return expr;
7296 : : /* static analysis guarentees a RETURN statement will be used before here. */
7297 : : __builtin_unreachable ();
7298 : : }
7299 : :
7300 : :
7301 : : /*
7302 : : MoveWithMode -
7303 : : */
7304 : :
7305 : 496127 : static void MoveWithMode (unsigned int tokno, unsigned int Des, unsigned int Exp, unsigned int Array, unsigned int destok, unsigned int exptok, bool checkOverflow)
7306 : : {
7307 : 496127 : unsigned int t;
7308 : :
7309 : 496127 : if ((SymbolTable_IsConstString (Exp)) && (SymbolTable_IsConst (Des)))
7310 : : {
7311 : 1426 : GenQuadOtok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, destok, M2LexBuf_UnknownTokenNo, exptok);
7312 : : }
7313 : : else
7314 : : {
7315 : 494701 : if ((SymbolTable_GetMode (Des)) == SymbolTable_RightValue)
7316 : : {
7317 : 157795 : if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
7318 : : {
7319 : 2688 : CheckPointerThroughNil (tokno, Exp); /* Des = *Exp */
7320 : 2688 : doIndrX (tokno, Des, Exp); /* Des = *Exp */
7321 : : }
7322 : : else
7323 : : {
7324 : 155107 : GenQuadOtok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, destok, M2LexBuf_UnknownTokenNo, exptok);
7325 : : }
7326 : : }
7327 : 336906 : else if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
7328 : : {
7329 : : /* avoid dangling else. */
7330 : 43244 : MarkArrayWritten (Array);
7331 : 43244 : if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
7332 : : {
7333 : 1106 : t = SymbolTable_MakeTemporary (tokno, SymbolTable_RightValue);
7334 : 1106 : SymbolTable_PutVar (t, SymbolTable_GetSType (Exp));
7335 : 1106 : CheckPointerThroughNil (tokno, Exp);
7336 : 1106 : doIndrX (tokno, t, Exp);
7337 : 1106 : CheckPointerThroughNil (tokno, Des); /* *Des = Exp */
7338 : 1106 : GenQuadO (tokno, M2Quads_XIndrOp, Des, SymbolTable_GetSType (Des), doVal (SymbolTable_GetSType (Des), t), checkOverflow); /* *Des = Exp */
7339 : : }
7340 : : else
7341 : : {
7342 : 42138 : CheckPointerThroughNil (tokno, Des); /* *Des = Exp */
7343 : 42138 : GenQuadO (tokno, M2Quads_XIndrOp, Des, SymbolTable_GetSType (Des), doVal (SymbolTable_GetSType (Des), Exp), checkOverflow); /* *Des = Exp */
7344 : : }
7345 : : }
7346 : : else
7347 : : {
7348 : : /* avoid dangling else. */
7349 : : /* This might be inside a const expression. */
7350 : 293662 : GenQuadOTypetok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, true, destok, M2LexBuf_UnknownTokenNo, exptok);
7351 : : }
7352 : : }
7353 : 496127 : }
7354 : :
7355 : :
7356 : : /*
7357 : : CheckBecomesMeta - checks to make sure that we are not
7358 : : assigning a variable to a constant.
7359 : : Also check we are not assigning to an
7360 : : unbounded array.
7361 : : */
7362 : :
7363 : 424124 : static void CheckBecomesMeta (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok)
7364 : : {
7365 : 424124 : if ((SymbolTable_IsConst (Des)) && (SymbolTable_IsVar (Exp)))
7366 : : {
7367 : 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);
7368 : : }
7369 : 424124 : if ((((SymbolTable_GetDType (Des)) != SymbolTable_NulSym) && (SymbolTable_IsVar (Des))) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (Des))))
7370 : : {
7371 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "in assignment, cannot assign to an unbounded array {%1ad}", 57, Des);
7372 : : }
7373 : 424124 : if ((((SymbolTable_GetDType (Exp)) != SymbolTable_NulSym) && (SymbolTable_IsVar (Exp))) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (Exp))))
7374 : : {
7375 : 0 : M2MetaError_MetaErrorT1 (exprtok, (const char *) "in assignment, cannot assign from an unbounded array {%1ad}", 59, Exp);
7376 : : }
7377 : 424124 : }
7378 : :
7379 : :
7380 : : /*
7381 : : BuildAssignmentBoolean - build the quadruples for a boolean variable or constant
7382 : : which will be assigned to the result of a boolean expression.
7383 : : For example:
7384 : :
7385 : : foo := a = b ;
7386 : : foo := a IN b ;
7387 : :
7388 : : The boolean result is contained in the control flow
7389 : : the true value will emerge from the quad path t.
7390 : : The false value will emerge from the quad path f.
7391 : : This procedure terminates both paths by backpatching
7392 : : and assigns TRUE or FALSE to the variable/constant.
7393 : : A variable maybe an L value so it will require dereferencing.
7394 : : */
7395 : :
7396 : 9980 : static void BuildAssignmentBoolean (unsigned int becomesTokNo, bool checkOverflow, unsigned int t, unsigned int f, unsigned int Des, unsigned int destok)
7397 : : {
7398 : 9980 : SymbolTable_PutVarConditional (Des, true); /* Des will contain the result of a boolean relop. */
7399 : : /* Conditional Boolean Assignment. */
7400 : 9980 : BackPatch (t, NextQuad);
7401 : 9980 : if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
7402 : : {
7403 : 64 : CheckPointerThroughNil (destok, Des);
7404 : 128 : GenQuadO (destok, M2Quads_XIndrOp, Des, M2Base_Boolean, M2Base_True, checkOverflow);
7405 : 64 : GenQuadO (destok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, NextQuad+2, false);
7406 : : }
7407 : : else
7408 : : {
7409 : : /* This might be inside a const expression. */
7410 : 19832 : GenQuadO (becomesTokNo, M2Quads_BecomesOp, Des, SymbolTable_NulSym, M2Base_True, checkOverflow);
7411 : 9916 : GenQuadO (destok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, NextQuad+2, false);
7412 : : }
7413 : 9980 : BackPatch (f, NextQuad);
7414 : 9980 : if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
7415 : : {
7416 : 64 : CheckPointerThroughNil (destok, Des);
7417 : 64 : GenQuadO (destok, M2Quads_XIndrOp, Des, M2Base_Boolean, M2Base_False, checkOverflow);
7418 : : }
7419 : : else
7420 : : {
7421 : 9916 : GenQuadO (becomesTokNo, M2Quads_BecomesOp, Des, SymbolTable_NulSym, M2Base_False, checkOverflow);
7422 : : }
7423 : 9980 : }
7424 : :
7425 : :
7426 : : /*
7427 : : doBuildAssignment - subsiduary procedure of BuildAssignment.
7428 : : It builds the assignment and optionally
7429 : : checks the types are compatible.
7430 : : */
7431 : :
7432 : 506113 : static void doBuildAssignment (unsigned int becomesTokNo, bool checkTypes, bool checkOverflow)
7433 : : {
7434 : 506113 : unsigned int r;
7435 : 506113 : unsigned int w;
7436 : 506113 : unsigned int t;
7437 : 506113 : unsigned int f;
7438 : 506113 : unsigned int Array;
7439 : 506113 : unsigned int Des;
7440 : 506113 : unsigned int Exp;
7441 : 506113 : unsigned int combinedtok;
7442 : 506113 : unsigned int destok;
7443 : 506113 : unsigned int exptok;
7444 : :
7445 : 506113 : M2Quads_DisplayStack ();
7446 : 506113 : if (IsBoolean (1))
7447 : : {
7448 : 19960 : PopBool (&t, &f);
7449 : 9980 : M2Quads_PopTtok (&Des, &destok);
7450 : 9980 : if ((SymbolTable_IsVar (Des)) || (SymbolTable_IsConstVar (Des)))
7451 : : {
7452 : 9980 : BuildAssignmentBoolean (becomesTokNo, checkOverflow, t, f, Des, destok);
7453 : : }
7454 : : else
7455 : : {
7456 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "expecting the designator {%1Ead} to be a constant or a variable and not a {%1dv}", 80, Des);
7457 : : }
7458 : : }
7459 : : else
7460 : : {
7461 : 496133 : PopTrwtok (&Exp, &r, &exptok);
7462 : 496133 : MarkAsRead (r);
7463 : 496133 : if (Exp == SymbolTable_NulSym)
7464 : : {
7465 : 0 : M2MetaError_MetaError0 ((const char *) "{%E}unknown expression found during assignment", 46);
7466 : 0 : M2Error_FlushErrors ();
7467 : : }
7468 : 496133 : Array = static_cast<unsigned int> (M2Quads_OperandA (1));
7469 : 496133 : PopTrwtok (&Des, &w, &destok);
7470 : 496133 : MarkAsWrite (w);
7471 : 496133 : CheckCompatibleWithBecomes (Des, Exp, destok, exptok);
7472 : 496133 : if (DebugTokPos)
7473 : : {
7474 : : M2MetaError_MetaErrorT1 (becomesTokNo, (const char *) "becomestok {%1Oad}", 18, Des);
7475 : : M2MetaError_MetaErrorT1 (destok, (const char *) "destok {%1Oad}", 14, Des);
7476 : : M2MetaError_MetaErrorT1 (exptok, (const char *) "exptok {%1Oad}", 14, Exp);
7477 : : }
7478 : 496133 : combinedtok = M2LexBuf_MakeVirtualTok (becomesTokNo, destok, exptok);
7479 : 496133 : if (DebugTokPos)
7480 : : {
7481 : : M2MetaError_MetaErrorT1 (combinedtok, (const char *) "combined {%1Oad}", 16, Des);
7482 : : }
7483 : 496133 : if (M2Options_StrictTypeAssignment)
7484 : : {
7485 : 496133 : BuildRange (M2Range_InitTypesAssignmentCheck (combinedtok, Des, Exp));
7486 : : }
7487 : 496133 : if (((SymbolTable_GetSType (Des)) != SymbolTable_NulSym) && (! (SymbolTable_IsSet (SymbolTable_GetDType (Des)))))
7488 : : {
7489 : : /* Tell code generator to test runtime values of assignment so ensure we
7490 : : catch overflow and underflow. */
7491 : 486535 : BuildRange (M2Range_InitAssignmentRangeCheck (combinedtok, Des, Exp, destok, exptok));
7492 : : }
7493 : 496127 : if (checkTypes)
7494 : : {
7495 : 424124 : CheckBecomesMeta (Des, Exp, combinedtok, destok, exptok);
7496 : : }
7497 : : /* Simple assignment. */
7498 : 496127 : MoveWithMode (combinedtok, Des, Exp, Array, destok, exptok, checkOverflow);
7499 : 496127 : if (checkTypes)
7500 : : {
7501 : 424124 : CheckAssignCompatible (Des, Exp, combinedtok, destok, exptok);
7502 : : }
7503 : : }
7504 : 506107 : M2Quads_DisplayStack ();
7505 : 506107 : }
7506 : :
7507 : :
7508 : : /*
7509 : : CheckAssignCompatible - checks to see that an assignment is compatible.
7510 : : It performs limited checking - thorough checking
7511 : : is done in pass 3. But we do what we can here
7512 : : given knowledge so far.
7513 : : */
7514 : :
7515 : 424124 : static void CheckAssignCompatible (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok)
7516 : : {
7517 : 424124 : unsigned int DesT;
7518 : 424124 : unsigned int ExpT;
7519 : 424124 : unsigned int DesL;
7520 : :
7521 : 424124 : DesT = SymbolTable_GetSType (Des);
7522 : 424124 : ExpT = SymbolTable_GetSType (Exp);
7523 : 424124 : DesL = SymbolTable_GetLType (Des);
7524 : 424124 : if (((SymbolTable_IsProcedure (Exp)) && ((DesT != SymbolTable_NulSym) && (! (SymbolTable_IsProcType (DesT))))) && ((DesL != SymbolTable_NulSym) && (! (SymbolTable_IsProcType (DesL)))))
7525 : : {
7526 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "incorrectly assigning a procedure to a designator {%1Ead} (designator is not a procedure type, {%1ast})", 103, Des);
7527 : : }
7528 : : /* We ignore checking of these types in pass 3 - but we do check them thoroughly post pass 3 */
7529 : 424124 : else if ((SymbolTable_IsProcedure (Exp)) && (SymbolTable_IsProcedureNested (Exp)))
7530 : : {
7531 : : /* avoid dangling else. */
7532 : 6 : M2MetaError_MetaErrorT1 (exprtok, (const char *) "cannot call nested procedure {%1Ead} indirectly as the outer scope will not be known", 84, Exp);
7533 : : }
7534 : 424118 : else if (SymbolTable_IsConstString (Exp))
7535 : : {
7536 : : /* avoid dangling else. */
7537 : : }
7538 : 421026 : else if ((DesT != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (DesT)))
7539 : : {
7540 : : /* avoid dangling else. */
7541 : : }
7542 : 421026 : else if ((ExpT != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (ExpT)))
7543 : : {
7544 : : /* avoid dangling else. */
7545 : : }
7546 : 421026 : else if ((DesL != SymbolTable_NulSym) && (SymbolTable_IsArray (DesL)))
7547 : : {
7548 : : /* avoid dangling else. */
7549 : : }
7550 : 420178 : else if (SymbolTable_IsConstructor (Exp))
7551 : : {
7552 : : /* avoid dangling else. */
7553 : 6426 : if (ExpT == SymbolTable_NulSym)
7554 : : {} /* empty. */
7555 : 6386 : else if (((DesT == SymbolTable_NulSym) && (SymbolTable_IsConst (Des))) && ((SymbolTable_IsConstructor (Des)) || (SymbolTable_IsConstSet (Des))))
7556 : : {
7557 : : /* avoid dangling else. */
7558 : 0 : SymbolTable_PutConst (Des, ExpT);
7559 : : }
7560 : 6386 : else if (! (M2Base_IsAssignmentCompatible (DesT, ExpT)))
7561 : : {
7562 : : /* avoid dangling else. */
7563 : 0 : M2MetaError_MetaErrorT1 (combinedtok, (const char *) "constructor expression is not compatible during assignment to {%1Ead}", 69, Des);
7564 : : }
7565 : : }
7566 : 413752 : else if (((DesT != SymbolTable_NulSym) && (SymbolTable_IsSet (DesT))) && (SymbolTable_IsConst (Exp)))
7567 : : {
7568 : : /* avoid dangling else. */
7569 : : }
7570 : 413622 : else if ((((((SymbolTable_IsConst (Exp)) && (ExpT != M2System_Address)) && (! (SymbolTable_IsConst (Des)))) && (DesL != SymbolTable_NulSym)) && ((DesL == M2Base_Cardinal) || (! (SymbolTable_IsSubrange (DesL))))) && (! (SymbolTable_IsEnumeration (DesL))))
7571 : : {
7572 : : /* avoid dangling else. */
7573 : 24916 : if ((M2Base_IsBaseType (DesL)) || (M2System_IsSystemType (DesL)))
7574 : : {
7575 : 24916 : M2Base_CheckAssignmentCompatible (combinedtok, ExpT, DesT);
7576 : : }
7577 : : else
7578 : : {
7579 : 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);
7580 : : }
7581 : : }
7582 : : else
7583 : : {
7584 : : /* avoid dangling else. */
7585 : 388706 : if (((DesT != SymbolTable_NulSym) && (SymbolTable_IsProcType (DesT))) && (SymbolTable_IsProcedure (Exp)))
7586 : : {
7587 : 32298 : DesT = SymbolTable_GetSType (DesT); /* we can at least check RETURN values of procedure variables */
7588 : : /* remember that thorough assignment checking is done post pass 3 */
7589 : 32298 : M2Base_CheckAssignmentCompatible (combinedtok, ExpT, DesT);
7590 : : }
7591 : : }
7592 : 424124 : }
7593 : :
7594 : :
7595 : : /*
7596 : : CheckBooleanId - Checks to see if the top operand is a boolean.
7597 : : If the operand is not a boolean then it is tested
7598 : : with true and a boolean is generated.
7599 : : The Stack:
7600 : :
7601 : :
7602 : : Entry Exit
7603 : : Ptr -> <- Ptr
7604 : : +------------+ +------------+
7605 : : | Sym | | t | f |
7606 : : |------------| |------------|
7607 : :
7608 : : Quadruples
7609 : :
7610 : : q If= Sym True _
7611 : : q+1 GotoOp _ _ _
7612 : : */
7613 : :
7614 : 85921 : static void CheckBooleanId (void)
7615 : : {
7616 : 85921 : unsigned int tok;
7617 : :
7618 : 85921 : if (! (IsBoolean (1)))
7619 : : {
7620 : 18027 : tok = static_cast<unsigned int> (M2Quads_OperandTok (1));
7621 : 18027 : if (SymbolTable_IsVar (M2Quads_OperandT (1)))
7622 : : {
7623 : 14403 : if ((SymbolTable_GetSType (M2Quads_OperandT (1))) != M2Base_Boolean)
7624 : : {
7625 : 0 : M2MetaError_MetaError1 ((const char *) "{%1Ua:is not a boolean expression}{!%1Ua:boolean expression expected}", 69, M2Quads_OperandT (1));
7626 : : }
7627 : : }
7628 : 18027 : M2Quads_PushT (M2Reserved_EqualTok);
7629 : 18027 : M2Quads_PushT (M2Base_True);
7630 : 18027 : M2Quads_BuildRelOp (tok);
7631 : : }
7632 : 85921 : }
7633 : :
7634 : :
7635 : : /*
7636 : : PushOne - pushes the value one to the stack.
7637 : : The Stack is changed:
7638 : :
7639 : :
7640 : : Entry Exit
7641 : : ===== ====
7642 : :
7643 : : <- Ptr
7644 : : +------------+
7645 : : Ptr -> | 1 | type |
7646 : : |------------|
7647 : : */
7648 : :
7649 : 16420 : static void PushOne (unsigned int tok, unsigned int type, const char *message_, unsigned int _message_high)
7650 : : {
7651 : 16420 : unsigned int const_;
7652 : 16420 : char message[_message_high+1];
7653 : :
7654 : : /* make a local copy of each unbounded array. */
7655 : 16420 : memcpy (message, message_, _message_high+1);
7656 : :
7657 : 16420 : if (type == SymbolTable_NulSym)
7658 : : {
7659 : 220 : const_ = SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), SymbolTable_NulSym);
7660 : 220 : SymbolTable_PutConstLitInternal (const_, true);
7661 : 220 : M2Quads_PushTFtok (const_, static_cast<unsigned int> (SymbolTable_NulSym), tok);
7662 : : }
7663 : 16200 : else if (SymbolTable_IsEnumeration (type))
7664 : : {
7665 : : /* avoid dangling else. */
7666 : 238 : if ((SymbolTable_NoOfElements (type)) == 0)
7667 : : {
7668 : 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);
7669 : 0 : PushZero (tok, type);
7670 : : }
7671 : : else
7672 : : {
7673 : 238 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
7674 : 238 : M2Quads_PushT (type);
7675 : 238 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_ZType), M2Base_ZType, tok);
7676 : 238 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
7677 : 238 : BuildConvertFunction (M2Base_Convert, true); /* Two parameters */
7678 : : }
7679 : : }
7680 : : else
7681 : : {
7682 : : /* avoid dangling else. */
7683 : 15962 : const_ = SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), type);
7684 : 15962 : SymbolTable_PutConstLitInternal (const_, true);
7685 : 15962 : M2Quads_PushTFtok (const_, type, tok);
7686 : : }
7687 : 16420 : }
7688 : :
7689 : :
7690 : : /*
7691 : : PushZero - pushes the value zero to the stack.
7692 : : The Stack is changed:
7693 : :
7694 : :
7695 : : Entry Exit
7696 : : ===== ====
7697 : :
7698 : : <- Ptr
7699 : : +------------+
7700 : : Ptr -> | 0 | type |
7701 : : |------------|
7702 : : */
7703 : :
7704 : 7944 : static void PushZero (unsigned int tok, unsigned int type)
7705 : : {
7706 : 7944 : if (type == SymbolTable_NulSym)
7707 : : {
7708 : 424 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym), static_cast<unsigned int> (SymbolTable_NulSym), tok);
7709 : : }
7710 : 7520 : else if (SymbolTable_IsEnumeration (type))
7711 : : {
7712 : : /* avoid dangling else. */
7713 : 196 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
7714 : 196 : M2Quads_PushTtok (type, tok);
7715 : 196 : M2Quads_PushTtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType), tok);
7716 : 196 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
7717 : 196 : BuildConvertFunction (M2Base_Convert, true); /* Two parameters */
7718 : : }
7719 : : else
7720 : : {
7721 : : /* avoid dangling else. */
7722 : 7324 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), type), type, tok);
7723 : : }
7724 : 7944 : }
7725 : :
7726 : :
7727 : : /*
7728 : : ForLoopLastIterator - calculate the last iterator value but avoid setting
7729 : : LastIterator twice if it is a constant (in the quads).
7730 : : In the ForLoopLastIteratorVariable case only one
7731 : : path will be chosen but at the time of quadruple
7732 : : generation we do not know the value of BySym.
7733 : : */
7734 : :
7735 : 2604 : static void ForLoopLastIterator (unsigned int LastIterator, unsigned int e1, unsigned int e2, unsigned int BySym, unsigned int e1tok, unsigned int e2tok, unsigned int bytok)
7736 : : {
7737 : 2604 : if (! (SymbolTable_IsConst (BySym)))
7738 : : {
7739 : 18 : M2MetaError_MetaErrorT1 (bytok, (const char *) "{%E}the {%kFOR} loop {%kBY} expression must be constant, the expression {%1a} is variable", 89, BySym);
7740 : 18 : M2MetaError_MetaErrorDecl (BySym, true);
7741 : : }
7742 : : else
7743 : : {
7744 : 2586 : e1 = DereferenceLValue (e1tok, e1);
7745 : 2586 : e2 = DereferenceLValue (e2tok, e2);
7746 : 2586 : GenQuadOTypetok (bytok, M2Quads_LastForIteratorOp, LastIterator, SymbolTable_Make2Tuple (e1, e2), BySym, false, false, bytok, M2LexBuf_MakeVirtual2Tok (e1tok, e2tok), bytok);
7747 : : }
7748 : 2604 : }
7749 : :
7750 : :
7751 : : /*
7752 : : BuildSizeCheckEnd - checks to see whether the function "called" was in fact SIZE.
7753 : : If so then we restore quadruple generation.
7754 : : */
7755 : :
7756 : 16144 : static void BuildSizeCheckEnd (unsigned int ProcSym)
7757 : : {
7758 : 16144 : if (((ProcSym == M2Size_Size) || (ProcSym == M2System_TSize)) || (ProcSym == M2System_TBitSize))
7759 : : {
7760 : 13166 : QuadrupleGeneration = true;
7761 : 13166 : BuildingSize = false;
7762 : : }
7763 : 2978 : else if (ProcSym == M2Base_High)
7764 : : {
7765 : : /* avoid dangling else. */
7766 : 2978 : QuadrupleGeneration = true;
7767 : 2978 : BuildingHigh = false;
7768 : : }
7769 : 16144 : }
7770 : :
7771 : :
7772 : : /*
7773 : : BuildRealProcedureCall - builds a real procedure call.
7774 : : The Stack:
7775 : :
7776 : :
7777 : : Entry Exit
7778 : :
7779 : : Ptr ->
7780 : : +----------------+
7781 : : | NoOfParam |
7782 : : |----------------|
7783 : : | Param 1 |
7784 : : |----------------|
7785 : : | Param 2 |
7786 : : |----------------|
7787 : : . .
7788 : : . .
7789 : : . .
7790 : : |----------------|
7791 : : | Param # |
7792 : : |----------------|
7793 : : | ProcSym | Type | Empty
7794 : : |----------------|
7795 : : */
7796 : :
7797 : 157404 : static void BuildRealProcedureCall (unsigned int tokno)
7798 : : {
7799 : 157404 : unsigned int NoOfParam;
7800 : 157404 : unsigned int ProcSym;
7801 : :
7802 : 157404 : M2Quads_PopT (&NoOfParam);
7803 : 157404 : M2Quads_PushT (NoOfParam);
7804 : 157404 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+2));
7805 : 157404 : ProcSym = PCSymBuild_SkipConst (ProcSym);
7806 : : /* --checkme-- */
7807 : 157404 : if (SymbolTable_IsVar (ProcSym))
7808 : : {
7809 : : /* Procedure Variable ? */
7810 : 672 : ProcSym = SymbolTable_SkipType (M2Quads_OperandF (NoOfParam+2));
7811 : : }
7812 : 157404 : if ((SymbolTable_IsDefImp (SymbolTable_GetScope (ProcSym))) && (SymbolTable_IsDefinitionForC (SymbolTable_GetScope (ProcSym))))
7813 : : {
7814 : 14582 : BuildRealFuncProcCall (tokno, false, true, false);
7815 : : }
7816 : : else
7817 : : {
7818 : 142822 : BuildRealFuncProcCall (tokno, false, false, false);
7819 : : }
7820 : 157398 : }
7821 : :
7822 : :
7823 : : /*
7824 : : BuildRealFuncProcCall - builds a real procedure or function call.
7825 : : The Stack:
7826 : :
7827 : :
7828 : : Entry Exit
7829 : :
7830 : : Ptr ->
7831 : : +----------------+
7832 : : | NoOfParam |
7833 : : |----------------|
7834 : : | Param 1 |
7835 : : |----------------|
7836 : : | Param 2 |
7837 : : |----------------|
7838 : : . .
7839 : : . .
7840 : : . .
7841 : : |----------------|
7842 : : | Param # |
7843 : : |----------------|
7844 : : | ProcSym | Type | Empty
7845 : : |----------------|
7846 : : */
7847 : :
7848 : 219144 : static void BuildRealFuncProcCall (unsigned int tokno, bool IsFunc, bool IsForC, bool ConstExpr)
7849 : : {
7850 : 219144 : bool AllocateProc;
7851 : 219144 : bool DeallocateProc;
7852 : 219144 : bool ForcedFunc;
7853 : 219144 : bool ParamConstant;
7854 : 219144 : unsigned int trash;
7855 : 219144 : unsigned int resulttok;
7856 : 219144 : unsigned int paramtok;
7857 : 219144 : unsigned int proctok;
7858 : 219144 : unsigned int NoOfParameters;
7859 : 219144 : unsigned int i;
7860 : 219144 : unsigned int pi;
7861 : 219144 : unsigned int ParamType;
7862 : 219144 : unsigned int Param1;
7863 : 219144 : unsigned int ReturnVar;
7864 : 219144 : unsigned int ProcSym;
7865 : 219144 : unsigned int Proc;
7866 : :
7867 : 219144 : Param1 = SymbolTable_NulSym; /* Used to remember first param for allocate/deallocate. */
7868 : 219144 : ParamType = SymbolTable_NulSym;
7869 : 219144 : CheckProcedureParameters (IsForC);
7870 : 219126 : M2Quads_PopT (&NoOfParameters);
7871 : 219126 : M2Quads_PushT (NoOfParameters); /* Restore stack to original state. */
7872 : 219126 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+2)); /* Restore stack to original state. */
7873 : 219126 : proctok = tokno; /* OperandTtok (NoOfParameters+2) ; */
7874 : 219126 : if (proctok == M2LexBuf_UnknownTokenNo) /* OperandTtok (NoOfParameters+2) ; */
7875 : : {
7876 : 0 : proctok = M2LexBuf_GetTokenNo ();
7877 : : }
7878 : 219126 : paramtok = proctok;
7879 : 219126 : ProcSym = PCSymBuild_SkipConst (ProcSym);
7880 : 219126 : ForcedFunc = false;
7881 : 219126 : AllocateProc = false;
7882 : 219126 : DeallocateProc = false;
7883 : 219126 : if (SymbolTable_IsVar (ProcSym))
7884 : : {
7885 : : /* Procedure Variable ? */
7886 : 748 : Proc = SymbolTable_SkipType (M2Quads_OperandF (NoOfParameters+2));
7887 : 748 : ParamConstant = false;
7888 : : }
7889 : : else
7890 : : {
7891 : 218378 : Proc = ProcSym;
7892 : 218378 : ParamConstant = true;
7893 : 218378 : AllocateProc = (SymbolTable_GetSymName (Proc)) == (NameKey_MakeKey ((const char *) "ALLOCATE", 8));
7894 : 218378 : DeallocateProc = (SymbolTable_GetSymName (Proc)) == (NameKey_MakeKey ((const char *) "DEALLOCATE", 10));
7895 : : }
7896 : 219126 : if (IsFunc)
7897 : : {
7898 : : /* avoid dangling else. */
7899 : 61728 : if ((SymbolTable_GetSType (Proc)) == SymbolTable_NulSym)
7900 : : {
7901 : 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);
7902 : : }
7903 : : }
7904 : : else
7905 : : {
7906 : : /* is being called as a procedure */
7907 : 157398 : if ((SymbolTable_GetSType (Proc)) != SymbolTable_NulSym)
7908 : : {
7909 : : /* however it was declared as a procedure function */
7910 : 8617 : if (! (SymbolTable_IsReturnOptionalAny (Proc)))
7911 : : {
7912 : 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);
7913 : : }
7914 : : IsFunc = true;
7915 : : ForcedFunc = true;
7916 : : }
7917 : : }
7918 : 219126 : if (AllocateProc || DeallocateProc)
7919 : : {
7920 : 1814 : Param1 = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+1)); /* Remember this before manipulating. */
7921 : : }
7922 : 219126 : ManipulateParameters (IsForC);
7923 : 219126 : CheckParameterOrdinals ();
7924 : 219126 : M2Quads_PopT (&NoOfParameters);
7925 : 219126 : if (IsFunc)
7926 : : {
7927 : 70345 : GenQuad (M2Quads_ParamOp, 0, Proc, ProcSym); /* Space for return value */
7928 : : }
7929 : 219126 : if (((NoOfParameters+1) == (SymbolTable_NoOfParamAny (Proc))) && (SymbolTable_UsesOptArgAny (Proc)))
7930 : : {
7931 : 3622 : GenQuad (M2Quads_OptParamOp, SymbolTable_NoOfParamAny (Proc), Proc, Proc);
7932 : : }
7933 : 219126 : i = NoOfParameters;
7934 : 219126 : pi = 1; /* stack index referencing stacked parameter, i */
7935 : 762532 : while (i > 0) /* stack index referencing stacked parameter, i */
7936 : : {
7937 : 543406 : paramtok = OperandTtok (pi);
7938 : 543406 : if (((AllocateProc || DeallocateProc) && (i == 1)) && (Param1 != SymbolTable_NulSym))
7939 : : {
7940 : 1814 : ParamType = GetItemPointedTo (Param1);
7941 : 1814 : if (ParamType == SymbolTable_NulSym)
7942 : : {
7943 : 0 : GenQuadO (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true);
7944 : : }
7945 : : else
7946 : : {
7947 : 1814 : if (AllocateProc)
7948 : : {
7949 : 1274 : trash = SymbolTable_MakeTemporary (paramtok, SymbolTable_RightValue);
7950 : 1274 : SymbolTable_PutVar (trash, ParamType);
7951 : 1274 : SymbolTable_PutVarHeap (trash, true);
7952 : : }
7953 : : else
7954 : : {
7955 : 540 : M2Debug_Assert (DeallocateProc);
7956 : 540 : trash = M2Base_Nil;
7957 : : }
7958 : 1814 : GenQuadOTrash (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true, trash);
7959 : : }
7960 : : }
7961 : : else
7962 : : {
7963 : 541592 : GenQuadO (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true);
7964 : : }
7965 : 543406 : if (! (SymbolTable_IsConst (M2Quads_OperandT (pi))))
7966 : : {
7967 : 458475 : ParamConstant = false;
7968 : : }
7969 : 543406 : i -= 1;
7970 : 543406 : pi += 1;
7971 : : }
7972 : 438252 : GenQuadO (proctok, M2Quads_CallOp, SymbolTable_NulSym, SymbolTable_NulSym, ProcSym, true);
7973 : 219126 : M2Quads_PopN (NoOfParameters+1); /* Destroy arguments and procedure call */
7974 : 219126 : if (IsFunc)
7975 : : {
7976 : : /* ReturnVar has the type of the procedure. */
7977 : 70345 : resulttok = M2LexBuf_MakeVirtualTok (proctok, proctok, paramtok);
7978 : 70345 : if (ConstExpr && (! (SymbolTable_IsProcedureBuiltinAvailable (Proc))))
7979 : : {
7980 : 0 : M2MetaError_MetaError1 ((const char *) "{%1d} {%1ad} cannot be used in a constant expression", 52, Proc);
7981 : 0 : ParamConstant = false;
7982 : : }
7983 : 70345 : ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (ParamConstant && ConstExpr));
7984 : 70345 : SymbolTable_PutVar (ReturnVar, SymbolTable_GetSType (Proc));
7985 : 140690 : GenQuadO (resulttok, M2Quads_FunctValueOp, ReturnVar, SymbolTable_NulSym, Proc, true);
7986 : 70345 : if (! ForcedFunc)
7987 : : {
7988 : 61728 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (Proc), resulttok);
7989 : : }
7990 : : }
7991 : 219126 : }
7992 : :
7993 : :
7994 : : /*
7995 : : CheckProcedureParameters - Checks the parameters which are being passed to
7996 : : procedure ProcSym.
7997 : :
7998 : : The Stack:
7999 : :
8000 : :
8001 : : Entry Exit
8002 : :
8003 : : Ptr -> <- Ptr
8004 : : +----------------+ +----------------+
8005 : : | NoOfParam | | NoOfParam |
8006 : : |----------------| |----------------|
8007 : : | Param 1 | | Param 1 |
8008 : : |----------------| |----------------|
8009 : : | Param 2 | | Param 2 |
8010 : : |----------------| |----------------|
8011 : : . . . .
8012 : : . . . .
8013 : : . . . .
8014 : : |----------------| |----------------|
8015 : : | Param # | | Param # |
8016 : : |----------------| |----------------|
8017 : : | ProcSym | Type | | ProcSym | Type |
8018 : : |----------------| |----------------|
8019 : :
8020 : : */
8021 : :
8022 : 219144 : static void CheckProcedureParameters (bool IsForC)
8023 : : {
8024 : 219144 : unsigned int proctok;
8025 : 219144 : unsigned int paramtok;
8026 : 219144 : NameKey_Name n1;
8027 : 219144 : NameKey_Name n2;
8028 : 219144 : unsigned int ParamCheckId;
8029 : 219144 : unsigned int Dim;
8030 : 219144 : unsigned int Actual;
8031 : 219144 : unsigned int FormalI;
8032 : 219144 : unsigned int ParamTotal;
8033 : 219144 : unsigned int pi;
8034 : 219144 : unsigned int Proc;
8035 : 219144 : unsigned int ProcSym;
8036 : 219144 : unsigned int i;
8037 : 219144 : DynamicStrings_String s;
8038 : :
8039 : 219144 : M2Quads_PopT (&ParamTotal);
8040 : 219144 : M2Quads_PushT (ParamTotal); /* Restore stack to origional state */
8041 : 219144 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((ParamTotal+1)+1)); /* Restore stack to origional state */
8042 : 219144 : proctok = OperandTtok ((ParamTotal+1)+1);
8043 : 219144 : if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (SymbolTable_GetDType (ProcSym))))
8044 : : {
8045 : : /* Procedure Variable ? */
8046 : 748 : Proc = SymbolTable_SkipType (M2Quads_OperandF ((ParamTotal+1)+1));
8047 : : }
8048 : : else
8049 : : {
8050 : 218396 : Proc = PCSymBuild_SkipConst (ProcSym);
8051 : : }
8052 : 219144 : if (! ((SymbolTable_IsProcedure (Proc)) || (SymbolTable_IsProcType (Proc))))
8053 : : {
8054 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
8055 : 12 : if (SymbolTable_IsUnknown (Proc))
8056 : : {
8057 : : /* Spellcheck. */
8058 : 0 : M2MetaError_MetaError1 ((const char *) "{%1Ua} is not recognised as a procedure, check declaration or import {%1&s}", 75, Proc);
8059 : 0 : SymbolTable_UnknownReported (Proc);
8060 : : }
8061 : : else
8062 : : {
8063 : : /* --fixme-- filter on Var, Const, Procedure. */
8064 : 12 : M2MetaError_MetaErrors1 ((const char *) "{%1a} is not recognised as a procedure, check declaration or import {%1&s}", 74, (const char *) "{%1Ua} is not recognised as a procedure, check declaration or import", 68, Proc);
8065 : : }
8066 : : }
8067 : 219144 : if (M2Options_CompilerDebugging)
8068 : : {
8069 : 0 : n1 = SymbolTable_GetSymName (Proc);
8070 : 0 : M2Printf_printf1 ((const char *) " %a ( ", 7, (const unsigned char *) &n1, (sizeof (n1)-1));
8071 : : }
8072 : 219144 : if (DebugTokPos)
8073 : : {
8074 : : s = DynamicStrings_InitString ((const char *) "procedure", 9);
8075 : : M2Error_WarnStringAt (s, proctok);
8076 : : }
8077 : 219144 : i = 1;
8078 : 219144 : pi = ParamTotal+1; /* stack index referencing stacked parameter, i */
8079 : 759428 : while (i <= ParamTotal) /* stack index referencing stacked parameter, i */
8080 : : {
8081 : 540302 : if (i <= (SymbolTable_NoOfParamAny (Proc)))
8082 : : {
8083 : : /* FormalI := GetParam(Proc, i) ; */
8084 : 535132 : FormalI = SymbolTable_GetNthParamAnyClosest (Proc, i, SymbolTable_GetCurrentModule ());
8085 : 535132 : if (M2Options_CompilerDebugging)
8086 : : {
8087 : 0 : n1 = SymbolTable_GetSymName (FormalI);
8088 : 0 : n2 = SymbolTable_GetSymName (SymbolTable_GetSType (FormalI));
8089 : 0 : M2Printf_printf2 ((const char *) "%a: %a", 6, (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
8090 : : }
8091 : 535132 : Actual = static_cast<unsigned int> (M2Quads_OperandT (pi));
8092 : 535132 : Dim = static_cast<unsigned int> (OperandD (pi));
8093 : 535132 : paramtok = OperandTtok (pi);
8094 : 535132 : if (DebugTokPos)
8095 : : {
8096 : : s = DynamicStrings_InitString ((const char *) "actual", 6);
8097 : : M2Error_WarnStringAt (s, paramtok);
8098 : : }
8099 : 535132 : ParamCheckId = M2Range_InitTypesParameterCheck (paramtok, Proc, i, FormalI, Actual, 0);
8100 : 535132 : BuildRange (ParamCheckId);
8101 : : /* Store the ParamCheckId on the quad stack so that any dependant checks
8102 : : can be cancelled if the type check above detects an error. */
8103 : 535132 : PutRangeDep (pi, ParamCheckId);
8104 : 535132 : if (SymbolTable_IsConst (Actual))
8105 : : {
8106 : : /* avoid dangling else. */
8107 : 120295 : if (SymbolTable_IsVarParamAny (Proc, i))
8108 : : {
8109 : 0 : FailParameter (paramtok, (const char *) "trying to pass a constant to a VAR parameter", 44, Actual, Proc, i);
8110 : : }
8111 : 120295 : else if (SymbolTable_IsConstString (Actual))
8112 : : {
8113 : : /* avoid dangling else. */
8114 : 39404 : if (! (SymbolTable_IsConstStringKnown (Actual)))
8115 : : {} /* empty. */
8116 : 39170 : else if ((SymbolTable_IsArray (SymbolTable_GetDType (FormalI))) && ((SymbolTable_GetSType (SymbolTable_GetDType (FormalI))) == M2Base_Char))
8117 : : {
8118 : : /* avoid dangling else. */
8119 : : }
8120 : 39146 : else if ((SymbolTable_GetStringLength (paramtok, Actual)) == 1)
8121 : : {
8122 : : /* avoid dangling else. */
8123 : 5408 : CheckParameter (paramtok, Actual, Dim, FormalI, Proc, i, static_cast<Lists_List> (NULL), ParamCheckId);
8124 : : }
8125 : 33738 : else if (! (SymbolTable_IsUnboundedParamAny (Proc, i)))
8126 : : {
8127 : : /* avoid dangling else. */
8128 : 0 : if (IsForC && ((SymbolTable_GetSType (FormalI)) == M2System_Address))
8129 : : {
8130 : 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);
8131 : : }
8132 : : else
8133 : : {
8134 : 0 : FailParameter (paramtok, (const char *) "cannot pass a string constant to a non unbounded array parameter", 64, Actual, Proc, i);
8135 : : }
8136 : : }
8137 : : }
8138 : : }
8139 : : else
8140 : : {
8141 : 414837 : CheckParameter (paramtok, Actual, Dim, FormalI, Proc, i, static_cast<Lists_List> (NULL), ParamCheckId);
8142 : : }
8143 : : }
8144 : : else
8145 : : {
8146 : 5158 : if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
8147 : : {
8148 : : /* these are varargs, therefore we don't check them */
8149 : 5158 : i = ParamTotal;
8150 : : }
8151 : : else
8152 : : {
8153 : 0 : M2MetaError_MetaErrorT2 (proctok, (const char *) "too many parameters, {%2n} passed to {%1a} ", 43, Proc, i);
8154 : : }
8155 : : }
8156 : 540284 : i += 1;
8157 : 540284 : pi -= 1;
8158 : 540284 : if (M2Options_CompilerDebugging)
8159 : : {
8160 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
8161 : 0 : if (i <= ParamTotal)
8162 : : {
8163 : 0 : M2Printf_printf0 ((const char *) "; ", 2);
8164 : : }
8165 : : else
8166 : : {
8167 : 0 : M2Printf_printf0 ((const char *) " ) ; \\n", 7);
8168 : : }
8169 : : }
8170 : : }
8171 : 219126 : }
8172 : :
8173 : :
8174 : : /*
8175 : : CheckProcTypeAndProcedure - checks the ProcType with the call.
8176 : : */
8177 : :
8178 : 48753 : static void CheckProcTypeAndProcedure (unsigned int tokno, unsigned int ProcType, unsigned int call, unsigned int ParamCheckId)
8179 : : {
8180 : 48753 : NameKey_Name n1;
8181 : 48753 : NameKey_Name n2;
8182 : 48753 : unsigned int i;
8183 : 48753 : unsigned int n;
8184 : 48753 : unsigned int t;
8185 : 48753 : unsigned int CheckedProcedure;
8186 : 48753 : M2Error_Error e;
8187 : :
8188 : 48753 : if (((SymbolTable_IsVar (call)) || (SymbolTable_IsTemporary (call))) || (SymbolTable_IsParameter (call)))
8189 : : {
8190 : 580 : CheckedProcedure = SymbolTable_GetDType (call);
8191 : : }
8192 : : else
8193 : : {
8194 : : CheckedProcedure = call;
8195 : : }
8196 : 48753 : if (ProcType != CheckedProcedure)
8197 : : {
8198 : 48243 : n = SymbolTable_NoOfParamAny (ProcType);
8199 : : /* We need to check the formal parameters between the procedure and proc type. */
8200 : 48243 : if (n != (SymbolTable_NoOfParamAny (CheckedProcedure)))
8201 : : {
8202 : 0 : e = M2Error_NewError (SymbolTable_GetDeclaredMod (ProcType));
8203 : 0 : n1 = SymbolTable_GetSymName (call);
8204 : 0 : n2 = SymbolTable_GetSymName (ProcType);
8205 : 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));
8206 : 0 : e = M2Error_ChainError (SymbolTable_GetDeclaredMod (call), e);
8207 : 0 : t = SymbolTable_NoOfParamAny (CheckedProcedure);
8208 : 0 : if (n < 2)
8209 : : {
8210 : 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));
8211 : : }
8212 : : else
8213 : : {
8214 : 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));
8215 : : }
8216 : : }
8217 : : else
8218 : : {
8219 : : i = 1;
8220 : 143763 : while (i <= n)
8221 : : {
8222 : 95520 : if ((SymbolTable_IsVarParamAny (ProcType, i)) != (SymbolTable_IsVarParamAny (CheckedProcedure, i)))
8223 : : {
8224 : 0 : M2MetaError_MetaError3 ((const char *) "parameter {%3n} in {%1dD} causes a mismatch it was declared as a {%2dv}", 71, ProcType, SymbolTable_GetNth (ProcType, i), i);
8225 : 0 : M2MetaError_MetaError3 ((const char *) "parameter {%3n} in {%1dD} causes a mismatch it was declared as a {%2dv}", 71, call, SymbolTable_GetNth (call, i), i);
8226 : : }
8227 : 95520 : BuildRange (M2Range_InitTypesParameterCheck (tokno, CheckedProcedure, i, SymbolTable_GetNthParamAnyClosest (CheckedProcedure, i, SymbolTable_GetCurrentModule ()), SymbolTable_GetParam (ProcType, i), ParamCheckId));
8228 : 95520 : i += 1;
8229 : : }
8230 : : }
8231 : : }
8232 : 48753 : }
8233 : :
8234 : :
8235 : : /*
8236 : : IsReallyPointer - returns TRUE is sym is a pointer, address or a type declared
8237 : : as a pointer or address.
8238 : : */
8239 : :
8240 : 1260 : static bool IsReallyPointer (unsigned int Sym)
8241 : : {
8242 : 1260 : if (SymbolTable_IsVar (Sym))
8243 : : {
8244 : 1260 : Sym = SymbolTable_GetSType (Sym);
8245 : : }
8246 : 1260 : Sym = SymbolTable_SkipType (Sym);
8247 : 1260 : return (SymbolTable_IsPointer (Sym)) || (Sym == M2System_Address);
8248 : : /* static analysis guarentees a RETURN statement will be used before here. */
8249 : : __builtin_unreachable ();
8250 : : }
8251 : :
8252 : :
8253 : : /*
8254 : : LegalUnboundedParam - returns TRUE if the parameter, Actual, can legitimately be
8255 : : passed to ProcSym, i, the, Formal, parameter.
8256 : : */
8257 : :
8258 : 9930 : static bool LegalUnboundedParam (unsigned int tokpos, unsigned int ProcSym, unsigned int i, unsigned int ActualType, unsigned int Actual, unsigned int Dimension, unsigned int Formal)
8259 : : {
8260 : 9930 : unsigned int FormalType;
8261 : 9930 : unsigned int n;
8262 : 9930 : unsigned int m;
8263 : :
8264 : 9930 : ActualType = SymbolTable_SkipType (ActualType);
8265 : 9930 : FormalType = SymbolTable_GetDType (Formal);
8266 : 9930 : FormalType = SymbolTable_GetSType (FormalType); /* type of the unbounded ARRAY */
8267 : 9930 : if (SymbolTable_IsArray (ActualType)) /* type of the unbounded ARRAY */
8268 : : {
8269 : 6900 : m = SymbolTable_GetDimension (Formal);
8270 : 6900 : n = 0;
8271 : 14046 : while (SymbolTable_IsArray (ActualType))
8272 : : {
8273 : 7068 : n += 1;
8274 : 7068 : ActualType = SymbolTable_GetDType (ActualType);
8275 : 7068 : if ((m == n) && (ActualType == FormalType))
8276 : : {
8277 : : return true;
8278 : : }
8279 : : }
8280 : 78 : if (n == m)
8281 : : {} /* empty. */
8282 : : else
8283 : : {
8284 : : /* now we fall though and test ActualType against FormalType */
8285 : 24 : if (M2System_IsGenericSystemType (FormalType))
8286 : : {
8287 : : return true;
8288 : : }
8289 : : else
8290 : : {
8291 : 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);
8292 : 12 : return false;
8293 : : }
8294 : : }
8295 : : }
8296 : 3030 : else if (SymbolTable_IsUnbounded (ActualType))
8297 : : {
8298 : : /* avoid dangling else. */
8299 : 36 : if ((Dimension == 0) && ((SymbolTable_GetDimension (Formal)) == (SymbolTable_GetDimension (Actual))))
8300 : : {
8301 : : /* now we fall though and test ActualType against FormalType */
8302 : 0 : ActualType = SymbolTable_GetSType (ActualType);
8303 : : }
8304 : : else
8305 : : {
8306 : 36 : if (M2System_IsGenericSystemType (FormalType))
8307 : : {
8308 : : return true;
8309 : : }
8310 : : else
8311 : : {
8312 : 12 : if (((SymbolTable_GetDimension (Actual))-Dimension) == (SymbolTable_GetDimension (Formal)))
8313 : : {
8314 : 12 : ActualType = SymbolTable_GetSType (ActualType);
8315 : : }
8316 : : else
8317 : : {
8318 : 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);
8319 : 0 : return false;
8320 : : }
8321 : : }
8322 : : }
8323 : : }
8324 : 3060 : if (((M2System_IsGenericSystemType (FormalType)) || (M2System_IsGenericSystemType (ActualType))) || (M2Base_IsAssignmentCompatible (FormalType, ActualType)))
8325 : : {
8326 : : /* we think it is legal, but we ask post pass 3 to check as
8327 : : not all types are known at this point */
8328 : 3054 : return true;
8329 : : }
8330 : : else
8331 : : {
8332 : 6 : FailParameter (tokpos, (const char *) "identifier with an incompatible type is being passed to this procedure", 70, Actual, ProcSym, i);
8333 : 6 : return false;
8334 : : }
8335 : : /* static analysis guarentees a RETURN statement will be used before here. */
8336 : : __builtin_unreachable ();
8337 : : }
8338 : :
8339 : :
8340 : : /*
8341 : : CheckParameter - checks that types ActualType and FormalType are compatible for parameter
8342 : : passing. ProcSym is the procedure and i is the parameter number.
8343 : :
8344 : : We obey the following rules:
8345 : :
8346 : : (1) we allow WORD, BYTE, LOC to be compitable with any like sized
8347 : : type.
8348 : : (2) we allow ADDRESS to be compatible with any pointer type.
8349 : : (3) we relax INTEGER and CARDINAL checking for Temporary variables.
8350 : :
8351 : : Note that type sizes are checked during the code generation pass.
8352 : : */
8353 : :
8354 : 420245 : static void CheckParameter (unsigned int tokpos, unsigned int Actual, unsigned int Dimension, unsigned int Formal, unsigned int ProcSym, unsigned int i, Lists_List TypeList, unsigned int ParamCheckId)
8355 : : {
8356 : 420245 : bool NewList;
8357 : 420245 : unsigned int ActualType;
8358 : 420245 : unsigned int FormalType;
8359 : :
8360 : 420245 : if ((SymbolTable_IsConstString (Actual)) && (! (SymbolTable_IsConstStringKnown (Actual))))
8361 : : {
8362 : : /* Cannot check if the string content is not yet known. */
8363 : : return;
8364 : : }
8365 : 420245 : FormalType = SymbolTable_GetDType (Formal);
8366 : 420245 : if ((SymbolTable_IsConstString (Actual)) && ((SymbolTable_GetStringLength (tokpos, Actual)) == 1)) /* if = 1 then it maybe treated as a char */
8367 : : {
8368 : 5408 : ActualType = M2Base_Char;
8369 : : }
8370 : 414837 : else if (Actual == M2Base_Boolean)
8371 : : {
8372 : : /* avoid dangling else. */
8373 : : ActualType = Actual;
8374 : : }
8375 : : else
8376 : : {
8377 : : /* avoid dangling else. */
8378 : 414837 : ActualType = SymbolTable_GetDType (Actual);
8379 : : }
8380 : 420239 : if (TypeList == NULL)
8381 : : {
8382 : 420239 : NewList = true;
8383 : 420239 : Lists_InitList (&TypeList);
8384 : : }
8385 : : else
8386 : : {
8387 : : NewList = false;
8388 : : }
8389 : 420239 : if (Lists_IsItemInList (TypeList, ActualType))
8390 : : {
8391 : : /* no need to check */
8392 : : return;
8393 : : }
8394 : 420239 : Lists_IncludeItemIntoList (TypeList, ActualType);
8395 : 420239 : if (SymbolTable_IsProcType (FormalType))
8396 : : {
8397 : 48753 : if ((! (SymbolTable_IsProcedure (Actual))) && ((ActualType == SymbolTable_NulSym) || (! (SymbolTable_IsProcType (SymbolTable_SkipType (ActualType))))))
8398 : : {
8399 : 0 : FailParameter (tokpos, (const char *) "expecting a procedure or procedure variable as a parameter", 58, Actual, ProcSym, i);
8400 : 0 : return;
8401 : : }
8402 : 48753 : if ((SymbolTable_IsProcedure (Actual)) && (SymbolTable_IsProcedureNested (Actual)))
8403 : : {
8404 : 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);
8405 : : }
8406 : : /* we can check the return type of both proc types */
8407 : 48753 : if ((ActualType != SymbolTable_NulSym) && (SymbolTable_IsProcType (ActualType)))
8408 : : {
8409 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
8410 : 580 : if (((SymbolTable_GetSType (ActualType)) != SymbolTable_NulSym) && ((SymbolTable_GetSType (FormalType)) == SymbolTable_NulSym))
8411 : : {
8412 : 0 : FailParameter (tokpos, (const char *) "the item being passed is a function whereas the formal procedure parameter is a procedure", 89, Actual, ProcSym, i);
8413 : 0 : return;
8414 : : }
8415 : 580 : else if (((SymbolTable_GetSType (ActualType)) == SymbolTable_NulSym) && ((SymbolTable_GetSType (FormalType)) != SymbolTable_NulSym))
8416 : : {
8417 : : /* avoid dangling else. */
8418 : 0 : FailParameter (tokpos, (const char *) "the item being passed is a procedure whereas the formal procedure parameter is a function", 89, Actual, ProcSym, i);
8419 : 0 : return;
8420 : : }
8421 : 580 : else if (M2Base_AssignmentRequiresWarning (SymbolTable_GetSType (ActualType), SymbolTable_GetSType (FormalType)))
8422 : : {
8423 : : /* avoid dangling else. */
8424 : 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);
8425 : 0 : return;
8426 : : }
8427 : 580 : else if (((M2System_IsGenericSystemType (SymbolTable_GetSType (FormalType))) || (M2System_IsGenericSystemType (SymbolTable_GetSType (ActualType)))) || (M2Base_IsAssignmentCompatible (SymbolTable_GetSType (ActualType), SymbolTable_GetSType (FormalType))))
8428 : : {
8429 : : /* avoid dangling else. */
8430 : : }
8431 : : else
8432 : : {
8433 : : /* avoid dangling else. */
8434 : : /* pass */
8435 : 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);
8436 : 0 : return;
8437 : : }
8438 : : }
8439 : : /* now to check each parameter of the proc type */
8440 : 48753 : CheckProcTypeAndProcedure (tokpos, FormalType, Actual, ParamCheckId);
8441 : : }
8442 : 371486 : else if ((ActualType != FormalType) && (ActualType != SymbolTable_NulSym))
8443 : : {
8444 : : /* avoid dangling else. */
8445 : 17876 : if (SymbolTable_IsUnknown (FormalType))
8446 : : {
8447 : : /* Spellcheck. */
8448 : 0 : FailParameter (tokpos, (const char *) "procedure parameter type is undeclared {%1&s}", 45, Actual, ProcSym, i);
8449 : 0 : return;
8450 : : }
8451 : 17876 : if ((SymbolTable_IsUnbounded (ActualType)) && (! (SymbolTable_IsUnboundedParamAny (ProcSym, i))))
8452 : : {
8453 : 0 : FailParameter (tokpos, (const char *) "attempting to pass an unbounded array to a NON unbounded parameter", 66, Actual, ProcSym, i);
8454 : 0 : return;
8455 : : }
8456 : 17876 : else if (SymbolTable_IsUnboundedParamAny (ProcSym, i))
8457 : : {
8458 : : /* avoid dangling else. */
8459 : 9930 : if (! (LegalUnboundedParam (tokpos, ProcSym, i, ActualType, Actual, Dimension, Formal)))
8460 : : {
8461 : : return;
8462 : : }
8463 : : }
8464 : 7946 : else if (ActualType != FormalType)
8465 : : {
8466 : : /* avoid dangling else. */
8467 : 7946 : if (M2Base_AssignmentRequiresWarning (FormalType, ActualType))
8468 : : {
8469 : 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);
8470 : : }
8471 : 7946 : else if (((M2System_IsGenericSystemType (FormalType)) || (M2System_IsGenericSystemType (ActualType))) || (M2Base_IsAssignmentCompatible (ActualType, FormalType)))
8472 : : {
8473 : : /* avoid dangling else. */
8474 : : }
8475 : : else
8476 : : {
8477 : : /* avoid dangling else. */
8478 : : /* so far we know it is legal, but not all types have been resolved
8479 : : and so this is checked later on in another pass. */
8480 : 24 : FailParameter (tokpos, (const char *) "identifier with an incompatible type is being passed to this procedure", 70, Actual, ProcSym, i);
8481 : : }
8482 : : }
8483 : : }
8484 : 420221 : if (NewList)
8485 : : {
8486 : 420221 : Lists_KillList (&TypeList);
8487 : : }
8488 : : }
8489 : :
8490 : :
8491 : : /*
8492 : : DescribeType - returns a String describing a symbol, Sym, name and its type.
8493 : : */
8494 : :
8495 : 0 : static DynamicStrings_String DescribeType (unsigned int Sym)
8496 : : {
8497 : 0 : DynamicStrings_String s;
8498 : 0 : DynamicStrings_String s1;
8499 : 0 : DynamicStrings_String s2;
8500 : 0 : unsigned int Low;
8501 : 0 : unsigned int High;
8502 : 0 : unsigned int Subrange;
8503 : 0 : unsigned int Subscript;
8504 : 0 : unsigned int Type;
8505 : :
8506 : 0 : s = static_cast<DynamicStrings_String> (NULL);
8507 : 0 : if (SymbolTable_IsConstString (Sym))
8508 : : {
8509 : : /* If = 1 then it maybe treated as a char. */
8510 : 0 : if ((SymbolTable_IsConstStringKnown (Sym)) && ((SymbolTable_GetStringLength (SymbolTable_GetDeclaredMod (Sym), Sym)) == 1))
8511 : : {
8512 : 0 : s = DynamicStrings_InitString ((const char *) "(constant string) or {%kCHAR}", 29);
8513 : : }
8514 : : else
8515 : : {
8516 : 0 : s = DynamicStrings_InitString ((const char *) "(constant string)", 17);
8517 : : }
8518 : : }
8519 : 0 : else if (SymbolTable_IsConst (Sym))
8520 : : {
8521 : : /* avoid dangling else. */
8522 : 0 : s = DynamicStrings_InitString ((const char *) "(constant)", 10);
8523 : : }
8524 : 0 : else if (SymbolTable_IsUnknown (Sym))
8525 : : {
8526 : : /* avoid dangling else. */
8527 : 0 : s = DynamicStrings_InitString ((const char *) "(unknown)", 9);
8528 : : }
8529 : : else
8530 : : {
8531 : : /* avoid dangling else. */
8532 : 0 : Type = SymbolTable_GetSType (Sym);
8533 : 0 : if (Type == SymbolTable_NulSym)
8534 : : {
8535 : 0 : s = DynamicStrings_InitString ((const char *) "(unknown)", 9);
8536 : : }
8537 : 0 : else if (SymbolTable_IsUnbounded (Type))
8538 : : {
8539 : : /* avoid dangling else. */
8540 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (SymbolTable_GetSType (Type)))));
8541 : 0 : s = FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "{%%kARRAY} {%%kOF} %s", 21)), (const unsigned char *) &s1, (sizeof (s1)-1));
8542 : : }
8543 : 0 : else if (SymbolTable_IsArray (Type))
8544 : : {
8545 : : /* avoid dangling else. */
8546 : 0 : s = DynamicStrings_InitString ((const char *) "{%kARRAY} [", 11);
8547 : 0 : Subscript = SymbolTable_GetArraySubscript (Type);
8548 : 0 : if (Subscript != SymbolTable_NulSym)
8549 : : {
8550 : 0 : M2Debug_Assert (SymbolTable_IsSubscript (Subscript));
8551 : 0 : Subrange = SymbolTable_GetSType (Subscript);
8552 : 0 : if (! (SymbolTable_IsSubrange (Subrange)))
8553 : : {
8554 : 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);
8555 : : }
8556 : 0 : M2Debug_Assert (SymbolTable_IsSubrange (Subrange));
8557 : 0 : SymbolTable_GetSubrange (Subrange, &High, &Low);
8558 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Low))));
8559 : 0 : s2 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (High))));
8560 : 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))));
8561 : : }
8562 : 0 : s1 = DynamicStrings_Mark (DescribeType (Type));
8563 : 0 : s = DynamicStrings_ConCat (DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "] OF ", 5))), s1);
8564 : : }
8565 : : else
8566 : : {
8567 : : /* avoid dangling else. */
8568 : 0 : if (SymbolTable_IsUnknown (Type))
8569 : : {
8570 : : /* Spellcheck. */
8571 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Type))));
8572 : 0 : s = FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "%s (currently unknown, check declaration or import) {%1&s}", 58)), (const unsigned char *) &s1, (sizeof (s1)-1));
8573 : : }
8574 : : else
8575 : : {
8576 : 0 : s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Type)));
8577 : : }
8578 : : }
8579 : : }
8580 : 0 : return s;
8581 : : /* static analysis guarentees a RETURN statement will be used before here. */
8582 : : __builtin_unreachable ();
8583 : : }
8584 : :
8585 : :
8586 : : /*
8587 : : FailParameter - generates an error message indicating that a parameter
8588 : : declaration has failed.
8589 : :
8590 : : The parameters are:
8591 : :
8592 : : CurrentState - string describing the current failing state.
8593 : : Actual - actual parameter.
8594 : : ParameterNo - parameter number that has failed.
8595 : : ProcedureSym - procedure symbol where parameter has failed.
8596 : :
8597 : : If any parameter is Nul then it is ignored.
8598 : : */
8599 : :
8600 : 42 : static void FailParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo)
8601 : : {
8602 : 42 : unsigned int FormalParam;
8603 : 42 : DynamicStrings_String Msg;
8604 : 42 : char CurrentState[_CurrentState_high+1];
8605 : :
8606 : : /* make a local copy of each unbounded array. */
8607 : 42 : memcpy (CurrentState, CurrentState_, _CurrentState_high+1);
8608 : :
8609 : 84 : Msg = DynamicStrings_InitString ((const char *) "parameter mismatch between the {%2N} parameter of procedure {%1Ead}, ", 69);
8610 : 42 : Msg = DynamicStrings_ConCat (Msg, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) CurrentState, _CurrentState_high)));
8611 : 42 : M2MetaError_MetaErrorStringT2 (tokpos, Msg, ProcedureSym, ParameterNo);
8612 : 42 : if ((SymbolTable_NoOfParamAny (ProcedureSym)) >= ParameterNo)
8613 : : {
8614 : 42 : FormalParam = SymbolTable_GetNthParamAnyClosest (ProcedureSym, ParameterNo, SymbolTable_GetCurrentModule ());
8615 : 42 : if (SymbolTable_IsUnboundedParamAny (ProcedureSym, ParameterNo))
8616 : : {
8617 : 18 : M2MetaError_MetaErrorT2 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "formal parameter {%1ad} has an open array type {%2tad}", 54, FormalParam, SymbolTable_GetSType (SymbolTable_GetSType (FormalParam)));
8618 : : }
8619 : : else
8620 : : {
8621 : 24 : M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "formal parameter {%1ad} has type {%1tad}", 40, FormalParam);
8622 : : }
8623 : : }
8624 : : else
8625 : : {
8626 : 0 : M2MetaError_MetaErrorT1 (SymbolTable_GetDeclaredMod (ProcedureSym), (const char *) "procedure declaration", 21, ProcedureSym);
8627 : : }
8628 : 42 : if ((SymbolTable_GetLType (Actual)) == SymbolTable_NulSym)
8629 : : {
8630 : 0 : M2MetaError_MetaError1 ((const char *) "actual parameter being passed is {%1Eda} {%1ad}", 47, Actual);
8631 : : }
8632 : : else
8633 : : {
8634 : 42 : if (SymbolTable_IsVar (Actual))
8635 : : {
8636 : 36 : M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (Actual), (const char *) "actual parameter variable being passed is {%1Eda} {%1ad} of an incompatible type {%1ts}", 87, Actual);
8637 : : }
8638 : : else
8639 : : {
8640 : 6 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "actual parameter being passed is {%1Eda} {%1ad} of an incompatible type {%1ts}", 78, Actual);
8641 : : }
8642 : : }
8643 : 42 : }
8644 : :
8645 : :
8646 : : /*
8647 : : WarnParameter - generates a warning message indicating that a parameter
8648 : : use might cause problems on another target.
8649 : :
8650 : : CurrentState - string describing the current failing state.
8651 : : Actual - actual parameter.
8652 : : ParameterNo - parameter number that has failed.
8653 : : ProcedureSym - procedure symbol where parameter has failed.
8654 : :
8655 : : If any parameter is Nul then it is ignored.
8656 : : */
8657 : :
8658 : 0 : static void WarnParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo)
8659 : : {
8660 : 0 : unsigned int FormalParam;
8661 : 0 : DynamicStrings_String Msg;
8662 : 0 : char CurrentState[_CurrentState_high+1];
8663 : :
8664 : : /* make a local copy of each unbounded array. */
8665 : 0 : memcpy (CurrentState, CurrentState_, _CurrentState_high+1);
8666 : :
8667 : 0 : Msg = DynamicStrings_InitString ((const char *) "{%W}parameter mismatch between the {%2N} parameter of procedure {%1ad}, ", 72);
8668 : 0 : Msg = DynamicStrings_ConCat (Msg, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) CurrentState, _CurrentState_high)));
8669 : 0 : M2MetaError_MetaErrorStringT2 (tokpos, Msg, ProcedureSym, ParameterNo);
8670 : 0 : if ((SymbolTable_NoOfParamAny (ProcedureSym)) >= ParameterNo)
8671 : : {
8672 : 0 : FormalParam = SymbolTable_GetNthParamAnyClosest (ProcedureSym, ParameterNo, SymbolTable_GetCurrentModule ());
8673 : 0 : if (SymbolTable_IsUnboundedParamAny (ProcedureSym, ParameterNo))
8674 : : {
8675 : 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)));
8676 : : }
8677 : : else
8678 : : {
8679 : 0 : M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "{%W}formal parameter {%1ad} has type {%1tad}", 44, FormalParam);
8680 : : }
8681 : : }
8682 : : else
8683 : : {
8684 : 0 : M2MetaError_MetaErrorT1 (SymbolTable_GetDeclaredMod (ProcedureSym), (const char *) "{%W}procedure declaration", 25, ProcedureSym);
8685 : : }
8686 : 0 : if ((SymbolTable_GetLType (Actual)) == SymbolTable_NulSym)
8687 : : {
8688 : 0 : M2MetaError_MetaError1 ((const char *) "actual parameter being passed is {%1Wda} {%1ad}", 47, Actual);
8689 : : }
8690 : : else
8691 : : {
8692 : 0 : if (SymbolTable_IsVar (Actual))
8693 : : {
8694 : 0 : M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (Actual), (const char *) "actual parameter variable being passed is {%1Wda} {%1ad} of type {%1ts}", 71, Actual);
8695 : : }
8696 : : else
8697 : : {
8698 : 0 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "actual parameter being passed is {%1Wda} {%1ad} of type {%1ts}", 62, Actual);
8699 : : }
8700 : : }
8701 : 0 : }
8702 : :
8703 : :
8704 : : /*
8705 : : doIndrX - perform des = *exp with a conversion if necessary.
8706 : : */
8707 : :
8708 : 16995 : static void doIndrX (unsigned int tok, unsigned int des, unsigned int exp)
8709 : : {
8710 : 16995 : unsigned int t;
8711 : :
8712 : 16995 : if ((SymbolTable_GetDType (des)) == (SymbolTable_GetDType (exp)))
8713 : : {
8714 : 16477 : GenQuadOtok (tok, M2Quads_IndrXOp, des, SymbolTable_GetSType (des), exp, true, tok, tok, tok);
8715 : : }
8716 : : else
8717 : : {
8718 : 518 : if (M2Options_StrictTypeAssignment)
8719 : : {
8720 : 518 : BuildRange (M2Range_InitTypesIndrXCheck (tok, des, exp));
8721 : : }
8722 : 518 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
8723 : 518 : SymbolTable_PutVar (t, SymbolTable_GetSType (exp));
8724 : 518 : GenQuadOtok (tok, M2Quads_IndrXOp, t, SymbolTable_GetSType (exp), exp, true, tok, tok, tok);
8725 : 518 : GenQuadOtok (tok, M2Quads_BecomesOp, des, SymbolTable_NulSym, doVal (SymbolTable_GetSType (des), t), true, tok, M2LexBuf_UnknownTokenNo, tok);
8726 : : }
8727 : 16995 : }
8728 : :
8729 : :
8730 : : /*
8731 : : MakeRightValue - returns a temporary which will have the RightValue of symbol, Sym.
8732 : : If Sym is a right value and has type, type, then no quadruples are
8733 : : generated and Sym is returned. Otherwise a new temporary is created
8734 : : and an IndrX quadruple is generated.
8735 : : */
8736 : :
8737 : 1520 : static unsigned int MakeRightValue (unsigned int tok, unsigned int Sym, unsigned int type)
8738 : : {
8739 : 1520 : unsigned int t;
8740 : :
8741 : 1520 : if ((SymbolTable_GetMode (Sym)) == SymbolTable_RightValue)
8742 : : {
8743 : 0 : if ((SymbolTable_GetSType (Sym)) == type)
8744 : : {
8745 : : return Sym;
8746 : : }
8747 : : else
8748 : : {
8749 : : /*
8750 : : type change or mode change, type changes are a pain, but I've
8751 : : left them here as it is perhaps easier to remove them later.
8752 : : */
8753 : 0 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
8754 : 0 : SymbolTable_PutVar (t, type);
8755 : 0 : GenQuadOtok (tok, M2Quads_BecomesOp, t, SymbolTable_NulSym, doVal (type, Sym), true, tok, tok, tok);
8756 : 0 : return t;
8757 : : }
8758 : : }
8759 : : else
8760 : : {
8761 : 1520 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
8762 : 1520 : SymbolTable_PutVar (t, type);
8763 : 1520 : CheckPointerThroughNil (tok, Sym);
8764 : 1520 : doIndrX (tok, t, Sym);
8765 : 1520 : return t;
8766 : : }
8767 : : /* static analysis guarentees a RETURN statement will be used before here. */
8768 : : __builtin_unreachable ();
8769 : : }
8770 : :
8771 : :
8772 : : /*
8773 : : MakeLeftValue - returns a temporary coresponding to the LeftValue of
8774 : : symbol, Sym. No quadruple is generated if Sym is already
8775 : : a LeftValue and has the same type.
8776 : : */
8777 : :
8778 : 196543 : static unsigned int MakeLeftValue (unsigned int tok, unsigned int Sym, SymbolTable_ModeOfAddr with, unsigned int type)
8779 : : {
8780 : 196543 : unsigned int t;
8781 : :
8782 : 196543 : if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
8783 : : {
8784 : 5138 : if ((SymbolTable_GetSType (Sym)) == type)
8785 : : {
8786 : : return Sym;
8787 : : }
8788 : : else
8789 : : {
8790 : : /*
8791 : : type change or mode change, type changes are a pain, but I've
8792 : : left them here as it is perhaps easier to remove them later
8793 : : */
8794 : 168 : t = SymbolTable_MakeTemporary (tok, with);
8795 : 168 : SymbolTable_PutVar (t, type);
8796 : 168 : GenQuadOtok (tok, M2Quads_BecomesOp, t, SymbolTable_NulSym, Sym, true, tok, M2LexBuf_UnknownTokenNo, tok);
8797 : 168 : return t;
8798 : : }
8799 : : }
8800 : : else
8801 : : {
8802 : 191405 : t = SymbolTable_MakeTemporary (tok, with);
8803 : 191405 : SymbolTable_PutVar (t, type);
8804 : 191405 : GenQuadOtok (tok, M2Quads_AddrOp, t, SymbolTable_NulSym, Sym, true, tok, M2LexBuf_UnknownTokenNo, tok);
8805 : 191405 : return t;
8806 : : }
8807 : : /* static analysis guarentees a RETURN statement will be used before here. */
8808 : : __builtin_unreachable ();
8809 : : }
8810 : :
8811 : :
8812 : : /*
8813 : : ManipulatePseudoCallParameters - manipulates the parameters to a pseudo function or
8814 : : procedure. It dereferences all LeftValue parameters
8815 : : and Boolean parameters.
8816 : : The Stack:
8817 : :
8818 : :
8819 : : Entry Exit
8820 : :
8821 : : Ptr -> exactly the same
8822 : : +----------------+
8823 : : | NoOfParameters |
8824 : : |----------------|
8825 : : | Param 1 |
8826 : : |----------------|
8827 : : | Param 2 |
8828 : : |----------------|
8829 : : . .
8830 : : . .
8831 : : . .
8832 : : |----------------|
8833 : : | Param # |
8834 : : |----------------|
8835 : : | ProcSym | Type |
8836 : : |----------------|
8837 : :
8838 : : */
8839 : :
8840 : 66544 : static void ManipulatePseudoCallParameters (void)
8841 : : {
8842 : 66544 : unsigned int NoOfParameters;
8843 : 66544 : unsigned int ProcSym;
8844 : 66544 : unsigned int Proc;
8845 : 66544 : unsigned int i;
8846 : 66544 : unsigned int pi;
8847 : 66544 : M2Quads_BoolFrame f;
8848 : :
8849 : 66544 : M2Quads_PopT (&NoOfParameters);
8850 : 66544 : M2Quads_PushT (NoOfParameters); /* restored to original state */
8851 : : /* Ptr points to the ProcSym */
8852 : 66544 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((NoOfParameters+1)+1));
8853 : 66544 : if (SymbolTable_IsVar (ProcSym))
8854 : : {
8855 : 0 : M2Error_InternalError ((const char *) "expecting a pseudo procedure or a type", 38);
8856 : : }
8857 : : else
8858 : : {
8859 : 66544 : Proc = ProcSym;
8860 : : }
8861 : 66544 : i = 1;
8862 : 66544 : pi = NoOfParameters+1;
8863 : 145818 : while (i <= NoOfParameters)
8864 : : {
8865 : 79274 : 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)))
8866 : : {
8867 : : /* must dereference LeftValue */
8868 : 1344 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pi));
8869 : 1344 : f->TrueExit = MakeRightValue (M2LexBuf_GetTokenNo (), M2Quads_OperandT (pi), SymbolTable_GetSType (M2Quads_OperandT (pi)));
8870 : : }
8871 : 79274 : i += 1;
8872 : 79274 : pi -= 1;
8873 : : }
8874 : 66544 : }
8875 : :
8876 : :
8877 : : /*
8878 : : ManipulateParameters - manipulates the procedure parameters in
8879 : : preparation for a procedure call.
8880 : : Prepares Boolean, Unbounded and VAR parameters.
8881 : : The Stack:
8882 : :
8883 : :
8884 : : Entry Exit
8885 : :
8886 : : Ptr -> exactly the same
8887 : : +----------------+
8888 : : | NoOfParameters |
8889 : : |----------------|
8890 : : | Param 1 |
8891 : : |----------------|
8892 : : | Param 2 |
8893 : : |----------------|
8894 : : . .
8895 : : . .
8896 : : . .
8897 : : |----------------|
8898 : : | Param # |
8899 : : |----------------|
8900 : : | ProcSym | Type |
8901 : : |----------------|
8902 : : */
8903 : :
8904 : 219126 : static void ManipulateParameters (bool IsForC)
8905 : : {
8906 : 219126 : unsigned int tokpos;
8907 : 219126 : unsigned int np;
8908 : 219126 : DynamicStrings_String s;
8909 : 219126 : unsigned int ArraySym;
8910 : 219126 : unsigned int UnboundedType;
8911 : 219126 : unsigned int ParamType;
8912 : 219126 : unsigned int NoOfParameters;
8913 : 219126 : unsigned int i;
8914 : 219126 : unsigned int pi;
8915 : 219126 : unsigned int ProcSym;
8916 : 219126 : unsigned int rw;
8917 : 219126 : unsigned int Proc;
8918 : 219126 : unsigned int t;
8919 : 219126 : M2Quads_BoolFrame f;
8920 : :
8921 : 219126 : M2Quads_PopT (&NoOfParameters);
8922 : 219126 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+1));
8923 : 219126 : tokpos = OperandTtok (NoOfParameters+1);
8924 : 219126 : if (SymbolTable_IsVar (ProcSym))
8925 : : {
8926 : : /* Procedure Variable ? */
8927 : 748 : Proc = SymbolTable_SkipType (M2Quads_OperandF (NoOfParameters+1));
8928 : : }
8929 : : else
8930 : : {
8931 : 218378 : Proc = PCSymBuild_SkipConst (ProcSym);
8932 : : }
8933 : 219126 : if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
8934 : : {
8935 : : /* avoid dangling else. */
8936 : 9653 : if (NoOfParameters < (SymbolTable_NoOfParamAny (Proc)))
8937 : : {
8938 : 0 : s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
8939 : 0 : np = SymbolTable_NoOfParamAny (Proc);
8940 : 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));
8941 : : }
8942 : : }
8943 : 209473 : else if (SymbolTable_UsesOptArgAny (Proc))
8944 : : {
8945 : : /* avoid dangling else. */
8946 : 3802 : if (! ((NoOfParameters == (SymbolTable_NoOfParamAny (Proc))) || ((NoOfParameters+1) == (SymbolTable_NoOfParamAny (Proc)))))
8947 : : {
8948 : 0 : s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
8949 : 0 : np = SymbolTable_NoOfParamAny (Proc);
8950 : 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));
8951 : : }
8952 : : }
8953 : 205671 : else if (NoOfParameters != (SymbolTable_NoOfParamAny (Proc)))
8954 : : {
8955 : : /* avoid dangling else. */
8956 : 0 : s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
8957 : 0 : np = SymbolTable_NoOfParamAny (Proc);
8958 : 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));
8959 : : }
8960 : 219126 : i = 1;
8961 : 219126 : pi = NoOfParameters;
8962 : 762532 : while (i <= NoOfParameters)
8963 : : {
8964 : 543406 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pi));
8965 : 543406 : rw = static_cast<unsigned int> (OperandMergeRW (pi));
8966 : 543406 : M2Debug_Assert (SymbolTable_IsLegal (rw));
8967 : 543406 : if (i > (SymbolTable_NoOfParamAny (Proc)))
8968 : : {
8969 : 8280 : if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
8970 : : {
8971 : : /* avoid dangling else. */
8972 : 8280 : if (((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym) && (SymbolTable_IsArray (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
8973 : : {
8974 : 156 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_RightValue, M2System_Address);
8975 : 156 : MarkAsReadWrite (rw);
8976 : : }
8977 : 8124 : else if (SymbolTable_IsConstString (M2Quads_OperandT (pi)))
8978 : : {
8979 : : /* avoid dangling else. */
8980 : 272 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), DeferMakeConstStringCnul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi)), SymbolTable_RightValue, M2System_Address);
8981 : 272 : MarkAsReadWrite (rw);
8982 : : }
8983 : 7852 : else if (((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (M2Quads_OperandT (pi)))))
8984 : : {
8985 : : /* avoid dangling else. */
8986 : 200 : MarkAsReadWrite (rw);
8987 : : /* pass the address field of an unbounded variable */
8988 : 200 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, M2Quads_OperandTok (pi));
8989 : 200 : PushTFAD (f->TrueExit, f->FalseExit, f->Unbounded, f->Dimension);
8990 : 200 : M2Quads_PushT (static_cast<unsigned int> (1));
8991 : 200 : BuildAdrFunction ();
8992 : 200 : M2Quads_PopT (&f->TrueExit);
8993 : : }
8994 : 7652 : else if ((SymbolTable_GetMode (M2Quads_OperandT (pi))) == SymbolTable_LeftValue)
8995 : : {
8996 : : /* avoid dangling else. */
8997 : 464 : MarkAsReadWrite (rw);
8998 : : /* must dereference LeftValue (even if we are passing variable as a vararg) */
8999 : 464 : t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
9000 : 464 : SymbolTable_PutVar (t, SymbolTable_GetSType (M2Quads_OperandT (pi)));
9001 : 464 : CheckPointerThroughNil (tokpos, M2Quads_OperandT (pi));
9002 : 464 : doIndrX (M2Quads_OperandTok (pi), t, M2Quads_OperandT (pi));
9003 : 464 : f->TrueExit = t;
9004 : : }
9005 : : }
9006 : : else
9007 : : {
9008 : 0 : M2MetaError_MetaErrorT2 (tokpos, (const char *) "attempting to pass too many parameters to procedure {%1a}, the {%2N} parameter does not exist", 93, Proc, i);
9009 : : }
9010 : : }
9011 : 535126 : else if (((IsForC && (SymbolTable_IsUnboundedParamAny (Proc, i))) && ((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym)) && (SymbolTable_IsArray (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
9012 : : {
9013 : : /* avoid dangling else. */
9014 : 24 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_RightValue, M2System_Address);
9015 : 24 : MarkAsReadWrite (rw);
9016 : : }
9017 : 535102 : else if (((IsForC && (SymbolTable_IsUnboundedParamAny (Proc, i))) && ((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym)) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
9018 : : {
9019 : : /* avoid dangling else. */
9020 : 184 : MarkAsReadWrite (rw);
9021 : : /* pass the address field of an unbounded variable */
9022 : 184 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, M2Quads_OperandTok (pi));
9023 : 184 : PushTFAD (f->TrueExit, f->FalseExit, f->Unbounded, f->Dimension);
9024 : 184 : M2Quads_PushT (static_cast<unsigned int> (1));
9025 : 184 : BuildAdrFunction ();
9026 : 184 : M2Quads_PopT (&f->TrueExit);
9027 : : }
9028 : 534918 : else if ((IsForC && (SymbolTable_IsConstString (M2Quads_OperandT (pi)))) && ((SymbolTable_IsUnboundedParamAny (Proc, i)) || ((SymbolTable_GetDType (SymbolTable_GetParam (Proc, i))) == M2System_Address)))
9029 : : {
9030 : : /* avoid dangling else. */
9031 : 9341 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), DeferMakeConstStringCnul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi)), SymbolTable_RightValue, M2System_Address);
9032 : 9341 : MarkAsReadWrite (rw);
9033 : : }
9034 : 525577 : else if (SymbolTable_IsUnboundedParamAny (Proc, i))
9035 : : {
9036 : : /* avoid dangling else. */
9037 : : /* always pass constant strings with a nul terminator, but leave the HIGH as before. */
9038 : 40785 : if (SymbolTable_IsConstString (M2Quads_OperandT (pi)))
9039 : : {
9040 : : /* this is a Modula-2 string which must be nul terminated. */
9041 : 26687 : f->TrueExit = DeferMakeConstStringM2nul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi));
9042 : : }
9043 : 40785 : t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
9044 : 40785 : UnboundedType = SymbolTable_GetSType (SymbolTable_GetParam (Proc, i));
9045 : 40785 : SymbolTable_PutVar (t, UnboundedType);
9046 : 40785 : ParamType = SymbolTable_GetSType (UnboundedType);
9047 : 40785 : if ((OperandD (pi)) == 0)
9048 : : {
9049 : 40737 : ArraySym = static_cast<unsigned int> (M2Quads_OperandT (pi));
9050 : : }
9051 : : else
9052 : : {
9053 : 48 : ArraySym = static_cast<unsigned int> (M2Quads_OperandA (pi));
9054 : : }
9055 : 40785 : if (SymbolTable_IsVarParamAny (Proc, i))
9056 : : {
9057 : 4450 : MarkArrayWritten (M2Quads_OperandT (pi));
9058 : 4450 : MarkArrayWritten (M2Quads_OperandA (pi));
9059 : 4450 : MarkAsReadWrite (rw);
9060 : 4450 : AssignUnboundedVar (OperandTtok (pi), M2Quads_OperandT (pi), ArraySym, t, ParamType, OperandD (pi));
9061 : : }
9062 : : else
9063 : : {
9064 : 36335 : MarkAsRead (rw);
9065 : 36335 : AssignUnboundedNonVar (OperandTtok (pi), M2Quads_OperandT (pi), ArraySym, t, ParamType, OperandD (pi));
9066 : : }
9067 : 40785 : f->TrueExit = t;
9068 : : }
9069 : 484792 : else if (SymbolTable_IsVarParamAny (Proc, i))
9070 : : {
9071 : : /* avoid dangling else. */
9072 : : /* must reference by address, but we contain the type of the referenced entity */
9073 : 16020 : MarkArrayWritten (M2Quads_OperandT (pi));
9074 : 16020 : MarkArrayWritten (M2Quads_OperandA (pi));
9075 : 16020 : MarkAsReadWrite (rw);
9076 : 16020 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_LeftValue, SymbolTable_GetSType (SymbolTable_GetParam (Proc, i)));
9077 : : }
9078 : 468772 : else if ((! (SymbolTable_IsVarParamAny (Proc, i))) && ((SymbolTable_GetMode (M2Quads_OperandT (pi))) == SymbolTable_LeftValue))
9079 : : {
9080 : : /* avoid dangling else. */
9081 : : /* must dereference LeftValue */
9082 : 1510 : t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
9083 : 1510 : SymbolTable_PutVar (t, SymbolTable_GetSType (M2Quads_OperandT (pi)));
9084 : 1510 : CheckPointerThroughNil (tokpos, M2Quads_OperandT (pi));
9085 : 1510 : doIndrX (M2Quads_OperandTok (pi), t, M2Quads_OperandT (pi));
9086 : 1510 : f->TrueExit = t;
9087 : 1510 : MarkAsRead (rw);
9088 : : }
9089 : : else
9090 : : {
9091 : : /* avoid dangling else. */
9092 : 467262 : MarkAsRead (rw);
9093 : : }
9094 : 543406 : i += 1;
9095 : 543406 : pi -= 1;
9096 : : }
9097 : 219126 : M2Quads_PushT (NoOfParameters);
9098 : 219126 : }
9099 : :
9100 : :
9101 : : /*
9102 : : CheckParameterOrdinals - check that ordinal values are within type range.
9103 : : */
9104 : :
9105 : 219126 : static void CheckParameterOrdinals (void)
9106 : : {
9107 : 219126 : unsigned int tokno;
9108 : 219126 : unsigned int Proc;
9109 : 219126 : unsigned int ProcSym;
9110 : 219126 : unsigned int Actual;
9111 : 219126 : unsigned int FormalI;
9112 : 219126 : unsigned int ParamTotal;
9113 : 219126 : unsigned int pi;
9114 : 219126 : unsigned int i;
9115 : :
9116 : 219126 : M2Quads_PopT (&ParamTotal);
9117 : 219126 : M2Quads_PushT (ParamTotal); /* Restore stack to origional state */
9118 : 219126 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((ParamTotal+1)+1)); /* Restore stack to origional state */
9119 : 219126 : if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (SymbolTable_GetDType (ProcSym))))
9120 : : {
9121 : : /* Indirect procedure call. */
9122 : 748 : Proc = SymbolTable_SkipType (M2Quads_OperandF ((ParamTotal+1)+1));
9123 : : }
9124 : : else
9125 : : {
9126 : 218378 : Proc = PCSymBuild_SkipConst (ProcSym);
9127 : : }
9128 : 219126 : i = 1;
9129 : 219126 : pi = ParamTotal+1; /* stack index referencing stacked parameter, i */
9130 : 762532 : while (i <= ParamTotal) /* stack index referencing stacked parameter, i */
9131 : : {
9132 : 543406 : if (i <= (SymbolTable_NoOfParamAny (Proc)))
9133 : : {
9134 : 535126 : FormalI = SymbolTable_GetParam (Proc, i);
9135 : 535126 : Actual = static_cast<unsigned int> (M2Quads_OperandT (pi));
9136 : 535126 : tokno = static_cast<unsigned int> (M2Quads_OperandTok (pi));
9137 : 535126 : if (M2Base_IsOrdinalType (SymbolTable_GetLType (FormalI)))
9138 : : {
9139 : 141995 : if (! (SymbolTable_IsSet (SymbolTable_GetDType (FormalI))))
9140 : : {
9141 : : /* Tell the code generator to test the runtime values of the assignment
9142 : : so ensure we catch overflow and underflow. */
9143 : 141995 : BuildRange (M2Range_InitParameterRangeCheck (tokno, Proc, i, FormalI, Actual, OperandRangeDep (pi)));
9144 : : }
9145 : : }
9146 : : }
9147 : 543406 : i += 1;
9148 : 543406 : pi -= 1;
9149 : : }
9150 : 219126 : }
9151 : :
9152 : :
9153 : : /*
9154 : : IsSameUnbounded - returns TRUE if unbounded types, t1, and, t2,
9155 : : are compatible.
9156 : : */
9157 : :
9158 : 36 : static bool IsSameUnbounded (unsigned int t1, unsigned int t2)
9159 : : {
9160 : 36 : M2Debug_Assert (SymbolTable_IsUnbounded (t1));
9161 : 36 : M2Debug_Assert (SymbolTable_IsUnbounded (t2));
9162 : 36 : return (SymbolTable_GetDType (t1)) == (SymbolTable_GetDType (t2));
9163 : : /* static analysis guarentees a RETURN statement will be used before here. */
9164 : : __builtin_unreachable ();
9165 : : }
9166 : :
9167 : :
9168 : : /*
9169 : : AssignUnboundedVar - assigns an Unbounded symbol fields,
9170 : : ArrayAddress and ArrayHigh, from an array symbol.
9171 : : UnboundedSym is not a VAR parameter and therefore
9172 : : this procedure can complete both of the fields.
9173 : : Sym can be a Variable with type Unbounded.
9174 : : Sym can be a Variable with type Array.
9175 : : Sym can be a String Constant.
9176 : :
9177 : : ParamType is the TYPE of the parameter
9178 : : */
9179 : :
9180 : 4450 : static void AssignUnboundedVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9181 : : {
9182 : 4450 : unsigned int Type;
9183 : :
9184 : 4450 : if (SymbolTable_IsConst (Sym))
9185 : : {
9186 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
9187 : : }
9188 : 4450 : else if (SymbolTable_IsVar (Sym))
9189 : : {
9190 : : /* avoid dangling else. */
9191 : 4450 : Type = SymbolTable_GetDType (Sym);
9192 : 4450 : if (Type == SymbolTable_NulSym)
9193 : : {
9194 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} has no type and cannot be passed to a VAR formal parameter", 65, Sym);
9195 : : }
9196 : 4450 : else if (SymbolTable_IsUnbounded (Type))
9197 : : {
9198 : : /* avoid dangling else. */
9199 : 1462 : if (Type == (SymbolTable_GetSType (UnboundedSym)))
9200 : : {
9201 : : /* Copy Unbounded Symbol ie. UnboundedSym := Sym */
9202 : 1426 : M2Quads_PushT (UnboundedSym);
9203 : 1426 : M2Quads_PushT (Sym);
9204 : 1426 : BuildAssignmentWithoutBounds (tok, false, true);
9205 : : }
9206 : 36 : else if ((IsSameUnbounded (Type, SymbolTable_GetSType (UnboundedSym))) || (M2System_IsGenericSystemType (ParamType)))
9207 : : {
9208 : : /* avoid dangling else. */
9209 : 36 : UnboundedVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9210 : : }
9211 : : else
9212 : : {
9213 : : /* avoid dangling else. */
9214 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
9215 : : }
9216 : : }
9217 : 2988 : else if ((SymbolTable_IsArray (Type)) || (M2System_IsGenericSystemType (ParamType)))
9218 : : {
9219 : : /* avoid dangling else. */
9220 : 2988 : UnboundedVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9221 : : }
9222 : : else
9223 : : {
9224 : : /* avoid dangling else. */
9225 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
9226 : : }
9227 : : }
9228 : : else
9229 : : {
9230 : : /* avoid dangling else. */
9231 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
9232 : : }
9233 : 4450 : }
9234 : :
9235 : :
9236 : : /*
9237 : : AssignUnboundedNonVar - assigns an Unbounded symbol fields,
9238 : : The difference between this procedure and
9239 : : AssignUnboundedVar is that this procedure cannot
9240 : : set the Unbounded.Address since the data from
9241 : : Sym will be copied because parameter is NOT a VAR
9242 : : parameter.
9243 : : UnboundedSym is not a VAR parameter and therefore
9244 : : this procedure can only complete the HIGH field
9245 : : and not the ADDRESS field.
9246 : : Sym can be a Variable with type Unbounded.
9247 : : Sym can be a Variable with type Array.
9248 : : Sym can be a String Constant.
9249 : :
9250 : : ParamType is the TYPE of the paramater
9251 : : */
9252 : :
9253 : 36335 : static void AssignUnboundedNonVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9254 : : {
9255 : 36335 : unsigned int Type;
9256 : :
9257 : 36335 : if (SymbolTable_IsConst (Sym)) /* was IsConstString(Sym) */
9258 : : {
9259 : 26741 : UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9260 : : }
9261 : 9594 : else if (SymbolTable_IsVar (Sym))
9262 : : {
9263 : : /* avoid dangling else. */
9264 : 9594 : Type = SymbolTable_GetDType (Sym);
9265 : 9594 : if (Type == SymbolTable_NulSym)
9266 : : {
9267 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} has no type and cannot be passed to a non VAR formal parameter", 69, Sym);
9268 : : }
9269 : 9594 : else if (SymbolTable_IsUnbounded (Type))
9270 : : {
9271 : : /* avoid dangling else. */
9272 : 4800 : UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9273 : : }
9274 : 4794 : else if ((SymbolTable_IsArray (Type)) || (M2System_IsGenericSystemType (ParamType)))
9275 : : {
9276 : : /* avoid dangling else. */
9277 : 4782 : UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9278 : : }
9279 : : else
9280 : : {
9281 : : /* avoid dangling else. */
9282 : 12 : M2MetaError_MetaErrorT1 (tok, (const char *) "illegal type parameter {%1Ead} expecting array or dynamic array", 63, Sym);
9283 : : }
9284 : : }
9285 : : else
9286 : : {
9287 : : /* avoid dangling else. */
9288 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "illegal parameter {%1Ead} which cannot be passed as {%kVAR} {%kARRAY} {%kOF} {%1tsad}", 85, Sym);
9289 : : }
9290 : 36335 : }
9291 : :
9292 : :
9293 : : /*
9294 : : GenHigh - generates a HighOp but it checks if op3 is a
9295 : : L value and if so it dereferences it. This
9296 : : is inefficient, however it is clean and we let the gcc
9297 : : backend detect these as common subexpressions.
9298 : : It will also detect that a R value -> L value -> R value
9299 : : via indirection and eleminate these.
9300 : : */
9301 : :
9302 : 42229 : static void GenHigh (unsigned int tok, unsigned int op1, unsigned int op2, unsigned int op3)
9303 : : {
9304 : 42229 : unsigned int sym;
9305 : :
9306 : 42229 : if (((SymbolTable_GetMode (op3)) == SymbolTable_LeftValue) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (op3))))
9307 : : {
9308 : 48 : sym = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
9309 : 48 : SymbolTable_PutVar (sym, SymbolTable_GetSType (op3));
9310 : 48 : doIndrX (tok, sym, op3);
9311 : 48 : GenQuadO (tok, M2Quads_HighOp, op1, op2, sym, true);
9312 : : }
9313 : : else
9314 : : {
9315 : 42181 : GenQuadO (tok, M2Quads_HighOp, op1, op2, op3, true);
9316 : : }
9317 : 42229 : }
9318 : :
9319 : :
9320 : : /*
9321 : : AssignHighField -
9322 : : */
9323 : :
9324 : 39503 : static void AssignHighField (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int actuali, unsigned int formali)
9325 : : {
9326 : 39503 : unsigned int ReturnVar;
9327 : 39503 : unsigned int ArrayType;
9328 : 39503 : unsigned int Field;
9329 : :
9330 : : /* Unbounded.ArrayHigh := HIGH(ArraySym) */
9331 : 39503 : M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
9332 : 39503 : Field = SymbolTable_GetUnboundedHighOffset (SymbolTable_GetSType (UnboundedSym), formali);
9333 : 39503 : M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
9334 : 39503 : M2Quads_PushT (static_cast<unsigned int> (1));
9335 : 39503 : M2Quads_BuildDesignatorRecord (tok);
9336 : 39503 : if (M2System_IsGenericSystemType (ParamType))
9337 : : {
9338 : 2036 : if (SymbolTable_IsConstString (Sym))
9339 : : {
9340 : 18 : M2Quads_PushTtok (DeferMakeLengthConst (tok, Sym), tok);
9341 : : }
9342 : : else
9343 : : {
9344 : 2018 : ArrayType = SymbolTable_GetSType (Sym);
9345 : 2018 : if (SymbolTable_IsUnbounded (ArrayType))
9346 : : {
9347 : : /*
9348 : : * SIZE(parameter) DIV TSIZE(ParamType)
9349 : : * however in this case parameter
9350 : : * is an unbounded symbol and therefore we must use
9351 : : * (HIGH(parameter)+1)*SIZE(unbounded type) DIV TSIZE(ParamType)
9352 : : *
9353 : : * we call upon the function SIZE(ArraySym)
9354 : : * remember SIZE doubles as
9355 : : * (HIGH(a)+1) * SIZE(ArrayType) for unbounded symbols
9356 : : */
9357 : 1106 : M2Quads_PushTFtok (calculateMultipicand (tok, ArraySym, ArrayType, actuali-1), M2Base_Cardinal, tok);
9358 : 1106 : M2Quads_PushT (M2Reserved_DivideTok); /* Divide by */
9359 : 1106 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok); /* TSIZE(ParamType) */
9360 : 1106 : M2Quads_PushTtok (ParamType, tok); /* TSIZE(ParamType) */
9361 : 1106 : M2Quads_PushT (static_cast<unsigned int> (1)); /* 1 parameter for TSIZE() */
9362 : 1106 : M2Quads_BuildFunctionCall (false); /* 1 parameter for TSIZE() */
9363 : 1106 : M2Quads_BuildBinaryOp ();
9364 : : }
9365 : : else
9366 : : {
9367 : : /* SIZE(parameter) DIV TSIZE(ParamType) */
9368 : 912 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok); /* TSIZE(ArrayType) */
9369 : 912 : M2Quads_PushTtok (ArrayType, tok); /* TSIZE(ArrayType) */
9370 : 912 : M2Quads_PushT (static_cast<unsigned int> (1)); /* 1 parameter for TSIZE() */
9371 : 912 : M2Quads_BuildFunctionCall (true); /* 1 parameter for TSIZE() */
9372 : 912 : M2Quads_PushT (M2Reserved_DivideTok); /* Divide by */
9373 : 912 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok); /* TSIZE(ParamType) */
9374 : 912 : M2Quads_PushTtok (ParamType, tok); /* TSIZE(ParamType) */
9375 : 912 : M2Quads_PushT (static_cast<unsigned int> (1)); /* 1 parameter for TSIZE() */
9376 : 912 : M2Quads_BuildFunctionCall (true); /* 1 parameter for TSIZE() */
9377 : 912 : M2Quads_BuildBinaryOp ();
9378 : : }
9379 : : /* now convert from no of elements into HIGH by subtracting 1 */
9380 : 2018 : M2Quads_PushT (M2Reserved_MinusTok); /* -1 */
9381 : 2018 : M2Quads_PushTtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal), tok); /* -1 */
9382 : 2018 : M2Quads_BuildBinaryOp ();
9383 : : }
9384 : : }
9385 : : else
9386 : : {
9387 : 37467 : ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
9388 : 37467 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
9389 : 37467 : if (((actuali != formali) && (ArraySym != SymbolTable_NulSym)) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (ArraySym))))
9390 : : {
9391 : 12 : GenHigh (tok, ReturnVar, actuali, ArraySym);
9392 : : }
9393 : : else
9394 : : {
9395 : 37455 : GenHigh (tok, ReturnVar, formali, Sym);
9396 : : }
9397 : 37467 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), tok);
9398 : : }
9399 : 39503 : BuildAssignmentWithoutBounds (tok, false, true);
9400 : 39503 : }
9401 : :
9402 : :
9403 : : /*
9404 : : AssignHighFields -
9405 : : */
9406 : :
9407 : 39347 : static void AssignHighFields (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9408 : : {
9409 : 39347 : unsigned int type;
9410 : 39347 : unsigned int actuali;
9411 : 39347 : unsigned int formali;
9412 : 39347 : unsigned int actualn;
9413 : 39347 : unsigned int formaln;
9414 : :
9415 : 39347 : type = SymbolTable_GetDType (Sym);
9416 : 39347 : actualn = 1;
9417 : 39347 : if ((type != SymbolTable_NulSym) && ((SymbolTable_IsUnbounded (type)) || (SymbolTable_IsArray (type))))
9418 : : {
9419 : 11724 : actualn = SymbolTable_GetDimension (type);
9420 : : }
9421 : 39347 : actuali = dim+1;
9422 : 39347 : formali = 1;
9423 : 39347 : formaln = SymbolTable_GetDimension (SymbolTable_GetDType (UnboundedSym));
9424 : 78850 : while ((actuali < actualn) && (formali < formaln))
9425 : : {
9426 : 156 : AssignHighField (tok, Sym, ArraySym, UnboundedSym, SymbolTable_NulSym, actuali, formali);
9427 : 156 : actuali += 1;
9428 : 156 : formali += 1;
9429 : : }
9430 : 39347 : AssignHighField (tok, Sym, ArraySym, UnboundedSym, ParamType, actuali, formali);
9431 : 39347 : }
9432 : :
9433 : :
9434 : : /*
9435 : : UnboundedNonVarLinkToArray - links an array, ArraySym, to an unbounded
9436 : : array, UnboundedSym. The parameter is a
9437 : : NON VAR variety.
9438 : : */
9439 : :
9440 : 36323 : static void UnboundedNonVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9441 : : {
9442 : 36323 : unsigned int Field;
9443 : 36323 : unsigned int AddressField;
9444 : :
9445 : : /* Unbounded.ArrayAddress := to be assigned at runtime. */
9446 : 36323 : M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
9447 : 36323 : Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
9448 : 36323 : M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
9449 : 36323 : M2Quads_PushT (static_cast<unsigned int> (1));
9450 : 36323 : M2Quads_BuildDesignatorRecord (tok);
9451 : 36323 : M2Quads_PopT (&AddressField);
9452 : : /* caller saves non var unbounded array contents. */
9453 : 72646 : GenQuadO (tok, M2Quads_UnboundedOp, AddressField, SymbolTable_NulSym, Sym, false);
9454 : 36323 : AssignHighFields (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9455 : 36323 : }
9456 : :
9457 : :
9458 : : /*
9459 : : UnboundedVarLinkToArray - links an array, ArraySym, to an unbounded array,
9460 : : UnboundedSym. The parameter is a VAR variety.
9461 : : */
9462 : :
9463 : 3024 : static void UnboundedVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9464 : : {
9465 : 3024 : unsigned int SymType;
9466 : 3024 : unsigned int Field;
9467 : :
9468 : 3024 : SymType = SymbolTable_GetSType (Sym);
9469 : : /* Unbounded.ArrayAddress := ADR(Sym) */
9470 : 3024 : M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
9471 : 3024 : Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
9472 : 3024 : M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
9473 : 3024 : M2Quads_PushT (static_cast<unsigned int> (1));
9474 : 3024 : M2Quads_BuildDesignatorRecord (tok);
9475 : 3024 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok); /* ADR (Sym). */
9476 : 3024 : if ((SymbolTable_IsUnbounded (SymType)) && (dim == 0)) /* ADR (Sym). */
9477 : : {
9478 : 12 : PushTFADtok (Sym, SymType, UnboundedSym, dim, tok);
9479 : : }
9480 : : else
9481 : : {
9482 : 3012 : PushTFADtok (Sym, SymType, ArraySym, dim, tok);
9483 : : }
9484 : 3024 : M2Quads_PushT (static_cast<unsigned int> (1)); /* 1 parameter for ADR(). */
9485 : 3024 : M2Quads_BuildFunctionCall (false); /* 1 parameter for ADR(). */
9486 : 3024 : BuildAssignmentWithoutBounds (tok, false, true);
9487 : 3024 : AssignHighFields (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9488 : 3024 : }
9489 : :
9490 : :
9491 : : /*
9492 : : BuildPseudoProcedureCall - builds a pseudo procedure call.
9493 : : This procedure does not directly alter the
9494 : : stack, but by calling routines the stack
9495 : : will change in the following way when this
9496 : : procedure returns.
9497 : :
9498 : : The Stack:
9499 : :
9500 : :
9501 : : Entry Exit
9502 : :
9503 : : Ptr ->
9504 : : +----------------+
9505 : : | NoOfParam |
9506 : : |----------------|
9507 : : | Param 1 |
9508 : : |----------------|
9509 : : | Param 2 |
9510 : : |----------------|
9511 : : . .
9512 : : . .
9513 : : . .
9514 : : |----------------|
9515 : : | Param # |
9516 : : |----------------|
9517 : : | ProcSym | Type | Empty
9518 : : |----------------|
9519 : : */
9520 : :
9521 : 21502 : static void BuildPseudoProcedureCall (unsigned int tokno)
9522 : : {
9523 : 21502 : unsigned int NoOfParam;
9524 : 21502 : unsigned int ProcSym;
9525 : :
9526 : 21502 : M2Quads_PopT (&NoOfParam);
9527 : 21502 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
9528 : 21502 : M2Quads_PushT (NoOfParam);
9529 : : /* Compile time stack restored to entry state */
9530 : 21502 : if (ProcSym == M2Base_New)
9531 : : {
9532 : 864 : BuildNewProcedure (tokno);
9533 : : }
9534 : 20638 : else if (ProcSym == M2Base_Dispose)
9535 : : {
9536 : : /* avoid dangling else. */
9537 : 324 : BuildDisposeProcedure (tokno);
9538 : : }
9539 : 20314 : else if (ProcSym == M2Base_Inc)
9540 : : {
9541 : : /* avoid dangling else. */
9542 : 14378 : BuildIncProcedure (tokno);
9543 : : }
9544 : 5936 : else if (ProcSym == M2Base_Dec)
9545 : : {
9546 : : /* avoid dangling else. */
9547 : 3932 : BuildDecProcedure (tokno);
9548 : : }
9549 : 2004 : else if (ProcSym == M2Base_Incl)
9550 : : {
9551 : : /* avoid dangling else. */
9552 : 1122 : BuildInclProcedure (tokno);
9553 : : }
9554 : 882 : else if (ProcSym == M2Base_Excl)
9555 : : {
9556 : : /* avoid dangling else. */
9557 : 770 : BuildExclProcedure (tokno);
9558 : : }
9559 : 112 : else if (ProcSym == M2System_Throw)
9560 : : {
9561 : : /* avoid dangling else. */
9562 : 112 : BuildThrowProcedure (tokno);
9563 : : }
9564 : : else
9565 : : {
9566 : : /* avoid dangling else. */
9567 : 0 : M2Error_InternalError ((const char *) "pseudo procedure not implemented yet", 36);
9568 : : }
9569 : 21502 : }
9570 : :
9571 : :
9572 : : /*
9573 : : GetItemPointedTo - returns the symbol type that is being pointed to
9574 : : by Sym.
9575 : : */
9576 : :
9577 : 3002 : static unsigned int GetItemPointedTo (unsigned int Sym)
9578 : : {
9579 : 6012 : if (SymbolTable_IsPointer (Sym))
9580 : : {
9581 : 3002 : return SymbolTable_GetSType (Sym);
9582 : : }
9583 : 3010 : else if ((SymbolTable_IsVar (Sym)) || (SymbolTable_IsType (Sym)))
9584 : : {
9585 : : /* avoid dangling else. */
9586 : 3010 : return GetItemPointedTo (SymbolTable_GetSType (Sym));
9587 : : }
9588 : : else
9589 : : {
9590 : : /* avoid dangling else. */
9591 : : return SymbolTable_NulSym;
9592 : : }
9593 : : /* static analysis guarentees a RETURN statement will be used before here. */
9594 : : __builtin_unreachable ();
9595 : : }
9596 : :
9597 : :
9598 : : /*
9599 : : BuildThrowProcedure - builds the pseudo procedure call M2RTS.Throw.
9600 : : The Stack:
9601 : :
9602 : :
9603 : : Entry Exit
9604 : :
9605 : : Ptr ->
9606 : : +----------------+
9607 : : | NoOfParam |
9608 : : |----------------|
9609 : : | Param 1 |
9610 : : |----------------|
9611 : : | Param 2 |
9612 : : |----------------|
9613 : : . .
9614 : : . .
9615 : : . .
9616 : : |----------------|
9617 : : | Param # |
9618 : : |----------------|
9619 : : | ProcSym | Type | Empty
9620 : : |----------------|
9621 : : */
9622 : :
9623 : 112 : static void BuildThrowProcedure (unsigned int functok)
9624 : : {
9625 : 112 : unsigned int op;
9626 : 112 : unsigned int NoOfParam;
9627 : :
9628 : 112 : M2Quads_PopT (&NoOfParam);
9629 : 112 : if (NoOfParam == 1)
9630 : : {
9631 : 112 : op = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
9632 : 112 : GenQuadO (functok, M2Quads_ThrowOp, SymbolTable_NulSym, SymbolTable_NulSym, op, false);
9633 : : }
9634 : : else
9635 : : {
9636 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure %{1Ea} takes one INTEGER parameter", 55, M2System_Throw);
9637 : : }
9638 : 112 : M2Quads_PopN (NoOfParam+1);
9639 : 112 : }
9640 : :
9641 : :
9642 : : /*
9643 : : BuildNewProcedure - builds the pseudo procedure call NEW.
9644 : : This procedure is traditionally a "macro" for
9645 : : NEW(x, ...) --> ALLOCATE(x, TSIZE(x^, ...))
9646 : : One method of implementation is to emulate a "macro"
9647 : : processor by pushing the relevant input tokens
9648 : : back onto the input stack.
9649 : : However this causes two problems:
9650 : :
9651 : : (i) Unnecessary code is produced for x^
9652 : : (ii) SIZE must be imported from SYSTEM
9653 : : Therefore we chose an alternative method of
9654 : : implementation;
9655 : : generate quadruples for ALLOCATE(x, TSIZE(x^, ...))
9656 : : this, although slightly more efficient,
9657 : : is more complex and circumvents problems (i) and (ii).
9658 : :
9659 : : The Stack:
9660 : :
9661 : :
9662 : : Entry Exit
9663 : :
9664 : : Ptr ->
9665 : : +----------------+
9666 : : | NoOfParam |
9667 : : |----------------|
9668 : : | Param 1 |
9669 : : |----------------|
9670 : : | Param 2 |
9671 : : |----------------|
9672 : : . .
9673 : : . .
9674 : : . .
9675 : : |----------------|
9676 : : | Param # |
9677 : : |----------------|
9678 : : | ProcSym | Type | Empty
9679 : : |----------------|
9680 : : */
9681 : :
9682 : 864 : static void BuildNewProcedure (unsigned int functok)
9683 : : {
9684 : 864 : unsigned int NoOfParam;
9685 : 864 : unsigned int SizeSym;
9686 : 864 : unsigned int PtrSym;
9687 : 864 : unsigned int ProcSym;
9688 : 864 : unsigned int paramtok;
9689 : 864 : unsigned int combinedtok;
9690 : :
9691 : 864 : M2Quads_PopT (&NoOfParam);
9692 : 864 : if (NoOfParam >= 1)
9693 : : {
9694 : 864 : ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "ALLOCATE", 8));
9695 : 864 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
9696 : : {
9697 : 864 : PtrSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
9698 : 864 : paramtok = OperandTtok (1);
9699 : 864 : if (IsReallyPointer (PtrSym))
9700 : : {
9701 : 864 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
9702 : : /*
9703 : : Build macro: ALLOCATE( PtrSym, SIZE(PtrSym^) )
9704 : : */
9705 : 864 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, paramtok); /* Procedure */
9706 : : /* x^ */
9707 : 864 : M2Quads_PushTtok (GetItemPointedTo (PtrSym), paramtok);
9708 : 864 : M2Quads_PushT (static_cast<unsigned int> (1)); /* One parameter */
9709 : 864 : M2Quads_BuildFunctionCall (false); /* One parameter */
9710 : 864 : M2Quads_PopT (&SizeSym);
9711 : 864 : M2Quads_PushTtok (ProcSym, combinedtok); /* ALLOCATE */
9712 : 864 : M2Quads_PushTtok (PtrSym, paramtok); /* x */
9713 : 864 : M2Quads_PushTtok (SizeSym, paramtok); /* TSIZE(x^) */
9714 : 864 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
9715 : 864 : M2Quads_BuildProcedureCall (combinedtok); /* Two parameters */
9716 : : }
9717 : : else
9718 : : {
9719 : 0 : M2MetaError_MetaErrorT0 (paramtok, (const char *) "parameter to {%EkNEW} must be a pointer", 39);
9720 : : }
9721 : : }
9722 : : else
9723 : : {
9724 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}ALLOCATE procedure not found for NEW substitution", 53);
9725 : : }
9726 : : }
9727 : : else
9728 : : {
9729 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the pseudo procedure {%EkNEW} has one or more parameters", 56);
9730 : : }
9731 : 864 : M2Quads_PopN (NoOfParam+1);
9732 : 864 : }
9733 : :
9734 : :
9735 : : /*
9736 : : BuildDisposeProcedure - builds the pseudo procedure call DISPOSE.
9737 : : This procedure is traditionally a "macro" for
9738 : : DISPOSE(x) --> DEALLOCATE(x, TSIZE(x^))
9739 : : One method of implementation is to emulate a "macro"
9740 : : processor by pushing the relevant input tokens
9741 : : back onto the input stack.
9742 : : However this causes two problems:
9743 : :
9744 : : (i) Unnecessary code is produced for x^
9745 : : (ii) TSIZE must be imported from SYSTEM
9746 : : Therefore we chose an alternative method of
9747 : : implementation;
9748 : : generate quadruples for DEALLOCATE(x, TSIZE(x^))
9749 : : this, although slightly more efficient,
9750 : : is more complex and circumvents problems (i)
9751 : : and (ii).
9752 : :
9753 : : The Stack:
9754 : :
9755 : :
9756 : : Entry Exit
9757 : :
9758 : : Ptr ->
9759 : : +----------------+
9760 : : | NoOfParam |
9761 : : |----------------|
9762 : : | Param 1 |
9763 : : |----------------|
9764 : : | Param 2 |
9765 : : |----------------|
9766 : : . .
9767 : : . .
9768 : : . .
9769 : : |----------------|
9770 : : | Param # |
9771 : : |----------------|
9772 : : | ProcSym | Type | Empty
9773 : : |----------------|
9774 : : */
9775 : :
9776 : 324 : static void BuildDisposeProcedure (unsigned int functok)
9777 : : {
9778 : 324 : unsigned int NoOfParam;
9779 : 324 : unsigned int SizeSym;
9780 : 324 : unsigned int PtrSym;
9781 : 324 : unsigned int ProcSym;
9782 : 324 : unsigned int combinedtok;
9783 : 324 : unsigned int paramtok;
9784 : :
9785 : 324 : M2Quads_PopT (&NoOfParam);
9786 : 324 : if (NoOfParam >= 1)
9787 : : {
9788 : 324 : ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "DEALLOCATE", 10));
9789 : 324 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
9790 : : {
9791 : 324 : PtrSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
9792 : 324 : paramtok = OperandTtok (1);
9793 : 324 : if (IsReallyPointer (PtrSym))
9794 : : {
9795 : 324 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
9796 : : /*
9797 : : Build macro: DEALLOCATE( PtrSym, TSIZE(PtrSym^) )
9798 : : */
9799 : 324 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, paramtok); /* Procedure */
9800 : : /* x^ */
9801 : 324 : M2Quads_PushTtok (GetItemPointedTo (PtrSym), paramtok);
9802 : 324 : M2Quads_PushT (static_cast<unsigned int> (1)); /* One parameter */
9803 : 324 : M2Quads_BuildFunctionCall (false); /* One parameter */
9804 : 324 : M2Quads_PopT (&SizeSym);
9805 : 324 : M2Quads_PushTtok (ProcSym, combinedtok); /* DEALLOCATE */
9806 : 324 : M2Quads_PushTtok (PtrSym, paramtok); /* x */
9807 : 324 : M2Quads_PushTtok (SizeSym, paramtok); /* TSIZE(x^) */
9808 : 324 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
9809 : 324 : M2Quads_BuildProcedureCall (combinedtok); /* Two parameters */
9810 : : }
9811 : : else
9812 : : {
9813 : 0 : M2MetaError_MetaErrorT0 (paramtok, (const char *) "argument to {%EkDISPOSE} must be a pointer", 42);
9814 : : }
9815 : : }
9816 : : else
9817 : : {
9818 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}DEALLOCATE procedure not found for DISPOSE substitution", 59);
9819 : : }
9820 : : }
9821 : : else
9822 : : {
9823 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the pseudo procedure {%EkDISPOSE} has one or more parameters", 60);
9824 : : }
9825 : 324 : M2Quads_PopN (NoOfParam+1);
9826 : 324 : }
9827 : :
9828 : :
9829 : : /*
9830 : : CheckRangeIncDec - performs des := des <tok> expr
9831 : : with range checking (if enabled).
9832 : :
9833 : : Stack
9834 : : Entry Exit
9835 : :
9836 : : +------------+
9837 : : empty | des + expr |
9838 : : |------------|
9839 : : */
9840 : :
9841 : 18310 : static void CheckRangeIncDec (unsigned int tokenpos, unsigned int des, unsigned int expr, NameKey_Name tok)
9842 : : {
9843 : 18310 : unsigned int dtype;
9844 : 18310 : unsigned int etype;
9845 : :
9846 : 18310 : dtype = SymbolTable_GetDType (des);
9847 : 18310 : etype = SymbolTable_GetDType (expr);
9848 : 18310 : if ((etype == SymbolTable_NulSym) && (SymbolTable_IsPointer (SymbolTable_GetTypeMode (des))))
9849 : : {
9850 : 24 : expr = ConvertToAddress (tokenpos, expr);
9851 : 24 : etype = M2System_Address;
9852 : : }
9853 : 18310 : if (M2Options_WholeValueChecking && ! MustNotCheckBounds)
9854 : : {
9855 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
9856 : 1476 : if (tok == M2Reserved_PlusTok)
9857 : : {
9858 : 792 : BuildRange (M2Range_InitIncRangeCheck (des, expr));
9859 : : }
9860 : : else
9861 : : {
9862 : 684 : BuildRange (M2Range_InitDecRangeCheck (des, expr));
9863 : : }
9864 : : }
9865 : 18310 : if (M2Base_IsExpressionCompatible (dtype, etype))
9866 : : {
9867 : : /* the easy case simulate a straightforward macro */
9868 : 16840 : M2Quads_PushTFtok (des, dtype, tokenpos);
9869 : 16840 : M2Quads_PushT (tok);
9870 : 16840 : M2Quads_PushTFtok (expr, etype, tokenpos);
9871 : 16840 : doBuildBinaryOp (false, true);
9872 : : }
9873 : : else
9874 : : {
9875 : 1470 : if ((((M2Base_IsOrdinalType (dtype)) || (dtype == M2System_Address)) || (SymbolTable_IsPointer (dtype))) && (((M2Base_IsOrdinalType (etype)) || (etype == M2System_Address)) || (SymbolTable_IsPointer (etype))))
9876 : : {
9877 : 1470 : M2Quads_PushTFtok (des, dtype, tokenpos);
9878 : 1470 : M2Quads_PushT (tok);
9879 : 1470 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tokenpos);
9880 : 1470 : M2Quads_PushTtok (dtype, tokenpos);
9881 : 1470 : M2Quads_PushTtok (expr, tokenpos);
9882 : 1470 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
9883 : 1470 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
9884 : 1470 : doBuildBinaryOp (false, true);
9885 : : }
9886 : : else
9887 : : {
9888 : 0 : if (tok == M2Reserved_PlusTok)
9889 : : {
9890 : 0 : M2MetaError_MetaError0 ((const char *) "cannot perform {%EkINC} using non ordinal types", 47);
9891 : : }
9892 : : else
9893 : : {
9894 : 0 : M2MetaError_MetaError0 ((const char *) "cannot perform {%EkDEC} using non ordinal types", 47);
9895 : : }
9896 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (tokenpos, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym), static_cast<unsigned int> (SymbolTable_NulSym), tokenpos);
9897 : : }
9898 : : }
9899 : 18310 : }
9900 : :
9901 : :
9902 : : /*
9903 : : BuildIncProcedure - builds the pseudo procedure call INC.
9904 : : INC is a procedure which increments a variable.
9905 : : It takes one or two parameters:
9906 : : INC(a, b) or INC(a)
9907 : : a := a+b or a := a+1
9908 : :
9909 : : The Stack:
9910 : :
9911 : :
9912 : : Entry Exit
9913 : :
9914 : : Ptr ->
9915 : : +----------------+
9916 : : | NoOfParam |
9917 : : |----------------|
9918 : : | Param 1 |
9919 : : |----------------|
9920 : : | Param 2 |
9921 : : |----------------|
9922 : : . .
9923 : : . .
9924 : : . .
9925 : : |----------------|
9926 : : | Param # |
9927 : : |----------------|
9928 : : | ProcSym | Type | Empty
9929 : : |----------------|
9930 : : */
9931 : :
9932 : 14378 : static void BuildIncProcedure (unsigned int proctok)
9933 : : {
9934 : 14378 : unsigned int NoOfParam;
9935 : 14378 : unsigned int dtype;
9936 : 14378 : unsigned int OperandSym;
9937 : 14378 : unsigned int VarSym;
9938 : 14378 : unsigned int TempSym;
9939 : :
9940 : 14378 : M2Quads_PopT (&NoOfParam);
9941 : 14378 : if ((NoOfParam == 1) || (NoOfParam == 2))
9942 : : {
9943 : 14378 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam)); /* Bottom/first parameter. */
9944 : 14378 : if (SymbolTable_IsVar (VarSym)) /* Bottom/first parameter. */
9945 : : {
9946 : 14378 : dtype = SymbolTable_GetDType (VarSym);
9947 : 14378 : if (NoOfParam == 2)
9948 : : {
9949 : 2742 : OperandSym = DereferenceLValue (proctok, M2Quads_OperandT (1));
9950 : : }
9951 : : else
9952 : : {
9953 : 11636 : PushOne (proctok, dtype, (const char *) "the {%EkINC} will cause an overflow {%1ad}", 42);
9954 : 11636 : M2Quads_PopT (&OperandSym);
9955 : : }
9956 : 14378 : M2Quads_PushTtok (VarSym, proctok);
9957 : 14378 : TempSym = DereferenceLValue (proctok, VarSym);
9958 : 14378 : CheckRangeIncDec (proctok, TempSym, OperandSym, M2Reserved_PlusTok); /* TempSym + OperandSym. */
9959 : 14378 : BuildAssignmentWithoutBounds (proctok, false, true); /* VarSym := TempSym + OperandSym. */
9960 : : }
9961 : : else
9962 : : {
9963 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "base procedure {%EkINC} expects a variable as a parameter but was given {%1Ed}", 78, VarSym);
9964 : : }
9965 : : }
9966 : : else
9967 : : {
9968 : 0 : M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkINC} expects 1 or 2 parameters", 53);
9969 : : }
9970 : 14378 : M2Quads_PopN (NoOfParam+1);
9971 : 14378 : }
9972 : :
9973 : :
9974 : : /*
9975 : : BuildDecProcedure - builds the pseudo procedure call DEC.
9976 : : DEC is a procedure which decrements a variable.
9977 : : It takes one or two parameters:
9978 : : DEC(a, b) or DEC(a)
9979 : : a := a-b or a := a-1
9980 : :
9981 : : The Stack:
9982 : :
9983 : :
9984 : : Entry Exit
9985 : :
9986 : : Ptr ->
9987 : : +----------------+
9988 : : | NoOfParam |
9989 : : |----------------|
9990 : : | Param 1 |
9991 : : |----------------|
9992 : : | Param 2 |
9993 : : |----------------|
9994 : : . .
9995 : : . .
9996 : : . .
9997 : : |----------------|
9998 : : | Param # |
9999 : : |----------------|
10000 : : | ProcSym | Type | Empty
10001 : : |----------------|
10002 : : */
10003 : :
10004 : 3932 : static void BuildDecProcedure (unsigned int proctok)
10005 : : {
10006 : 3932 : unsigned int NoOfParam;
10007 : 3932 : unsigned int dtype;
10008 : 3932 : unsigned int OperandSym;
10009 : 3932 : unsigned int VarSym;
10010 : 3932 : unsigned int TempSym;
10011 : :
10012 : 3932 : M2Quads_PopT (&NoOfParam);
10013 : 3932 : if ((NoOfParam == 1) || (NoOfParam == 2))
10014 : : {
10015 : 3932 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam)); /* Bottom/first parameter. */
10016 : 3932 : if (SymbolTable_IsVar (VarSym)) /* Bottom/first parameter. */
10017 : : {
10018 : 3932 : dtype = SymbolTable_GetDType (VarSym);
10019 : 3932 : if (NoOfParam == 2)
10020 : : {
10021 : 1392 : OperandSym = DereferenceLValue (proctok, M2Quads_OperandT (1));
10022 : : }
10023 : : else
10024 : : {
10025 : 2540 : PushOne (proctok, dtype, (const char *) "the {%EkDEC} will cause an overflow {%1ad}", 42);
10026 : 2540 : M2Quads_PopT (&OperandSym);
10027 : : }
10028 : 3932 : M2Quads_PushTtok (VarSym, proctok);
10029 : 3932 : TempSym = DereferenceLValue (M2Quads_OperandTok (NoOfParam), VarSym);
10030 : 3932 : CheckRangeIncDec (proctok, TempSym, OperandSym, M2Reserved_MinusTok); /* TempSym - OperandSym. */
10031 : 3932 : BuildAssignmentWithoutBounds (proctok, false, true); /* VarSym := TempSym - OperandSym. */
10032 : : }
10033 : : else
10034 : : {
10035 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "base procedure {%EkDEC} expects a variable as a parameter but was given {%1Ed}", 78, VarSym);
10036 : : }
10037 : : }
10038 : : else
10039 : : {
10040 : 0 : M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkDEC} expects 1 or 2 parameters", 53);
10041 : : }
10042 : 3932 : M2Quads_PopN (NoOfParam+1);
10043 : 3932 : }
10044 : :
10045 : :
10046 : : /*
10047 : : DereferenceLValue - checks to see whether, operand, is declare as an LValue
10048 : : and if so it dereferences it.
10049 : : */
10050 : :
10051 : 30650 : static unsigned int DereferenceLValue (unsigned int tok, unsigned int operand)
10052 : : {
10053 : 30650 : unsigned int sym;
10054 : :
10055 : 30650 : if ((SymbolTable_GetMode (operand)) == SymbolTable_LeftValue)
10056 : : {
10057 : : /* dereference the pointer */
10058 : 1492 : sym = SymbolTable_MakeTemporary (tok, AreConstant (SymbolTable_IsConst (operand)));
10059 : 746 : SymbolTable_PutVar (sym, SymbolTable_GetSType (operand));
10060 : 746 : M2Quads_PushTtok (sym, tok);
10061 : 746 : M2Quads_PushTtok (operand, tok);
10062 : 746 : BuildAssignmentWithoutBounds (tok, false, true);
10063 : 746 : return sym;
10064 : : }
10065 : : else
10066 : : {
10067 : : return operand;
10068 : : }
10069 : : /* static analysis guarentees a RETURN statement will be used before here. */
10070 : : __builtin_unreachable ();
10071 : : }
10072 : :
10073 : :
10074 : : /*
10075 : : BuildInclProcedure - builds the pseudo procedure call INCL.
10076 : : INCL is a procedure which adds bit b into a BITSET a.
10077 : : It takes two parameters:
10078 : : INCL(a, b)
10079 : :
10080 : : a := a + {b}
10081 : :
10082 : : The Stack:
10083 : :
10084 : :
10085 : : Entry Exit
10086 : :
10087 : : Ptr ->
10088 : : +----------------+
10089 : : | NoOfParam |
10090 : : |----------------|
10091 : : | Param 1 |
10092 : : |----------------|
10093 : : | Param 2 |
10094 : : |----------------|
10095 : : | ProcSym | Type | Empty
10096 : : |----------------|
10097 : : */
10098 : :
10099 : 1122 : static void BuildInclProcedure (unsigned int proctok)
10100 : : {
10101 : 1122 : unsigned int optok;
10102 : 1122 : unsigned int NoOfParam;
10103 : 1122 : unsigned int DerefSym;
10104 : 1122 : unsigned int OperandSym;
10105 : 1122 : unsigned int VarSym;
10106 : :
10107 : 1122 : M2Quads_PopT (&NoOfParam);
10108 : 1122 : if (NoOfParam == 2)
10109 : : {
10110 : 1122 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10111 : 1122 : MarkArrayWritten (M2Quads_OperandA (2));
10112 : 1122 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10113 : 1122 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10114 : 1122 : if (SymbolTable_IsVar (VarSym))
10115 : : {
10116 : 1116 : if (SymbolTable_IsSet (SymbolTable_GetDType (VarSym)))
10117 : : {
10118 : 1116 : DerefSym = DereferenceLValue (optok, OperandSym);
10119 : 1116 : BuildRange (M2Range_InitInclCheck (VarSym, DerefSym));
10120 : 1116 : GenQuadO (proctok, M2Quads_InclOp, VarSym, SymbolTable_NulSym, DerefSym, false);
10121 : : }
10122 : : else
10123 : : {
10124 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "the first parameter to {%EkINCL} must be a set variable but is {%1Ed}", 69, VarSym);
10125 : : }
10126 : : }
10127 : : else
10128 : : {
10129 : 6 : M2MetaError_MetaErrorT1 (proctok, (const char *) "base procedure {%EkINCL} expects a variable as a parameter but is {%1Ed}", 72, VarSym);
10130 : : }
10131 : : }
10132 : : else
10133 : : {
10134 : 0 : M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkINCL} expects 1 or 2 parameters", 54);
10135 : : }
10136 : 1122 : M2Quads_PopN (NoOfParam+1);
10137 : 1122 : }
10138 : :
10139 : :
10140 : : /*
10141 : : BuildExclProcedure - builds the pseudo procedure call EXCL.
10142 : : INCL is a procedure which removes bit b from SET a.
10143 : : It takes two parameters:
10144 : : EXCL(a, b)
10145 : :
10146 : : a := a - {b}
10147 : :
10148 : : The Stack:
10149 : :
10150 : :
10151 : : Entry Exit
10152 : :
10153 : : Ptr ->
10154 : : +----------------+
10155 : : | NoOfParam |
10156 : : |----------------|
10157 : : | Param 1 |
10158 : : |----------------|
10159 : : | Param 2 |
10160 : : |----------------|
10161 : : | ProcSym | Type | Empty
10162 : : |----------------|
10163 : : */
10164 : :
10165 : 770 : static void BuildExclProcedure (unsigned int proctok)
10166 : : {
10167 : 770 : unsigned int optok;
10168 : 770 : unsigned int NoOfParam;
10169 : 770 : unsigned int DerefSym;
10170 : 770 : unsigned int OperandSym;
10171 : 770 : unsigned int VarSym;
10172 : :
10173 : 770 : M2Quads_PopT (&NoOfParam);
10174 : 770 : if (NoOfParam == 2)
10175 : : {
10176 : 770 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10177 : 770 : MarkArrayWritten (M2Quads_OperandA (2));
10178 : 770 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10179 : 770 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10180 : 770 : if (SymbolTable_IsVar (VarSym))
10181 : : {
10182 : 770 : if (SymbolTable_IsSet (SymbolTable_GetDType (VarSym)))
10183 : : {
10184 : 770 : DerefSym = DereferenceLValue (optok, OperandSym);
10185 : 770 : BuildRange (M2Range_InitExclCheck (VarSym, DerefSym));
10186 : 770 : GenQuadO (proctok, M2Quads_ExclOp, VarSym, SymbolTable_NulSym, DerefSym, false);
10187 : : }
10188 : : else
10189 : : {
10190 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "the first parameter to {%EkEXCL} must be a set variable but is {%1Ed}", 69, VarSym);
10191 : : }
10192 : : }
10193 : : else
10194 : : {
10195 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "base procedure {%EkEXCL} expects a variable as a parameter but is {%1Ed}", 72, VarSym);
10196 : : }
10197 : : }
10198 : : else
10199 : : {
10200 : 0 : M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkEXCL} expects 1 or 2 parameters", 54);
10201 : : }
10202 : 770 : M2Quads_PopN (NoOfParam+1);
10203 : 770 : }
10204 : :
10205 : :
10206 : : /*
10207 : : BuildTypeCoercion - builds the type coersion.
10208 : : Modula-2 allows types to be coersed with no runtime
10209 : : penility.
10210 : : It insists that the TSIZE(t1)=TSIZE(t2) where
10211 : : t2 variable := t2(variable of type t1).
10212 : : The ReturnVar on the stack is of type t2.
10213 : :
10214 : : The Stack:
10215 : :
10216 : :
10217 : : Entry Exit
10218 : :
10219 : : Ptr ->
10220 : : +----------------+
10221 : : | NoOfParam |
10222 : : |----------------|
10223 : : | Param 1 |
10224 : : |----------------|
10225 : : | Param 2 |
10226 : : |----------------|
10227 : : . .
10228 : : . .
10229 : : . .
10230 : : |----------------|
10231 : : | Param # | <- Ptr
10232 : : |----------------| +------------+
10233 : : | ProcSym | Type | | ReturnVar |
10234 : : |----------------| |------------|
10235 : :
10236 : : Quadruples:
10237 : :
10238 : : CoerceOp ReturnVar Type Param1
10239 : :
10240 : : A type coercion will only be legal if the different
10241 : : types have exactly the same size.
10242 : : Since we can only decide this after M2Eval has processed
10243 : : the symbol table then we create a quadruple explaining
10244 : : the coercion taking place, the code generator can test
10245 : : this assertion and report an error if the type sizes
10246 : : differ.
10247 : : */
10248 : :
10249 : 2538 : static void BuildTypeCoercion (bool ConstExpr)
10250 : : {
10251 : 2538 : unsigned int resulttok;
10252 : 2538 : unsigned int proctok;
10253 : 2538 : unsigned int exptok;
10254 : 2538 : unsigned int r;
10255 : 2538 : unsigned int exp;
10256 : 2538 : unsigned int NoOfParam;
10257 : 2538 : unsigned int ReturnVar;
10258 : 2538 : unsigned int ProcSym;
10259 : :
10260 : 2538 : M2Quads_PopT (&NoOfParam);
10261 : 2538 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
10262 : 2538 : proctok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
10263 : 2538 : if (! (SymbolTable_IsAModula2Type (ProcSym)))
10264 : : {
10265 : 0 : M2MetaError_MetaError1 ((const char *) "coersion expecting a type, seen {%1Ea} which is {%1Ed}", 54, ProcSym);
10266 : : }
10267 : 2538 : if (NoOfParam == 1)
10268 : : {
10269 : 2538 : PopTrwtok (&exp, &r, &exptok);
10270 : 2538 : MarkAsRead (r);
10271 : 2538 : resulttok = M2LexBuf_MakeVirtual2Tok (proctok, exptok);
10272 : 2538 : M2Quads_PopN (1); /* Pop procedure. */
10273 : 2538 : if (ConstExprError (ProcSym, exp, exptok, ConstExpr)) /* Pop procedure. */
10274 : : {
10275 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
10276 : 0 : SymbolTable_PutVar (ReturnVar, ProcSym); /* Set ReturnVar's TYPE. */
10277 : : }
10278 : : /* Set ReturnVar's TYPE. */
10279 : 2538 : else if ((SymbolTable_IsConst (exp)) || (SymbolTable_IsVar (exp)))
10280 : : {
10281 : : /* avoid dangling else. */
10282 : 5076 : ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (SymbolTable_IsConst (exp)));
10283 : 2538 : SymbolTable_PutVar (ReturnVar, ProcSym); /* Set ReturnVar's TYPE. */
10284 : 2538 : GenQuad (M2Quads_CoerceOp, ReturnVar, ProcSym, exp); /* Set ReturnVar's TYPE. */
10285 : : }
10286 : : else
10287 : : {
10288 : : /* avoid dangling else. */
10289 : 0 : M2MetaError_MetaError2 ((const char *) "trying to coerse {%1EMRad} which is not a variable or constant into {%2ad}", 74, exp, ProcSym);
10290 : 0 : M2MetaError_MetaError2 ((const char *) "trying to coerse {%1ECad} which is not a variable or constant into {%2ad}", 73, exp, ProcSym);
10291 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_RightValue);
10292 : 0 : SymbolTable_PutVar (ReturnVar, ProcSym); /* Set ReturnVar's TYPE. */
10293 : : }
10294 : 2538 : M2Quads_PushTFtok (ReturnVar, ProcSym, resulttok);
10295 : : }
10296 : : else
10297 : : {
10298 : 0 : M2MetaError_MetaError0 ((const char *) "{%E}only one parameter expected in a TYPE coersion", 50);
10299 : : }
10300 : 2538 : }
10301 : :
10302 : :
10303 : : /*
10304 : : BuildRealFunctionCall - builds a function call.
10305 : : The Stack:
10306 : :
10307 : :
10308 : : Entry Exit
10309 : :
10310 : : Ptr ->
10311 : : +----------------+
10312 : : | NoOfParam |
10313 : : |----------------|
10314 : : | Param 1 |
10315 : : |----------------|
10316 : : | Param 2 |
10317 : : |----------------|
10318 : : . .
10319 : : . .
10320 : : . .
10321 : : |----------------|
10322 : : | Param # | <- Ptr
10323 : : |----------------| +------------+
10324 : : | ProcSym | Type | | ReturnVar |
10325 : : |----------------| |------------|
10326 : : */
10327 : :
10328 : 61740 : static void BuildRealFunctionCall (unsigned int tokno, bool ConstExpr)
10329 : : {
10330 : 61740 : unsigned int NoOfParam;
10331 : 61740 : unsigned int ProcSym;
10332 : :
10333 : 61740 : M2Quads_PopT (&NoOfParam);
10334 : 61740 : M2Quads_PushT (NoOfParam);
10335 : 61740 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+2));
10336 : 61740 : ProcSym = PCSymBuild_SkipConst (ProcSym);
10337 : 61740 : if (SymbolTable_IsVar (ProcSym))
10338 : : {
10339 : : /* Procedure Variable therefore get its type to see if it is a FOR "C" call. */
10340 : 82 : ProcSym = SymbolTable_SkipType (M2Quads_OperandF (NoOfParam+2));
10341 : : }
10342 : 61740 : if ((SymbolTable_IsDefImp (SymbolTable_GetScope (ProcSym))) && (SymbolTable_IsDefinitionForC (SymbolTable_GetScope (ProcSym))))
10343 : : {
10344 : 7342 : BuildRealFuncProcCall (tokno, true, true, ConstExpr);
10345 : : }
10346 : : else
10347 : : {
10348 : 54398 : BuildRealFuncProcCall (tokno, true, false, ConstExpr);
10349 : : }
10350 : 61728 : }
10351 : :
10352 : :
10353 : : /*
10354 : : BuildPseudoFunctionCall - builds the pseudo function
10355 : : The Stack:
10356 : :
10357 : :
10358 : : Entry Exit
10359 : :
10360 : : Ptr ->
10361 : : +----------------+
10362 : : | NoOfParam |
10363 : : |----------------|
10364 : : | Param 1 |
10365 : : |----------------|
10366 : : | Param 2 |
10367 : : |----------------|
10368 : : . .
10369 : : . .
10370 : : . .
10371 : : |----------------|
10372 : : | Param # | <- Ptr
10373 : : |----------------| +------------+
10374 : : | ProcSym | Type | | ReturnVar |
10375 : : |----------------| |------------|
10376 : :
10377 : : */
10378 : :
10379 : 42534 : static void BuildPseudoFunctionCall (bool ConstExpr)
10380 : : {
10381 : 42534 : unsigned int NoOfParam;
10382 : 42534 : unsigned int ProcSym;
10383 : :
10384 : 42534 : M2Quads_PopT (&NoOfParam);
10385 : 42534 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
10386 : 42534 : ProcSym = PCSymBuild_SkipConst (ProcSym);
10387 : 42534 : M2Quads_PushT (NoOfParam);
10388 : : /* Compile time stack restored to entry state. */
10389 : 42534 : if (ProcSym == M2Base_High)
10390 : : {
10391 : 2978 : BuildHighFunction ();
10392 : : }
10393 : 39556 : else if (ProcSym == M2Base_LengthS)
10394 : : {
10395 : : /* avoid dangling else. */
10396 : 346 : BuildLengthFunction (ProcSym, ConstExpr);
10397 : : }
10398 : 39210 : else if (ProcSym == M2System_Adr)
10399 : : {
10400 : : /* avoid dangling else. */
10401 : 9698 : BuildAdrFunction ();
10402 : : }
10403 : 29512 : else if (ProcSym == M2Size_Size)
10404 : : {
10405 : : /* avoid dangling else. */
10406 : 2050 : BuildSizeFunction ();
10407 : : }
10408 : 27462 : else if (ProcSym == M2System_TSize)
10409 : : {
10410 : : /* avoid dangling else. */
10411 : 4758 : BuildTSizeFunction ();
10412 : : }
10413 : 22704 : else if (ProcSym == M2System_TBitSize)
10414 : : {
10415 : : /* avoid dangling else. */
10416 : 6364 : BuildTBitSizeFunction ();
10417 : : }
10418 : 16340 : else if (ProcSym == M2Base_Convert)
10419 : : {
10420 : : /* avoid dangling else. */
10421 : 12 : BuildConvertFunction (ProcSym, ConstExpr);
10422 : : }
10423 : 16328 : else if (ProcSym == M2Base_Odd)
10424 : : {
10425 : : /* avoid dangling else. */
10426 : 46 : BuildOddFunction (ProcSym, ConstExpr);
10427 : : }
10428 : 16282 : else if (ProcSym == M2Base_Abs)
10429 : : {
10430 : : /* avoid dangling else. */
10431 : 176 : BuildAbsFunction (ProcSym, ConstExpr);
10432 : : }
10433 : 16106 : else if (ProcSym == M2Base_Cap)
10434 : : {
10435 : : /* avoid dangling else. */
10436 : 124 : BuildCapFunction (ProcSym, ConstExpr);
10437 : : }
10438 : 15982 : else if (ProcSym == M2Base_Val)
10439 : : {
10440 : : /* avoid dangling else. */
10441 : 4896 : BuildValFunction (ProcSym, ConstExpr);
10442 : : }
10443 : 11086 : else if (ProcSym == M2Base_Chr)
10444 : : {
10445 : : /* avoid dangling else. */
10446 : 1022 : BuildChrFunction (ProcSym, ConstExpr);
10447 : : }
10448 : 10064 : else if (M2Base_IsOrd (ProcSym))
10449 : : {
10450 : : /* avoid dangling else. */
10451 : 4724 : BuildOrdFunction (ProcSym, ConstExpr);
10452 : : }
10453 : 5340 : else if (M2Base_IsInt (ProcSym))
10454 : : {
10455 : : /* avoid dangling else. */
10456 : 6 : BuildIntFunction (ProcSym, ConstExpr);
10457 : : }
10458 : 5334 : else if (M2Base_IsTrunc (ProcSym))
10459 : : {
10460 : : /* avoid dangling else. */
10461 : 60 : BuildTruncFunction (ProcSym, ConstExpr);
10462 : : }
10463 : 5274 : else if (M2Base_IsFloat (ProcSym))
10464 : : {
10465 : : /* avoid dangling else. */
10466 : 88 : BuildFloatFunction (ProcSym, ConstExpr);
10467 : : }
10468 : 5186 : else if (ProcSym == M2Base_Min)
10469 : : {
10470 : : /* avoid dangling else. */
10471 : 1226 : BuildMinFunction ();
10472 : : }
10473 : 3960 : else if (ProcSym == M2Base_Max)
10474 : : {
10475 : : /* avoid dangling else. */
10476 : 2032 : BuildMaxFunction ();
10477 : : }
10478 : 1928 : else if (ProcSym == M2System_AddAdr)
10479 : : {
10480 : : /* avoid dangling else. */
10481 : 36 : BuildAddAdrFunction (ProcSym, ConstExpr);
10482 : : }
10483 : 1892 : else if (ProcSym == M2System_SubAdr)
10484 : : {
10485 : : /* avoid dangling else. */
10486 : 12 : BuildSubAdrFunction (ProcSym, ConstExpr);
10487 : : }
10488 : 1880 : else if (ProcSym == M2System_DifAdr)
10489 : : {
10490 : : /* avoid dangling else. */
10491 : 12 : BuildDifAdrFunction (ProcSym, ConstExpr);
10492 : : }
10493 : 1868 : else if (ProcSym == M2System_Cast)
10494 : : {
10495 : : /* avoid dangling else. */
10496 : 156 : BuildCastFunction (ProcSym, ConstExpr);
10497 : : }
10498 : 1712 : else if (ProcSym == M2System_Shift)
10499 : : {
10500 : : /* avoid dangling else. */
10501 : 682 : BuildShiftFunction ();
10502 : : }
10503 : 1030 : else if (ProcSym == M2System_Rotate)
10504 : : {
10505 : : /* avoid dangling else. */
10506 : 406 : BuildRotateFunction ();
10507 : : }
10508 : 624 : else if (ProcSym == M2System_MakeAdr)
10509 : : {
10510 : : /* avoid dangling else. */
10511 : 12 : BuildMakeAdrFunction ();
10512 : : }
10513 : 612 : else if (ProcSym == M2Base_Re)
10514 : : {
10515 : : /* avoid dangling else. */
10516 : 60 : BuildReFunction (ProcSym, ConstExpr);
10517 : : }
10518 : 552 : else if (ProcSym == M2Base_Im)
10519 : : {
10520 : : /* avoid dangling else. */
10521 : 60 : BuildImFunction (ProcSym, ConstExpr);
10522 : : }
10523 : 492 : else if (ProcSym == M2Base_Cmplx)
10524 : : {
10525 : : /* avoid dangling else. */
10526 : 492 : BuildCmplxFunction (ProcSym, ConstExpr);
10527 : : }
10528 : : else
10529 : : {
10530 : : /* avoid dangling else. */
10531 : 0 : M2Error_InternalError ((const char *) "pseudo function not implemented yet", 35);
10532 : : }
10533 : 42522 : }
10534 : :
10535 : :
10536 : : /*
10537 : : BuildAddAdrFunction - builds the pseudo procedure call ADDADR.
10538 : :
10539 : : PROCEDURE ADDADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
10540 : :
10541 : : Which returns address given by (addr + offset),
10542 : : [ the standard says that it _may_
10543 : : "raise an exception if this address is not valid."
10544 : : currently we do not generate any exception code ]
10545 : :
10546 : : The Stack:
10547 : :
10548 : : Entry Exit
10549 : :
10550 : : Ptr ->
10551 : : +----------------+
10552 : : | NoOfParam |
10553 : : |----------------|
10554 : : | Param 1 |
10555 : : |----------------|
10556 : : | Param 2 | <- Ptr
10557 : : |----------------| +------------+
10558 : : | ProcSym | Type | | ReturnVar |
10559 : : |----------------| |------------|
10560 : : */
10561 : :
10562 : 36 : static void BuildAddAdrFunction (unsigned int ProcSym, bool ConstExpr)
10563 : : {
10564 : 36 : unsigned int combinedtok;
10565 : 36 : unsigned int functok;
10566 : 36 : unsigned int vartok;
10567 : 36 : unsigned int optok;
10568 : 36 : unsigned int opa;
10569 : 36 : unsigned int ReturnVar;
10570 : 36 : unsigned int NoOfParam;
10571 : 36 : unsigned int OperandSym;
10572 : 36 : unsigned int VarSym;
10573 : :
10574 : 36 : M2Quads_PopT (&NoOfParam);
10575 : 36 : functok = OperandTtok (NoOfParam+1);
10576 : 36 : if (NoOfParam == 2)
10577 : : {
10578 : 36 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10579 : 36 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
10580 : 36 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10581 : 36 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10582 : 36 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
10583 : 36 : M2Quads_PopN (NoOfParam+1);
10584 : 36 : if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
10585 : : {
10586 : : /* Fake return result. */
10587 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10588 : : }
10589 : 36 : else if (SymbolTable_IsVar (VarSym))
10590 : : {
10591 : : /* avoid dangling else. */
10592 : 36 : if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
10593 : : {
10594 : 36 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
10595 : 36 : SymbolTable_PutVar (ReturnVar, M2System_Address);
10596 : 36 : opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
10597 : 72 : GenQuadOtok (combinedtok, M2Quads_AddOp, ReturnVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
10598 : 36 : M2Quads_PushTFtok (ReturnVar, M2System_Address, combinedtok);
10599 : : }
10600 : : else
10601 : : {
10602 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the first parameter to ADDADR {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsdv}", 114, VarSym);
10603 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10604 : : }
10605 : : }
10606 : : else
10607 : : {
10608 : : /* avoid dangling else. */
10609 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure ADDADR expects a variable of type ADDRESS or POINTER as its first parameter", 96);
10610 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10611 : : }
10612 : : }
10613 : : else
10614 : : {
10615 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure {%EkADDADR} expects 2 parameters", 53);
10616 : 0 : M2Quads_PopN (NoOfParam+1);
10617 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, functok);
10618 : : }
10619 : 36 : }
10620 : :
10621 : :
10622 : : /*
10623 : : BuildSubAdrFunction - builds the pseudo procedure call ADDADR.
10624 : :
10625 : : PROCEDURE SUBADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
10626 : :
10627 : : Which returns address given by (addr - offset),
10628 : : [ the standard says that it _may_
10629 : : "raise an exception if this address is not valid."
10630 : : currently we do not generate any exception code ]
10631 : :
10632 : : The Stack:
10633 : :
10634 : : Entry Exit
10635 : :
10636 : : Ptr ->
10637 : : +----------------+
10638 : : | NoOfParam |
10639 : : |----------------|
10640 : : | Param 1 |
10641 : : |----------------|
10642 : : | Param 2 | <- Ptr
10643 : : |----------------| +------------+
10644 : : | ProcSym | Type | | ReturnVar |
10645 : : |----------------| |------------|
10646 : : */
10647 : :
10648 : 12 : static void BuildSubAdrFunction (unsigned int ProcSym, bool ConstExpr)
10649 : : {
10650 : 12 : unsigned int functok;
10651 : 12 : unsigned int combinedtok;
10652 : 12 : unsigned int optok;
10653 : 12 : unsigned int vartok;
10654 : 12 : unsigned int ReturnVar;
10655 : 12 : unsigned int NoOfParam;
10656 : 12 : unsigned int OperandSym;
10657 : 12 : unsigned int opa;
10658 : 12 : unsigned int VarSym;
10659 : :
10660 : 12 : M2Quads_PopT (&NoOfParam);
10661 : 12 : functok = OperandTtok (NoOfParam+1);
10662 : 12 : if (NoOfParam == 2)
10663 : : {
10664 : 12 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10665 : 12 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10666 : 12 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10667 : 12 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
10668 : 12 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
10669 : 12 : M2Quads_PopN (NoOfParam+1);
10670 : 12 : if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
10671 : : {
10672 : : /* Fake return result. */
10673 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10674 : : }
10675 : 12 : else if (SymbolTable_IsVar (VarSym))
10676 : : {
10677 : : /* avoid dangling else. */
10678 : 12 : if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
10679 : : {
10680 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
10681 : 12 : SymbolTable_PutVar (ReturnVar, M2System_Address);
10682 : 12 : opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
10683 : 24 : GenQuadOtok (combinedtok, M2Quads_SubOp, ReturnVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
10684 : 12 : M2Quads_PushTFtok (ReturnVar, M2System_Address, combinedtok);
10685 : : }
10686 : : else
10687 : : {
10688 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the first parameter to {%EkSUBADR} {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsdv}", 119, VarSym);
10689 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (vartok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, vartok);
10690 : : }
10691 : : }
10692 : : else
10693 : : {
10694 : : /* avoid dangling else. */
10695 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
10696 : 0 : M2MetaError_MetaErrorT0 (combinedtok, (const char *) "{%E}SYSTEM procedure {%EkSUBADR} expects a variable of type ADDRESS or POINTER as its first parameter", 101);
10697 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10698 : : }
10699 : : }
10700 : : else
10701 : : {
10702 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure {%EkSUBADR} expects 2 parameters", 53);
10703 : 0 : M2Quads_PopN (NoOfParam+1);
10704 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, functok);
10705 : : }
10706 : 12 : }
10707 : :
10708 : :
10709 : : /*
10710 : : BuildDifAdrFunction - builds the pseudo procedure call DIFADR.
10711 : :
10712 : : PROCEDURE DIFADR (addr1, addr2: ADDRESS): INTEGER ;
10713 : :
10714 : : Which returns address given by (addr1 - addr2),
10715 : : [ the standard says that it _may_
10716 : : "raise an exception if this address is invalid or
10717 : : address space is non-contiguous."
10718 : : currently we do not generate any exception code ]
10719 : :
10720 : : The Stack:
10721 : :
10722 : : Entry Exit
10723 : :
10724 : : Ptr ->
10725 : : +----------------+
10726 : : | NoOfParam |
10727 : : |----------------|
10728 : : | Param 1 |
10729 : : |----------------|
10730 : : | Param 2 | <- Ptr
10731 : : |----------------| +------------+
10732 : : | ProcSym | Type | | ReturnVar |
10733 : : |----------------| |------------|
10734 : : */
10735 : :
10736 : 12 : static void BuildDifAdrFunction (unsigned int ProcSym, bool ConstExpr)
10737 : : {
10738 : 12 : unsigned int functok;
10739 : 12 : unsigned int optok;
10740 : 12 : unsigned int vartok;
10741 : 12 : unsigned int combinedtok;
10742 : 12 : unsigned int TempVar;
10743 : 12 : unsigned int NoOfParam;
10744 : 12 : unsigned int OperandSym;
10745 : 12 : unsigned int opa;
10746 : 12 : unsigned int VarSym;
10747 : :
10748 : 12 : M2Quads_PopT (&NoOfParam);
10749 : 12 : functok = OperandTtok (NoOfParam+1);
10750 : 12 : if (NoOfParam >= 1)
10751 : : {
10752 : 12 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10753 : 12 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10754 : : }
10755 : : else
10756 : : {
10757 : : optok = functok;
10758 : : }
10759 : 12 : if (NoOfParam == 2)
10760 : : {
10761 : 12 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10762 : 12 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
10763 : 12 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
10764 : 12 : M2Quads_PopN (NoOfParam+1);
10765 : 12 : if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
10766 : : {
10767 : : /* Fake return result. */
10768 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10769 : : }
10770 : 12 : else if (SymbolTable_IsVar (VarSym))
10771 : : {
10772 : : /* avoid dangling else. */
10773 : 12 : if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
10774 : : {
10775 : 12 : if ((IsReallyPointer (OperandSym)) || ((SymbolTable_GetSType (OperandSym)) == M2System_Address))
10776 : : {
10777 : 12 : TempVar = SymbolTable_MakeTemporary (vartok, SymbolTable_RightValue);
10778 : 12 : SymbolTable_PutVar (TempVar, M2System_Address);
10779 : 12 : opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
10780 : 24 : GenQuadOtok (combinedtok, M2Quads_SubOp, TempVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
10781 : : /*
10782 : : Build macro: CONVERT( INTEGER, TempVar )
10783 : : */
10784 : 12 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
10785 : 12 : M2Quads_PushTtok (M2Base_Integer, functok);
10786 : 12 : M2Quads_PushTtok (TempVar, vartok);
10787 : 12 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
10788 : 12 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* Two parameters */
10789 : : }
10790 : : else
10791 : : {
10792 : 0 : M2MetaError_MetaError1 ((const char *) "the second parameter to {%EkDIFADR} {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsdv}", 120, OperandSym);
10793 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10794 : : }
10795 : : }
10796 : : else
10797 : : {
10798 : 0 : M2MetaError_MetaErrorT1 (vartok, (const char *) "the first parameter to {%EkDIFADR} {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsdv}", 119, VarSym);
10799 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10800 : : }
10801 : : }
10802 : : else
10803 : : {
10804 : : /* avoid dangling else. */
10805 : 0 : M2MetaError_MetaError0 ((const char *) "{%E}SYSTEM procedure {%EkDIFADR} expects a variable of type ADDRESS or POINTER as its first parameter", 101);
10806 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10807 : : }
10808 : : }
10809 : : else
10810 : : {
10811 : 0 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
10812 : 0 : M2MetaError_MetaErrorT0 (combinedtok, (const char *) "{%E}SYSTEM procedure {%EkDIFADR} expects 2 parameters", 53);
10813 : 0 : M2Quads_PopN (NoOfParam+1);
10814 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10815 : : }
10816 : 12 : }
10817 : :
10818 : :
10819 : : /*
10820 : : BuildHighFunction - checks the stack in preparation for generating
10821 : : quadruples which perform HIGH.
10822 : : This procedure does not alter the stack but
10823 : : determines whether, a, in HIGH(a) is an ArraySym
10824 : : or UnboundedSym.
10825 : : Both cases are different and appropriate quadruple
10826 : : generating routines are called.
10827 : :
10828 : : The Stack:
10829 : :
10830 : :
10831 : : Entry Exit
10832 : :
10833 : : Ptr ->
10834 : : +----------------+
10835 : : | NoOfParam |
10836 : : |----------------|
10837 : : | Param 1 |
10838 : : |----------------|
10839 : : | Param 2 |
10840 : : |----------------|
10841 : : . .
10842 : : . .
10843 : : . .
10844 : : |----------------|
10845 : : | Param # | <- Ptr
10846 : : |----------------| +------------+
10847 : : | ProcSym | Type | | ReturnVar |
10848 : : |----------------| |------------|
10849 : :
10850 : : */
10851 : :
10852 : 2978 : static void BuildHighFunction (void)
10853 : : {
10854 : 2978 : unsigned int functok;
10855 : 2978 : unsigned int combinedtok;
10856 : 2978 : unsigned int paramtok;
10857 : 2978 : unsigned int ProcSym;
10858 : 2978 : unsigned int Type;
10859 : 2978 : unsigned int NoOfParam;
10860 : 2978 : unsigned int Param;
10861 : :
10862 : 2978 : M2Quads_PopT (&NoOfParam);
10863 : 2978 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
10864 : 2978 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
10865 : 2978 : BuildSizeCheckEnd (ProcSym); /* quadruple generation now on */
10866 : 2978 : if (NoOfParam == 1) /* quadruple generation now on */
10867 : : {
10868 : 2978 : Param = static_cast<unsigned int> (M2Quads_OperandT (1));
10869 : 2978 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10870 : 2978 : combinedtok = M2LexBuf_MakeVirtualTok (paramtok, functok, paramtok);
10871 : 2978 : Type = SymbolTable_GetDType (Param);
10872 : : /* Restore stack to original form */
10873 : 2978 : M2Quads_PushT (NoOfParam);
10874 : 2978 : if (((! (SymbolTable_IsVar (Param))) && (! (SymbolTable_IsConstString (Param)))) && (! (SymbolTable_IsConst (Param))))
10875 : : {
10876 : : /* we cannot test for IsConst(Param) AND (GetSType(Param)=Char) as the type might not be assigned yet */
10877 : 0 : M2MetaError_MetaError1 ((const char *) "base procedure {%EkHIGH} expects a variable or string constant as its parameter {%1d:rather than {%1d}} {%1asa}", 111, Param);
10878 : : }
10879 : 2978 : else if ((Type != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (Type)))
10880 : : {
10881 : : /* avoid dangling else. */
10882 : 2744 : BuildHighFromUnbounded (combinedtok);
10883 : : }
10884 : : else
10885 : : {
10886 : : /* avoid dangling else. */
10887 : 234 : BuildConstHighFromSym (combinedtok);
10888 : : }
10889 : : }
10890 : : else
10891 : : {
10892 : 0 : M2MetaError_MetaError0 ((const char *) "base procedure {%EkHIGH} requires one parameter", 47);
10893 : 0 : M2Quads_PopN (2);
10894 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
10895 : : }
10896 : 2978 : }
10897 : :
10898 : :
10899 : : /*
10900 : : BuildConstHighFromSym - builds the pseudo function HIGH from an Sym.
10901 : : Sym is a constant or an array which has constant bounds
10902 : : and therefore it can be calculated at compile time.
10903 : :
10904 : : The Stack:
10905 : :
10906 : :
10907 : : Entry Exit
10908 : :
10909 : : Ptr ->
10910 : : +----------------+
10911 : : | NoOfParam |
10912 : : |----------------|
10913 : : | Param 1 |
10914 : : |----------------|
10915 : : | Param 2 |
10916 : : |----------------|
10917 : : . .
10918 : : . .
10919 : : . .
10920 : : |----------------|
10921 : : | Param # | <- Ptr
10922 : : |----------------| +------------+
10923 : : | ProcSym | Type | | ReturnVar |
10924 : : |----------------| |------------|
10925 : : */
10926 : :
10927 : 234 : static void BuildConstHighFromSym (unsigned int tok)
10928 : : {
10929 : 234 : unsigned int NoOfParam;
10930 : 234 : unsigned int ReturnVar;
10931 : :
10932 : 234 : M2Quads_PopT (&NoOfParam);
10933 : 234 : ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
10934 : 234 : SymbolTable_PutConst (ReturnVar, M2Base_Cardinal);
10935 : 234 : GenHigh (tok, ReturnVar, 1, M2Quads_OperandT (1));
10936 : 234 : M2Quads_PopN (NoOfParam+1);
10937 : 234 : M2Quads_PushTtok (ReturnVar, tok);
10938 : 234 : }
10939 : :
10940 : :
10941 : : /*
10942 : : BuildHighFromUnbounded - builds the pseudo function HIGH from an
10943 : : UnboundedSym.
10944 : :
10945 : : The Stack:
10946 : :
10947 : :
10948 : : Entry Exit
10949 : :
10950 : : Ptr ->
10951 : : +----------------+
10952 : : | NoOfParam |
10953 : : |----------------|
10954 : : | Param # | <- Ptr
10955 : : |----------------| +------------+
10956 : : | ProcSym | Type | | ReturnVar |
10957 : : |----------------| |------------|
10958 : :
10959 : : */
10960 : :
10961 : 2744 : static void BuildHighFromUnbounded (unsigned int tok)
10962 : : {
10963 : 2744 : unsigned int Dim;
10964 : 2744 : unsigned int NoOfParam;
10965 : 2744 : unsigned int ReturnVar;
10966 : :
10967 : 2744 : M2Quads_PopT (&NoOfParam);
10968 : 2744 : M2Debug_Assert (NoOfParam == 1);
10969 : 2744 : ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
10970 : 2744 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
10971 : 2744 : Dim = static_cast<unsigned int> (OperandD (1));
10972 : 2744 : Dim += 1;
10973 : 2744 : if (Dim > 1)
10974 : : {
10975 : 36 : GenHigh (tok, ReturnVar, Dim, M2Quads_OperandA (1));
10976 : : }
10977 : : else
10978 : : {
10979 : 2708 : GenHigh (tok, ReturnVar, Dim, M2Quads_OperandT (1));
10980 : : }
10981 : 2744 : M2Quads_PopN (2);
10982 : 2744 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), tok);
10983 : 2744 : }
10984 : :
10985 : :
10986 : : /*
10987 : : GetQualidentImport - returns the symbol as if it were qualified from, module.n.
10988 : : This is used to reference runtime support procedures and an
10989 : : error is generated if the symbol cannot be obtained.
10990 : : */
10991 : :
10992 : 46746 : static unsigned int GetQualidentImport (unsigned int tokno, NameKey_Name n, NameKey_Name module)
10993 : : {
10994 : 46746 : unsigned int sym;
10995 : 46746 : unsigned int ModSym;
10996 : :
10997 : 46746 : ModSym = M2Batch_MakeDefinitionSource (tokno, module);
10998 : 46746 : if (ModSym == SymbolTable_NulSym)
10999 : : {
11000 : 0 : M2MetaError_MetaErrorNT2 (tokno, (const char *) "module %a cannot be found and is needed to import %a", 52, module, n);
11001 : 0 : M2Error_FlushErrors ();
11002 : 0 : return SymbolTable_NulSym;
11003 : : }
11004 : 46746 : M2Debug_Assert (SymbolTable_IsDefImp (ModSym));
11005 : 46746 : if (((SymbolTable_GetExported (tokno, ModSym, n)) == SymbolTable_NulSym) || (SymbolTable_IsUnknown (SymbolTable_GetExported (tokno, ModSym, n))))
11006 : : {
11007 : 0 : sym = SymbolTable_GetExported (tokno, ModSym, n);
11008 : 0 : if (SymbolTable_IsUnknown (sym))
11009 : : {
11010 : : /* Spellcheck. */
11011 : 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);
11012 : 0 : M2MetaError_MetaErrorT1 (tokno, (const char *) "unknown symbol {%1&s}", 21, sym);
11013 : 0 : SymbolTable_UnknownReported (sym);
11014 : : }
11015 : : else
11016 : : {
11017 : 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);
11018 : : }
11019 : 0 : M2Error_FlushErrors ();
11020 : 0 : return SymbolTable_NulSym;
11021 : : }
11022 : 46746 : return SymbolTable_GetExported (tokno, M2Batch_MakeDefinitionSource (tokno, module), n);
11023 : : /* static analysis guarentees a RETURN statement will be used before here. */
11024 : : __builtin_unreachable ();
11025 : : }
11026 : :
11027 : :
11028 : : /*
11029 : : ConstExprError - return TRUE if a constant expression is being built and Var is a variable.
11030 : : */
11031 : :
11032 : 71592 : static bool ConstExprError (unsigned int Func, unsigned int Var, unsigned int optok, bool ConstExpr)
11033 : : {
11034 : 71592 : if (ConstExpr && (SymbolTable_IsVar (Var)))
11035 : : {
11036 : 108 : M2MetaError_MetaErrorT2 (optok, (const char *) "the procedure function {%1Ea} is being called from within a constant expression and therefore the parameter {%2a} must be a constant, seen a {%2dav}", 148, Func, Var);
11037 : 108 : return true;
11038 : : }
11039 : : else
11040 : : {
11041 : 71484 : return false;
11042 : : }
11043 : : /* static analysis guarentees a RETURN statement will be used before here. */
11044 : : __builtin_unreachable ();
11045 : : }
11046 : :
11047 : :
11048 : : /*
11049 : : DeferMakeLengthConst - creates a constant which contains the length of string, sym.
11050 : : */
11051 : :
11052 : 66 : static unsigned int DeferMakeLengthConst (unsigned int tok, unsigned int sym)
11053 : : {
11054 : 66 : unsigned int const_;
11055 : :
11056 : 66 : const_ = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
11057 : 66 : SymbolTable_PutVar (const_, M2Base_ZType);
11058 : 132 : GenQuadO (tok, M2Quads_StringLengthOp, const_, 0, sym, false);
11059 : 66 : return const_;
11060 : : /* static analysis guarentees a RETURN statement will be used before here. */
11061 : : __builtin_unreachable ();
11062 : : }
11063 : :
11064 : :
11065 : : /*
11066 : : BuildLengthFunction - builds the inline standard function LENGTH.
11067 : :
11068 : : The Stack:
11069 : :
11070 : :
11071 : : Entry Exit
11072 : :
11073 : : Ptr ->
11074 : : +----------------+
11075 : : | NoOfParam |
11076 : : |----------------|
11077 : : | Param 1 | <- Ptr
11078 : : |----------------| +------------+
11079 : : | ProcSym | Type | | ReturnVar |
11080 : : |----------------| |------------|
11081 : :
11082 : : */
11083 : :
11084 : 346 : static void BuildLengthFunction (unsigned int Function, bool ConstExpr)
11085 : : {
11086 : 346 : unsigned int combinedtok;
11087 : 346 : unsigned int paramtok;
11088 : 346 : unsigned int functok;
11089 : 346 : unsigned int ProcSym;
11090 : 346 : unsigned int Type;
11091 : 346 : unsigned int NoOfParam;
11092 : 346 : unsigned int Param;
11093 : 346 : unsigned int ReturnVar;
11094 : :
11095 : 346 : M2Quads_PopT (&NoOfParam);
11096 : 346 : Param = static_cast<unsigned int> (M2Quads_OperandT (1));
11097 : 346 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11098 : 346 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11099 : : /* Restore stack to origional form. */
11100 : 346 : M2Quads_PushT (NoOfParam);
11101 : 346 : Type = SymbolTable_GetSType (Param); /* Get the type from the symbol, not the stack. */
11102 : 346 : if (NoOfParam != 1) /* Get the type from the symbol, not the stack. */
11103 : : {
11104 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "base procedure {%1EkLENGTH} expects 1 parameter, seen {%1n} parameters", 70, NoOfParam);
11105 : : }
11106 : 346 : if (NoOfParam >= 1)
11107 : : {
11108 : 346 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, paramtok);
11109 : 346 : if ((SymbolTable_IsConst (Param)) && ((SymbolTable_GetSType (Param)) == M2Base_Char))
11110 : : {
11111 : 6 : M2Quads_PopT (&NoOfParam);
11112 : 6 : M2Quads_PopN (NoOfParam+1);
11113 : 6 : ReturnVar = SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal);
11114 : 6 : M2Quads_PushTtok (ReturnVar, combinedtok);
11115 : : }
11116 : 340 : else if (SymbolTable_IsConstString (Param))
11117 : : {
11118 : : /* avoid dangling else. */
11119 : 48 : M2Quads_PopT (&NoOfParam);
11120 : 48 : ReturnVar = DeferMakeLengthConst (combinedtok, M2Quads_OperandT (1));
11121 : 48 : M2Quads_PopN (NoOfParam+1);
11122 : 48 : M2Quads_PushTtok (ReturnVar, combinedtok);
11123 : : }
11124 : : else
11125 : : {
11126 : : /* avoid dangling else. */
11127 : 292 : ProcSym = GetQualidentImport (functok, NameKey_MakeKey ((const char *) "Length", 6), NameKey_MakeKey ((const char *) "M2RTS", 5));
11128 : 292 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
11129 : : {
11130 : 292 : M2Quads_PopT (&NoOfParam);
11131 : 292 : if (SymbolTable_IsConst (Param))
11132 : : {
11133 : : /* This can be folded in M2GenGCC. */
11134 : 0 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_ImmediateValue);
11135 : 0 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
11136 : 0 : GenQuad (M2Quads_StandardFunctionOp, ReturnVar, ProcSym, Param);
11137 : 0 : M2Quads_PopN (NoOfParam+1);
11138 : 0 : M2Quads_PushTtok (ReturnVar, combinedtok);
11139 : : }
11140 : 292 : else if (ConstExprError (Function, Param, paramtok, ConstExpr))
11141 : : {
11142 : : /* avoid dangling else. */
11143 : : /* Fake a result as we have detected and reported an error. */
11144 : 6 : M2Quads_PopN (NoOfParam+1);
11145 : 6 : ReturnVar = SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal);
11146 : 6 : M2Quads_PushTtok (ReturnVar, combinedtok);
11147 : : }
11148 : : else
11149 : : {
11150 : : /* avoid dangling else. */
11151 : : /* We must resolve this at runtime or in the GCC optimizer. */
11152 : 286 : M2Quads_PopTF (&Param, &Type);
11153 : 286 : M2Quads_PopN (NoOfParam);
11154 : 286 : M2Quads_PushTtok (ProcSym, functok);
11155 : 286 : M2Quads_PushTFtok (Param, Type, paramtok);
11156 : 286 : M2Quads_PushT (NoOfParam);
11157 : 286 : BuildRealFunctionCall (functok, false);
11158 : : }
11159 : : }
11160 : : else
11161 : : {
11162 : 0 : M2Quads_PopT (&NoOfParam);
11163 : 0 : M2Quads_PopN (NoOfParam+1);
11164 : 0 : M2Quads_PushTtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), combinedtok);
11165 : 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);
11166 : : }
11167 : : }
11168 : : }
11169 : : else
11170 : : {
11171 : : /* NoOfParam is _very_ wrong, we flush all outstanding errors */
11172 : 0 : M2Error_FlushErrors ();
11173 : : }
11174 : 346 : }
11175 : :
11176 : :
11177 : : /*
11178 : : BuildOddFunction - builds the pseudo procedure call ODD.
11179 : : This procedure is actually a "macro" for
11180 : : ORD(x) --> VAL(BOOLEAN, x MOD 2)
11181 : : However we cannot push tokens back onto the input stack
11182 : : because the compiler is currently building a function
11183 : : call and expecting a ReturnVar on the stack.
11184 : : Hence we manipulate the stack and call
11185 : : BuildConvertFunction.
11186 : :
11187 : : The Stack:
11188 : :
11189 : :
11190 : : Entry Exit
11191 : :
11192 : : Ptr ->
11193 : : +----------------+
11194 : : | NoOfParam |
11195 : : |----------------|
11196 : : | Param 1 |
11197 : : |----------------|
11198 : : | Param 2 |
11199 : : |----------------|
11200 : : . .
11201 : : . .
11202 : : . .
11203 : : |----------------|
11204 : : | Param # |
11205 : : |----------------|
11206 : : | ProcSym | Type | Empty
11207 : : |----------------|
11208 : : */
11209 : :
11210 : 46 : static void BuildOddFunction (unsigned int ProcSym, bool ConstExpr)
11211 : : {
11212 : 46 : unsigned int combinedtok;
11213 : 46 : unsigned int optok;
11214 : 46 : unsigned int functok;
11215 : 46 : unsigned int NoOfParam;
11216 : 46 : unsigned int Res;
11217 : 46 : unsigned int Var;
11218 : :
11219 : 46 : M2Quads_PopT (&NoOfParam);
11220 : 46 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11221 : 46 : if (NoOfParam == 1)
11222 : : {
11223 : 46 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11224 : 46 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11225 : 46 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
11226 : 46 : if (ConstExprError (ProcSym, Var, optok, ConstExpr))
11227 : : {
11228 : : /* Nothing to do. */
11229 : 6 : M2Quads_PushTtok (M2Base_False, combinedtok);
11230 : : }
11231 : 40 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11232 : : {
11233 : : /* avoid dangling else. */
11234 : 40 : M2Quads_PopN (NoOfParam+1);
11235 : : /* compute (x MOD 2) */
11236 : 40 : M2Quads_PushTFtok (Var, SymbolTable_GetSType (Var), optok);
11237 : 40 : M2Quads_PushT (M2Reserved_ModTok);
11238 : 40 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (optok, NameKey_MakeKey ((const char *) "2", 1), M2Base_ZType), M2Base_ZType, optok);
11239 : 40 : M2Quads_BuildBinaryOp ();
11240 : 40 : M2Quads_PopT (&Res);
11241 : : /* compute IF ...=0 */
11242 : 40 : M2Quads_PushTtok (Res, optok);
11243 : 40 : M2Quads_PushT (M2Reserved_EqualTok);
11244 : 40 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (optok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType), M2Base_ZType, optok);
11245 : 40 : M2Quads_BuildRelOp (combinedtok);
11246 : 40 : M2Quads_BuildThenIf ();
11247 : 40 : Res = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
11248 : 40 : SymbolTable_PutVar (Res, M2Base_Boolean);
11249 : 40 : M2Quads_PushTtok (Res, combinedtok);
11250 : 40 : M2Quads_PushTtok (M2Base_False, combinedtok);
11251 : 40 : M2Quads_BuildAssignment (combinedtok);
11252 : 40 : M2Quads_BuildElse ();
11253 : 40 : M2Quads_PushTtok (Res, combinedtok);
11254 : 40 : M2Quads_PushTtok (M2Base_True, combinedtok);
11255 : 40 : M2Quads_BuildAssignment (combinedtok);
11256 : 40 : M2Quads_BuildEndIf ();
11257 : 40 : M2Quads_PushTtok (Res, combinedtok);
11258 : : }
11259 : : else
11260 : : {
11261 : : /* avoid dangling else. */
11262 : 0 : M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%1EkODD} must be a variable or constant, seen {%1ad}", 70, Var);
11263 : 0 : M2Quads_PushTtok (M2Base_False, combinedtok);
11264 : : }
11265 : : }
11266 : : else
11267 : : {
11268 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%E1kODD} only has one parameter, seen {%1n} parameters", 76, NoOfParam);
11269 : 0 : M2Quads_PushTtok (M2Base_False, functok);
11270 : : }
11271 : 46 : }
11272 : :
11273 : :
11274 : : /*
11275 : : BuildAbsFunction - builds a call to the standard function ABS.
11276 : :
11277 : : We cannot implement it as a macro or inline an
11278 : : IF THEN statement as the IF THEN ELSE requires
11279 : : we write the value to the same variable (or constant)
11280 : : twice. The macro implementation will fail as
11281 : : the compiler maybe building a function
11282 : : call and expecting a ReturnVar on the stack.
11283 : : The only method to implement this is to pass it to the
11284 : : gcc backend.
11285 : :
11286 : : The Stack:
11287 : :
11288 : :
11289 : : Entry Exit
11290 : :
11291 : : Ptr ->
11292 : : +----------------+
11293 : : | NoOfParam |
11294 : : |----------------|
11295 : : | Param 1 |
11296 : : |----------------|
11297 : : | Param 2 |
11298 : : |----------------|
11299 : : . .
11300 : : . .
11301 : : . .
11302 : : |----------------|
11303 : : | Param # |
11304 : : |----------------|
11305 : : | ProcSym | Type | Empty
11306 : : |----------------|
11307 : : */
11308 : :
11309 : 176 : static void BuildAbsFunction (unsigned int ProcSym, bool ConstExpr)
11310 : : {
11311 : 176 : unsigned int vartok;
11312 : 176 : unsigned int functok;
11313 : 176 : unsigned int combinedtok;
11314 : 176 : unsigned int NoOfParam;
11315 : 176 : unsigned int Res;
11316 : 176 : unsigned int Var;
11317 : :
11318 : 176 : M2Quads_PopT (&NoOfParam);
11319 : 176 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11320 : 176 : if (NoOfParam == 1)
11321 : : {
11322 : 176 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11323 : 176 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11324 : 176 : M2Quads_PopN (NoOfParam+1);
11325 : 176 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
11326 : 176 : if (ConstExprError (ProcSym, Var, vartok, ConstExpr))
11327 : : {
11328 : : /* Create fake result. */
11329 : 24 : Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11330 : 12 : SymbolTable_PutVar (Res, SymbolTable_GetSType (Var));
11331 : 12 : M2Quads_PushTFtok (Res, SymbolTable_GetSType (Var), combinedtok);
11332 : : }
11333 : 164 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11334 : : {
11335 : : /* avoid dangling else. */
11336 : 316 : Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11337 : 158 : SymbolTable_PutVar (Res, SymbolTable_GetSType (Var));
11338 : 316 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, Res, ProcSym, Var, false);
11339 : 158 : M2Quads_PushTFtok (Res, SymbolTable_GetSType (Var), combinedtok);
11340 : : }
11341 : : else
11342 : : {
11343 : : /* avoid dangling else. */
11344 : 6 : M2MetaError_MetaErrorT1 (vartok, (const char *) "the parameter to {%AkABS} must be a variable or constant, seen {%1ad}", 69, Var);
11345 : : }
11346 : : }
11347 : : else
11348 : : {
11349 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkABS} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
11350 : : }
11351 : 170 : }
11352 : :
11353 : :
11354 : : /*
11355 : : BuildCapFunction - builds the pseudo procedure call CAP.
11356 : : We generate a the following quad:
11357 : :
11358 : :
11359 : : StandardFunctionOp ReturnVal Cap Param1
11360 : :
11361 : : The Stack:
11362 : :
11363 : :
11364 : : Entry Exit
11365 : :
11366 : : Ptr ->
11367 : : +----------------+
11368 : : | NoOfParam = 1 |
11369 : : |----------------|
11370 : : | Param 1 |
11371 : : |----------------| +-------------+
11372 : : | ProcSym | Type | | ReturnVal |
11373 : : |----------------| |-------------|
11374 : : */
11375 : :
11376 : 124 : static void BuildCapFunction (unsigned int ProcSym, bool ConstExpr)
11377 : : {
11378 : 124 : unsigned int optok;
11379 : 124 : unsigned int functok;
11380 : 124 : unsigned int combinedtok;
11381 : 124 : unsigned int NoOfParam;
11382 : 124 : unsigned int Res;
11383 : 124 : unsigned int Var;
11384 : :
11385 : 124 : M2Quads_PopT (&NoOfParam);
11386 : 124 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11387 : 124 : if (NoOfParam == 1)
11388 : : {
11389 : 124 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11390 : 124 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11391 : 124 : M2Quads_PopN (NoOfParam+1);
11392 : 124 : if (ConstExprError (ProcSym, Var, optok, ConstExpr))
11393 : : {
11394 : : /* Create fake result. */
11395 : 12 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11396 : 24 : Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11397 : 12 : SymbolTable_PutVar (Res, M2Base_Char);
11398 : 12 : M2Quads_PushTFtok (Res, M2Base_Char, combinedtok);
11399 : : }
11400 : 112 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11401 : : {
11402 : : /* avoid dangling else. */
11403 : 112 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11404 : 224 : Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11405 : 112 : SymbolTable_PutVar (Res, M2Base_Char);
11406 : 224 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, Res, ProcSym, Var, false);
11407 : 112 : M2Quads_PushTFtok (Res, M2Base_Char, combinedtok);
11408 : : }
11409 : : else
11410 : : {
11411 : : /* avoid dangling else. */
11412 : 0 : M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%AkCAP} must be a variable or constant, seen {%1ad}", 69, Var);
11413 : : }
11414 : : }
11415 : : else
11416 : : {
11417 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkCAP} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
11418 : : }
11419 : 124 : }
11420 : :
11421 : :
11422 : : /*
11423 : : BuildChrFunction - builds the pseudo procedure call CHR.
11424 : : This procedure is actually a "macro" for
11425 : : CHR(x) --> CONVERT(CHAR, x)
11426 : : However we cannot push tokens back onto the input stack
11427 : : because the compiler is currently building a function
11428 : : call and expecting a ReturnVar on the stack.
11429 : : Hence we manipulate the stack and call
11430 : : BuildConvertFunction.
11431 : :
11432 : : The Stack:
11433 : :
11434 : :
11435 : : Entry Exit
11436 : :
11437 : : Ptr ->
11438 : : +----------------+
11439 : : | NoOfParam |
11440 : : |----------------|
11441 : : | Param 1 |
11442 : : |----------------|
11443 : : | Param 2 |
11444 : : |----------------|
11445 : : . .
11446 : : . .
11447 : : . .
11448 : : |----------------|
11449 : : | Param # |
11450 : : |----------------|
11451 : : | ProcSym | Type | Empty
11452 : : |----------------|
11453 : : */
11454 : :
11455 : 1022 : static void BuildChrFunction (unsigned int ProcSym, bool ConstExpr)
11456 : : {
11457 : 1022 : unsigned int functok;
11458 : 1022 : unsigned int combinedtok;
11459 : 1022 : unsigned int optok;
11460 : 1022 : unsigned int ReturnVar;
11461 : 1022 : unsigned int NoOfParam;
11462 : 1022 : unsigned int Var;
11463 : :
11464 : 1022 : M2Quads_PopT (&NoOfParam);
11465 : 1022 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11466 : 1022 : if (NoOfParam == 1)
11467 : : {
11468 : 1022 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11469 : 1022 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11470 : 1022 : M2Quads_PopN (NoOfParam+1);
11471 : 1022 : if (ConstExprError (ProcSym, Var, optok, ConstExpr))
11472 : : {
11473 : : /* Generate fake result. */
11474 : 12 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11475 : 24 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11476 : 12 : SymbolTable_PutVar (ReturnVar, M2Base_Char);
11477 : 12 : M2Quads_PushTFtok (ReturnVar, M2Base_Char, combinedtok);
11478 : : }
11479 : 1010 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11480 : : {
11481 : : /* avoid dangling else. */
11482 : : /*
11483 : : Build macro: CONVERT( CHAR, Var )
11484 : : */
11485 : 1010 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
11486 : 1010 : M2Quads_PushTtok (M2Base_Char, functok);
11487 : 1010 : M2Quads_PushTtok (Var, optok);
11488 : 1010 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
11489 : 1010 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* Two parameters */
11490 : : }
11491 : : else
11492 : : {
11493 : : /* avoid dangling else. */
11494 : 0 : M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%AkCHR} must be a variable or constant, seen {%1ad}", 69, Var);
11495 : : }
11496 : : }
11497 : : else
11498 : : {
11499 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkCHR} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
11500 : : }
11501 : 1022 : }
11502 : :
11503 : :
11504 : : /*
11505 : : BuildOrdFunction - builds the pseudo procedure call ORD.
11506 : : This procedure is actually a "macro" for
11507 : : ORD(x) --> CONVERT(GetSType(sym), x)
11508 : : However we cannot push tokens back onto the input stack
11509 : : because the compiler is currently building a function
11510 : : call and expecting a ReturnVar on the stack.
11511 : : Hence we manipulate the stack and call
11512 : : BuildConvertFunction.
11513 : :
11514 : : The Stack:
11515 : :
11516 : :
11517 : : Entry Exit
11518 : :
11519 : : Ptr ->
11520 : : +----------------+
11521 : : | NoOfParam |
11522 : : |----------------|
11523 : : | Param 1 |
11524 : : |----------------|
11525 : : | Param 2 |
11526 : : |----------------|
11527 : : . .
11528 : : . .
11529 : : . .
11530 : : |----------------|
11531 : : | Param # |
11532 : : |----------------|
11533 : : | ProcSym | Type | Empty
11534 : : |----------------|
11535 : : */
11536 : :
11537 : 4724 : static void BuildOrdFunction (unsigned int Sym, bool ConstExpr)
11538 : : {
11539 : 4724 : unsigned int combinedtok;
11540 : 4724 : unsigned int functok;
11541 : 4724 : unsigned int optok;
11542 : 4724 : unsigned int ReturnVar;
11543 : 4724 : unsigned int NoOfParam;
11544 : 4724 : unsigned int Type;
11545 : 4724 : unsigned int Var;
11546 : :
11547 : 4724 : M2Quads_PopT (&NoOfParam);
11548 : 4724 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11549 : 4724 : if (NoOfParam == 1)
11550 : : {
11551 : 4724 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11552 : 4724 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11553 : 4724 : M2Quads_PopN (NoOfParam+1);
11554 : 4724 : if (ConstExprError (Sym, Var, optok, ConstExpr))
11555 : : {
11556 : : /* Generate fake result. */
11557 : 12 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11558 : 24 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11559 : 12 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
11560 : 12 : M2Quads_PushTFtok (ReturnVar, M2Base_Cardinal, combinedtok);
11561 : : }
11562 : 4712 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11563 : : {
11564 : : /* avoid dangling else. */
11565 : 4712 : Type = SymbolTable_GetSType (Sym);
11566 : : /*
11567 : : Build macro: CONVERT( CARDINAL, Var )
11568 : : */
11569 : 4712 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
11570 : 4712 : M2Quads_PushTtok (Type, optok);
11571 : 4712 : M2Quads_PushTtok (Var, optok);
11572 : 4712 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
11573 : 4712 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* Two parameters */
11574 : : }
11575 : : else
11576 : : {
11577 : : /* avoid dangling else. */
11578 : 0 : M2MetaError_MetaErrorT2 (optok, (const char *) "the parameter to {%1Aa} must be a variable or constant, seen {%2ad}", 67, Sym, Var);
11579 : : }
11580 : : }
11581 : : else
11582 : : {
11583 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the pseudo procedure {%1Aa} only has one parameter, seen {%2n} parameters", 73, Sym, NoOfParam);
11584 : : }
11585 : 4724 : }
11586 : :
11587 : :
11588 : : /*
11589 : : BuildIntFunction - builds the pseudo procedure call INT.
11590 : : This procedure is actually a "macro" for
11591 : : INT(x) --> CONVERT(INTEGER, x)
11592 : : However we cannot push tokens back onto the input stack
11593 : : because the compiler is currently building a function
11594 : : call and expecting a ReturnVar on the stack.
11595 : : Hence we manipulate the stack and call
11596 : : BuildConvertFunction.
11597 : :
11598 : : The Stack:
11599 : :
11600 : :
11601 : : Entry Exit
11602 : :
11603 : : Ptr ->
11604 : : +----------------+
11605 : : | NoOfParam |
11606 : : |----------------|
11607 : : | Param 1 |
11608 : : |----------------|
11609 : : | Param 2 |
11610 : : |----------------|
11611 : : . .
11612 : : . .
11613 : : . .
11614 : : |----------------|
11615 : : | Param # |
11616 : : |----------------|
11617 : : | ProcSym | Type | Empty
11618 : : |----------------|
11619 : : */
11620 : :
11621 : 6 : static void BuildIntFunction (unsigned int Sym, bool ConstExpr)
11622 : : {
11623 : 6 : unsigned int combinedtok;
11624 : 6 : unsigned int functok;
11625 : 6 : unsigned int optok;
11626 : 6 : unsigned int ReturnVar;
11627 : 6 : unsigned int NoOfParam;
11628 : 6 : unsigned int Type;
11629 : 6 : unsigned int Var;
11630 : :
11631 : 6 : M2Quads_PopT (&NoOfParam);
11632 : 6 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11633 : 6 : if (NoOfParam == 1)
11634 : : {
11635 : 6 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11636 : 6 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11637 : 6 : M2Quads_PopN (NoOfParam+1);
11638 : 6 : if (ConstExprError (Sym, Var, optok, ConstExpr))
11639 : : {
11640 : : /* Generate fake result. */
11641 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11642 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11643 : 6 : SymbolTable_PutVar (ReturnVar, M2Base_Integer);
11644 : 6 : M2Quads_PushTFtok (ReturnVar, M2Base_Integer, combinedtok);
11645 : : }
11646 : 0 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11647 : : {
11648 : : /* avoid dangling else. */
11649 : 0 : Type = SymbolTable_GetSType (Sym); /* return type of function */
11650 : : /* Build macro: CONVERT( CARDINAL, Var ). */
11651 : 0 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
11652 : 0 : M2Quads_PushTtok (Type, functok);
11653 : 0 : M2Quads_PushTtok (Var, optok);
11654 : 0 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
11655 : 0 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* Two parameters */
11656 : : }
11657 : : else
11658 : : {
11659 : : /* avoid dangling else. */
11660 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, optok, optok);
11661 : 0 : M2MetaError_MetaErrorT2 (optok, (const char *) "the parameter to {%1Ea} must be a variable or constant, seen {%2ad}", 67, Sym, Var);
11662 : 0 : M2Quads_PushTtok (combinedtok, SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType));
11663 : : }
11664 : : }
11665 : : else
11666 : : {
11667 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the pseudo procedure {%1Ea} only has one parameter, seen {%2n} parameters", 73, Sym, NoOfParam);
11668 : 0 : M2Quads_PushTtok (functok, SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType));
11669 : : }
11670 : 6 : }
11671 : :
11672 : :
11673 : : /*
11674 : : BuildMakeAdrFunction - builds the pseudo procedure call MAKEADR.
11675 : :
11676 : : The Stack:
11677 : :
11678 : :
11679 : : Entry Exit
11680 : :
11681 : : Ptr ->
11682 : : +----------------+
11683 : : | NoOfParam |
11684 : : |----------------|
11685 : : | Param 1 |
11686 : : |----------------|
11687 : : | Param 2 |
11688 : : |----------------|
11689 : : . .
11690 : : . .
11691 : : . .
11692 : : |----------------|
11693 : : | Param # |
11694 : : |----------------|
11695 : : | ProcSym | Type | Empty
11696 : : |----------------|
11697 : : */
11698 : :
11699 : 12 : static void BuildMakeAdrFunction (void)
11700 : : {
11701 : 12 : unsigned int functok;
11702 : 12 : unsigned int starttok;
11703 : 12 : unsigned int endtok;
11704 : 12 : unsigned int resulttok;
11705 : 12 : bool AreConst;
11706 : 12 : unsigned int i;
11707 : 12 : unsigned int pi;
11708 : 12 : unsigned int NoOfParameters;
11709 : 12 : unsigned int ReturnVar;
11710 : :
11711 : 12 : M2Quads_PopT (&NoOfParameters);
11712 : 12 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParameters+1));
11713 : 12 : if (NoOfParameters > 0)
11714 : : {
11715 : 12 : starttok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParameters+1)); /* ADR token. */
11716 : 12 : endtok = static_cast<unsigned int> (M2Quads_OperandTok (1)); /* last parameter. */
11717 : 24 : GenQuad (M2Quads_ParamOp, 0, M2System_MakeAdr, M2System_MakeAdr); /* last parameter. */
11718 : 12 : i = NoOfParameters;
11719 : : /* stack index referencing stacked parameter, i */
11720 : 12 : pi = 1;
11721 : 24 : while (i > 0)
11722 : : {
11723 : 12 : GenQuadO (M2Quads_OperandTok (pi), M2Quads_ParamOp, i, M2System_MakeAdr, M2Quads_OperandT (pi), true);
11724 : 12 : i -= 1;
11725 : 12 : pi += 1;
11726 : : }
11727 : : AreConst = true;
11728 : : i = 1;
11729 : 24 : while (i <= NoOfParameters)
11730 : : {
11731 : 12 : if (SymbolTable_IsVar (M2Quads_OperandT (i)))
11732 : : {
11733 : : AreConst = false;
11734 : : }
11735 : 12 : else if (! (SymbolTable_IsConst (M2Quads_OperandT (i))))
11736 : : {
11737 : : /* avoid dangling else. */
11738 : 0 : M2MetaError_MetaError1 ((const char *) "problem in the {%1EN} argument for {%kMAKEADR}, all arguments to {%kMAKEADR} must be either variables or constants", 114, i);
11739 : : }
11740 : 12 : i += 1;
11741 : : }
11742 : : /* ReturnVar - will have the type of the procedure */
11743 : 12 : resulttok = M2LexBuf_MakeVirtualTok (starttok, starttok, endtok);
11744 : 12 : ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (AreConst));
11745 : 12 : SymbolTable_PutVar (ReturnVar, SymbolTable_GetSType (M2System_MakeAdr));
11746 : 24 : GenQuadO (resulttok, M2Quads_FunctValueOp, ReturnVar, SymbolTable_NulSym, M2System_MakeAdr, true);
11747 : 12 : M2Quads_PopN (NoOfParameters+1);
11748 : 12 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (M2System_MakeAdr), resulttok);
11749 : : }
11750 : : else
11751 : : {
11752 : 0 : M2MetaError_MetaError1 ((const char *) "the pseudo procedure {%EkMAKEADR} requires at least one parameter, seen {%1n}", 77, NoOfParameters);
11753 : 0 : M2Quads_PopN (1);
11754 : 0 : M2Quads_PushTFtok (M2Base_Nil, SymbolTable_GetSType (M2System_MakeAdr), functok);
11755 : : }
11756 : 12 : }
11757 : :
11758 : :
11759 : : /*
11760 : : BuildShiftFunction - builds the pseudo procedure call SHIFT.
11761 : :
11762 : : PROCEDURE SHIFT (val: <any type>;
11763 : : num: INTEGER): <any type> ;
11764 : :
11765 : : "Returns a bit sequence obtained from val by
11766 : : shifting up or down (left or right) by the
11767 : : absolute value of num, introducing
11768 : : zeros as necessary. The direction is down if
11769 : : the sign of num is negative, otherwise the
11770 : : direction is up."
11771 : :
11772 : : The Stack:
11773 : :
11774 : : Entry Exit
11775 : :
11776 : : Ptr ->
11777 : : +----------------+
11778 : : | NoOfParam |
11779 : : |----------------|
11780 : : | Param 1 |
11781 : : |----------------|
11782 : : | Param 2 | <- Ptr
11783 : : |----------------| +------------+
11784 : : | ProcSym | Type | | ReturnVar |
11785 : : |----------------| |------------|
11786 : : */
11787 : :
11788 : 682 : static void BuildShiftFunction (void)
11789 : : {
11790 : 682 : unsigned int combinedtok;
11791 : 682 : unsigned int paramtok;
11792 : 682 : unsigned int functok;
11793 : 682 : unsigned int vartok;
11794 : 682 : unsigned int exptok;
11795 : 682 : unsigned int r;
11796 : 682 : unsigned int procSym;
11797 : 682 : unsigned int returnVar;
11798 : 682 : unsigned int NoOfParam;
11799 : 682 : unsigned int derefExp;
11800 : 682 : unsigned int Exp;
11801 : 682 : unsigned int varSet;
11802 : :
11803 : 682 : M2Quads_PopT (&NoOfParam);
11804 : 682 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11805 : 682 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11806 : 682 : if (NoOfParam == 2)
11807 : : {
11808 : 682 : PopTrwtok (&Exp, &r, &exptok);
11809 : 682 : MarkAsRead (r);
11810 : 682 : M2Quads_PopTtok (&varSet, &vartok);
11811 : 682 : M2Quads_PopT (&procSym);
11812 : 682 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
11813 : 682 : if (((SymbolTable_GetSType (varSet)) != SymbolTable_NulSym) && ((SymbolTable_IsSet (SymbolTable_GetDType (varSet))) || (M2System_IsGenericSystemType (SymbolTable_GetDType (varSet)))))
11814 : : {
11815 : 682 : derefExp = DereferenceLValue (exptok, Exp);
11816 : 682 : BuildRange (M2Range_InitShiftCheck (varSet, derefExp));
11817 : 682 : returnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
11818 : 682 : SymbolTable_PutVar (returnVar, SymbolTable_GetSType (varSet));
11819 : 1364 : GenQuadO (combinedtok, M2Quads_LogicalShiftOp, returnVar, varSet, derefExp, true);
11820 : 682 : M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (varSet), combinedtok);
11821 : : }
11822 : : else
11823 : : {
11824 : 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);
11825 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, combinedtok);
11826 : : }
11827 : : }
11828 : : else
11829 : : {
11830 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
11831 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%kSHIFT} requires at least two parameters, seen {%1En}", 76, NoOfParam);
11832 : 0 : M2Quads_PopN (NoOfParam+1);
11833 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, combinedtok);
11834 : : }
11835 : 682 : }
11836 : :
11837 : :
11838 : : /*
11839 : : BuildRotateFunction - builds the pseudo procedure call ROTATE.
11840 : :
11841 : : PROCEDURE ROTATE (val: <any type>;
11842 : : num: INTEGER): <any type> ;
11843 : :
11844 : : "Returns a bit sequence obtained from val
11845 : : by rotating up or down (left or right) by
11846 : : the absolute value of num. The direction is
11847 : : down if the sign of num is negative, otherwise
11848 : : the direction is up."
11849 : :
11850 : : The Stack:
11851 : :
11852 : : Entry Exit
11853 : :
11854 : : Ptr ->
11855 : : +----------------+
11856 : : | NoOfParam |
11857 : : |----------------|
11858 : : | Param 1 |
11859 : : |----------------|
11860 : : | Param 2 | <- Ptr
11861 : : |----------------| +------------+
11862 : : | ProcSym | Type | | ReturnVar |
11863 : : |----------------| |------------|
11864 : : */
11865 : :
11866 : 406 : static void BuildRotateFunction (void)
11867 : : {
11868 : 406 : unsigned int combinedtok;
11869 : 406 : unsigned int functok;
11870 : 406 : unsigned int vartok;
11871 : 406 : unsigned int exptok;
11872 : 406 : unsigned int r;
11873 : 406 : unsigned int procSym;
11874 : 406 : unsigned int returnVar;
11875 : 406 : unsigned int NoOfParam;
11876 : 406 : unsigned int derefExp;
11877 : 406 : unsigned int Exp;
11878 : 406 : unsigned int varSet;
11879 : :
11880 : 406 : M2Quads_PopT (&NoOfParam);
11881 : 406 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11882 : 406 : if (NoOfParam == 2)
11883 : : {
11884 : 406 : PopTrwtok (&Exp, &r, &exptok);
11885 : 406 : MarkAsRead (r);
11886 : 406 : M2Quads_PopTtok (&varSet, &vartok);
11887 : 406 : M2Quads_PopT (&procSym);
11888 : 406 : if (((SymbolTable_GetSType (varSet)) != SymbolTable_NulSym) && ((SymbolTable_IsSet (SymbolTable_GetDType (varSet))) || (M2System_IsGenericSystemType (SymbolTable_GetDType (varSet)))))
11889 : : {
11890 : 406 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
11891 : 406 : derefExp = DereferenceLValue (exptok, Exp);
11892 : 406 : BuildRange (M2Range_InitRotateCheck (varSet, derefExp));
11893 : 406 : returnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
11894 : 406 : SymbolTable_PutVar (returnVar, SymbolTable_GetSType (varSet));
11895 : 812 : GenQuadO (combinedtok, M2Quads_LogicalRotateOp, returnVar, varSet, derefExp, true);
11896 : 406 : M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (varSet), combinedtok);
11897 : : }
11898 : : else
11899 : : {
11900 : 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);
11901 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
11902 : : }
11903 : : }
11904 : : else
11905 : : {
11906 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "SYSTEM procedure {%EkROTATE} expects 2 parameters and was given {%1n} parameters", 80, NoOfParam);
11907 : 0 : M2Quads_PopN (NoOfParam+1);
11908 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
11909 : : }
11910 : 406 : }
11911 : :
11912 : :
11913 : : /*
11914 : : BuildValFunction - builds the pseudo procedure call VAL.
11915 : : This procedure is actually a "macro" for
11916 : : VAL(Type, x) --> CONVERT(Type, x)
11917 : : However we cannot push tokens back onto the input stack
11918 : : because the compiler is currently building a function
11919 : : call and expecting a ReturnVar on the stack.
11920 : : Hence we manipulate the stack and call
11921 : : BuildConvertFunction.
11922 : :
11923 : : The Stack:
11924 : :
11925 : :
11926 : : Entry Exit
11927 : :
11928 : : Ptr ->
11929 : : +----------------+
11930 : : | NoOfParam |
11931 : : |----------------|
11932 : : | Param 1 |
11933 : : |----------------|
11934 : : | Param 2 |
11935 : : |----------------|
11936 : : . .
11937 : : . .
11938 : : . .
11939 : : |----------------|
11940 : : | Param # |
11941 : : |----------------|
11942 : : | ProcSym | Type | Empty
11943 : : |----------------|
11944 : : */
11945 : :
11946 : 4896 : static void BuildValFunction (unsigned int ProcSym, bool ConstExpr)
11947 : : {
11948 : 4896 : unsigned int combinedtok;
11949 : 4896 : unsigned int functok;
11950 : 4896 : unsigned int ReturnVar;
11951 : 4896 : unsigned int NoOfParam;
11952 : 4896 : unsigned int Exp;
11953 : 4896 : unsigned int Type;
11954 : 4896 : unsigned int tok;
11955 : 4896 : unsigned int r;
11956 : 4896 : unsigned int typetok;
11957 : 4896 : unsigned int exptok;
11958 : :
11959 : 4896 : M2Quads_PopT (&NoOfParam);
11960 : 4896 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11961 : 4896 : if (NoOfParam == 2)
11962 : : {
11963 : 4896 : PopTrwtok (&Exp, &r, &exptok);
11964 : 4896 : MarkAsRead (r);
11965 : 4896 : M2Quads_PopTtok (&Type, &typetok);
11966 : 4896 : M2Quads_PopTtok (&ProcSym, &tok);
11967 : 4896 : if (SymbolTable_IsUnknown (Type))
11968 : : {
11969 : : /* It is sensible not to try and recover when we dont know the return type. */
11970 : 6 : M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type found in builtin procedure function {%AkVAL} {%1ad} {%1&s}", 74, Type);
11971 : : /* Non recoverable error. */
11972 : 0 : SymbolTable_UnknownReported (Type);
11973 : : }
11974 : 4890 : else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
11975 : : {
11976 : : /* avoid dangling else. */
11977 : : /* Generate fake result. */
11978 : 6 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
11979 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
11980 : 6 : SymbolTable_PutVar (ReturnVar, Type);
11981 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
11982 : : }
11983 : 4884 : 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))))
11984 : : {
11985 : : /* avoid dangling else. */
11986 : : /*
11987 : : Build macro: CONVERT( Type, Var )
11988 : : */
11989 : 4884 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
11990 : 4884 : M2Quads_PushTtok (Type, typetok);
11991 : 4884 : M2Quads_PushTtok (Exp, exptok);
11992 : 4884 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
11993 : 4884 : BuildConvertFunction (M2Base_Convert, ConstExpr);
11994 : : }
11995 : : else
11996 : : {
11997 : : /* avoid dangling else. */
11998 : : /* non recoverable error. */
11999 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkVAL} has the following formal parameter declaration {%kVAL} (type, expression)", 104);
12000 : : }
12001 : : }
12002 : : else
12003 : : {
12004 : : /* non recoverable error. */
12005 : 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);
12006 : : }
12007 : 4890 : }
12008 : :
12009 : :
12010 : : /*
12011 : : BuildCastFunction - builds the pseudo procedure call CAST.
12012 : : This procedure is actually a "macro" for
12013 : : CAST(Type, x) --> Type(x)
12014 : : However we cannot push tokens back onto the input stack
12015 : : because the compiler is currently building a function
12016 : : call and expecting a ReturnVar on the stack.
12017 : : Hence we manipulate the stack and call
12018 : : BuildConvertFunction.
12019 : :
12020 : : The Stack:
12021 : :
12022 : :
12023 : : Entry Exit
12024 : :
12025 : : Ptr ->
12026 : : +----------------+
12027 : : | NoOfParam |
12028 : : |----------------|
12029 : : | Param 1 |
12030 : : |----------------|
12031 : : | Param 2 |
12032 : : |----------------|
12033 : : . .
12034 : : . .
12035 : : . .
12036 : : |----------------|
12037 : : | Param # |
12038 : : |----------------|
12039 : : | ProcSym | Type | Empty
12040 : : |----------------|
12041 : : */
12042 : :
12043 : 156 : static void BuildCastFunction (unsigned int ProcSym, bool ConstExpr)
12044 : : {
12045 : 156 : unsigned int combinedtok;
12046 : 156 : unsigned int exptok;
12047 : 156 : unsigned int typetok;
12048 : 156 : unsigned int functok;
12049 : 156 : unsigned int ReturnVar;
12050 : 156 : unsigned int NoOfParam;
12051 : 156 : unsigned int Exp;
12052 : 156 : unsigned int Type;
12053 : :
12054 : 156 : M2Quads_PopT (&NoOfParam);
12055 : 156 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
12056 : 156 : if (NoOfParam == 2)
12057 : : {
12058 : 156 : Type = static_cast<unsigned int> (M2Quads_OperandT (2));
12059 : 156 : typetok = static_cast<unsigned int> (M2Quads_OperandTok (2));
12060 : 156 : Exp = static_cast<unsigned int> (M2Quads_OperandT (1));
12061 : 156 : exptok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12062 : 156 : if (SymbolTable_IsUnknown (Type))
12063 : : {
12064 : : /* We cannot recover if we dont have a type. */
12065 : 0 : M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type {%1Aad} found in {%kCAST} {%1&s}", 48, Type);
12066 : : /* Non recoverable error. */
12067 : 0 : SymbolTable_UnknownReported (Type);
12068 : : }
12069 : 156 : else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
12070 : : {
12071 : : /* avoid dangling else. */
12072 : : /* Generate fake result. */
12073 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
12074 : 0 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
12075 : 0 : SymbolTable_PutVar (ReturnVar, Type);
12076 : 0 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12077 : : }
12078 : 156 : else if (((((((SymbolTable_IsSet (Type)) || (SymbolTable_IsEnumeration (Type))) || (SymbolTable_IsSubrange (Type))) || (SymbolTable_IsType (Type))) || (SymbolTable_IsPointer (Type))) || (SymbolTable_IsArray (Type))) || (SymbolTable_IsProcType (Type)))
12079 : : {
12080 : : /* avoid dangling else. */
12081 : 156 : if (SymbolTable_IsConst (Exp))
12082 : : {
12083 : 30 : M2Quads_PopN (NoOfParam+1);
12084 : : /*
12085 : : Build macro: Type( Var )
12086 : : */
12087 : 30 : M2Quads_PushTFtok (Type, static_cast<unsigned int> (SymbolTable_NulSym), typetok);
12088 : 30 : M2Quads_PushTtok (Exp, exptok);
12089 : 30 : M2Quads_PushT (static_cast<unsigned int> (1)); /* one parameter */
12090 : 30 : BuildTypeCoercion (ConstExpr); /* one parameter */
12091 : : }
12092 : 126 : else if ((SymbolTable_IsVar (Exp)) || (SymbolTable_IsProcedure (Exp)))
12093 : : {
12094 : : /* avoid dangling else. */
12095 : 126 : M2Quads_PopN (NoOfParam+1);
12096 : 126 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, exptok);
12097 : 126 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
12098 : 126 : SymbolTable_PutVar (ReturnVar, Type);
12099 : 252 : GenQuadO (combinedtok, M2Quads_CastOp, ReturnVar, Type, Exp, false);
12100 : 126 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12101 : : }
12102 : : else
12103 : : {
12104 : : /* avoid dangling else. */
12105 : : /* non recoverable error. */
12106 : 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);
12107 : : }
12108 : : }
12109 : : else
12110 : : {
12111 : : /* avoid dangling else. */
12112 : : /* non recoverable error. */
12113 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkCAST} has the following formal parameter declaration {%kCAST} (type, expression)", 106);
12114 : : }
12115 : : }
12116 : : else
12117 : : {
12118 : : /* non recoverable error. */
12119 : 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);
12120 : : }
12121 : 156 : }
12122 : :
12123 : :
12124 : : /*
12125 : : BuildConvertFunction - builds the pseudo function CONVERT.
12126 : : CONVERT( Type, Variable ) ;
12127 : :
12128 : : The Stack:
12129 : :
12130 : :
12131 : : Entry Exit
12132 : :
12133 : : Ptr ->
12134 : : +----------------+
12135 : : | NoOfParam |
12136 : : |----------------|
12137 : : | Param 1 |
12138 : : |----------------|
12139 : : | Param 2 |
12140 : : |----------------|
12141 : : . .
12142 : : . .
12143 : : . .
12144 : : |----------------|
12145 : : | Param # | <- Ptr
12146 : : |----------------| +---------------------+
12147 : : | ProcSym | Type | | ReturnVar | Param1 |
12148 : : |----------------| |---------------------|
12149 : :
12150 : : Quadruples:
12151 : :
12152 : : ConvertOp ReturnVar Param1 Param2
12153 : :
12154 : : Converts variable Param2 into a variable Param1
12155 : : with a type Param1.
12156 : : */
12157 : :
12158 : 56246 : static void BuildConvertFunction (unsigned int ProcSym, bool ConstExpr)
12159 : : {
12160 : 56246 : unsigned int combinedtok;
12161 : 56246 : unsigned int functok;
12162 : 56246 : unsigned int typetok;
12163 : 56246 : unsigned int exptok;
12164 : 56246 : unsigned int t;
12165 : 56246 : unsigned int r;
12166 : 56246 : unsigned int Exp;
12167 : 56246 : unsigned int Type;
12168 : 56246 : unsigned int NoOfParam;
12169 : 56246 : unsigned int ReturnVar;
12170 : :
12171 : 56246 : M2Quads_PopT (&NoOfParam);
12172 : 56246 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
12173 : 56246 : if (NoOfParam == 2)
12174 : : {
12175 : 56246 : PopTrwtok (&Exp, &r, &exptok);
12176 : 56246 : MarkAsRead (r);
12177 : 56246 : M2Quads_PopTtok (&Type, &typetok);
12178 : 56246 : M2Quads_PopT (&ProcSym);
12179 : 56246 : if (SymbolTable_IsUnknown (Type))
12180 : : {
12181 : : /* We cannot recover if we dont have a type. */
12182 : 0 : M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type {%1Aad} found in {%kCONVERT} {%1&s}", 51, Type);
12183 : : /* Non recoverable error. */
12184 : 0 : SymbolTable_UnknownReported (Type);
12185 : : }
12186 : 56246 : else if (SymbolTable_IsUnknown (Exp))
12187 : : {
12188 : : /* avoid dangling else. */
12189 : : /* We cannot recover if we dont have an expression. */
12190 : 0 : M2MetaError_MetaErrorT1 (typetok, (const char *) "unknown {%1Ad} {%1ad} found in {%kCONVERT} {%1&s}", 49, Exp);
12191 : : /* Non recoverable error. */
12192 : 0 : SymbolTable_UnknownReported (Exp);
12193 : : }
12194 : 56246 : else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
12195 : : {
12196 : : /* avoid dangling else. */
12197 : : /* Generate fake result. */
12198 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
12199 : 0 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
12200 : 0 : SymbolTable_PutVar (ReturnVar, Type);
12201 : 0 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12202 : : }
12203 : 56246 : 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))))
12204 : : {
12205 : : /* avoid dangling else. */
12206 : : /* firstly dereference Var */
12207 : 56240 : if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
12208 : : {
12209 : 0 : t = SymbolTable_MakeTemporary (exptok, SymbolTable_RightValue);
12210 : 0 : SymbolTable_PutVar (t, SymbolTable_GetSType (Exp));
12211 : 0 : CheckPointerThroughNil (exptok, Exp);
12212 : 0 : doIndrX (exptok, t, Exp);
12213 : 0 : Exp = t;
12214 : : }
12215 : 56240 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
12216 : 112480 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
12217 : 56240 : SymbolTable_PutVar (ReturnVar, Type);
12218 : 112480 : GenQuadO (combinedtok, M2Quads_ConvertOp, ReturnVar, Type, Exp, true);
12219 : 56240 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12220 : : }
12221 : : else
12222 : : {
12223 : : /* avoid dangling else. */
12224 : : /* non recoverable error. */
12225 : 6 : M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkCONVERT} has the following formal parameter declaration {%kCONVERT} (type, expression)", 112);
12226 : : }
12227 : : }
12228 : : else
12229 : : {
12230 : : /* non recoverable error. */
12231 : 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);
12232 : : }
12233 : 56240 : }
12234 : :
12235 : :
12236 : : /*
12237 : : CheckBaseTypeValue - checks to see whether the value, min, really exists.
12238 : : */
12239 : :
12240 : 2026 : static unsigned int CheckBaseTypeValue (unsigned int tok, unsigned int type, unsigned int min, unsigned int func)
12241 : : {
12242 : 2026 : if (((type == M2Base_Real) || (type == M2Base_LongReal)) || (type == M2Base_ShortReal))
12243 : : {
12244 : 102 : SymbolTable_PushValue (min);
12245 : 102 : if (! (M2ALU_IsValueAndTreeKnown ()))
12246 : : {
12247 : 0 : M2MetaError_MetaErrorT2 (tok, (const char *) "{%1Ead} ({%2ad}) cannot be calculated at compile time for the target architecture", 81, func, type);
12248 : 0 : return SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType);
12249 : : }
12250 : : }
12251 : : return min;
12252 : : /* static analysis guarentees a RETURN statement will be used before here. */
12253 : : __builtin_unreachable ();
12254 : : }
12255 : :
12256 : :
12257 : : /*
12258 : : GetTypeMin - returns the minimium value of type and generate an error
12259 : : if this is unavailable.
12260 : : */
12261 : :
12262 : 1302 : static unsigned int GetTypeMin (unsigned int tok, unsigned int func, unsigned int type)
12263 : : {
12264 : 1302 : unsigned int min;
12265 : :
12266 : 1302 : min = GetTypeMinLower (tok, func, type);
12267 : 1302 : if (min == SymbolTable_NulSym)
12268 : : {
12269 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "unable to obtain the {%AkMIN} value for type {%1ad}", 51, type);
12270 : : }
12271 : 1302 : return min;
12272 : : /* static analysis guarentees a RETURN statement will be used before here. */
12273 : : __builtin_unreachable ();
12274 : : }
12275 : :
12276 : :
12277 : : /*
12278 : : GetTypeMinLower - obtain the maximum value for type.
12279 : : */
12280 : :
12281 : 1302 : static unsigned int GetTypeMinLower (unsigned int tok, unsigned int func, unsigned int type)
12282 : : {
12283 : 1302 : unsigned int min;
12284 : 1302 : unsigned int max;
12285 : :
12286 : 1302 : if (SymbolTable_IsSubrange (type))
12287 : : {
12288 : 282 : min = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
12289 : 282 : SymbolTable_PutVar (min, type);
12290 : 564 : GenQuad (M2Quads_SubrangeLowOp, min, SymbolTable_NulSym, type);
12291 : 282 : return min;
12292 : : }
12293 : 1020 : else if (SymbolTable_IsSet (SymbolTable_SkipType (type)))
12294 : : {
12295 : : /* avoid dangling else. */
12296 : 60 : return GetTypeMin (tok, func, SymbolTable_GetSType (SymbolTable_SkipType (type)));
12297 : : }
12298 : 960 : else if ((M2Base_IsBaseType (type)) || (SymbolTable_IsEnumeration (type)))
12299 : : {
12300 : : /* avoid dangling else. */
12301 : 758 : M2Base_GetBaseTypeMinMax (type, &min, &max);
12302 : 758 : min = CheckBaseTypeValue (tok, type, min, func);
12303 : 758 : return min;
12304 : : }
12305 : 202 : else if (M2System_IsSystemType (type))
12306 : : {
12307 : : /* avoid dangling else. */
12308 : 186 : M2System_GetSystemTypeMinMax (type, &min, &max);
12309 : 186 : return min;
12310 : : }
12311 : 16 : else if ((SymbolTable_GetSType (type)) == SymbolTable_NulSym)
12312 : : {
12313 : : /* avoid dangling else. */
12314 : : return SymbolTable_NulSym;
12315 : : }
12316 : : else
12317 : : {
12318 : : /* avoid dangling else. */
12319 : 16 : return GetTypeMin (tok, func, SymbolTable_GetSType (type));
12320 : : }
12321 : : /* static analysis guarentees a RETURN statement will be used before here. */
12322 : : __builtin_unreachable ();
12323 : : }
12324 : :
12325 : :
12326 : : /*
12327 : : GetTypeMax - returns the maximum value of type and generate an error
12328 : : if this is unavailable.
12329 : : */
12330 : :
12331 : 2258 : static unsigned int GetTypeMax (unsigned int tok, unsigned int func, unsigned int type)
12332 : : {
12333 : 2258 : unsigned int max;
12334 : :
12335 : 2258 : max = GetTypeMaxLower (tok, func, type);
12336 : 2258 : if (max == SymbolTable_NulSym)
12337 : : {
12338 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "unable to obtain the {%AkMAX} value for type {%1ad}", 51, type);
12339 : : }
12340 : 2258 : return max;
12341 : : /* static analysis guarentees a RETURN statement will be used before here. */
12342 : : __builtin_unreachable ();
12343 : : }
12344 : :
12345 : :
12346 : : /*
12347 : : GetTypeMaxLower - obtain the maximum value for type.
12348 : : */
12349 : :
12350 : 2258 : static unsigned int GetTypeMaxLower (unsigned int tok, unsigned int func, unsigned int type)
12351 : : {
12352 : 2258 : unsigned int min;
12353 : 2258 : unsigned int max;
12354 : :
12355 : 2258 : if (SymbolTable_IsSubrange (type))
12356 : : {
12357 : 562 : max = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
12358 : 562 : SymbolTable_PutVar (max, type);
12359 : 1124 : GenQuad (M2Quads_SubrangeHighOp, max, SymbolTable_NulSym, type);
12360 : 562 : return max;
12361 : : }
12362 : 1696 : else if (SymbolTable_IsSet (SymbolTable_SkipType (type)))
12363 : : {
12364 : : /* avoid dangling else. */
12365 : 210 : return GetTypeMax (tok, func, SymbolTable_GetSType (SymbolTable_SkipType (type)));
12366 : : }
12367 : 1486 : else if ((M2Base_IsBaseType (type)) || (SymbolTable_IsEnumeration (type)))
12368 : : {
12369 : : /* avoid dangling else. */
12370 : 1268 : M2Base_GetBaseTypeMinMax (type, &min, &max);
12371 : 1268 : min = CheckBaseTypeValue (tok, type, min, func);
12372 : 1268 : return max;
12373 : : }
12374 : 218 : else if (M2System_IsSystemType (type))
12375 : : {
12376 : : /* avoid dangling else. */
12377 : 202 : M2System_GetSystemTypeMinMax (type, &min, &max);
12378 : 202 : return max;
12379 : : }
12380 : 16 : else if ((SymbolTable_GetSType (type)) == SymbolTable_NulSym)
12381 : : {
12382 : : /* avoid dangling else. */
12383 : : return SymbolTable_NulSym;
12384 : : }
12385 : : else
12386 : : {
12387 : : /* avoid dangling else. */
12388 : 16 : return GetTypeMax (tok, func, SymbolTable_GetSType (type));
12389 : : }
12390 : : /* static analysis guarentees a RETURN statement will be used before here. */
12391 : : __builtin_unreachable ();
12392 : : }
12393 : :
12394 : :
12395 : : /*
12396 : : BuildMinFunction - builds the pseudo function call Min.
12397 : :
12398 : : The Stack:
12399 : :
12400 : : Entry Exit
12401 : :
12402 : : Ptr ->
12403 : : +----------------+
12404 : : | NoOfParam=1 |
12405 : : |----------------|
12406 : : | Param 1 |
12407 : : |----------------|
12408 : : | ProcSym | Type | Empty
12409 : : |----------------|
12410 : : */
12411 : :
12412 : 1226 : static void BuildMinFunction (void)
12413 : : {
12414 : 1226 : unsigned int combinedtok;
12415 : 1226 : unsigned int functok;
12416 : 1226 : unsigned int vartok;
12417 : 1226 : unsigned int func;
12418 : 1226 : unsigned int min;
12419 : 1226 : unsigned int NoOfParam;
12420 : 1226 : unsigned int Var;
12421 : :
12422 : 1226 : M2Quads_PopT (&NoOfParam);
12423 : 1226 : func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12424 : 1226 : functok = OperandTtok (NoOfParam+1);
12425 : 1226 : if (NoOfParam == 1)
12426 : : {
12427 : 1226 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12428 : 1226 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12429 : 1226 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12430 : 1226 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok); /* destroy arguments to this function */
12431 : 1226 : if (SymbolTable_IsAModula2Type (Var))
12432 : : {
12433 : 1226 : min = GetTypeMin (vartok, func, Var);
12434 : 1226 : M2Quads_PushTFtok (min, SymbolTable_GetSType (min), combinedtok);
12435 : : }
12436 : 0 : else if (SymbolTable_IsVar (Var))
12437 : : {
12438 : : /* avoid dangling else. */
12439 : 0 : min = GetTypeMin (vartok, func, SymbolTable_GetSType (Var));
12440 : 0 : M2Quads_PushTFtok (min, SymbolTable_GetSType (Var), combinedtok);
12441 : : }
12442 : : else
12443 : : {
12444 : : /* avoid dangling else. */
12445 : : /* non recoverable error. */
12446 : 0 : M2MetaError_MetaErrorT1 (vartok, (const char *) "parameter to {%AkMIN} must be a type or a variable, seen {%1ad}", 63, Var);
12447 : : }
12448 : : }
12449 : : else
12450 : : {
12451 : : /* non recoverable error. */
12452 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkMIN} only has one parameter, seen {%1n}", 82, NoOfParam);
12453 : : }
12454 : 1226 : }
12455 : :
12456 : :
12457 : : /*
12458 : : BuildMaxFunction - builds the pseudo function call Max.
12459 : :
12460 : : The Stack:
12461 : :
12462 : : Entry Exit
12463 : :
12464 : : Ptr ->
12465 : : +----------------+
12466 : : | NoOfParam=1 |
12467 : : |----------------|
12468 : : | Param 1 |
12469 : : |----------------|
12470 : : | ProcSym | Type | Empty
12471 : : |----------------|
12472 : : */
12473 : :
12474 : 2032 : static void BuildMaxFunction (void)
12475 : : {
12476 : 2032 : unsigned int combinedtok;
12477 : 2032 : unsigned int functok;
12478 : 2032 : unsigned int vartok;
12479 : 2032 : unsigned int func;
12480 : 2032 : unsigned int max;
12481 : 2032 : unsigned int NoOfParam;
12482 : 2032 : unsigned int Var;
12483 : :
12484 : 2032 : M2Quads_PopT (&NoOfParam);
12485 : 2032 : func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12486 : 2032 : functok = OperandTtok (NoOfParam+1);
12487 : 2032 : if (NoOfParam == 1)
12488 : : {
12489 : 2032 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12490 : 2032 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12491 : 2032 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12492 : 2032 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok); /* destroy arguments to this function */
12493 : 2032 : if (SymbolTable_IsAModula2Type (Var))
12494 : : {
12495 : 2032 : max = GetTypeMax (vartok, func, Var);
12496 : 2032 : M2Quads_PushTFtok (max, SymbolTable_GetSType (max), combinedtok);
12497 : : }
12498 : 0 : else if (SymbolTable_IsVar (Var))
12499 : : {
12500 : : /* avoid dangling else. */
12501 : 0 : max = GetTypeMax (vartok, func, SymbolTable_GetSType (Var));
12502 : 0 : M2Quads_PushTFtok (max, SymbolTable_GetSType (Var), combinedtok);
12503 : : }
12504 : : else
12505 : : {
12506 : : /* avoid dangling else. */
12507 : : /* non recoverable error. */
12508 : 0 : M2MetaError_MetaErrorT1 (vartok, (const char *) "parameter to {%AkMAX} must be a type or a variable, seen {%1ad}", 63, Var);
12509 : : }
12510 : : }
12511 : : else
12512 : : {
12513 : : /* non recoverable error. */
12514 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkMAX} only has one parameter, seen {%1n}", 81, NoOfParam);
12515 : : }
12516 : 2032 : }
12517 : :
12518 : :
12519 : : /*
12520 : : BuildTruncFunction - builds the pseudo procedure call TRUNC.
12521 : : This procedure is actually a "macro" for
12522 : : TRUNC(x) --> CONVERT(INTEGER, x)
12523 : : However we cannot push tokens back onto the input stack
12524 : : because the compiler is currently building a function
12525 : : call and expecting a ReturnVar on the stack.
12526 : : Hence we manipulate the stack and call
12527 : : BuildConvertFunction.
12528 : :
12529 : : The Stack:
12530 : :
12531 : :
12532 : : Entry Exit
12533 : :
12534 : : Ptr ->
12535 : : +----------------+
12536 : : | NoOfParam |
12537 : : |----------------|
12538 : : | Param 1 |
12539 : : |----------------|
12540 : : | Param 2 |
12541 : : |----------------|
12542 : : . .
12543 : : . .
12544 : : . .
12545 : : |----------------|
12546 : : | Param # |
12547 : : |----------------|
12548 : : | ProcSym | Type | Empty
12549 : : |----------------|
12550 : : */
12551 : :
12552 : 60 : static void BuildTruncFunction (unsigned int Sym, bool ConstExpr)
12553 : : {
12554 : 60 : unsigned int combinedtok;
12555 : 60 : unsigned int vartok;
12556 : 60 : unsigned int functok;
12557 : 60 : unsigned int NoOfParam;
12558 : 60 : unsigned int ReturnVar;
12559 : 60 : unsigned int ProcSym;
12560 : 60 : unsigned int Type;
12561 : 60 : unsigned int Var;
12562 : :
12563 : 60 : M2Quads_PopT (&NoOfParam);
12564 : 60 : M2Debug_Assert (M2Base_IsTrunc (M2Quads_OperandT (NoOfParam+1)));
12565 : 60 : functok = OperandTtok (NoOfParam+1);
12566 : 60 : if (NoOfParam == 1)
12567 : : {
12568 : 60 : ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "CONVERT", 7));
12569 : 60 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
12570 : : {
12571 : 60 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12572 : 60 : vartok = OperandTtok (1);
12573 : 60 : Type = SymbolTable_GetSType (Sym);
12574 : 60 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12575 : 60 : if (ConstExprError (Sym, Var, vartok, ConstExpr))
12576 : : {
12577 : : /* Generate fake result. */
12578 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
12579 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12580 : 6 : SymbolTable_PutVar (ReturnVar, Type);
12581 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12582 : : }
12583 : 54 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
12584 : : {
12585 : : /* avoid dangling else. */
12586 : 54 : if (M2Base_IsRealType (SymbolTable_GetSType (Var)))
12587 : : {
12588 : : /* build macro: CONVERT( INTEGER, Var ). */
12589 : 54 : M2Quads_PushTFtok (ProcSym, static_cast<unsigned int> (SymbolTable_NulSym), functok);
12590 : 54 : M2Quads_PushTtok (Type, functok);
12591 : 54 : M2Quads_PushTtok (Var, vartok);
12592 : 54 : M2Quads_PushT (static_cast<unsigned int> (2)); /* two parameters */
12593 : 54 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* two parameters */
12594 : : }
12595 : : else
12596 : : {
12597 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "argument to {%1Ead} must be a float point type", 46, Sym);
12598 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), Type), Type, functok);
12599 : : }
12600 : : }
12601 : : else
12602 : : {
12603 : : /* avoid dangling else. */
12604 : 0 : M2MetaError_MetaErrorT2 (vartok, (const char *) "argument to {%1Ead} must be a variable or constant, seen {%2ad}", 63, Sym, Var);
12605 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), Type), Type, functok);
12606 : : }
12607 : : }
12608 : : else
12609 : : {
12610 : 0 : M2Error_InternalError ((const char *) "CONVERT procedure not found for TRUNC substitution", 50);
12611 : : }
12612 : : }
12613 : : else
12614 : : {
12615 : : /* non recoverable error. */
12616 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkTRUNC} only has one parameter, seen {%1n}", 84, NoOfParam);
12617 : : }
12618 : 60 : }
12619 : :
12620 : :
12621 : : /*
12622 : : BuildFloatFunction - builds the pseudo procedure call FLOAT.
12623 : : This procedure is actually a "macro" for
12624 : : FLOAT(x) --> CONVERT(REAL, x)
12625 : : However we cannot push tokens back onto the input stack
12626 : : because the compiler is currently building a function
12627 : : call and expecting a ReturnVar on the stack.
12628 : : Hence we manipulate the stack and call
12629 : : BuildConvertFunction.
12630 : :
12631 : : The Stack:
12632 : :
12633 : :
12634 : : Entry Exit
12635 : :
12636 : : Ptr ->
12637 : : +----------------+
12638 : : | NoOfParam |
12639 : : |----------------|
12640 : : | Param 1 |
12641 : : |----------------|
12642 : : | Param 2 |
12643 : : |----------------|
12644 : : . .
12645 : : . .
12646 : : . .
12647 : : |----------------|
12648 : : | Param # |
12649 : : |----------------|
12650 : : | ProcSym | Type | Empty
12651 : : |----------------|
12652 : : */
12653 : :
12654 : 88 : static void BuildFloatFunction (unsigned int Sym, bool ConstExpr)
12655 : : {
12656 : 88 : unsigned int combinedtok;
12657 : 88 : unsigned int vartok;
12658 : 88 : unsigned int functok;
12659 : 88 : unsigned int NoOfParam;
12660 : 88 : unsigned int ReturnVar;
12661 : 88 : unsigned int Type;
12662 : 88 : unsigned int Var;
12663 : 88 : unsigned int ProcSym;
12664 : :
12665 : 88 : M2Quads_PopT (&NoOfParam);
12666 : 88 : functok = OperandTtok (NoOfParam+1);
12667 : 88 : Type = SymbolTable_GetSType (Sym);
12668 : 88 : if (NoOfParam == 1)
12669 : : {
12670 : 88 : ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "CONVERT", 7));
12671 : 88 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
12672 : : {
12673 : 88 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12674 : 88 : vartok = OperandTtok (1);
12675 : 88 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function. */
12676 : 88 : if (ConstExprError (Sym, Var, vartok, ConstExpr))
12677 : : {
12678 : : /* Generate fake result. */
12679 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
12680 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12681 : 6 : SymbolTable_PutVar (ReturnVar, Type);
12682 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12683 : : }
12684 : 82 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
12685 : : {
12686 : : /* avoid dangling else. */
12687 : : /* build macro: CONVERT (REAL, Var). */
12688 : 82 : M2Quads_PushTFtok (ProcSym, static_cast<unsigned int> (SymbolTable_NulSym), functok);
12689 : 82 : M2Quads_PushTtok (Type, functok);
12690 : 82 : M2Quads_PushTtok (Var, vartok);
12691 : 82 : M2Quads_PushT (static_cast<unsigned int> (2)); /* two parameters. */
12692 : 82 : BuildConvertFunction (ProcSym, ConstExpr); /* two parameters. */
12693 : : }
12694 : : else
12695 : : {
12696 : : /* avoid dangling else. */
12697 : 0 : M2MetaError_MetaErrorT1 (vartok, (const char *) "argument to {%1Ead} must be a variable or constant", 50, ProcSym);
12698 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0.0", 3), Type), Type, functok);
12699 : : }
12700 : : }
12701 : : else
12702 : : {
12703 : 0 : M2Error_InternalError ((const char *) "CONVERT procedure not found for FLOAT substitution", 50);
12704 : : }
12705 : : }
12706 : : else
12707 : : {
12708 : 0 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function. */
12709 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter", 61, Sym); /* destroy arguments to this function. */
12710 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0.0", 3), Type), Type, functok);
12711 : : }
12712 : 88 : }
12713 : :
12714 : :
12715 : : /*
12716 : : BuildReFunction - builds the pseudo procedure call RE.
12717 : :
12718 : : The Stack:
12719 : :
12720 : :
12721 : : Entry Exit
12722 : :
12723 : : Ptr ->
12724 : : +----------------+
12725 : : | NoOfParam |
12726 : : |----------------|
12727 : : | Param 1 |
12728 : : |----------------|
12729 : : | Param 2 |
12730 : : |----------------|
12731 : : . .
12732 : : . .
12733 : : . .
12734 : : |----------------|
12735 : : | Param # |
12736 : : |----------------|
12737 : : | ProcSym | Type | Empty
12738 : : |----------------|
12739 : : */
12740 : :
12741 : 60 : static void BuildReFunction (unsigned int Sym, bool ConstExpr)
12742 : : {
12743 : 60 : unsigned int func;
12744 : 60 : unsigned int combinedtok;
12745 : 60 : unsigned int vartok;
12746 : 60 : unsigned int functok;
12747 : 60 : unsigned int NoOfParam;
12748 : 60 : unsigned int ReturnVar;
12749 : 60 : unsigned int Type;
12750 : 60 : unsigned int Var;
12751 : :
12752 : 60 : M2Quads_PopT (&NoOfParam);
12753 : 60 : functok = OperandTtok (NoOfParam+1);
12754 : 60 : func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12755 : 60 : if (NoOfParam == 1)
12756 : : {
12757 : 60 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12758 : 60 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12759 : 60 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
12760 : 60 : Type = M2Base_ComplexToScalar (SymbolTable_GetDType (Var));
12761 : 60 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12762 : 60 : if (ConstExprError (Sym, Var, vartok, ConstExpr))
12763 : : {
12764 : : /* Generate fake result. */
12765 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
12766 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12767 : 6 : SymbolTable_PutVar (ReturnVar, Type);
12768 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12769 : : }
12770 : 54 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
12771 : : {
12772 : : /* avoid dangling else. */
12773 : 108 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12774 : 54 : SymbolTable_PutVar (ReturnVar, Type);
12775 : 108 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Re, Var, false);
12776 : 54 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12777 : : }
12778 : : else
12779 : : {
12780 : : /* avoid dangling else. */
12781 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, combinedtok);
12782 : 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);
12783 : : }
12784 : : }
12785 : : else
12786 : : {
12787 : 0 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12788 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, functok); /* destroy arguments to this function */
12789 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter, seen {%2n}", 73, func, NoOfParam);
12790 : : }
12791 : 60 : }
12792 : :
12793 : :
12794 : : /*
12795 : : BuildImFunction - builds the pseudo procedure call IM.
12796 : :
12797 : : The Stack:
12798 : :
12799 : :
12800 : : Entry Exit
12801 : :
12802 : : Ptr ->
12803 : : +----------------+
12804 : : | NoOfParam |
12805 : : |----------------|
12806 : : | Param 1 |
12807 : : |----------------|
12808 : : | Param 2 |
12809 : : |----------------|
12810 : : . .
12811 : : . .
12812 : : . .
12813 : : |----------------|
12814 : : | Param # |
12815 : : |----------------|
12816 : : | ProcSym | Type | Empty
12817 : : |----------------|
12818 : : */
12819 : :
12820 : 60 : static void BuildImFunction (unsigned int Sym, bool ConstExpr)
12821 : : {
12822 : 60 : unsigned int func;
12823 : 60 : unsigned int combinedtok;
12824 : 60 : unsigned int vartok;
12825 : 60 : unsigned int functok;
12826 : 60 : unsigned int NoOfParam;
12827 : 60 : unsigned int ReturnVar;
12828 : 60 : unsigned int Type;
12829 : 60 : unsigned int Var;
12830 : :
12831 : 60 : M2Quads_PopT (&NoOfParam);
12832 : 60 : functok = OperandTtok (NoOfParam+1);
12833 : 60 : func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12834 : 60 : if (NoOfParam == 1)
12835 : : {
12836 : 60 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12837 : 60 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12838 : 60 : Type = M2Base_ComplexToScalar (SymbolTable_GetDType (Var));
12839 : 60 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
12840 : 60 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12841 : 60 : if (ConstExprError (Sym, Var, vartok, ConstExpr))
12842 : : {
12843 : : /* Generate fake result. */
12844 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
12845 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12846 : 6 : SymbolTable_PutVar (ReturnVar, Type);
12847 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12848 : : }
12849 : 54 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
12850 : : {
12851 : : /* avoid dangling else. */
12852 : 108 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12853 : 54 : SymbolTable_PutVar (ReturnVar, M2Base_ComplexToScalar (SymbolTable_GetDType (Var)));
12854 : 108 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Im, Var, false);
12855 : 54 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), combinedtok);
12856 : : }
12857 : : else
12858 : : {
12859 : : /* avoid dangling else. */
12860 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, combinedtok);
12861 : 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);
12862 : : }
12863 : : }
12864 : : else
12865 : : {
12866 : 0 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12867 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, functok); /* destroy arguments to this function */
12868 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter, seen {%2n}", 73, func, NoOfParam);
12869 : : }
12870 : 60 : }
12871 : :
12872 : :
12873 : : /*
12874 : : BuildCmplxFunction - builds the pseudo procedure call CMPLX.
12875 : :
12876 : : The Stack:
12877 : :
12878 : :
12879 : : Entry Exit
12880 : :
12881 : : Ptr ->
12882 : : +----------------+
12883 : : | NoOfParam |
12884 : : |----------------|
12885 : : | Param 1 |
12886 : : |----------------|
12887 : : | Param 2 |
12888 : : |----------------|
12889 : : . .
12890 : : . .
12891 : : . .
12892 : : |----------------|
12893 : : | Param # |
12894 : : |----------------|
12895 : : | ProcSym | Type | Empty
12896 : : |----------------|
12897 : : */
12898 : :
12899 : 492 : static void BuildCmplxFunction (unsigned int func, bool ConstExpr)
12900 : : {
12901 : 492 : bool failure;
12902 : 492 : unsigned int functok;
12903 : 492 : unsigned int rtok;
12904 : 492 : unsigned int ltok;
12905 : 492 : unsigned int combinedtok;
12906 : 492 : unsigned int NoOfParam;
12907 : 492 : unsigned int type;
12908 : 492 : unsigned int ReturnVar;
12909 : 492 : unsigned int l;
12910 : 492 : unsigned int r;
12911 : :
12912 : 492 : M2Quads_PopT (&NoOfParam);
12913 : 492 : functok = OperandTtok (NoOfParam+1);
12914 : 492 : if (NoOfParam == 2)
12915 : : {
12916 : 492 : l = static_cast<unsigned int> (M2Quads_OperandT (2));
12917 : 492 : ltok = OperandTtok (2);
12918 : 492 : r = static_cast<unsigned int> (M2Quads_OperandT (1));
12919 : 492 : rtok = OperandTtok (1);
12920 : 492 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, rtok);
12921 : 492 : M2Quads_PopN (NoOfParam+1); /* Destroy arguments to this function. */
12922 : 492 : type = M2Base_GetCmplxReturnType (SymbolTable_GetDType (l), SymbolTable_GetDType (r)); /* Destroy arguments to this function. */
12923 : 570 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant ((SymbolTable_IsConst (l)) && (SymbolTable_IsConst (r))));
12924 : 492 : SymbolTable_PutVar (ReturnVar, type);
12925 : 492 : failure = false;
12926 : 492 : if (ConstExprError (func, l, ltok, ConstExpr))
12927 : : {
12928 : : /* ConstExprError has generated an error message we will fall through
12929 : : and check the right operand. */
12930 : : failure = true;
12931 : : }
12932 : 492 : if (ConstExprError (func, r, rtok, ConstExpr))
12933 : : {
12934 : : /* Right operand is in error as a variable. */
12935 : : failure = true;
12936 : : }
12937 : 486 : if (failure)
12938 : : {
12939 : : /* Generate a fake result if either operand was a variable (and we
12940 : : are in a const expression). */
12941 : 6 : M2Quads_PushTFtok (ReturnVar, type, combinedtok);
12942 : : }
12943 : 486 : else if (((SymbolTable_IsVar (l)) || (SymbolTable_IsConst (l))) && ((SymbolTable_IsVar (r)) || (SymbolTable_IsConst (r))))
12944 : : {
12945 : : /* avoid dangling else. */
12946 : 486 : M2Base_CheckExpressionCompatible (combinedtok, SymbolTable_GetSType (l), SymbolTable_GetSType (r));
12947 : 486 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Cmplx, SymbolTable_Make2Tuple (l, r), true);
12948 : 486 : M2Quads_PushTFtok (ReturnVar, type, combinedtok);
12949 : : }
12950 : : else
12951 : : {
12952 : : /* avoid dangling else. */
12953 : 0 : if ((SymbolTable_IsVar (l)) || (SymbolTable_IsConst (l)))
12954 : : {
12955 : 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);
12956 : : }
12957 : : else
12958 : : {
12959 : 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);
12960 : : }
12961 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_CType), M2Base_CType, combinedtok);
12962 : : }
12963 : : }
12964 : : else
12965 : : {
12966 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure {%1Ead} requires two parameters, seen {%2n}", 65, func, NoOfParam);
12967 : 0 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12968 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_CType), M2Base_CType, functok); /* destroy arguments to this function */
12969 : : }
12970 : 492 : }
12971 : :
12972 : :
12973 : : /*
12974 : : BuildAdrFunction - builds the pseudo function ADR
12975 : : The Stack:
12976 : :
12977 : :
12978 : : Entry Exit
12979 : :
12980 : : Ptr ->
12981 : : +----------------+
12982 : : | NoOfParam |
12983 : : |----------------|
12984 : : | Param 1 |
12985 : : |----------------|
12986 : : | Param 2 |
12987 : : |----------------|
12988 : : . .
12989 : : . .
12990 : : . .
12991 : : |----------------|
12992 : : | Param # | <- Ptr
12993 : : |----------------| +------------+
12994 : : | ProcSym | Type | | ReturnVar |
12995 : : |----------------| |------------|
12996 : :
12997 : : */
12998 : :
12999 : 178504 : static void BuildAdrFunction (void)
13000 : : {
13001 : 178504 : unsigned int endtok;
13002 : 178504 : unsigned int combinedTok;
13003 : 178504 : unsigned int procTok;
13004 : 178504 : unsigned int t;
13005 : 178504 : unsigned int UnboundedSym;
13006 : 178504 : unsigned int Dim;
13007 : 178504 : unsigned int Field;
13008 : 178504 : unsigned int noOfParameters;
13009 : 178504 : unsigned int procSym;
13010 : 178504 : unsigned int returnVar;
13011 : 178504 : unsigned int Type;
13012 : 178504 : unsigned int rw;
13013 : :
13014 : 178504 : M2Quads_DisplayStack ();
13015 : 178504 : M2Quads_PopT (&noOfParameters);
13016 : 178504 : procSym = static_cast<unsigned int> (M2Quads_OperandT (noOfParameters+1));
13017 : 178504 : procTok = static_cast<unsigned int> (M2Quads_OperandTok (noOfParameters+1)); /* token of procedure ADR. */
13018 : 178504 : endtok = static_cast<unsigned int> (M2Quads_OperandTok (1)); /* last parameter. */
13019 : 178504 : combinedTok = M2LexBuf_MakeVirtualTok (procTok, procTok, endtok); /* last parameter. */
13020 : 178504 : if (noOfParameters != 1)
13021 : : {
13022 : 0 : M2MetaError_MetaErrorNT0 (combinedTok, (const char *) "SYSTEM procedure ADR expects 1 parameter", 40);
13023 : 0 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
13024 : 0 : M2Quads_PushTF (M2Base_Nil, M2System_Address); /* destroy the arguments and function */
13025 : : }
13026 : 178504 : else if (SymbolTable_IsConstString (M2Quads_OperandT (1)))
13027 : : {
13028 : : /* avoid dangling else. */
13029 : 170706 : returnVar = MakeLeftValue (combinedTok, M2Quads_OperandT (1), SymbolTable_RightValue, SymbolTable_GetSType (procSym));
13030 : 170706 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
13031 : 170706 : M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (returnVar), combinedTok); /* destroy the arguments and function */
13032 : : }
13033 : 7798 : else if ((! (SymbolTable_IsVar (M2Quads_OperandT (1)))) && (! (SymbolTable_IsProcedure (M2Quads_OperandT (1)))))
13034 : : {
13035 : : /* avoid dangling else. */
13036 : 0 : M2MetaError_MetaErrorNT0 (combinedTok, (const char *) "SYSTEM procedure ADR expects a variable, procedure or a constant string as its parameter", 88);
13037 : 0 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
13038 : 0 : M2Quads_PushTFtok (M2Base_Nil, M2System_Address, combinedTok); /* destroy the arguments and function */
13039 : : }
13040 : 7798 : else if (SymbolTable_IsProcedure (M2Quads_OperandT (1)))
13041 : : {
13042 : : /* avoid dangling else. */
13043 : 24 : returnVar = MakeLeftValue (combinedTok, M2Quads_OperandT (1), SymbolTable_RightValue, SymbolTable_GetSType (procSym));
13044 : 24 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
13045 : 24 : M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (returnVar), combinedTok); /* destroy the arguments and function */
13046 : : }
13047 : : else
13048 : : {
13049 : : /* avoid dangling else. */
13050 : 7774 : Type = SymbolTable_GetSType (M2Quads_OperandT (1));
13051 : 7774 : Dim = static_cast<unsigned int> (OperandD (1));
13052 : 7774 : MarkArrayWritten (M2Quads_OperandT (1));
13053 : 7774 : MarkArrayWritten (M2Quads_OperandA (1));
13054 : : /* if the operand is an unbounded which has not been indexed
13055 : : then we will lookup its address from the unbounded record.
13056 : : Otherwise we obtain the address of the operand.
13057 : : */
13058 : 7774 : if ((SymbolTable_IsUnbounded (Type)) && (Dim == 0))
13059 : : {
13060 : : /* we will reference the address field of the unbounded structure */
13061 : 2358 : UnboundedSym = static_cast<unsigned int> (M2Quads_OperandT (1));
13062 : 2358 : rw = static_cast<unsigned int> (OperandRW (1));
13063 : 2358 : PushTFrw (UnboundedSym, SymbolTable_GetSType (UnboundedSym), rw);
13064 : 2358 : Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
13065 : 2358 : M2Quads_PushTF (Field, SymbolTable_GetSType (Field));
13066 : 2358 : M2Quads_PushT (static_cast<unsigned int> (1));
13067 : 2358 : M2Quads_BuildDesignatorRecord (combinedTok);
13068 : 2358 : PopTrw (&returnVar, &rw);
13069 : 2358 : if ((SymbolTable_GetMode (returnVar)) == SymbolTable_LeftValue)
13070 : : {
13071 : 0 : t = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
13072 : 0 : SymbolTable_PutVar (t, SymbolTable_GetSType (procSym));
13073 : 0 : doIndrX (combinedTok, t, returnVar);
13074 : 0 : returnVar = t;
13075 : : }
13076 : : else
13077 : : {
13078 : : /* we need to cast returnVar into ADDRESS */
13079 : 2358 : t = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
13080 : 2358 : SymbolTable_PutVar (t, SymbolTable_GetSType (procSym));
13081 : 2358 : GenQuadO (combinedTok, M2Quads_ConvertOp, t, SymbolTable_GetSType (procSym), returnVar, false);
13082 : 2358 : returnVar = t;
13083 : : }
13084 : : }
13085 : : else
13086 : : {
13087 : 5416 : returnVar = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
13088 : 5416 : SymbolTable_PutVar (returnVar, SymbolTable_GetSType (procSym));
13089 : 5416 : if ((SymbolTable_GetMode (M2Quads_OperandT (1))) == SymbolTable_LeftValue)
13090 : : {
13091 : 440 : SymbolTable_PutVar (returnVar, SymbolTable_GetSType (procSym));
13092 : 440 : GenQuadO (combinedTok, M2Quads_ConvertOp, returnVar, SymbolTable_GetSType (procSym), M2Quads_OperandT (1), false);
13093 : : }
13094 : : else
13095 : : {
13096 : 4976 : GenQuadO (combinedTok, M2Quads_AddrOp, returnVar, SymbolTable_NulSym, M2Quads_OperandT (1), false);
13097 : : }
13098 : 5416 : SymbolTable_PutWriteQuad (M2Quads_OperandT (1), SymbolTable_GetMode (M2Quads_OperandT (1)), NextQuad-1);
13099 : 5416 : rw = static_cast<unsigned int> (OperandMergeRW (1));
13100 : 5416 : M2Debug_Assert (SymbolTable_IsLegal (rw));
13101 : : }
13102 : 7774 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
13103 : 7774 : PushTFrwtok (returnVar, SymbolTable_GetSType (returnVar), rw, combinedTok); /* destroy the arguments and function */
13104 : : }
13105 : 178504 : }
13106 : :
13107 : :
13108 : : /*
13109 : : BuildSizeFunction - builds the pseudo function SIZE
13110 : : The Stack:
13111 : :
13112 : :
13113 : : Entry Exit
13114 : :
13115 : : Ptr ->
13116 : : +----------------+
13117 : : | NoOfParam |
13118 : : |----------------|
13119 : : | Param 1 |
13120 : : |----------------|
13121 : : | Param 2 |
13122 : : |----------------|
13123 : : . .
13124 : : . .
13125 : : . .
13126 : : |----------------|
13127 : : | Param # | <- Ptr
13128 : : |----------------| +------------+
13129 : : | ProcSym | Type | | ReturnVar |
13130 : : |----------------| |------------|
13131 : : */
13132 : :
13133 : 2050 : static void BuildSizeFunction (void)
13134 : : {
13135 : 2050 : unsigned int resulttok;
13136 : 2050 : unsigned int paramtok;
13137 : 2050 : unsigned int functok;
13138 : 2050 : unsigned int dim;
13139 : 2050 : unsigned int Type;
13140 : 2050 : unsigned int NoOfParam;
13141 : 2050 : unsigned int ProcSym;
13142 : 2050 : unsigned int ReturnVar;
13143 : :
13144 : 2050 : M2Quads_PopT (&NoOfParam);
13145 : 2050 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
13146 : 2050 : functok = OperandTtok (NoOfParam+1);
13147 : 2050 : if (NoOfParam != 1)
13148 : : {
13149 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "{%E} SYSTEM procedure function {%kSIZE} requires one parameter, seen {%1n}", 74, NoOfParam);
13150 : 0 : resulttok = functok;
13151 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13152 : : }
13153 : 2050 : else if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
13154 : : {
13155 : : /* avoid dangling else. */
13156 : 968 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
13157 : 968 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13158 : 968 : BuildSizeCheckEnd (ProcSym); /* Quadruple generation now on. */
13159 : 968 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue); /* Quadruple generation now on. */
13160 : 968 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, M2Quads_OperandT (1), true);
13161 : : }
13162 : 1082 : else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
13163 : : {
13164 : : /* avoid dangling else. */
13165 : 1076 : BuildSizeCheckEnd (ProcSym); /* Quadruple generation now on. */
13166 : 1076 : Type = SymbolTable_GetSType (M2Quads_OperandT (1)); /* Quadruple generation now on. */
13167 : 1076 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
13168 : 1076 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13169 : 1076 : if (SymbolTable_IsUnbounded (Type))
13170 : : {
13171 : : /* Eg. SIZE(a) ; where a is unbounded dereference HIGH and multiply by the TYPE. */
13172 : 168 : dim = static_cast<unsigned int> (OperandD (1));
13173 : 168 : if (dim == 0)
13174 : : {
13175 : 72 : ReturnVar = calculateMultipicand (resulttok, M2Quads_OperandT (1), Type, dim);
13176 : : }
13177 : : else
13178 : : {
13179 : 96 : ReturnVar = calculateMultipicand (resulttok, M2Quads_OperandA (1), Type, dim);
13180 : : }
13181 : : }
13182 : : else
13183 : : {
13184 : 908 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13185 : 908 : if (Type == SymbolTable_NulSym)
13186 : : {
13187 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "cannot get the type and size of {%1Ead}", 39, M2Quads_OperandT (1));
13188 : : }
13189 : 908 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, Type, true);
13190 : : }
13191 : : }
13192 : : else
13193 : : {
13194 : : /* avoid dangling else. */
13195 : 6 : resulttok = functok;
13196 : 6 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure {%kSIZE} expects a variable or type as its parameter, seen {%1Ed}", 86, M2Quads_OperandT (1));
13197 : 6 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13198 : : }
13199 : 2050 : M2Quads_PopN (NoOfParam+1); /* Destroy the arguments and function. */
13200 : 2050 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok); /* Destroy the arguments and function. */
13201 : 2050 : }
13202 : :
13203 : :
13204 : : /*
13205 : : BuildTSizeFunction - builds the pseudo function TSIZE
13206 : : The Stack:
13207 : :
13208 : :
13209 : : Entry Exit
13210 : :
13211 : : Ptr ->
13212 : : +----------------+
13213 : : | NoOfParam |
13214 : : |----------------|
13215 : : | Param 1 |
13216 : : |----------------|
13217 : : | Param 2 |
13218 : : |----------------|
13219 : : . .
13220 : : . .
13221 : : . .
13222 : : |----------------|
13223 : : | Param # | <- Ptr
13224 : : |----------------| +------------+
13225 : : | ProcSym | Type | | ReturnVar |
13226 : : |----------------| |------------|
13227 : :
13228 : : */
13229 : :
13230 : 4758 : static void BuildTSizeFunction (void)
13231 : : {
13232 : 4758 : unsigned int resulttok;
13233 : 4758 : unsigned int paramtok;
13234 : 4758 : unsigned int functok;
13235 : 4758 : unsigned int NoOfParam;
13236 : 4758 : unsigned int ProcSym;
13237 : 4758 : unsigned int Record;
13238 : 4758 : unsigned int ReturnVar;
13239 : :
13240 : 4758 : M2Quads_PopT (&NoOfParam);
13241 : 4758 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
13242 : 4758 : functok = OperandTtok (NoOfParam);
13243 : 4758 : BuildSizeCheckEnd (ProcSym); /* quadruple generation now on */
13244 : 4758 : if (NoOfParam == 1) /* quadruple generation now on */
13245 : : {
13246 : 4758 : paramtok = OperandTtok (1);
13247 : 4758 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13248 : 4758 : if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
13249 : : {
13250 : 4724 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13251 : 4724 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
13252 : 4724 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, M2Quads_OperandT (1), false);
13253 : : }
13254 : 34 : else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
13255 : : {
13256 : : /* avoid dangling else. */
13257 : 28 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13258 : 28 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
13259 : 28 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, SymbolTable_GetSType (M2Quads_OperandT (1)), false);
13260 : : }
13261 : : else
13262 : : {
13263 : : /* avoid dangling else. */
13264 : 6 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTSIZE} expects a variable or type as its first parameter, seen {%1Ed}", 102, M2Quads_OperandT (1));
13265 : 6 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13266 : : }
13267 : : }
13268 : 0 : else if (NoOfParam == 0)
13269 : : {
13270 : : /* avoid dangling else. */
13271 : 0 : resulttok = functok;
13272 : 0 : M2MetaError_MetaErrorT0 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTSIZE} expects either one or two parameters, seen none", 87);
13273 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13274 : : }
13275 : : else
13276 : : {
13277 : : /* avoid dangling else. */
13278 : 0 : Record = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
13279 : 0 : paramtok = OperandTtok (1);
13280 : 0 : resulttok = OperandTtok (NoOfParam);
13281 : 0 : if (SymbolTable_IsRecord (Record))
13282 : : {
13283 : 0 : paramtok = OperandTtok (1);
13284 : 0 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13285 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13286 : 0 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
13287 : 0 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, Record, false);
13288 : : }
13289 : : else
13290 : : {
13291 : 0 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13292 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTSIZE} expects the first parameter to be a record type, seen {%1d}", 99, Record);
13293 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13294 : : }
13295 : : }
13296 : 4758 : M2Quads_PopN (NoOfParam+1); /* destroy the arguments and function */
13297 : 4758 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok); /* destroy the arguments and function */
13298 : 4758 : }
13299 : :
13300 : :
13301 : : /*
13302 : : BuildTBitSizeFunction - builds the pseudo function TBITSIZE
13303 : : The Stack:
13304 : :
13305 : :
13306 : : Entry Exit
13307 : :
13308 : : Ptr ->
13309 : : +----------------+
13310 : : | NoOfParam |
13311 : : |----------------|
13312 : : | Param 1 |
13313 : : |----------------|
13314 : : | Param 2 |
13315 : : |----------------|
13316 : : . .
13317 : : . .
13318 : : . .
13319 : : |----------------|
13320 : : | Param # | <- Ptr
13321 : : |----------------| +------------+
13322 : : | ProcSym | Type | | ReturnVar |
13323 : : |----------------| |------------|
13324 : :
13325 : : */
13326 : :
13327 : 6364 : static void BuildTBitSizeFunction (void)
13328 : : {
13329 : 6364 : unsigned int resulttok;
13330 : 6364 : unsigned int paramtok;
13331 : 6364 : unsigned int functok;
13332 : 6364 : unsigned int NoOfParam;
13333 : 6364 : unsigned int ProcSym;
13334 : 6364 : unsigned int Record;
13335 : 6364 : unsigned int ReturnVar;
13336 : :
13337 : 6364 : M2Quads_PopT (&NoOfParam);
13338 : 6364 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
13339 : 6364 : functok = OperandTtok (NoOfParam);
13340 : 6364 : BuildSizeCheckEnd (ProcSym); /* quadruple generation now on */
13341 : 6364 : if (NoOfParam == 1) /* quadruple generation now on */
13342 : : {
13343 : 6364 : paramtok = OperandTtok (1);
13344 : 6364 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13345 : 6364 : if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
13346 : : {
13347 : 6292 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13348 : 6292 : GenQuadO (resulttok, M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1), false);
13349 : : }
13350 : 72 : else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
13351 : : {
13352 : : /* avoid dangling else. */
13353 : 72 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13354 : 72 : GenQuadO (resulttok, M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1), false);
13355 : : }
13356 : : else
13357 : : {
13358 : : /* avoid dangling else. */
13359 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTBITSIZE} expects a variable as its first parameter, seen {%1d}", 96, M2Quads_OperandT (1));
13360 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13361 : : }
13362 : : }
13363 : 0 : else if (NoOfParam == 0)
13364 : : {
13365 : : /* avoid dangling else. */
13366 : 0 : resulttok = functok;
13367 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure function {%kTBITSIZE} expects either one or two parameters, seen none", 90);
13368 : 0 : ReturnVar = SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13369 : : }
13370 : : else
13371 : : {
13372 : : /* avoid dangling else. */
13373 : 0 : Record = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
13374 : 0 : paramtok = OperandTtok (1);
13375 : 0 : resulttok = OperandTtok (NoOfParam);
13376 : 0 : if (SymbolTable_IsRecord (Record))
13377 : : {
13378 : 0 : paramtok = OperandTtok (1);
13379 : 0 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13380 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13381 : 0 : GenQuad (M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1));
13382 : : }
13383 : : else
13384 : : {
13385 : 0 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13386 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTBITSIZE} expects the first parameter to be a record type, seen {%1d}", 102, Record);
13387 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13388 : : }
13389 : : }
13390 : 6364 : M2Quads_PopN (NoOfParam+1); /* destroy the arguments and function */
13391 : 6364 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok); /* destroy the arguments and function */
13392 : 6364 : }
13393 : :
13394 : :
13395 : : /*
13396 : : ExpectingParameterType -
13397 : : */
13398 : :
13399 : 90939 : static void ExpectingParameterType (unsigned int BlockSym, unsigned int Type)
13400 : : {
13401 : 90939 : if (! (SymbolTable_IsAModula2Type (Type)))
13402 : : {
13403 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13404 : 6 : if (((Type == SymbolTable_NulSym) || (SymbolTable_IsPartialUnbounded (Type))) || (SymbolTable_IsUnknown (Type)))
13405 : : {
13406 : 0 : if (SymbolTable_IsUnknown (Type))
13407 : : {
13408 : : /* Spellcheck. */
13409 : 0 : M2MetaError_MetaError2 ((const char *) "the type used in the formal parameter declaration in {%1Md} {%1a} is unknown {%2&s}", 83, BlockSym, Type);
13410 : 0 : SymbolTable_UnknownReported (Type);
13411 : : }
13412 : : else
13413 : : {
13414 : 0 : M2MetaError_MetaError1 ((const char *) "the type used in the formal parameter declaration in {%1Md} {%1a} is unknown", 76, BlockSym);
13415 : : }
13416 : : }
13417 : : else
13418 : : {
13419 : : /* --fixme-- filter spellcheck on type. */
13420 : 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);
13421 : : }
13422 : : }
13423 : 90939 : }
13424 : :
13425 : :
13426 : : /*
13427 : : ExpectingVariableType -
13428 : : */
13429 : :
13430 : 82544 : static void ExpectingVariableType (unsigned int BlockSym, unsigned int Type)
13431 : : {
13432 : 82544 : if (! (SymbolTable_IsAModula2Type (Type)))
13433 : : {
13434 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13435 : 0 : if (Type == SymbolTable_NulSym)
13436 : : {
13437 : 0 : M2MetaError_MetaError1 ((const char *) "the type used during the variable declaration section in procedure {%1EMad} is unknown", 86, BlockSym);
13438 : 0 : M2MetaError_MetaError1 ((const char *) "the type used during the variable declaration section in procedure {%1Ead} is unknown", 85, BlockSym);
13439 : : }
13440 : 0 : else if ((SymbolTable_IsPartialUnbounded (Type)) || (SymbolTable_IsUnknown (Type)))
13441 : : {
13442 : : /* avoid dangling else. */
13443 : : /* Spellcheck. */
13444 : 0 : M2MetaError_MetaError2 ((const char *) "the type {%1EMad} used during variable declaration section in procedure {%2ad} is unknown {%1&s}", 96, Type, BlockSym);
13445 : 0 : M2MetaError_MetaError2 ((const char *) "the type {%1Ead} used during variable declaration section in procedure {%2Mad} is unknown", 89, Type, BlockSym);
13446 : 0 : SymbolTable_UnknownReported (Type);
13447 : : }
13448 : : else
13449 : : {
13450 : : /* avoid dangling else. */
13451 : 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);
13452 : : }
13453 : : }
13454 : 82544 : }
13455 : :
13456 : :
13457 : : /*
13458 : : CheckVariablesAndParameterTypesInBlock - checks to make sure that block, BlockSym, has
13459 : : parameters types and variable types which are legal.
13460 : : */
13461 : :
13462 : 179752 : static void CheckVariablesAndParameterTypesInBlock (unsigned int BlockSym)
13463 : : {
13464 : 179752 : unsigned int i;
13465 : 179752 : unsigned int n;
13466 : 179752 : unsigned int ParamNo;
13467 : :
13468 : 179752 : if (SymbolTable_IsProcedure (BlockSym))
13469 : : {
13470 : 80928 : ParamNo = SymbolTable_NoOfParamAny (BlockSym);
13471 : : }
13472 : : else
13473 : : {
13474 : : ParamNo = 0;
13475 : : }
13476 : 179752 : i = 1;
13477 : 1307428 : do {
13478 : 1307428 : n = SymbolTable_GetNth (BlockSym, i);
13479 : 1307428 : if (((n != SymbolTable_NulSym) && (! (SymbolTable_IsTemporary (n)))) && ((SymbolTable_IsProcedure (BlockSym)) || (((SymbolTable_IsDefImp (BlockSym)) && ((SymbolTable_GetMainModule ()) == BlockSym)) || (SymbolTable_IsModule (BlockSym)))))
13480 : : {
13481 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13482 : 173483 : if (i <= ParamNo)
13483 : : {
13484 : : /* n is a parameter */
13485 : 90939 : ExpectingParameterType (BlockSym, SymbolTable_GetSType (n));
13486 : : }
13487 : : else
13488 : : {
13489 : : /* n is a local variable */
13490 : 82544 : ExpectingVariableType (BlockSym, SymbolTable_GetSType (n));
13491 : : }
13492 : : }
13493 : 1307428 : i += 1;
13494 : 1307428 : } while (! (n == SymbolTable_NulSym));
13495 : 179752 : }
13496 : :
13497 : :
13498 : : /*
13499 : : IsNeverAltered - returns TRUE if variable, sym, is never altered
13500 : : between quadruples: Start..End
13501 : : */
13502 : :
13503 : 30 : static bool IsNeverAltered (unsigned int sym, unsigned int Start, unsigned int End)
13504 : : {
13505 : 30 : unsigned int WriteStart;
13506 : 30 : unsigned int WriteEnd;
13507 : :
13508 : 30 : SymbolTable_GetWriteLimitQuads (sym, SymbolTable_GetMode (sym), Start, End, &WriteStart, &WriteEnd);
13509 : 30 : return (WriteStart == 0) && (WriteEnd == 0);
13510 : : /* static analysis guarentees a RETURN statement will be used before here. */
13511 : : __builtin_unreachable ();
13512 : : }
13513 : :
13514 : :
13515 : : /*
13516 : : IsConditionVariable - returns TRUE if the condition at quadruple, q, is variable.
13517 : : */
13518 : :
13519 : 24 : static bool IsConditionVariable (unsigned int q, unsigned int Start, unsigned int End)
13520 : : {
13521 : 24 : M2Quads_QuadOperator op;
13522 : 24 : unsigned int op1;
13523 : 24 : unsigned int op2;
13524 : 24 : unsigned int op3;
13525 : 24 : bool LeftFixed;
13526 : 24 : bool RightFixed;
13527 : :
13528 : 24 : M2Quads_GetQuad (q, &op, &op1, &op2, &op3);
13529 : 24 : if (op == M2Quads_GotoOp)
13530 : : {
13531 : : return false;
13532 : : }
13533 : : else
13534 : : {
13535 : 24 : LeftFixed = SymbolTable_IsConst (op1);
13536 : 24 : RightFixed = SymbolTable_IsConst (op2);
13537 : 24 : if (! LeftFixed)
13538 : : {
13539 : 24 : LeftFixed = IsNeverAltered (op1, Start, End);
13540 : : }
13541 : 24 : if (! RightFixed)
13542 : : {
13543 : 6 : RightFixed = IsNeverAltered (op2, Start, End);
13544 : : }
13545 : 24 : return ! (LeftFixed && RightFixed);
13546 : : }
13547 : : /* static analysis guarentees a RETURN statement will be used before here. */
13548 : : __builtin_unreachable ();
13549 : : }
13550 : :
13551 : :
13552 : : /*
13553 : : IsInfiniteLoop - returns TRUE if an infinite loop is found.
13554 : : Given a backwards jump at, End, it returns a BOOLEAN which depends on
13555 : : whether a jump is found to jump beyond, End. If a conditonal jump is found
13556 : : to pass over, End, the condition is tested for global variables, procedure variables and
13557 : : constants.
13558 : :
13559 : : constant - ignored
13560 : : variables - tested to see whether they are altered inside the loop
13561 : : global variable - the procedure tests to see whether it is altered as above
13562 : : but will also test to see whether this loop calls a procedure
13563 : : in which case it believes the loop NOT to be infinite
13564 : : (as this procedure call might alter the global variable)
13565 : :
13566 : : Note that this procedure can easily be fooled by the user altering variables
13567 : : with pointers.
13568 : : */
13569 : :
13570 : 24 : static bool IsInfiniteLoop (unsigned int End)
13571 : : {
13572 : 24 : bool SeenCall;
13573 : 24 : bool IsGlobal;
13574 : 24 : unsigned int Current;
13575 : 24 : unsigned int Start;
13576 : 24 : M2Quads_QuadOperator op;
13577 : 24 : unsigned int op1;
13578 : 24 : unsigned int op2;
13579 : 24 : unsigned int op3;
13580 : :
13581 : 24 : SeenCall = false;
13582 : 24 : IsGlobal = false;
13583 : 24 : M2Quads_GetQuad (End, &op, &op1, &op2, &Start);
13584 : 24 : Current = Start;
13585 : 216 : while (Current != End)
13586 : : {
13587 : 216 : M2Quads_GetQuad (Current, &op, &op1, &op2, &op3);
13588 : : /* remember that this function is only called once we have optimized the redundant gotos and conditionals */
13589 : 216 : if ((M2Quads_IsConditional (Current)) && ! IsGlobal)
13590 : : {
13591 : 24 : IsGlobal = ((SymbolTable_IsVar (op1)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op1))))) || ((SymbolTable_IsVar (op2)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op2)))));
13592 : : }
13593 : 216 : if (op == M2Quads_CallOp)
13594 : : {
13595 : 12 : SeenCall = true;
13596 : : }
13597 : 216 : if ((op == M2Quads_GotoOp) || ((M2Quads_IsConditional (Current)) && (IsConditionVariable (Current, Start, End))))
13598 : : {
13599 : 24 : if ((op3 > End) || (op3 < Start))
13600 : : {
13601 : : return false; /* may jump out of this loop, good */
13602 : : }
13603 : : }
13604 : 192 : Current = M2Quads_GetNextQuad (Current);
13605 : : }
13606 : 0 : M2Quads_GetQuad (End, &op, &op1, &op2, &op3);
13607 : 0 : if (M2Quads_IsConditional (End))
13608 : : {
13609 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13610 : 0 : if (IsConditionVariable (End, Start, End))
13611 : : {
13612 : : return false;
13613 : : }
13614 : : else
13615 : : {
13616 : 0 : if (! IsGlobal)
13617 : : {
13618 : 0 : IsGlobal = ((SymbolTable_IsVar (op1)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op1))))) || ((SymbolTable_IsVar (op2)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op2)))));
13619 : : }
13620 : : }
13621 : : }
13622 : : /* we have found a likely infinite loop if no conditional uses a global and no procedure call was seen */
13623 : 0 : return ! (IsGlobal && SeenCall);
13624 : : /* static analysis guarentees a RETURN statement will be used before here. */
13625 : : __builtin_unreachable ();
13626 : : }
13627 : :
13628 : :
13629 : : /*
13630 : : CheckVariablesInBlock - given a block, BlockSym, check whether all variables are used.
13631 : : */
13632 : :
13633 : 179752 : static void CheckVariablesInBlock (unsigned int BlockSym)
13634 : : {
13635 : 0 : CheckVariablesAndParameterTypesInBlock (BlockSym);
13636 : 0 : }
13637 : :
13638 : :
13639 : : /*
13640 : : CheckFunctionReturn - checks to see that a RETURN statement was present in a function.
13641 : : */
13642 : :
13643 : 80928 : static void CheckFunctionReturn (unsigned int ProcSym)
13644 : : {
13645 : 80928 : M2Quads_QuadOperator Op;
13646 : 80928 : unsigned int Op1;
13647 : 80928 : unsigned int Op2;
13648 : 80928 : unsigned int Op3;
13649 : 80928 : unsigned int Scope;
13650 : 80928 : unsigned int Start;
13651 : 80928 : unsigned int End;
13652 : :
13653 : 80928 : if ((SymbolTable_GetSType (ProcSym)) != SymbolTable_NulSym)
13654 : : {
13655 : : /* yes it is a function */
13656 : 18963 : SymbolTable_GetProcedureQuads (ProcSym, &Scope, &Start, &End);
13657 : 18963 : M2Quads_GetQuad (Start, &Op, &Op1, &Op2, &Op3);
13658 : 18963 : if (Start == 0)
13659 : : {
13660 : 0 : M2Error_InternalError ((const char *) "incorrect start quad", 20);
13661 : : }
13662 : 771435 : while (((Start != End) && (Op != M2Quads_ReturnValueOp)) && (Op != M2Quads_InlineOp))
13663 : : {
13664 : 752472 : Start = M2Quads_GetNextQuad (Start);
13665 : 752472 : M2Quads_GetQuad (Start, &Op, &Op1, &Op2, &Op3);
13666 : : }
13667 : 18963 : if ((Op != M2Quads_ReturnValueOp) && (Op != M2Quads_InlineOp))
13668 : : {
13669 : : /* an InlineOp can always be used to emulate a RETURN */
13670 : 6 : M2MetaError_MetaError1 ((const char *) "procedure function {%1Ea} does not RETURN a value", 49, ProcSym);
13671 : : }
13672 : : }
13673 : 80928 : }
13674 : :
13675 : :
13676 : : /*
13677 : : CheckReturnType - checks to see that the return type from currentProc is
13678 : : assignment compatible with actualType.
13679 : : */
13680 : :
13681 : 27679 : static void CheckReturnType (unsigned int tokno, unsigned int currentProc, unsigned int actualVal, unsigned int actualType)
13682 : : {
13683 : 27679 : unsigned int procType;
13684 : 27679 : DynamicStrings_String s1;
13685 : 27679 : DynamicStrings_String s2;
13686 : 27679 : NameKey_Name n1;
13687 : 27679 : NameKey_Name n2;
13688 : :
13689 : 27679 : procType = SymbolTable_GetSType (currentProc);
13690 : 27679 : if (procType == SymbolTable_NulSym)
13691 : : {
13692 : 0 : M2MetaError_MetaError1 ((const char *) "attempting to RETURN a value from procedure {%1Ea} which was not a declared as a procedure function", 99, currentProc);
13693 : : }
13694 : 27679 : else if (M2Base_AssignmentRequiresWarning (actualType, SymbolTable_GetSType (currentProc)))
13695 : : {
13696 : : /* avoid dangling else. */
13697 : 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);
13698 : : }
13699 : 27679 : else if (! (M2Base_IsAssignmentCompatible (actualType, procType)))
13700 : : {
13701 : : /* avoid dangling else. */
13702 : 0 : n1 = SymbolTable_GetSymName (actualType);
13703 : 0 : n2 = SymbolTable_GetSymName (procType);
13704 : 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));
13705 : : }
13706 : 27679 : else if ((SymbolTable_IsProcedure (actualVal)) && (! (M2Base_IsAssignmentCompatible (actualVal, procType))))
13707 : : {
13708 : : /* avoid dangling else. */
13709 : : /*
13710 : : MetaWarnings2('attempting to RETURN a value with an incompatible type {%1ad} from function {%2a} which returns {%2ta}',
13711 : : actualVal, currentProc)
13712 : :
13713 : : --fixme-- introduce MetaWarning, MetaWarning2, MetaWarning3 into M2MetaError
13714 : : */
13715 : 0 : s1 = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (actualVal)));
13716 : 0 : s2 = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (procType)));
13717 : 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)));
13718 : : }
13719 : 27679 : else if ((SymbolTable_IsProcedure (actualVal)) && (! (M2Base_IsAssignmentCompatible (actualVal, SymbolTable_GetSType (CurrentProc)))))
13720 : : {
13721 : : /* avoid dangling else. */
13722 : 0 : n1 = SymbolTable_GetSymName (actualVal);
13723 : 0 : n2 = SymbolTable_GetSymName (SymbolTable_GetSType (currentProc));
13724 : 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));
13725 : : }
13726 : : else
13727 : : {
13728 : : /* avoid dangling else. */
13729 : : /* this checks the types are compatible, not the data contents. */
13730 : 27679 : BuildRange (M2Range_InitTypesReturnTypeCheck (tokno, currentProc, actualVal));
13731 : : }
13732 : 27679 : }
13733 : :
13734 : :
13735 : : /*
13736 : : BuildReturnLower - check the return type and value to ensure type
13737 : : compatibility and no range overflow will occur.
13738 : : */
13739 : :
13740 : 27679 : static void BuildReturnLower (unsigned int tokcombined, unsigned int tokexpr, unsigned int e1, unsigned int t1)
13741 : : {
13742 : 27679 : unsigned int e2;
13743 : 27679 : unsigned int t2;
13744 : :
13745 : : /* This will check that the type returned is compatible with
13746 : : the formal return type of the procedure. */
13747 : 27679 : CheckReturnType (tokcombined, CurrentProc, e1, t1);
13748 : : /* Dereference LeftValue if necessary. */
13749 : 27679 : if ((SymbolTable_GetMode (e1)) == SymbolTable_LeftValue)
13750 : : {
13751 : 172 : t2 = SymbolTable_GetSType (CurrentProc);
13752 : 172 : e2 = SymbolTable_MakeTemporary (tokexpr, SymbolTable_RightValue);
13753 : 172 : SymbolTable_PutVar (e2, t2);
13754 : 172 : CheckPointerThroughNil (tokexpr, e1);
13755 : 172 : doIndrX (tokexpr, e2, e1);
13756 : 172 : e1 = e2;
13757 : : }
13758 : : /* Here we check the data contents to ensure no overflow. */
13759 : 27679 : BuildRange (M2Range_InitReturnRangeCheck (tokcombined, CurrentProc, e1));
13760 : 27679 : GenQuadOtok (tokcombined, M2Quads_ReturnValueOp, e1, SymbolTable_NulSym, CurrentProc, false, tokcombined, M2LexBuf_UnknownTokenNo, SymbolTable_GetDeclaredMod (CurrentProc));
13761 : 27679 : }
13762 : :
13763 : :
13764 : : /*
13765 : : IsReadOnly - a helper procedure function to detect constants.
13766 : : */
13767 : :
13768 : 275489 : static bool IsReadOnly (unsigned int sym)
13769 : : {
13770 : 275489 : return (SymbolTable_IsConst (sym)) || ((SymbolTable_IsVar (sym)) && (SymbolTable_IsVarConst (sym)));
13771 : : /* static analysis guarentees a RETURN statement will be used before here. */
13772 : : __builtin_unreachable ();
13773 : : }
13774 : :
13775 : :
13776 : : /*
13777 : : BuildDesignatorError - removes the designator from the stack and replaces
13778 : : it with an error symbol.
13779 : : */
13780 : :
13781 : 54 : static void BuildDesignatorError (const char *message_, unsigned int _message_high)
13782 : : {
13783 : 54 : unsigned int combinedTok;
13784 : 54 : unsigned int arrayTok;
13785 : 54 : unsigned int exprTok;
13786 : 54 : unsigned int e;
13787 : 54 : unsigned int d;
13788 : 54 : unsigned int error;
13789 : 54 : unsigned int Sym;
13790 : 54 : unsigned int Type;
13791 : 54 : char message[_message_high+1];
13792 : :
13793 : : /* make a local copy of each unbounded array. */
13794 : 54 : memcpy (message, message_, _message_high+1);
13795 : :
13796 : 54 : M2Quads_PopTtok (&e, &exprTok);
13797 : 54 : PopTFDtok (&Sym, &Type, &d, &arrayTok);
13798 : 54 : combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, exprTok);
13799 : 54 : error = SymbolTable_MakeError (combinedTok, NameKey_MakeKey ((const char *) message, _message_high));
13800 : 54 : PushTFDtok (error, Type, d, arrayTok);
13801 : 54 : }
13802 : :
13803 : :
13804 : : /*
13805 : : BuildDesignatorPointerError - removes the designator from the stack and replaces
13806 : : it with an error symbol.
13807 : : */
13808 : :
13809 : 2 : static void BuildDesignatorPointerError (unsigned int type, unsigned int rw, unsigned int tokpos, const char *message_, unsigned int _message_high)
13810 : : {
13811 : 2 : unsigned int error;
13812 : 2 : char message[_message_high+1];
13813 : :
13814 : : /* make a local copy of each unbounded array. */
13815 : 2 : memcpy (message, message_, _message_high+1);
13816 : :
13817 : 2 : error = SymbolTable_MakeError (tokpos, NameKey_MakeKey ((const char *) message, _message_high));
13818 : 2 : if ((SymbolTable_GetSType (type)) != SymbolTable_NulSym)
13819 : : {
13820 : 2 : type = SymbolTable_GetSType (type);
13821 : : }
13822 : 2 : PushTFrwtok (error, type, rw, tokpos);
13823 : 2 : }
13824 : :
13825 : :
13826 : : /*
13827 : : BuildDesignatorArrayStaticDynamic - Builds the array referencing.
13828 : : The purpose of this procedure is to work out
13829 : : whether the DesignatorArray is a static or
13830 : : dynamic array and to call the appropriate
13831 : : BuildRoutine.
13832 : :
13833 : : The Stack is expected to contain:
13834 : :
13835 : :
13836 : : Entry Exit
13837 : : ===== ====
13838 : :
13839 : : Ptr ->
13840 : : +--------------+
13841 : : | e | <- Ptr
13842 : : |--------------| +------------+
13843 : : | Sym | Type | | S | T |
13844 : : |--------------| |------------|
13845 : : */
13846 : :
13847 : 56756 : static void BuildDesignatorArrayStaticDynamic (void)
13848 : : {
13849 : 56756 : unsigned int combinedTok;
13850 : 56756 : unsigned int arrayTok;
13851 : 56756 : unsigned int exprTok;
13852 : 56756 : unsigned int e;
13853 : 56756 : unsigned int type;
13854 : 56756 : unsigned int dim;
13855 : 56756 : unsigned int result;
13856 : 56756 : unsigned int Sym;
13857 : 56756 : unsigned int Type;
13858 : :
13859 : 56756 : if (SymbolTable_IsConst (M2Quads_OperandT (2)))
13860 : : {
13861 : 204 : type = SymbolTable_GetDType (M2Quads_OperandT (2));
13862 : 204 : if ((type != SymbolTable_NulSym) && (SymbolTable_IsArray (type)))
13863 : : {
13864 : 204 : M2Quads_PopTtok (&e, &exprTok);
13865 : 204 : PopTFDtok (&Sym, &Type, &dim, &arrayTok);
13866 : 204 : result = SymbolTable_MakeTemporary (exprTok, SymbolTable_RightValue);
13867 : 204 : SymbolTable_PutVar (result, Type);
13868 : 204 : M2Quads_PushTFtok (result, SymbolTable_GetSType (result), exprTok);
13869 : 204 : M2Quads_PushTtok (Sym, arrayTok);
13870 : 204 : combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, exprTok);
13871 : 204 : SymbolTable_PutVarConst (result, true);
13872 : 204 : M2Quads_BuildAssignConstant (combinedTok);
13873 : 204 : PushTFDtok (result, SymbolTable_GetDType (result), dim, arrayTok);
13874 : 204 : M2Quads_PushTtok (e, exprTok);
13875 : : }
13876 : : }
13877 : 56756 : if ((! (SymbolTable_IsVar (M2Quads_OperandT (2)))) && (! (SymbolTable_IsTemporary (M2Quads_OperandT (2)))))
13878 : : {
13879 : 18 : M2MetaError_MetaErrorT1 (OperandTtok (2), (const char *) "can only access arrays using constants, variables or formal parameters not {%1Ead}", 82, M2Quads_OperandT (2));
13880 : 18 : BuildDesignatorError ((const char *) "bad array access", 16);
13881 : : }
13882 : 56756 : Sym = static_cast<unsigned int> (M2Quads_OperandT (2));
13883 : 56756 : Type = SymbolTable_GetDType (Sym);
13884 : 56756 : arrayTok = OperandTtok (2);
13885 : 56756 : if (Type == SymbolTable_NulSym)
13886 : : {
13887 : 0 : if ((arrayTok == M2LexBuf_UnknownTokenNo) || (arrayTok == M2LexBuf_BuiltinTokenNo))
13888 : : {
13889 : 0 : arrayTok = M2LexBuf_GetTokenNo ();
13890 : : }
13891 : 0 : M2MetaError_MetaErrorT0 (arrayTok, (const char *) "type of array is undefined", 26);
13892 : 0 : BuildDesignatorError ((const char *) "bad array access", 16);
13893 : : }
13894 : 56756 : else if (SymbolTable_IsUnbounded (Type))
13895 : : {
13896 : : /* avoid dangling else. */
13897 : 8994 : BuildDynamicArray ();
13898 : : }
13899 : 47762 : else if (SymbolTable_IsArray (Type))
13900 : : {
13901 : : /* avoid dangling else. */
13902 : 47732 : BuildStaticArray ();
13903 : : }
13904 : : else
13905 : : {
13906 : : /* avoid dangling else. */
13907 : 30 : M2MetaError_MetaErrorT1 (arrayTok, (const char *) "can only index static or dynamic arrays, {%1Ead} is not an array but a {%tadv}", 78, Sym);
13908 : 30 : BuildDesignatorError ((const char *) "bad array access", 16);
13909 : : }
13910 : 56750 : }
13911 : :
13912 : :
13913 : : /*
13914 : : BuildStaticArray - Builds the array referencing for static arrays.
13915 : : The Stack is expected to contain:
13916 : :
13917 : :
13918 : : Entry Exit
13919 : : ===== ====
13920 : :
13921 : : Ptr ->
13922 : : +--------------+
13923 : : | e | <- Ptr
13924 : : |--------------| +------------+
13925 : : | Sym | Type | | S | T |
13926 : : |--------------| |------------|
13927 : : */
13928 : :
13929 : 47732 : static void BuildStaticArray (void)
13930 : : {
13931 : 47732 : unsigned int combinedTok;
13932 : 47732 : unsigned int indexTok;
13933 : 47732 : unsigned int arrayTok;
13934 : 47732 : unsigned int rw;
13935 : 47732 : unsigned int Dim;
13936 : 47732 : unsigned int Array;
13937 : 47732 : unsigned int Index;
13938 : 47732 : unsigned int BackEndType;
13939 : 47732 : unsigned int Type;
13940 : 47732 : unsigned int Adr;
13941 : :
13942 : 47732 : Index = static_cast<unsigned int> (M2Quads_OperandT (1));
13943 : 47732 : indexTok = OperandTtok (1);
13944 : 47732 : Array = static_cast<unsigned int> (M2Quads_OperandT (2));
13945 : 47732 : arrayTok = OperandTtok (2);
13946 : 47732 : Type = SymbolTable_SkipType (M2Quads_OperandF (2));
13947 : 47732 : rw = static_cast<unsigned int> (OperandMergeRW (2));
13948 : 47732 : M2Debug_Assert (SymbolTable_IsLegal (rw));
13949 : 47732 : Dim = static_cast<unsigned int> (OperandD (2));
13950 : 47732 : Dim += 1;
13951 : 47732 : if ((SymbolTable_GetMode (Index)) == SymbolTable_LeftValue)
13952 : : {
13953 : 176 : Index = MakeRightValue (indexTok, Index, SymbolTable_GetSType (Index));
13954 : : }
13955 : 47726 : BuildRange (M2Range_InitStaticArraySubscriptRangeCheck (SymbolTable_GetArraySubscript (Type), Index, Dim));
13956 : : /* now make Adr point to the address of the indexed element */
13957 : 47726 : combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, indexTok);
13958 : 47726 : Adr = SymbolTable_MakeTemporary (combinedTok, SymbolTable_LeftValue);
13959 : 47726 : if (SymbolTable_IsVar (Array))
13960 : : {
13961 : : /* BuildDesignatorArray may have detected des is a constant. */
13962 : 47726 : SymbolTable_PutVarConst (Adr, SymbolTable_IsVarConst (Array));
13963 : : }
13964 : 47726 : SymbolTable_PutVarArrayRef (Adr, true);
13965 : : /*
13966 : : From now on it must reference the array element by its lvalue
13967 : : - so we create the type of the referenced entity
13968 : : */
13969 : 47726 : BackEndType = SymbolTable_MakePointer (combinedTok, NameKey_NulName);
13970 : 47726 : SymbolTable_PutPointer (BackEndType, SymbolTable_GetDType (Type));
13971 : : /* PutVar(Adr, BackEndType) ; */
13972 : 47726 : SymbolTable_PutLeftValueFrontBackType (Adr, SymbolTable_GetDType (Type), BackEndType);
13973 : 95452 : GenQuadO (combinedTok, M2Quads_ArrayOp, Adr, Index, Array, true);
13974 : 47726 : M2Quads_PopN (2); /* remove all parameters to this procedure */
13975 : 47726 : PushTFDrwtok (Adr, SymbolTable_GetSType (Adr), Dim, rw, combinedTok); /* remove all parameters to this procedure */
13976 : 47726 : }
13977 : :
13978 : :
13979 : : /*
13980 : : calculateMultipicand - generates quadruples which calculate the
13981 : : multiplicand for the array at dimension, dim.
13982 : : */
13983 : :
13984 : 12052 : static unsigned int calculateMultipicand (unsigned int tok, unsigned int arraySym, unsigned int arrayType, unsigned int dim)
13985 : : {
13986 : 12052 : unsigned int ti;
13987 : 12052 : unsigned int tj;
13988 : 12052 : unsigned int tk;
13989 : 12052 : unsigned int tl;
13990 : :
13991 : 12052 : if (dim == (SymbolTable_GetDimension (arrayType)))
13992 : : {
13993 : : /* ti has no type since constant */
13994 : 10268 : ti = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
13995 : 10268 : SymbolTable_PutVar (ti, M2Base_Cardinal);
13996 : 10268 : GenQuadO (tok, M2Quads_ElementSizeOp, ti, arrayType, 1, true);
13997 : : }
13998 : : else
13999 : : {
14000 : 1784 : dim += 1;
14001 : 1784 : tk = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
14002 : 1784 : SymbolTable_PutVar (tk, M2Base_Cardinal);
14003 : 1784 : GenHigh (tok, tk, dim, arraySym);
14004 : 1784 : tl = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
14005 : 1784 : SymbolTable_PutVar (tl, M2Base_Cardinal);
14006 : 1784 : GenQuadOtok (tok, M2Quads_AddOp, tl, tk, SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal), true, tok, tok, tok);
14007 : 1784 : tj = calculateMultipicand (tok, arraySym, arrayType, dim);
14008 : 1784 : ti = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
14009 : 1784 : SymbolTable_PutVar (ti, M2Base_Cardinal);
14010 : 1784 : GenQuadO (tok, M2Quads_MultOp, ti, tj, tl, true);
14011 : : }
14012 : 12052 : return ti;
14013 : : /* static analysis guarentees a RETURN statement will be used before here. */
14014 : : __builtin_unreachable ();
14015 : : }
14016 : :
14017 : :
14018 : : /*
14019 : : ConvertToAddress - convert sym to an address.
14020 : : */
14021 : :
14022 : 9078 : static unsigned int ConvertToAddress (unsigned int tokpos, unsigned int sym)
14023 : : {
14024 : 9078 : unsigned int adr;
14025 : :
14026 : 9078 : if ((SymbolTable_GetSType (sym)) == M2System_Address)
14027 : : {
14028 : : return sym;
14029 : : }
14030 : : else
14031 : : {
14032 : 9066 : M2Quads_PushTF (SymbolTable_RequestSym (tokpos, NameKey_MakeKey ((const char *) "CONVERT", 7)), static_cast<unsigned int> (SymbolTable_NulSym));
14033 : 9066 : M2Quads_PushT (M2System_Address);
14034 : 9066 : M2Quads_PushTtok (sym, tokpos);
14035 : 9066 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
14036 : 9066 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
14037 : 9066 : M2Quads_PopT (&adr);
14038 : 9066 : return adr;
14039 : : }
14040 : : /* static analysis guarentees a RETURN statement will be used before here. */
14041 : : __builtin_unreachable ();
14042 : : }
14043 : :
14044 : :
14045 : : /*
14046 : : BuildDynamicArray - Builds the array referencing for dynamic arrays.
14047 : : The Stack is expected to contain:
14048 : :
14049 : :
14050 : : Entry Exit
14051 : : ===== ====
14052 : :
14053 : : Ptr ->
14054 : : +-----------------------+
14055 : : | Index | <- Ptr
14056 : : |-----------------------| +---------------------------+
14057 : : | ArraySym | Type | Dim | | S | T | ArraySym | Dim+1 |
14058 : : |-----------------------| |---------------------------|
14059 : :
14060 : :
14061 : : if Dim=1
14062 : : then
14063 : : S := base of ArraySym + TSIZE(Type)*Index
14064 : : else
14065 : : S := S + TSIZE(Type)*Index
14066 : : fi
14067 : : */
14068 : :
14069 : 8994 : static void BuildDynamicArray (void)
14070 : : {
14071 : 8994 : unsigned int combinedTok;
14072 : 8994 : unsigned int arrayTok;
14073 : 8994 : unsigned int indexTok;
14074 : 8994 : unsigned int Sym;
14075 : 8994 : unsigned int idx;
14076 : 8994 : unsigned int Type;
14077 : 8994 : unsigned int Adr;
14078 : 8994 : unsigned int ArraySym;
14079 : 8994 : unsigned int BackEndType;
14080 : 8994 : unsigned int UnboundedType;
14081 : 8994 : unsigned int PtrToBase;
14082 : 8994 : unsigned int Base;
14083 : 8994 : unsigned int Dim;
14084 : 8994 : unsigned int rw;
14085 : 8994 : unsigned int ti;
14086 : 8994 : unsigned int tj;
14087 : 8994 : unsigned int tk;
14088 : 8994 : unsigned int tka;
14089 : :
14090 : 8994 : M2Quads_DisplayStack ();
14091 : 8994 : Sym = static_cast<unsigned int> (M2Quads_OperandT (2));
14092 : 8994 : Type = SymbolTable_SkipType (M2Quads_OperandF (2));
14093 : 8994 : arrayTok = static_cast<unsigned int> (M2Quads_OperandTok (2));
14094 : 8994 : indexTok = static_cast<unsigned int> (M2Quads_OperandTok (1));
14095 : 8994 : combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, indexTok);
14096 : 8994 : Dim = static_cast<unsigned int> (OperandD (2));
14097 : 8994 : rw = static_cast<unsigned int> (OperandMergeRW (2));
14098 : 8994 : M2Debug_Assert (SymbolTable_IsLegal (rw));
14099 : 8994 : Dim += 1;
14100 : 8994 : if (Dim == 1)
14101 : : {
14102 : : /*
14103 : : Base has type address since
14104 : : BuildDesignatorRecord references by address.
14105 : :
14106 : : Build a record for retrieving the address of dynamic array.
14107 : : BuildDesignatorRecord will generate the required quadruples,
14108 : : therefore build sets up the stack for BuildDesignatorRecord
14109 : : which will generate the quads to access the record.
14110 : : */
14111 : 8856 : ArraySym = Sym;
14112 : 8856 : UnboundedType = SymbolTable_GetUnboundedRecordType (SymbolTable_GetSType (Sym));
14113 : 8856 : PushTFrwtok (Sym, UnboundedType, rw, arrayTok);
14114 : 8856 : M2Quads_PushTF (SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (Sym)), SymbolTable_GetSType (SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (Sym))));
14115 : 8856 : M2Quads_PushT (static_cast<unsigned int> (1)); /* One record field to dereference */
14116 : 8856 : M2Quads_BuildDesignatorRecord (combinedTok); /* One record field to dereference */
14117 : 8856 : M2Quads_PopT (&PtrToBase);
14118 : 8856 : M2Quads_DisplayStack ();
14119 : : /* Now actually copy Unbounded.ArrayAddress into base */
14120 : 8856 : if ((SymbolTable_GetMode (PtrToBase)) == SymbolTable_LeftValue)
14121 : : {
14122 : 0 : Base = SymbolTable_MakeTemporary (arrayTok, SymbolTable_RightValue);
14123 : 0 : SymbolTable_PutVar (Base, M2System_Address); /* has type ADDRESS */
14124 : 0 : CheckPointerThroughNil (arrayTok, PtrToBase); /* has type ADDRESS */
14125 : 0 : GenQuad (M2Quads_IndrXOp, Base, M2System_Address, PtrToBase); /* Base = *PtrToBase */
14126 : : }
14127 : : else
14128 : : {
14129 : 8856 : M2Debug_Assert ((SymbolTable_GetMode (PtrToBase)) != SymbolTable_ImmediateValue);
14130 : 8856 : Base = PtrToBase;
14131 : : }
14132 : : }
14133 : : else
14134 : : {
14135 : : /* Base already calculated previously and pushed to stack */
14136 : 138 : UnboundedType = SymbolTable_SkipType (M2Quads_OperandF (2));
14137 : 138 : Base = Sym;
14138 : 138 : ArraySym = static_cast<unsigned int> (M2Quads_OperandA (2));
14139 : : }
14140 : 8994 : M2Debug_Assert ((SymbolTable_GetSType (Sym)) == Type);
14141 : 8994 : ti = calculateMultipicand (indexTok, Sym, Type, Dim);
14142 : 8994 : idx = static_cast<unsigned int> (M2Quads_OperandT (1));
14143 : 8994 : if ((SymbolTable_IsConst (idx)) && (SymbolTable_IsConst (ti)))
14144 : : {
14145 : : /* tj has no type since constant */
14146 : 460 : tj = SymbolTable_MakeTemporary (indexTok, SymbolTable_ImmediateValue);
14147 : 460 : tk = SymbolTable_MakeTemporary (indexTok, SymbolTable_ImmediateValue);
14148 : 460 : SymbolTable_PutVar (tj, M2Base_Cardinal);
14149 : 460 : SymbolTable_PutVar (tk, M2Base_Cardinal);
14150 : : }
14151 : : else
14152 : : {
14153 : : /* tj has Cardinal type since we have multiplied array indices */
14154 : 8534 : tj = SymbolTable_MakeTemporary (indexTok, SymbolTable_RightValue);
14155 : 8534 : if ((SymbolTable_GetSType (idx)) != M2Base_Cardinal)
14156 : : {
14157 : 270 : M2Quads_PushTF (SymbolTable_RequestSym (indexTok, NameKey_MakeKey ((const char *) "CONVERT", 7)), static_cast<unsigned int> (SymbolTable_NulSym));
14158 : 270 : M2Quads_PushT (M2Base_Cardinal);
14159 : 270 : M2Quads_PushTtok (idx, indexTok);
14160 : 270 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
14161 : 270 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
14162 : 270 : M2Quads_PopT (&idx);
14163 : : }
14164 : 8534 : SymbolTable_PutVar (tj, M2Base_Cardinal);
14165 : 8534 : tk = SymbolTable_MakeTemporary (indexTok, SymbolTable_RightValue);
14166 : 8534 : SymbolTable_PutVar (tk, M2Base_Cardinal);
14167 : : }
14168 : 8994 : BuildRange (M2Range_InitDynamicArraySubscriptRangeCheck (ArraySym, idx, Dim));
14169 : 8994 : M2Quads_PushTtok (tj, indexTok);
14170 : 8994 : M2Quads_PushTtok (idx, indexTok);
14171 : 8994 : BuildAssignmentWithoutBounds (indexTok, false, true);
14172 : 17988 : GenQuad (M2Quads_MultOp, tk, ti, tj);
14173 : 17988 : Adr = SymbolTable_MakeTemporary (combinedTok, SymbolTable_LeftValue);
14174 : 8994 : SymbolTable_PutVarArrayRef (Adr, true);
14175 : : /*
14176 : : Ok must reference by address
14177 : : - but we contain the type of the referenced entity
14178 : : */
14179 : 8994 : BackEndType = SymbolTable_MakePointer (combinedTok, NameKey_NulName);
14180 : 8994 : SymbolTable_PutPointer (BackEndType, SymbolTable_GetSType (Type));
14181 : : /* Create a temporary pointer for addition. */
14182 : 8994 : tka = ConvertToAddress (combinedTok, tk);
14183 : 8994 : if (Dim == (SymbolTable_GetDimension (Type)))
14184 : : {
14185 : 8676 : SymbolTable_PutLeftValueFrontBackType (Adr, SymbolTable_GetSType (Type), BackEndType);
14186 : 17352 : GenQuadOtok (combinedTok, M2Quads_AddOp, Adr, Base, tka, false, combinedTok, combinedTok, combinedTok);
14187 : 8676 : M2Quads_PopN (2);
14188 : 8676 : PushTFADrwtok (Adr, SymbolTable_GetSType (Adr), ArraySym, Dim, rw, combinedTok);
14189 : : }
14190 : : else
14191 : : {
14192 : : /* more to index */
14193 : 318 : SymbolTable_PutLeftValueFrontBackType (Adr, Type, BackEndType);
14194 : 636 : GenQuadOtok (combinedTok, M2Quads_AddOp, Adr, Base, tka, false, combinedTok, combinedTok, combinedTok);
14195 : 318 : M2Quads_PopN (2);
14196 : 318 : PushTFADrwtok (Adr, SymbolTable_GetSType (Adr), ArraySym, Dim, rw, combinedTok);
14197 : : }
14198 : 8994 : }
14199 : :
14200 : :
14201 : : /*
14202 : : DebugLocation -
14203 : : */
14204 : :
14205 : 58144 : static void DebugLocation (unsigned int tok, const char *message_, unsigned int _message_high)
14206 : : {
14207 : 58144 : char message[_message_high+1];
14208 : :
14209 : : /* make a local copy of each unbounded array. */
14210 : 58144 : memcpy (message, message_, _message_high+1);
14211 : :
14212 : 58144 : if (DebugTokPos)
14213 : : {
14214 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) message, _message_high), tok);
14215 : : }
14216 : 58144 : }
14217 : :
14218 : :
14219 : : /*
14220 : : PushWith - pushes sym and type onto the with stack. It checks for
14221 : : previous declaration of this record type.
14222 : : */
14223 : :
14224 : 6158 : static void PushWith (unsigned int Sym, unsigned int Type, unsigned int Ref, unsigned int Tok)
14225 : : {
14226 : 6158 : unsigned int i;
14227 : 6158 : unsigned int n;
14228 : 6158 : M2Quads_WithFrame f;
14229 : :
14230 : 6158 : if (M2Options_Pedantic)
14231 : : {
14232 : 0 : n = M2StackAddress_NoOfItemsInStackAddress (WithStack);
14233 : 0 : i = 1; /* Top of the stack. */
14234 : : /* Search for other declarations of the with using Type. */
14235 : 0 : while (i <= n)
14236 : : {
14237 : 0 : f = static_cast<M2Quads_WithFrame> (M2StackAddress_PeepAddress (WithStack, i));
14238 : 0 : if (f->RecordSym == Type)
14239 : : {
14240 : 0 : M2MetaError_MetaErrorT1 (Tok, (const char *) "cannot have nested {%kWITH} statements referencing the same {%kRECORD} {%1Ead}", 78, Sym);
14241 : 0 : M2MetaError_MetaErrorT1 (f->RecordTokPos, (const char *) "cannot have nested {%kWITH} statements referencing the same {%kRECORD} {%1Ead}", 78, f->RecordSym);
14242 : : }
14243 : 0 : i += 1;
14244 : : }
14245 : : }
14246 : 6158 : Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T4));
14247 : 6158 : f->RecordSym = Sym;
14248 : 6158 : f->RecordType = Type;
14249 : 6158 : f->RecordRef = Ref;
14250 : 6158 : f->rw = Sym;
14251 : 6158 : f->RecordTokPos = Tok;
14252 : 6158 : M2StackAddress_PushAddress (WithStack, reinterpret_cast <void *> (f));
14253 : 6158 : }
14254 : :
14255 : 6158 : static void PopWith (void)
14256 : : {
14257 : 6158 : M2Quads_WithFrame f;
14258 : :
14259 : 6158 : f = static_cast<M2Quads_WithFrame> (M2StackAddress_PopAddress (WithStack));
14260 : 6158 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T4));
14261 : 6158 : }
14262 : :
14263 : :
14264 : : /*
14265 : : BuildAccessWithField - similar to BuildDesignatorRecord except it
14266 : : does not perform the address operation.
14267 : : The address will have been computed at the
14268 : : beginning of the WITH statement.
14269 : : It also stops the GenQuad procedure from examining the
14270 : : with stack.
14271 : :
14272 : : The Stack
14273 : :
14274 : : Entry
14275 : :
14276 : : Ptr ->
14277 : : +--------------+
14278 : : | Field | Type1| <- Ptr
14279 : : |-------|------| +-------------+
14280 : : | Adr | Type2| | Sym | Type1|
14281 : : |--------------| |-------------|
14282 : : */
14283 : :
14284 : 30984 : static void BuildAccessWithField (void)
14285 : : {
14286 : 30984 : unsigned int rectok;
14287 : 30984 : unsigned int fieldtok;
14288 : 30984 : bool OldSuppressWith;
14289 : 30984 : unsigned int rw;
14290 : 30984 : unsigned int Field;
14291 : 30984 : unsigned int FieldType;
14292 : 30984 : unsigned int Record;
14293 : 30984 : unsigned int RecordType;
14294 : 30984 : unsigned int Ref;
14295 : :
14296 : 30984 : OldSuppressWith = SuppressWith;
14297 : 30984 : SuppressWith = true;
14298 : : /*
14299 : : now the WITH cannot look at the stack of outstanding WITH records.
14300 : : */
14301 : 30984 : M2Quads_PopTFtok (&Field, &FieldType, &fieldtok);
14302 : 30984 : PopTFrwtok (&Record, &RecordType, &rw, &rectok);
14303 : 30984 : Ref = SymbolTable_MakeComponentRef (SymbolTable_MakeComponentRecord (fieldtok, SymbolTable_RightValue, Record), Field);
14304 : 30984 : SymbolTable_PutVarConst (Ref, IsReadOnly (Record));
14305 : 61968 : GenQuadO (fieldtok, M2Quads_RecordFieldOp, Ref, Record, Field, true);
14306 : 30984 : PushTFrwtok (Ref, FieldType, rw, fieldtok);
14307 : 30984 : SuppressWith = OldSuppressWith;
14308 : 30984 : }
14309 : :
14310 : :
14311 : : /*
14312 : : PushConstructor -
14313 : : */
14314 : :
14315 : 47622 : static void PushConstructor (unsigned int sym)
14316 : : {
14317 : 47622 : M2Quads_ConstructorFrame c;
14318 : :
14319 : 47622 : Storage_ALLOCATE ((void **) &c, sizeof (M2Quads__T1));
14320 : 47622 : c->type = SymbolTable_SkipType (sym);
14321 : 47622 : c->index = 1;
14322 : 47622 : M2StackAddress_PushAddress (ConstructorStack, reinterpret_cast <void *> (c));
14323 : 47622 : }
14324 : :
14325 : :
14326 : : /*
14327 : : AddFieldTo - adds field, e, to, value.
14328 : : */
14329 : :
14330 : 25770 : static unsigned int AddFieldTo (unsigned int value, unsigned int e)
14331 : : {
14332 : 25770 : if (SymbolTable_IsSet (SymbolTable_GetDType (value)))
14333 : : {
14334 : 12028 : SymbolTable_PutConstSet (value);
14335 : 12028 : M2Quads_PushT (value);
14336 : 12028 : M2Quads_PushT (e);
14337 : 12028 : M2Quads_BuildInclBit ();
14338 : 12028 : M2Quads_PopT (&value);
14339 : : }
14340 : : else
14341 : : {
14342 : 13742 : SymbolTable_PushValue (value);
14343 : 13742 : M2ALU_AddField (M2LexBuf_GetTokenNo (), e);
14344 : 13742 : SymbolTable_PopValue (value);
14345 : : }
14346 : 25770 : return value;
14347 : : /* static analysis guarentees a RETURN statement will be used before here. */
14348 : : __builtin_unreachable ();
14349 : : }
14350 : :
14351 : :
14352 : : /*
14353 : : CheckLogicalOperator - returns a logical operator if the operands imply
14354 : : a logical operation should be performed.
14355 : : */
14356 : :
14357 : 78296 : static NameKey_Name CheckLogicalOperator (NameKey_Name Tok, unsigned int left, unsigned int lefttype)
14358 : : {
14359 : 78296 : if ((((Tok == M2Reserved_PlusTok) || (Tok == M2Reserved_TimesTok)) || (Tok == M2Reserved_DivideTok)) || (Tok == M2Reserved_MinusTok))
14360 : : {
14361 : : /* --fixme-- when we add complex arithmetic, we must check constructor is not a complex constant. */
14362 : 69174 : if ((((lefttype != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_SkipType (lefttype)))) || (SymbolTable_IsConstSet (left))) || (SymbolTable_IsConstructor (left)))
14363 : : {
14364 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
14365 : 1482 : if (Tok == M2Reserved_PlusTok)
14366 : : {
14367 : 1008 : return LogicalOrTok;
14368 : : }
14369 : 474 : else if (Tok == M2Reserved_DivideTok)
14370 : : {
14371 : : /* avoid dangling else. */
14372 : 124 : return LogicalXorTok;
14373 : : }
14374 : 350 : else if (Tok == M2Reserved_TimesTok)
14375 : : {
14376 : : /* avoid dangling else. */
14377 : 284 : return LogicalAndTok;
14378 : : }
14379 : 66 : else if (Tok == M2Reserved_MinusTok)
14380 : : {
14381 : : /* avoid dangling else. */
14382 : 66 : return LogicalDifferenceTok;
14383 : : }
14384 : : }
14385 : : }
14386 : : return Tok;
14387 : : /* static analysis guarentees a RETURN statement will be used before here. */
14388 : : __builtin_unreachable ();
14389 : : }
14390 : :
14391 : :
14392 : : /*
14393 : : CheckDivModRem - initiates calls to check the divisor for DIV, MOD, REM
14394 : : expressions.
14395 : : */
14396 : :
14397 : 77696 : static void CheckDivModRem (unsigned int TokPos, NameKey_Name tok, unsigned int d, unsigned int e)
14398 : : {
14399 : 77696 : if (tok == M2Reserved_DivTok)
14400 : : {
14401 : 6648 : BuildRange (M2Range_InitWholeZeroDivisionCheck (TokPos, d, e));
14402 : : }
14403 : 71048 : else if (tok == M2Reserved_ModTok)
14404 : : {
14405 : : /* avoid dangling else. */
14406 : 2378 : BuildRange (M2Range_InitWholeZeroDivisionCheck (TokPos, d, e));
14407 : : }
14408 : 68670 : else if (tok == M2Reserved_RemTok)
14409 : : {
14410 : : /* avoid dangling else. */
14411 : 96 : BuildRange (M2Range_InitWholeZeroRemainderCheck (TokPos, d, e));
14412 : : }
14413 : 77696 : }
14414 : :
14415 : :
14416 : : /*
14417 : : doConvert - convert, sym, to a new symbol with, type.
14418 : : Return the new symbol.
14419 : : */
14420 : :
14421 : 5220 : static unsigned int doConvert (unsigned int type, unsigned int sym)
14422 : : {
14423 : 5220 : if ((SymbolTable_GetSType (sym)) != type)
14424 : : {
14425 : 1086 : M2Quads_PushTF (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym));
14426 : 1086 : M2Quads_PushT (type);
14427 : 1086 : M2Quads_PushT (sym);
14428 : 1086 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
14429 : 1086 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
14430 : 1080 : M2Quads_PopT (&sym);
14431 : : }
14432 : 5214 : return sym;
14433 : : /* static analysis guarentees a RETURN statement will be used before here. */
14434 : : __builtin_unreachable ();
14435 : : }
14436 : :
14437 : :
14438 : : /*
14439 : : doBuildBinaryOp - build the binary op, with or without type
14440 : : checking.
14441 : : */
14442 : :
14443 : 91614 : static void doBuildBinaryOp (bool checkTypes, bool checkOverflow)
14444 : : {
14445 : 91614 : DynamicStrings_String s;
14446 : 91614 : NameKey_Name NewOp;
14447 : 91614 : NameKey_Name Operator;
14448 : 91614 : unsigned int OperatorPos;
14449 : 91614 : unsigned int OldPos;
14450 : 91614 : unsigned int leftrw;
14451 : 91614 : unsigned int rightrw;
14452 : 91614 : unsigned int t1;
14453 : 91614 : unsigned int f1;
14454 : 91614 : unsigned int t2;
14455 : 91614 : unsigned int f2;
14456 : 91614 : unsigned int lefttype;
14457 : 91614 : unsigned int righttype;
14458 : 91614 : unsigned int left;
14459 : 91614 : unsigned int right;
14460 : 91614 : unsigned int leftpos;
14461 : 91614 : unsigned int rightpos;
14462 : 91614 : unsigned int value;
14463 : :
14464 : 91614 : Operator = static_cast<NameKey_Name> (M2Quads_OperandT (2));
14465 : 91614 : if (Operator == M2Reserved_OrTok)
14466 : : {
14467 : 3630 : CheckBooleanId ();
14468 : 3630 : PopBooltok (&t1, &f1, &rightpos);
14469 : 3630 : M2Quads_PopTtok (&Operator, &OperatorPos);
14470 : 3630 : PopBooltok (&t2, &f2, &leftpos);
14471 : 3630 : M2Debug_Assert (f2 == 0);
14472 : 3630 : OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
14473 : 3630 : PushBooltok (Merge (t1, t2), f1, OperatorPos);
14474 : : }
14475 : 87984 : else if ((Operator == M2Reserved_AndTok) || (Operator == M2Reserved_AmbersandTok))
14476 : : {
14477 : : /* avoid dangling else. */
14478 : 9688 : CheckBooleanId ();
14479 : 9688 : PopBooltok (&t1, &f1, &rightpos);
14480 : 9688 : M2Quads_PopTtok (&Operator, &OperatorPos);
14481 : 9688 : PopBooltok (&t2, &f2, &leftpos);
14482 : 9688 : M2Debug_Assert (t2 == 0);
14483 : 9688 : OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
14484 : 9688 : PushBooltok (t1, Merge (f1, f2), OperatorPos);
14485 : : }
14486 : : else
14487 : : {
14488 : : /* avoid dangling else. */
14489 : 78296 : PopTFrwtok (&right, &righttype, &rightrw, &rightpos);
14490 : 78296 : M2Quads_PopTtok (&Operator, &OperatorPos);
14491 : 78296 : PopTFrwtok (&left, &lefttype, &leftrw, &leftpos);
14492 : 78296 : MarkAsRead (rightrw);
14493 : 78296 : MarkAsRead (leftrw);
14494 : 78296 : NewOp = CheckLogicalOperator (Operator, left, lefttype); /* right, righttype, */
14495 : 78296 : if (NewOp == Operator)
14496 : : {
14497 : : /* avoid dangling else. */
14498 : : /*
14499 : : BinaryOps and UnaryOps only work with immediate and
14500 : : offset addressing. This is fine for calculating
14501 : : array and record offsets but we need to get the real
14502 : : values to perform normal arithmetic. Not address
14503 : : arithmetic.
14504 : :
14505 : : However the set operators will dereference LValues
14506 : : (to optimize large set arithemetic)
14507 : : */
14508 : 76814 : if ((SymbolTable_GetMode (right)) == SymbolTable_LeftValue)
14509 : : {
14510 : 298 : value = SymbolTable_MakeTemporary (rightpos, SymbolTable_RightValue);
14511 : 298 : SymbolTable_PutVar (value, righttype);
14512 : 298 : CheckPointerThroughNil (rightpos, right);
14513 : 298 : doIndrX (rightpos, value, right);
14514 : 298 : right = value;
14515 : : }
14516 : 76814 : if ((SymbolTable_GetMode (left)) == SymbolTable_LeftValue)
14517 : : {
14518 : 852 : value = SymbolTable_MakeTemporary (leftpos, SymbolTable_RightValue);
14519 : 852 : SymbolTable_PutVar (value, lefttype);
14520 : 852 : CheckPointerThroughNil (leftpos, left);
14521 : 852 : doIndrX (leftpos, value, left);
14522 : 852 : left = value;
14523 : : }
14524 : : }
14525 : : /* CheckForGenericNulSet(e1, e2, t1, t2) */
14526 : 78296 : OldPos = OperatorPos;
14527 : 78296 : OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
14528 : 78296 : if (((Operator == M2Reserved_PlusTok) && (SymbolTable_IsConstString (left))) && (SymbolTable_IsConstString (right)))
14529 : : {
14530 : 492 : value = SymbolTable_MakeConstString (OperatorPos, NameKey_NulName);
14531 : 492 : SymbolTable_PutConstStringKnown (OperatorPos, value, NameKey_NulName, false, false);
14532 : 492 : GenQuadOtok (OperatorPos, MakeOp (M2Reserved_PlusTok), value, left, right, false, OperatorPos, leftpos, rightpos);
14533 : : }
14534 : : else
14535 : : {
14536 : 77804 : if (checkTypes)
14537 : : {
14538 : 59494 : BuildRange (M2Range_InitTypesExpressionCheck (OperatorPos, left, right, false, false));
14539 : : }
14540 : 121108 : value = SymbolTable_MakeTemporaryFromExpressions (OperatorPos, right, left, AreConstant ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right))));
14541 : 77696 : CheckDivModRem (OperatorPos, NewOp, value, right);
14542 : 77696 : if (DebugTokPos)
14543 : : {
14544 : : s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (M2LexBuf_GetTokenName (Operator)));
14545 : : M2Error_WarnStringAt (s, OldPos);
14546 : : s = DynamicStrings_InitString ((const char *) "left", 4);
14547 : : M2Error_WarnStringAt (s, leftpos);
14548 : : s = DynamicStrings_InitString ((const char *) "right", 5);
14549 : : M2Error_WarnStringAt (s, rightpos);
14550 : : s = DynamicStrings_InitString ((const char *) "caret", 5);
14551 : : M2Error_WarnStringAt (s, OldPos);
14552 : : s = DynamicStrings_InitString ((const char *) "combined", 8);
14553 : : M2Error_WarnStringAt (s, OperatorPos);
14554 : : }
14555 : : /* MetaErrorT1 (GetDeclaredMod (t), 'in binary with a {%1av}', t) */
14556 : 77696 : GenQuadOtok (OperatorPos, MakeOp (NewOp), value, left, right, checkOverflow, OperatorPos, leftpos, rightpos);
14557 : : }
14558 : 78188 : M2Quads_PushTFtok (value, SymbolTable_GetSType (value), OperatorPos);
14559 : : }
14560 : 91506 : }
14561 : :
14562 : :
14563 : : /*
14564 : : AreConstant - returns immediate addressing mode if b is true else
14565 : : offset mode is returned. b determines whether the
14566 : : operands are all constant - in which case we can use
14567 : : a constant temporary variable.
14568 : : */
14569 : :
14570 : 158773 : static SymbolTable_ModeOfAddr AreConstant (bool b)
14571 : : {
14572 : 158773 : if (b)
14573 : : {
14574 : : return SymbolTable_ImmediateValue;
14575 : : }
14576 : : else
14577 : : {
14578 : 59734 : return SymbolTable_RightValue;
14579 : : }
14580 : : /* static analysis guarentees a RETURN statement will be used before here. */
14581 : : __builtin_unreachable ();
14582 : : }
14583 : :
14584 : :
14585 : : /*
14586 : : ConvertBooleanToVariable - converts a BoolStack(i) from a Boolean True|False
14587 : : exit pair into a variable containing the value TRUE or
14588 : : FALSE. The parameter i is relative to the top
14589 : : of the stack.
14590 : : */
14591 : :
14592 : 7354 : static void ConvertBooleanToVariable (unsigned int tok, unsigned int i)
14593 : : {
14594 : 7354 : unsigned int Des;
14595 : 7354 : M2Quads_BoolFrame f;
14596 : :
14597 : 7354 : M2Debug_Assert (IsBoolean (i));
14598 : : /* We need to convert the boolean top of stack into a variable or
14599 : : constant boolean. */
14600 : 14708 : Des = SymbolTable_MakeTemporary (tok, AreConstant (M2Quads_IsInConstExpression ()));
14601 : 7354 : SymbolTable_PutVar (Des, M2Base_Boolean);
14602 : 7354 : SymbolTable_PutVarConditional (Des, true);
14603 : 7354 : M2Quads_PushTtok (Des, tok); /* we have just increased the stack so we must use i+1 */
14604 : 7354 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, i+1)); /* we have just increased the stack so we must use i+1 */
14605 : 14708 : PushBool (f->TrueExit, f->FalseExit);
14606 : 7354 : BuildAssignmentWithoutBounds (tok, false, true);
14607 : : /* Restored stack after the BuildAssign... above. */
14608 : 7354 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, i));
14609 : 7354 : f->TrueExit = Des; /* Alter Stack(i) to contain the variable. */
14610 : 7354 : f->FalseExit = M2Base_Boolean; /* Alter Stack(i) to contain the variable. */
14611 : 7354 : f->BooleanOp = false; /* No longer a Boolean True|False pair. */
14612 : 7354 : f->Unbounded = SymbolTable_NulSym; /* No longer a Boolean True|False pair. */
14613 : 7354 : f->Dimension = 0;
14614 : 7354 : f->ReadWrite = SymbolTable_NulSym;
14615 : 7354 : f->tokenno = tok;
14616 : 7354 : f->Annotation = DynamicStrings_KillString (f->Annotation);
14617 : 7354 : f->Annotation = DynamicStrings_InitString ((const char *) "%1s(%1d)|%2s(%2d)||boolean var|type", 35);
14618 : 7354 : f->RangeDep = 0;
14619 : 7354 : }
14620 : :
14621 : :
14622 : : /*
14623 : : DumpQuadSummary -
14624 : : */
14625 : :
14626 : 0 : static void DumpQuadSummary (unsigned int quad)
14627 : : {
14628 : 0 : M2Quads_QuadFrame f;
14629 : :
14630 : 0 : if (quad != 0)
14631 : : {
14632 : 0 : f = GetQF (quad);
14633 : 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));
14634 : : }
14635 : 0 : }
14636 : :
14637 : :
14638 : : /*
14639 : : BuildRelOpFromBoolean - builds a relational operator sequence of quadruples
14640 : : instead of using a temporary boolean variable.
14641 : : This function can only be used when we perform
14642 : : the following translation:
14643 : :
14644 : : (a=b) # (c=d) alternatively (a=b) = (c=d)
14645 : : ^ ^
14646 : :
14647 : : it only allows # = to be used as >= <= > < all
14648 : : assume a particular value for TRUE and FALSE.
14649 : : (In which case the user should specify ORD)
14650 : :
14651 : :
14652 : : before
14653 : :
14654 : : q if r1 op1 op2 t2
14655 : : q+1 Goto f2
14656 : : ...
14657 : : q+n if r2 op3 op4 t1
14658 : : q+n+1 Goto f1
14659 : :
14660 : : after (in case of =)
14661 : :
14662 : : q if r1 op1 op2 q+2
14663 : : q+1 Goto q+4
14664 : : q+2 if r2 op3 op4 t
14665 : : q+3 Goto f
14666 : : q+4 if r2 op3 op4 f
14667 : : q+5 Goto t
14668 : :
14669 : : after (in case of #)
14670 : :
14671 : : q if r1 op1 op2 q+2
14672 : : q+1 Goto q+n+2
14673 : : q+2 ...
14674 : : ... ...
14675 : : q+n if r2 op3 op4 f
14676 : : q+n+1 Goto t
14677 : : q+n+2 if r2 op3 op4 t
14678 : : q+n+3 Goto f
14679 : :
14680 : : The Stack is expected to contain:
14681 : :
14682 : :
14683 : : Entry Exit
14684 : : ===== ====
14685 : :
14686 : : Ptr ->
14687 : : +------------+
14688 : : | t1 | f1 |
14689 : : |------------|
14690 : : | Operator | <- Ptr
14691 : : |------------| +------------+
14692 : : | t2 | f2 | | t | f |
14693 : : |------------| |------------|
14694 : :
14695 : :
14696 : : */
14697 : :
14698 : 0 : static void BuildRelOpFromBoolean (unsigned int tokpos)
14699 : : {
14700 : 0 : unsigned int Tok;
14701 : 0 : unsigned int t1;
14702 : 0 : unsigned int f1;
14703 : 0 : unsigned int t2;
14704 : 0 : unsigned int f2;
14705 : 0 : M2Quads_QuadFrame f;
14706 : :
14707 : 0 : M2Debug_Assert ((IsBoolean (1)) && (IsBoolean (3)));
14708 : 0 : if ((M2Quads_OperandT (2)) == M2Reserved_EqualTok)
14709 : : {
14710 : : /* Are the two boolean expressions the same? */
14711 : 0 : PopBool (&t1, &f1);
14712 : 0 : M2Quads_PopT (&Tok);
14713 : 0 : PopBool (&t2, &f2);
14714 : : /* Give the false exit a second chance. */
14715 : 0 : BackPatch (t2, t1); /* q if _ _ q+2 */
14716 : 0 : BackPatch (f2, NextQuad); /* q+1 if _ _ q+4 */
14717 : 0 : M2Debug_Assert (NextQuad == (f1+1)); /* q+1 if _ _ q+4 */
14718 : 0 : f = GetQF (t1);
14719 : 0 : GenQuadO (tokpos, f->Operator, f->Operand1, f->Operand2, 0, false);
14720 : 0 : GenQuadO (tokpos, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
14721 : 0 : PushBooltok (Merge (NextQuad-1, t1), Merge (NextQuad-2, f1), tokpos);
14722 : : }
14723 : 0 : else if (((M2Quads_OperandT (2)) == M2Reserved_HashTok) || ((M2Quads_OperandT (2)) == M2Reserved_LessGreaterTok))
14724 : : {
14725 : : /* avoid dangling else. */
14726 : 0 : if (M2Options_CompilerDebugging)
14727 : : {
14728 : 0 : M2Printf_printf0 ((const char *) "BuildRelOpFromBoolean (NotEqualTok)\\n", 37);
14729 : 0 : M2Quads_DisplayStack ();
14730 : : }
14731 : : /* Are the two boolean expressions different? */
14732 : 0 : PopBool (&t1, &f1);
14733 : 0 : M2Quads_PopT (&Tok);
14734 : 0 : PopBool (&t2, &f2);
14735 : 0 : if (M2Options_CompilerDebugging)
14736 : : {
14737 : 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));
14738 : 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));
14739 : 0 : DumpQuadSummary (t1);
14740 : 0 : DumpQuadSummary (f1);
14741 : 0 : DumpQuadSummary (t2);
14742 : 0 : DumpQuadSummary (f2);
14743 : : }
14744 : : /* Give the false exit a second chance. */
14745 : 0 : BackPatch (t2, t1); /* q if _ _ q+2 */
14746 : 0 : BackPatch (f2, NextQuad); /* q+1 if _ _ q+4 */
14747 : 0 : M2Debug_Assert (NextQuad == (f1+1)); /* q+1 if _ _ q+4 */
14748 : 0 : f = GetQF (t1);
14749 : 0 : GenQuadO (tokpos, f->Operator, f->Operand1, f->Operand2, 0, false);
14750 : 0 : GenQuadO (tokpos, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
14751 : 0 : PushBooltok (Merge (NextQuad-2, f1), Merge (NextQuad-1, t1), tokpos);
14752 : : }
14753 : : else
14754 : : {
14755 : : /* avoid dangling else. */
14756 : 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);
14757 : : }
14758 : 0 : }
14759 : :
14760 : :
14761 : : /*
14762 : : CheckVariableOrConstantOrProcedure - checks to make sure sym is a variable, constant or procedure.
14763 : : */
14764 : :
14765 : 183922 : static void CheckVariableOrConstantOrProcedure (unsigned int tokpos, unsigned int sym)
14766 : : {
14767 : 183922 : unsigned int type;
14768 : :
14769 : 183922 : type = SymbolTable_GetSType (sym);
14770 : 183922 : if (SymbolTable_IsUnknown (sym))
14771 : : {
14772 : : /* Spellcheck. */
14773 : 12 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1EUad} has not been declared {%1&s}", 37, sym);
14774 : 12 : SymbolTable_UnknownReported (sym);
14775 : : }
14776 : 183910 : else if ((M2System_IsPseudoSystemFunction (sym)) || (M2Base_IsPseudoBaseFunction (sym)))
14777 : : {
14778 : : /* avoid dangling else. */
14779 : 6 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1Ead} expected a variable, procedure, constant or expression, not an intrinsic procedure function", 99, sym);
14780 : : }
14781 : 183904 : else if (((((! (SymbolTable_IsConst (sym))) && (! (SymbolTable_IsVar (sym)))) && (! (SymbolTable_IsProcedure (sym)))) && (! (SymbolTable_IsTemporary (sym)))) && ! MustNotCheckBounds)
14782 : : {
14783 : : /* avoid dangling else. */
14784 : 0 : M2MetaError_MetaErrorsT1 (tokpos, (const char *) "{%1Ead} expected a variable, procedure, constant or expression", 62, (const char *) "and it was declared as a {%1Ddv}", 32, sym);
14785 : : }
14786 : 183904 : else if ((type != SymbolTable_NulSym) && (SymbolTable_IsArray (type)))
14787 : : {
14788 : : /* avoid dangling else. */
14789 : 0 : M2MetaError_MetaErrorsT1 (tokpos, (const char *) "{%1EU} not expecting an array variable as an operand for either comparison or binary operation", 94, (const char *) "it was declared as a {%1Ddv}", 28, sym);
14790 : : }
14791 : 183904 : else if (((SymbolTable_IsConstString (sym)) && (SymbolTable_IsConstStringKnown (sym))) && ((SymbolTable_GetStringLength (tokpos, sym)) > 1))
14792 : : {
14793 : : /* avoid dangling else. */
14794 : 0 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1EU} not expecting a string constant as an operand for either comparison or binary operation", 94, sym);
14795 : : }
14796 : 183922 : }
14797 : :
14798 : :
14799 : : /*
14800 : : MakeOp - returns the equalent quadruple operator to a token, t.
14801 : : */
14802 : :
14803 : 170149 : static M2Quads_QuadOperator MakeOp (NameKey_Name t)
14804 : : {
14805 : 170149 : if (t == ArithPlusTok)
14806 : : {
14807 : : return M2Quads_ArithAddOp;
14808 : : }
14809 : 170149 : else if (t == M2Reserved_PlusTok)
14810 : : {
14811 : : /* avoid dangling else. */
14812 : : return M2Quads_AddOp;
14813 : : }
14814 : 145251 : else if (t == M2Reserved_MinusTok)
14815 : : {
14816 : : /* avoid dangling else. */
14817 : : return M2Quads_SubOp;
14818 : : }
14819 : 122525 : else if (t == M2Reserved_DivTok)
14820 : : {
14821 : : /* avoid dangling else. */
14822 : : return M2Quads_DivM2Op;
14823 : : }
14824 : 115877 : else if (t == M2Reserved_DivideTok)
14825 : : {
14826 : : /* avoid dangling else. */
14827 : : return M2Quads_DivTruncOp;
14828 : : }
14829 : 113419 : else if (t == M2Reserved_RemTok)
14830 : : {
14831 : : /* avoid dangling else. */
14832 : : return M2Quads_ModTruncOp;
14833 : : }
14834 : 113323 : else if (t == M2Reserved_ModTok)
14835 : : {
14836 : : /* avoid dangling else. */
14837 : : return M2Quads_ModM2Op;
14838 : : }
14839 : 110945 : else if (t == M2Reserved_TimesTok)
14840 : : {
14841 : : /* avoid dangling else. */
14842 : : return M2Quads_MultOp;
14843 : : }
14844 : 93425 : else if (t == M2Reserved_HashTok)
14845 : : {
14846 : : /* avoid dangling else. */
14847 : : return M2Quads_IfNotEquOp;
14848 : : }
14849 : 80817 : else if (t == M2Reserved_LessGreaterTok)
14850 : : {
14851 : : /* avoid dangling else. */
14852 : : return M2Quads_IfNotEquOp;
14853 : : }
14854 : 80733 : else if (t == M2Reserved_GreaterEqualTok)
14855 : : {
14856 : : /* avoid dangling else. */
14857 : : return M2Quads_IfGreEquOp;
14858 : : }
14859 : 70095 : else if (t == M2Reserved_LessEqualTok)
14860 : : {
14861 : : /* avoid dangling else. */
14862 : : return M2Quads_IfLessEquOp;
14863 : : }
14864 : 65243 : else if (t == M2Reserved_EqualTok)
14865 : : {
14866 : : /* avoid dangling else. */
14867 : : return M2Quads_IfEquOp;
14868 : : }
14869 : 17716 : else if (t == M2Reserved_LessTok)
14870 : : {
14871 : : /* avoid dangling else. */
14872 : : return M2Quads_IfLessOp;
14873 : : }
14874 : 10108 : else if (t == M2Reserved_GreaterTok)
14875 : : {
14876 : : /* avoid dangling else. */
14877 : : return M2Quads_IfGreOp;
14878 : : }
14879 : 3952 : else if (t == M2Reserved_InTok)
14880 : : {
14881 : : /* avoid dangling else. */
14882 : : return M2Quads_IfInOp;
14883 : : }
14884 : 1464 : else if (t == LogicalOrTok)
14885 : : {
14886 : : /* avoid dangling else. */
14887 : : return M2Quads_LogicalOrOp;
14888 : : }
14889 : 474 : else if (t == LogicalAndTok)
14890 : : {
14891 : : /* avoid dangling else. */
14892 : : return M2Quads_LogicalAndOp;
14893 : : }
14894 : 190 : else if (t == LogicalXorTok)
14895 : : {
14896 : : /* avoid dangling else. */
14897 : : return M2Quads_LogicalXorOp;
14898 : : }
14899 : 66 : else if (t == LogicalDifferenceTok)
14900 : : {
14901 : : /* avoid dangling else. */
14902 : : return M2Quads_LogicalDiffOp;
14903 : : }
14904 : : else
14905 : : {
14906 : : /* avoid dangling else. */
14907 : 0 : M2Error_InternalError ((const char *) "binary operation not implemented yet", 36);
14908 : : }
14909 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
14910 : : __builtin_unreachable ();
14911 : : }
14912 : :
14913 : :
14914 : : /*
14915 : : GenQuadO - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
14916 : : */
14917 : :
14918 : 5380777 : static void GenQuadO (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow)
14919 : : {
14920 : 1200769 : GenQuadOTrash (TokPos, Operation, Op1, Op2, Op3, overflow, SymbolTable_NulSym);
14921 : 714079 : }
14922 : :
14923 : :
14924 : : /*
14925 : : GenQuadOTrash - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
14926 : : */
14927 : :
14928 : 5382591 : static void GenQuadOTrash (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow, unsigned int trash)
14929 : : {
14930 : 5382591 : M2Quads_QuadFrame f;
14931 : :
14932 : : /* WriteString('Potential Quad: ') ; */
14933 : 5382591 : if (QuadrupleGeneration)
14934 : : {
14935 : 5380355 : if (NextQuad != Head)
14936 : : {
14937 : 5365220 : f = GetQF (NextQuad-1);
14938 : 5365220 : f->Next = NextQuad;
14939 : : }
14940 : 5380355 : PutQuadO (NextQuad, Operation, Op1, Op2, Op3, overflow);
14941 : 5380355 : f = GetQF (NextQuad);
14942 : 5380355 : f->Trash = trash;
14943 : 5380355 : f->Next = 0;
14944 : 5380355 : f->LineNo = M2LexBuf_GetLineNo ();
14945 : 5380355 : if (TokPos == M2LexBuf_UnknownTokenNo)
14946 : : {
14947 : 3219125 : f->TokenNo = M2LexBuf_GetTokenNo ();
14948 : : }
14949 : : else
14950 : : {
14951 : 2161230 : f->TokenNo = TokPos;
14952 : : }
14953 : 5380355 : if (M2Options_GetDebugTraceQuad ())
14954 : : {
14955 : 0 : M2Printf_printf0 ((const char *) "generating: ", 12);
14956 : 0 : M2Quads_DisplayQuad (NextQuad);
14957 : : }
14958 : : /* MetaErrorT1 (TokenNo, '{%1On}', NextQuad) */
14959 : 5380355 : CheckBreak (NextQuad);
14960 : 5380355 : NewQuad (&NextQuad);
14961 : : }
14962 : 5382591 : }
14963 : :
14964 : :
14965 : : /*
14966 : : GenQuad - Generate a quadruple with Operation, Op1, Op2, Op3.
14967 : : */
14968 : :
14969 : 3149125 : static void GenQuad (M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3)
14970 : : {
14971 : 2171830 : GenQuadO (M2LexBuf_UnknownTokenNo, Operation, Op1, Op2, Op3, true);
14972 : 619213 : }
14973 : :
14974 : :
14975 : : /*
14976 : : GenQuadOtok - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
14977 : : */
14978 : :
14979 : 574285 : 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)
14980 : : {
14981 : 482324 : GenQuadOTypetok (TokPos, Operation, Op1, Op2, Op3, overflow, true, Op1Pos, Op2Pos, Op3Pos);
14982 : 251716 : }
14983 : :
14984 : :
14985 : : /*
14986 : : GenQuadOTypetok - assigns the fields of the quadruple with
14987 : : the parameters.
14988 : : */
14989 : :
14990 : 873137 : 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)
14991 : : {
14992 : 873137 : M2Quads_QuadFrame f;
14993 : :
14994 : : /* WriteString('Potential Quad: ') ; */
14995 : 873137 : if (QuadrupleGeneration)
14996 : : {
14997 : 872447 : if (NextQuad != Head)
14998 : : {
14999 : 872447 : f = GetQF (NextQuad-1);
15000 : 872447 : f->Next = NextQuad;
15001 : : }
15002 : 872447 : PutQuadOType (NextQuad, Operation, Op1, Op2, Op3, overflow, typecheck);
15003 : 872447 : f = GetQF (NextQuad);
15004 : 872447 : f->Next = 0;
15005 : 872447 : f->LineNo = M2LexBuf_GetLineNo ();
15006 : 872447 : if (TokPos == M2LexBuf_UnknownTokenNo)
15007 : : {
15008 : 0 : f->TokenNo = M2LexBuf_GetTokenNo ();
15009 : : }
15010 : : else
15011 : : {
15012 : 872447 : f->TokenNo = TokPos;
15013 : : }
15014 : 872447 : f->op1pos = Op1Pos;
15015 : 872447 : f->op2pos = Op2Pos;
15016 : 872447 : f->op3pos = Op3Pos;
15017 : 872447 : if (M2Options_GetDebugTraceQuad ())
15018 : : {
15019 : 0 : M2Printf_printf0 ((const char *) "generating: ", 12);
15020 : 0 : M2Quads_DisplayQuad (NextQuad);
15021 : : }
15022 : : /* MetaErrorT1 (TokenNo, '{%1On}', NextQuad) */
15023 : 872447 : CheckBreak (NextQuad);
15024 : 872447 : NewQuad (&NextQuad);
15025 : : }
15026 : 873137 : }
15027 : :
15028 : :
15029 : : /*
15030 : : DumpUntil - dump all quadruples until we seen the ending quadruple
15031 : : with procsym in the third operand.
15032 : : Return the quad number containing the match.
15033 : : */
15034 : :
15035 : 0 : static unsigned int DumpUntil (M2Quads_QuadOperator ending, unsigned int procsym, unsigned int quad)
15036 : : {
15037 : 0 : M2Quads_QuadOperator op;
15038 : 0 : unsigned int op1;
15039 : 0 : unsigned int op2;
15040 : 0 : unsigned int op3;
15041 : 0 : M2Quads_QuadFrame f;
15042 : :
15043 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "\\n...\\n\\n", 9);
15044 : 0 : do {
15045 : 0 : M2Quads_GetQuad (quad, &op, &op1, &op2, &op3);
15046 : 0 : M2Quads_DisplayQuad (quad);
15047 : 0 : f = GetQF (quad);
15048 : 0 : quad = f->Next;
15049 : 0 : } while (! ((op == ending) && (op3 == procsym)));
15050 : 0 : return quad;
15051 : : /* static analysis guarentees a RETURN statement will be used before here. */
15052 : : __builtin_unreachable ();
15053 : : }
15054 : :
15055 : :
15056 : : /*
15057 : : GetCtorInit - return the init procedure for the module.
15058 : : */
15059 : :
15060 : 0 : static unsigned int GetCtorInit (unsigned int sym)
15061 : : {
15062 : 0 : unsigned int ctor;
15063 : 0 : unsigned int init;
15064 : 0 : unsigned int fini;
15065 : 0 : unsigned int dep;
15066 : :
15067 : 0 : SymbolTable_GetModuleCtors (sym, &ctor, &init, &fini, &dep);
15068 : 0 : return init;
15069 : : /* static analysis guarentees a RETURN statement will be used before here. */
15070 : : __builtin_unreachable ();
15071 : : }
15072 : :
15073 : :
15074 : : /*
15075 : : GetCtorFini - return the fini procedure for the module.
15076 : : */
15077 : :
15078 : 0 : static unsigned int GetCtorFini (unsigned int sym)
15079 : : {
15080 : 0 : unsigned int ctor;
15081 : 0 : unsigned int init;
15082 : 0 : unsigned int fini;
15083 : 0 : unsigned int dep;
15084 : :
15085 : 0 : SymbolTable_GetModuleCtors (sym, &ctor, &init, &fini, &dep);
15086 : 0 : return fini;
15087 : : /* static analysis guarentees a RETURN statement will be used before here. */
15088 : : __builtin_unreachable ();
15089 : : }
15090 : :
15091 : :
15092 : : /*
15093 : : DumpQuadrupleFilter -
15094 : : */
15095 : :
15096 : 0 : static void DumpQuadrupleFilter (void)
15097 : : {
15098 : 0 : M2Quads_QuadFrame f;
15099 : 0 : unsigned int i;
15100 : 0 : M2Quads_QuadOperator op;
15101 : 0 : unsigned int op1;
15102 : 0 : unsigned int op2;
15103 : 0 : unsigned int op3;
15104 : :
15105 : 0 : i = Head;
15106 : 0 : while (i != 0)
15107 : : {
15108 : 0 : M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
15109 : 0 : if ((op == M2Quads_ProcedureScopeOp) && (M2LangDump_IsDumpRequired (op3, true)))
15110 : : {
15111 : 0 : i = DumpUntil (M2Quads_KillLocalVarOp, op3, i);
15112 : : }
15113 : 0 : else if ((op == M2Quads_InitStartOp) && (M2LangDump_IsDumpRequired (GetCtorInit (op3), true)))
15114 : : {
15115 : : /* avoid dangling else. */
15116 : 0 : i = DumpUntil (M2Quads_InitEndOp, op3, i);
15117 : : }
15118 : 0 : else if ((op == M2Quads_FinallyStartOp) && (M2LangDump_IsDumpRequired (GetCtorFini (op3), true)))
15119 : : {
15120 : : /* avoid dangling else. */
15121 : 0 : i = DumpUntil (M2Quads_FinallyEndOp, op3, i);
15122 : : }
15123 : : else
15124 : : {
15125 : : /* avoid dangling else. */
15126 : 0 : f = GetQF (i);
15127 : 0 : i = f->Next;
15128 : : }
15129 : : }
15130 : 0 : }
15131 : :
15132 : :
15133 : : /*
15134 : : DumpQuadrupleAll - dump all quadruples.
15135 : : */
15136 : :
15137 : 0 : static void DumpQuadrupleAll (void)
15138 : : {
15139 : 0 : M2Quads_QuadFrame f;
15140 : 0 : unsigned int i;
15141 : :
15142 : 0 : i = Head;
15143 : 0 : while (i != 0)
15144 : : {
15145 : 0 : M2Quads_DisplayQuad (i);
15146 : 0 : f = GetQF (i);
15147 : 0 : i = f->Next;
15148 : : }
15149 : 0 : }
15150 : :
15151 : :
15152 : : /*
15153 : : BackPatch - Makes each of the quadruples on the list pointed to by
15154 : : QuadNo take quadruple Value as a target.
15155 : : */
15156 : :
15157 : 415585 : static void BackPatch (unsigned int QuadNo, unsigned int Value)
15158 : : {
15159 : 415585 : unsigned int i;
15160 : 415585 : M2Quads_QuadFrame f;
15161 : :
15162 : 415585 : if (QuadrupleGeneration)
15163 : : {
15164 : 661412 : while (QuadNo != 0)
15165 : : {
15166 : 245839 : f = GetQF (QuadNo);
15167 : 245839 : i = f->Operand3; /* Next Link along the BackPatch */
15168 : 245839 : ManipulateReference (QuadNo, Value); /* Filling in the BackPatch. */
15169 : 245839 : QuadNo = i;
15170 : : }
15171 : : }
15172 : 415585 : }
15173 : :
15174 : :
15175 : : /*
15176 : : Merge - joins two quad lists, QuadList2 to the end of QuadList1.
15177 : : A QuadList of value zero is a nul list.
15178 : : */
15179 : :
15180 : 54604 : static unsigned int Merge (unsigned int QuadList1, unsigned int QuadList2)
15181 : : {
15182 : 54604 : unsigned int i;
15183 : 54604 : unsigned int j;
15184 : 54604 : M2Quads_QuadFrame f;
15185 : :
15186 : 54604 : if (QuadList1 == 0)
15187 : : {
15188 : : return QuadList2;
15189 : : }
15190 : 26826 : else if (QuadList2 == 0)
15191 : : {
15192 : : /* avoid dangling else. */
15193 : : return QuadList1;
15194 : : }
15195 : : else
15196 : : {
15197 : : /* avoid dangling else. */
15198 : : i = QuadList1;
15199 : 52606 : do {
15200 : 52606 : j = i;
15201 : 52606 : f = GetQF (i);
15202 : 52606 : i = f->Operand3;
15203 : 52606 : } while (! (i == 0));
15204 : 23546 : ManipulateReference (j, QuadList2);
15205 : 23546 : return QuadList1;
15206 : : }
15207 : : /* static analysis guarentees a RETURN statement will be used before here. */
15208 : : __builtin_unreachable ();
15209 : : }
15210 : :
15211 : :
15212 : : /*
15213 : : DisplayProcedureAttributes -
15214 : : */
15215 : :
15216 : 0 : static void DisplayProcedureAttributes (unsigned int proc)
15217 : : {
15218 : 0 : if (SymbolTable_IsCtor (proc))
15219 : : {
15220 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (ctor)", 7);
15221 : : }
15222 : 0 : if (SymbolTable_IsPublic (proc))
15223 : : {
15224 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (public)", 9);
15225 : : }
15226 : 0 : if (SymbolTable_IsExtern (proc))
15227 : : {
15228 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (extern)", 9);
15229 : : }
15230 : 0 : if (SymbolTable_IsMonoName (proc))
15231 : : {
15232 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (mononame)", 11);
15233 : : }
15234 : 0 : }
15235 : :
15236 : :
15237 : : /*
15238 : : WriteQuad - Writes out the Quad BufferQuad.
15239 : : */
15240 : :
15241 : 0 : static void WriteQuad (unsigned int BufferQuad)
15242 : : {
15243 : 0 : NameKey_Name n1;
15244 : 0 : NameKey_Name n2;
15245 : 0 : M2Quads_QuadFrame f;
15246 : 0 : NameKey_Name n;
15247 : 0 : unsigned int l;
15248 : :
15249 : 0 : f = GetQF (BufferQuad);
15250 : 0 : M2Quads_WriteOperator (f->Operator);
15251 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " [%d]", 5, (const unsigned char *) &f->NoOfTimesReferenced, (sizeof (f->NoOfTimesReferenced)-1));
15252 : 0 : if (f->ConstExpr)
15253 : : {
15254 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " const ", 7);
15255 : : }
15256 : : else
15257 : : {
15258 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 7);
15259 : : }
15260 : 0 : switch (f->Operator)
15261 : : {
15262 : 0 : case M2Quads_LastForIteratorOp:
15263 : 0 : M2Quads_WriteOperand (f->Operand1);
15264 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15265 : 0 : M2Quads_WriteOperand (f->Operand2);
15266 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15267 : 0 : M2Quads_WriteOperand (f->Operand3);
15268 : 0 : break;
15269 : :
15270 : 0 : case M2Quads_HighOp:
15271 : 0 : M2Quads_WriteOperand (f->Operand1);
15272 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %4d ", 7, (const unsigned char *) &f->Operand2, (sizeof (f->Operand2)-1));
15273 : 0 : M2Quads_WriteOperand (f->Operand3);
15274 : 0 : break;
15275 : :
15276 : 0 : case M2Quads_InitAddressOp:
15277 : 0 : case M2Quads_SavePriorityOp:
15278 : 0 : case M2Quads_RestorePriorityOp:
15279 : 0 : case M2Quads_SubrangeLowOp:
15280 : 0 : case M2Quads_SubrangeHighOp:
15281 : 0 : case M2Quads_BecomesOp:
15282 : 0 : case M2Quads_InclOp:
15283 : 0 : case M2Quads_ExclOp:
15284 : 0 : case M2Quads_UnboundedOp:
15285 : 0 : case M2Quads_ReturnValueOp:
15286 : 0 : case M2Quads_FunctValueOp:
15287 : 0 : case M2Quads_NegateOp:
15288 : 0 : case M2Quads_AddrOp:
15289 : 0 : case M2Quads_StringConvertCnulOp:
15290 : 0 : case M2Quads_StringConvertM2nulOp:
15291 : 0 : case M2Quads_StringLengthOp:
15292 : 0 : M2Quads_WriteOperand (f->Operand1);
15293 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15294 : 0 : M2Quads_WriteOperand (f->Operand3);
15295 : 0 : break;
15296 : :
15297 : 0 : case M2Quads_ElementSizeOp:
15298 : 0 : case M2Quads_IfInOp:
15299 : 0 : case M2Quads_IfNotInOp:
15300 : 0 : case M2Quads_IfNotEquOp:
15301 : 0 : case M2Quads_IfEquOp:
15302 : 0 : case M2Quads_IfLessOp:
15303 : 0 : case M2Quads_IfGreOp:
15304 : 0 : case M2Quads_IfLessEquOp:
15305 : 0 : case M2Quads_IfGreEquOp:
15306 : 0 : M2Quads_WriteOperand (f->Operand1);
15307 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15308 : 0 : M2Quads_WriteOperand (f->Operand2);
15309 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %4d", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
15310 : 0 : break;
15311 : :
15312 : 0 : case M2Quads_InlineOp:
15313 : 0 : case M2Quads_RetryOp:
15314 : 0 : case M2Quads_TryOp:
15315 : 0 : case M2Quads_GotoOp:
15316 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d", 3, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
15317 : 0 : break;
15318 : :
15319 : 0 : case M2Quads_StatementNoteOp:
15320 : 0 : l = M2LexBuf_TokenToLineNo (f->Operand3, 0);
15321 : 0 : n = M2LexBuf_GetTokenName (f->Operand3);
15322 : 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));
15323 : 0 : break;
15324 : :
15325 : 0 : case M2Quads_LineNumberOp:
15326 : 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));
15327 : 0 : break;
15328 : :
15329 : 0 : case M2Quads_EndFileOp:
15330 : 0 : n1 = SymbolTable_GetSymName (f->Operand3);
15331 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%a", 2, (const unsigned char *) &n1, (sizeof (n1)-1));
15332 : 0 : break;
15333 : :
15334 : 0 : case M2Quads_ThrowOp:
15335 : 0 : case M2Quads_ReturnOp:
15336 : 0 : case M2Quads_CallOp:
15337 : 0 : case M2Quads_KillLocalVarOp:
15338 : 0 : M2Quads_WriteOperand (f->Operand3);
15339 : 0 : break;
15340 : :
15341 : 0 : case M2Quads_ProcedureScopeOp:
15342 : 0 : n1 = SymbolTable_GetSymName (f->Operand2);
15343 : 0 : n2 = SymbolTable_GetSymName (f->Operand3);
15344 : 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));
15345 : 0 : DisplayProcedureAttributes (f->Operand3);
15346 : 0 : break;
15347 : :
15348 : 0 : case M2Quads_NewLocalVarOp:
15349 : 0 : case M2Quads_FinallyStartOp:
15350 : 0 : case M2Quads_FinallyEndOp:
15351 : 0 : case M2Quads_InitEndOp:
15352 : 0 : case M2Quads_InitStartOp:
15353 : 0 : n1 = SymbolTable_GetSymName (f->Operand2);
15354 : 0 : n2 = SymbolTable_GetSymName (f->Operand3);
15355 : 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));
15356 : 0 : break;
15357 : :
15358 : 0 : case M2Quads_ModuleScopeOp:
15359 : 0 : case M2Quads_StartModFileOp:
15360 : 0 : n1 = SymbolTable_GetSymName (f->Operand3);
15361 : 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));
15362 : 0 : break;
15363 : :
15364 : 0 : case M2Quads_StartDefFileOp:
15365 : 0 : n1 = SymbolTable_GetSymName (f->Operand3);
15366 : 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));
15367 : 0 : break;
15368 : :
15369 : 0 : case M2Quads_OptParamOp:
15370 : 0 : case M2Quads_ParamOp:
15371 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d ", 5, (const unsigned char *) &f->Operand1, (sizeof (f->Operand1)-1));
15372 : 0 : M2Quads_WriteOperand (f->Operand2);
15373 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15374 : 0 : M2Quads_WriteOperand (f->Operand3);
15375 : 0 : break;
15376 : :
15377 : 0 : case M2Quads_SizeOp:
15378 : 0 : case M2Quads_RecordFieldOp:
15379 : 0 : case M2Quads_IndrXOp:
15380 : 0 : case M2Quads_XIndrOp:
15381 : 0 : case M2Quads_ArrayOp:
15382 : 0 : case M2Quads_LogicalShiftOp:
15383 : 0 : case M2Quads_LogicalRotateOp:
15384 : 0 : case M2Quads_LogicalOrOp:
15385 : 0 : case M2Quads_LogicalAndOp:
15386 : 0 : case M2Quads_LogicalXorOp:
15387 : 0 : case M2Quads_LogicalDiffOp:
15388 : 0 : case M2Quads_ArithAddOp:
15389 : 0 : case M2Quads_CoerceOp:
15390 : 0 : case M2Quads_ConvertOp:
15391 : 0 : case M2Quads_CastOp:
15392 : 0 : case M2Quads_AddOp:
15393 : 0 : case M2Quads_SubOp:
15394 : 0 : case M2Quads_MultOp:
15395 : 0 : case M2Quads_DivM2Op:
15396 : 0 : case M2Quads_ModM2Op:
15397 : 0 : case M2Quads_ModFloorOp:
15398 : 0 : case M2Quads_DivCeilOp:
15399 : 0 : case M2Quads_ModCeilOp:
15400 : 0 : case M2Quads_DivFloorOp:
15401 : 0 : case M2Quads_ModTruncOp:
15402 : 0 : case M2Quads_DivTruncOp:
15403 : 0 : M2Quads_WriteOperand (f->Operand1);
15404 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15405 : 0 : M2Quads_WriteOperand (f->Operand2);
15406 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15407 : 0 : M2Quads_WriteOperand (f->Operand3);
15408 : 0 : break;
15409 : :
15410 : : case M2Quads_DummyOp:
15411 : : case M2Quads_CodeOnOp:
15412 : : case M2Quads_CodeOffOp:
15413 : : case M2Quads_ProfileOnOp:
15414 : : case M2Quads_ProfileOffOp:
15415 : : case M2Quads_OptimizeOnOp:
15416 : : case M2Quads_OptimizeOffOp:
15417 : : break;
15418 : :
15419 : 0 : case M2Quads_BuiltinConstOp:
15420 : 0 : M2Quads_WriteOperand (f->Operand1);
15421 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %a", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
15422 : 0 : break;
15423 : :
15424 : 0 : case M2Quads_BuiltinTypeInfoOp:
15425 : 0 : M2Quads_WriteOperand (f->Operand1);
15426 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %a", 5, (const unsigned char *) &f->Operand2, (sizeof (f->Operand2)-1));
15427 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %a", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
15428 : 0 : break;
15429 : :
15430 : 0 : case M2Quads_StandardFunctionOp:
15431 : 0 : M2Quads_WriteOperand (f->Operand1);
15432 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15433 : 0 : M2Quads_WriteOperand (f->Operand2);
15434 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15435 : 0 : M2Quads_WriteOperand (f->Operand3);
15436 : 0 : break;
15437 : :
15438 : : case M2Quads_CatchBeginOp:
15439 : : case M2Quads_CatchEndOp:
15440 : : break;
15441 : :
15442 : 0 : case M2Quads_RangeCheckOp:
15443 : 0 : case M2Quads_ErrorOp:
15444 : 0 : M2Range_WriteRangeCheck (f->Operand3);
15445 : 0 : break;
15446 : :
15447 : 0 : case M2Quads_SaveExceptionOp:
15448 : 0 : case M2Quads_RestoreExceptionOp:
15449 : 0 : M2Quads_WriteOperand (f->Operand1);
15450 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15451 : 0 : M2Quads_WriteOperand (f->Operand3);
15452 : 0 : break;
15453 : :
15454 : :
15455 : 0 : default:
15456 : 0 : M2Error_InternalError ((const char *) "quadruple not recognised", 24);
15457 : 0 : break;
15458 : : }
15459 : 0 : }
15460 : :
15461 : :
15462 : : /*
15463 : : WriteOperand - displays the operands name, symbol id and mode of addressing.
15464 : : */
15465 : :
15466 : 0 : static void WriteMode (SymbolTable_ModeOfAddr Mode)
15467 : : {
15468 : 0 : switch (Mode)
15469 : : {
15470 : 0 : case SymbolTable_ImmediateValue:
15471 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "i", 1);
15472 : 0 : break;
15473 : :
15474 : 0 : case SymbolTable_NoValue:
15475 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "n", 1);
15476 : 0 : break;
15477 : :
15478 : 0 : case SymbolTable_RightValue:
15479 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "r", 1);
15480 : 0 : break;
15481 : :
15482 : 0 : case SymbolTable_LeftValue:
15483 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "l", 1);
15484 : 0 : break;
15485 : :
15486 : :
15487 : 0 : default:
15488 : 0 : M2Error_InternalError ((const char *) "unrecognised mode", 17);
15489 : 0 : break;
15490 : : }
15491 : 0 : }
15492 : :
15493 : :
15494 : : /*
15495 : : PushExit - pushes the exit value onto the EXIT stack.
15496 : : */
15497 : :
15498 : 610 : static void PushExit (unsigned int Exit)
15499 : : {
15500 : 0 : M2StackWord_PushWord (ExitStack, Exit);
15501 : 94 : }
15502 : :
15503 : :
15504 : : /*
15505 : : PopExit - pops the exit value from the EXIT stack.
15506 : : */
15507 : :
15508 : 610 : static unsigned int PopExit (void)
15509 : : {
15510 : 0 : return M2StackWord_PopWord (ExitStack);
15511 : : /* static analysis guarentees a RETURN statement will be used before here. */
15512 : : __builtin_unreachable ();
15513 : : }
15514 : :
15515 : :
15516 : : /*
15517 : : PushFor - pushes the exit value onto the FOR stack.
15518 : : */
15519 : :
15520 : 10422 : static void PushFor (unsigned int Exit)
15521 : : {
15522 : 0 : M2StackWord_PushWord (ForStack, Exit);
15523 : 0 : }
15524 : :
15525 : :
15526 : : /*
15527 : : PopFor - pops the exit value from the FOR stack.
15528 : : */
15529 : :
15530 : 10416 : static unsigned int PopFor (void)
15531 : : {
15532 : 0 : return M2StackWord_PopWord (ForStack);
15533 : : /* static analysis guarentees a RETURN statement will be used before here. */
15534 : : __builtin_unreachable ();
15535 : : }
15536 : :
15537 : :
15538 : : /*
15539 : : OperandTno - returns the ident operand stored in the true position
15540 : : on the boolean stack. This is exactly the same as
15541 : : OperandT but it has no IsBoolean checking.
15542 : : */
15543 : :
15544 : 210625034 : static unsigned int OperandTno (unsigned int pos)
15545 : : {
15546 : 210625034 : M2Quads_BoolFrame f;
15547 : :
15548 : 210625034 : M2Debug_Assert (pos > 0);
15549 : 210625034 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15550 : 210625034 : return static_cast<unsigned int> (f->TrueExit);
15551 : : /* static analysis guarentees a RETURN statement will be used before here. */
15552 : : __builtin_unreachable ();
15553 : : }
15554 : :
15555 : :
15556 : : /*
15557 : : OperandFno - returns the ident operand stored in the false position
15558 : : on the boolean stack. This is exactly the same as
15559 : : OperandF but it has no IsBoolean checking.
15560 : : */
15561 : :
15562 : 177492 : static unsigned int OperandFno (unsigned int pos)
15563 : : {
15564 : 177492 : M2Quads_BoolFrame f;
15565 : :
15566 : 177492 : M2Debug_Assert (pos > 0);
15567 : 177492 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15568 : 177492 : return static_cast<unsigned int> (f->FalseExit);
15569 : : /* static analysis guarentees a RETURN statement will be used before here. */
15570 : : __builtin_unreachable ();
15571 : : }
15572 : :
15573 : :
15574 : : /*
15575 : : OperandTtok - returns the token associated with the position, pos
15576 : : on the boolean stack.
15577 : : */
15578 : :
15579 : 57838897 : static unsigned int OperandTtok (unsigned int pos)
15580 : : {
15581 : 57838897 : M2Quads_BoolFrame f;
15582 : :
15583 : 57838897 : M2Debug_Assert (pos > 0);
15584 : 57838897 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15585 : 57838897 : return f->tokenno;
15586 : : /* static analysis guarentees a RETURN statement will be used before here. */
15587 : : __builtin_unreachable ();
15588 : : }
15589 : :
15590 : :
15591 : : /*
15592 : : PopBooltok - Pops a True and a False exit quad number from the True/False
15593 : : stack.
15594 : : */
15595 : :
15596 : 226254 : static void PopBooltok (unsigned int *True, unsigned int *False, unsigned int *tokno)
15597 : : {
15598 : 226254 : M2Quads_BoolFrame f;
15599 : :
15600 : 226254 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15601 : 226254 : (*True) = f->TrueExit;
15602 : 226254 : (*False) = f->FalseExit;
15603 : 226254 : (*tokno) = f->tokenno;
15604 : 226254 : M2Debug_Assert (f->BooleanOp);
15605 : 226254 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15606 : 226254 : }
15607 : :
15608 : :
15609 : : /*
15610 : : PushBooltok - Push a True and a False exit quad numbers onto the
15611 : : True/False stack.
15612 : : */
15613 : :
15614 : 233608 : static void PushBooltok (unsigned int True, unsigned int False, unsigned int tokno)
15615 : : {
15616 : 233608 : M2Quads_BoolFrame f;
15617 : :
15618 : 233608 : M2Debug_Assert (True <= NextQuad);
15619 : 233608 : M2Debug_Assert (False <= NextQuad);
15620 : 233608 : f = newBoolFrame ();
15621 : 233608 : f->TrueExit = True;
15622 : 233608 : f->FalseExit = False;
15623 : 233608 : f->BooleanOp = true;
15624 : 233608 : f->tokenno = tokno;
15625 : 233608 : f->Annotation = static_cast<DynamicStrings_String> (NULL);
15626 : 233608 : f->RangeDep = 0;
15627 : 233608 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15628 : 233608 : M2Quads_Annotate ((const char *) "<q%1d>|<q%2d>||true quad|false quad", 35);
15629 : 233608 : }
15630 : :
15631 : :
15632 : : /*
15633 : : PopBool - Pops a True and a False exit quad number from the True/False
15634 : : stack.
15635 : : */
15636 : :
15637 : 192898 : static void PopBool (unsigned int *True, unsigned int *False)
15638 : : {
15639 : 192898 : unsigned int tokno;
15640 : :
15641 : 9980 : PopBooltok (True, False, &tokno);
15642 : 0 : }
15643 : :
15644 : :
15645 : : /*
15646 : : PushBool - Push a True and a False exit quad numbers onto the
15647 : : True/False stack.
15648 : : */
15649 : :
15650 : 121609 : static void PushBool (unsigned int True, unsigned int False)
15651 : : {
15652 : 7354 : PushBooltok (True, False, M2LexBuf_UnknownTokenNo);
15653 : 13318 : }
15654 : :
15655 : :
15656 : : /*
15657 : : IsBoolean - returns true is the Stack position pos contains a Boolean
15658 : : Exit. False is returned if an Ident is stored.
15659 : : */
15660 : :
15661 : 272368468 : static bool IsBoolean (unsigned int pos)
15662 : : {
15663 : 272368468 : M2Quads_BoolFrame f;
15664 : :
15665 : 272368468 : M2Debug_Assert (pos > 0);
15666 : 272368468 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15667 : 272368468 : return f->BooleanOp;
15668 : : /* static analysis guarentees a RETURN statement will be used before here. */
15669 : : __builtin_unreachable ();
15670 : : }
15671 : :
15672 : :
15673 : : /*
15674 : : OperandD - returns possible array dimension associated with the ident
15675 : : operand stored on the boolean stack.
15676 : : */
15677 : :
15678 : 684114 : static unsigned int OperandD (unsigned int pos)
15679 : : {
15680 : 684114 : M2Quads_BoolFrame f;
15681 : :
15682 : 684114 : M2Debug_Assert (pos > 0);
15683 : 684114 : M2Debug_Assert (! (IsBoolean (pos)));
15684 : 684114 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15685 : 684114 : return static_cast<unsigned int> (f->Dimension);
15686 : : /* static analysis guarentees a RETURN statement will be used before here. */
15687 : : __builtin_unreachable ();
15688 : : }
15689 : :
15690 : :
15691 : : /*
15692 : : OperandRW - returns the rw operand stored on the boolean stack.
15693 : : */
15694 : :
15695 : 746266 : static unsigned int OperandRW (unsigned int pos)
15696 : : {
15697 : 746266 : M2Quads_BoolFrame f;
15698 : :
15699 : 746266 : M2Debug_Assert (pos > 0);
15700 : 746266 : M2Debug_Assert (! (IsBoolean (pos)));
15701 : 746266 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15702 : 746266 : return static_cast<unsigned int> (f->ReadWrite);
15703 : : /* static analysis guarentees a RETURN statement will be used before here. */
15704 : : __builtin_unreachable ();
15705 : : }
15706 : :
15707 : :
15708 : : /*
15709 : : OperandMergeRW - returns the rw operand if not NulSym else it
15710 : : returns True.
15711 : : */
15712 : :
15713 : 722430 : static unsigned int OperandMergeRW (unsigned int pos)
15714 : : {
15715 : 722430 : if ((OperandRW (pos)) == SymbolTable_NulSym)
15716 : : {
15717 : 700952 : return M2Quads_OperandT (pos);
15718 : : }
15719 : : else
15720 : : {
15721 : 21478 : return OperandRW (pos);
15722 : : }
15723 : : /* static analysis guarentees a RETURN statement will be used before here. */
15724 : : __builtin_unreachable ();
15725 : : }
15726 : :
15727 : :
15728 : : /*
15729 : : OperandRangeDep - return the range dependant associated with the quad stack.
15730 : : */
15731 : :
15732 : 141995 : static unsigned int OperandRangeDep (unsigned int pos)
15733 : : {
15734 : 141995 : M2Quads_BoolFrame f;
15735 : :
15736 : 141995 : M2Debug_Assert (! (IsBoolean (pos)));
15737 : 141995 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15738 : 141995 : return f->RangeDep;
15739 : : /* static analysis guarentees a RETURN statement will be used before here. */
15740 : : __builtin_unreachable ();
15741 : : }
15742 : :
15743 : :
15744 : : /*
15745 : : PutRangeDep - assigns the quad stack pos RangeDep to dep.
15746 : : */
15747 : :
15748 : 535132 : static void PutRangeDep (unsigned int pos, unsigned int dep)
15749 : : {
15750 : 535132 : M2Quads_BoolFrame f;
15751 : :
15752 : 535132 : M2Debug_Assert (! (IsBoolean (pos)));
15753 : 535132 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15754 : 535132 : f->RangeDep = dep;
15755 : 535132 : }
15756 : :
15757 : :
15758 : : /*
15759 : : UseLineNote - uses the line note and returns it to the free list.
15760 : : */
15761 : :
15762 : 5220 : static void UseLineNote (M2Quads_LineNote l)
15763 : : {
15764 : 5220 : M2Quads_QuadFrame f;
15765 : :
15766 : 5220 : f = GetQF (NextQuad-1);
15767 : 5220 : if ((f->Operator == M2Quads_LineNumberOp) && (f->Operand1 == ((unsigned int ) (l->File))))
15768 : : {} /* empty. */
15769 : : else
15770 : : {
15771 : : /* do nothing */
15772 : : if (false)
15773 : : {
15774 : : GenQuad (M2Quads_LineNumberOp, (unsigned int ) (l->File), SymbolTable_NulSym, (unsigned int ) (l->Line));
15775 : : }
15776 : : }
15777 : 5220 : l->Next = FreeLineList;
15778 : 5220 : FreeLineList = l;
15779 : 5220 : }
15780 : :
15781 : :
15782 : : /*
15783 : : PopLineNo - pops a line note from the line stack.
15784 : : */
15785 : :
15786 : 5220 : static M2Quads_LineNote PopLineNo (void)
15787 : : {
15788 : 5220 : M2Quads_LineNote l;
15789 : :
15790 : 5220 : l = static_cast<M2Quads_LineNote> (M2StackAddress_PopAddress (LineStack));
15791 : 5220 : if (l == NULL)
15792 : : {
15793 : 0 : M2Error_InternalError ((const char *) "no line note available", 22);
15794 : : }
15795 : 5220 : return l;
15796 : : /* static analysis guarentees a RETURN statement will be used before here. */
15797 : : __builtin_unreachable ();
15798 : : }
15799 : :
15800 : :
15801 : : /*
15802 : : InitLineNote - creates a line note and initializes it to
15803 : : contain, file, line.
15804 : : */
15805 : :
15806 : 5220 : static M2Quads_LineNote InitLineNote (NameKey_Name file, unsigned int line)
15807 : : {
15808 : 5220 : M2Quads_LineNote l;
15809 : :
15810 : 5220 : if (FreeLineList == NULL)
15811 : : {
15812 : 2412 : Storage_ALLOCATE ((void **) &l, sizeof (M2Quads__T6));
15813 : : }
15814 : : else
15815 : : {
15816 : 2808 : l = FreeLineList;
15817 : 2808 : FreeLineList = FreeLineList->Next;
15818 : : }
15819 : 5220 : l->File = file;
15820 : 5220 : l->Line = line;
15821 : 5220 : return l;
15822 : : /* static analysis guarentees a RETURN statement will be used before here. */
15823 : : __builtin_unreachable ();
15824 : : }
15825 : :
15826 : :
15827 : : /*
15828 : : PushLineNote -
15829 : : */
15830 : :
15831 : 5220 : static void PushLineNote (M2Quads_LineNote l)
15832 : : {
15833 : 0 : M2StackAddress_PushAddress (LineStack, reinterpret_cast <void *> (l));
15834 : 0 : }
15835 : :
15836 : :
15837 : : /*
15838 : : BuildStmtNoteTok - adds a nop (with an assigned tokenno location) to the code.
15839 : : */
15840 : :
15841 : 549176 : static void BuildStmtNoteTok (unsigned int tokenno)
15842 : : {
15843 : 549176 : NameKey_Name filename;
15844 : 549176 : M2Quads_QuadFrame f;
15845 : :
15846 : 549176 : f = GetQF (NextQuad-1);
15847 : : /* no need to have multiple notes at the same position. */
15848 : 549176 : if ((f->Operator != M2Quads_StatementNoteOp) || (f->Operand3 != tokenno))
15849 : : {
15850 : 541770 : filename = NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()));
15851 : 541770 : GenQuad (M2Quads_StatementNoteOp, (unsigned int ) (filename), SymbolTable_NulSym, tokenno);
15852 : : }
15853 : 549176 : }
15854 : :
15855 : :
15856 : : /*
15857 : : GetRecordOrField -
15858 : : */
15859 : :
15860 : 12042 : static unsigned int GetRecordOrField (void)
15861 : : {
15862 : 12042 : unsigned int f;
15863 : :
15864 : 12042 : VarientFieldNo += 1;
15865 : 12042 : f = static_cast<unsigned int> (Lists_GetItemFromList (VarientFields, VarientFieldNo));
15866 : 12042 : if (DebugVarients)
15867 : : {
15868 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
15869 : : if (SymbolTable_IsRecord (f))
15870 : : {
15871 : : 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));
15872 : : }
15873 : : else
15874 : : {
15875 : : 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));
15876 : : }
15877 : : }
15878 : 12042 : return f;
15879 : : /* static analysis guarentees a RETURN statement will be used before here. */
15880 : : __builtin_unreachable ();
15881 : : }
15882 : :
15883 : :
15884 : : /*
15885 : : PushTFAD - Push True, False, Array, Dim, numbers onto the
15886 : : True/False stack. True and False are assumed to
15887 : : contain Symbols or Ident etc.
15888 : : */
15889 : :
15890 : 384 : static void PushTFAD (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim)
15891 : : {
15892 : 384 : M2Quads_BoolFrame f;
15893 : :
15894 : 384 : f = newBoolFrame ();
15895 : 384 : f->TrueExit = static_cast<unsigned int> (True);
15896 : 384 : f->FalseExit = static_cast<unsigned int> (False);
15897 : 384 : f->Unbounded = static_cast<unsigned int> (Array);
15898 : 384 : f->Dimension = static_cast<unsigned int> (Dim);
15899 : 384 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15900 : 384 : }
15901 : :
15902 : :
15903 : : /*
15904 : : PushTFADtok - Push True, False, Array, Dim, numbers onto the
15905 : : True/False stack. True and False are assumed to
15906 : : contain Symbols or Ident etc.
15907 : : */
15908 : :
15909 : 3024 : static void PushTFADtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int tokno)
15910 : : {
15911 : 3024 : M2Quads_BoolFrame f;
15912 : :
15913 : 3024 : f = newBoolFrame ();
15914 : 3024 : f->TrueExit = static_cast<unsigned int> (True);
15915 : 3024 : f->FalseExit = static_cast<unsigned int> (False);
15916 : 3024 : f->Unbounded = static_cast<unsigned int> (Array);
15917 : 3024 : f->Dimension = static_cast<unsigned int> (Dim);
15918 : 3024 : f->tokenno = tokno;
15919 : 3024 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15920 : 3024 : }
15921 : :
15922 : :
15923 : : /*
15924 : : PushTFADrwtok - Push True, False, Array, Dim, rw, numbers onto the
15925 : : True/False stack. True and False are assumed to
15926 : : contain Symbols or Ident etc.
15927 : : */
15928 : :
15929 : 8994 : static void PushTFADrwtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int rw, unsigned int Tok)
15930 : : {
15931 : 8994 : M2Quads_BoolFrame f;
15932 : :
15933 : 8994 : f = newBoolFrame ();
15934 : 8994 : f->TrueExit = static_cast<unsigned int> (True);
15935 : 8994 : f->FalseExit = static_cast<unsigned int> (False);
15936 : 8994 : f->Unbounded = static_cast<unsigned int> (Array);
15937 : 8994 : f->Dimension = static_cast<unsigned int> (Dim);
15938 : 8994 : f->ReadWrite = static_cast<unsigned int> (rw);
15939 : 8994 : f->tokenno = Tok;
15940 : 8994 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15941 : 8994 : }
15942 : :
15943 : :
15944 : : /*
15945 : : PopTFrwtok - Pop a True and False number from the True/False stack.
15946 : : True and False are assumed to contain Symbols or Ident etc.
15947 : : */
15948 : :
15949 : 314380 : static void PopTFrwtok (unsigned int *True, unsigned int *False, unsigned int *rw, unsigned int *tokno)
15950 : : {
15951 : 314380 : M2Quads_BoolFrame f;
15952 : :
15953 : 314380 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15954 : 314380 : (*True) = static_cast<unsigned int> (f->TrueExit);
15955 : 314380 : (*False) = static_cast<unsigned int> (f->FalseExit);
15956 : 314380 : M2Debug_Assert (! f->BooleanOp);
15957 : 314380 : (*rw) = static_cast<unsigned int> (f->ReadWrite);
15958 : 314380 : (*tokno) = f->tokenno;
15959 : 314380 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15960 : 314380 : }
15961 : :
15962 : :
15963 : : /*
15964 : : PushTFrwtok - Push an item onto the stack in the T (true) position,
15965 : : it is assummed to be a token and its token location is recorded.
15966 : : */
15967 : :
15968 : 322284 : static void PushTFrwtok (unsigned int True, unsigned int False, unsigned int rw, unsigned int tokno)
15969 : : {
15970 : 322284 : M2Quads_BoolFrame f;
15971 : :
15972 : 322284 : f = newBoolFrame ();
15973 : 322284 : f->TrueExit = static_cast<unsigned int> (True);
15974 : 322284 : f->FalseExit = static_cast<unsigned int> (False);
15975 : 322284 : f->ReadWrite = static_cast<unsigned int> (rw);
15976 : 322284 : f->tokenno = tokno;
15977 : 322284 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15978 : 322284 : }
15979 : :
15980 : :
15981 : : /*
15982 : : PushTFDtok - Push True, False, Dim, numbers onto the
15983 : : True/False stack. True and False are assumed to
15984 : : contain Symbols or Ident etc.
15985 : : */
15986 : :
15987 : 258 : static void PushTFDtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int Tok)
15988 : : {
15989 : 258 : M2Quads_BoolFrame f;
15990 : :
15991 : 258 : f = newBoolFrame ();
15992 : 258 : f->TrueExit = static_cast<unsigned int> (True);
15993 : 258 : f->FalseExit = static_cast<unsigned int> (False);
15994 : 258 : f->Dimension = static_cast<unsigned int> (Dim);
15995 : 258 : f->tokenno = Tok;
15996 : 258 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15997 : 258 : }
15998 : :
15999 : :
16000 : : /*
16001 : : PopTFDtok - Pop a True, False, Dim number from the True/False stack.
16002 : : True and False are assumed to contain Symbols or Ident etc.
16003 : : */
16004 : :
16005 : 258 : static void PopTFDtok (unsigned int *True, unsigned int *False, unsigned int *Dim, unsigned int *Tok)
16006 : : {
16007 : 258 : M2Quads_BoolFrame f;
16008 : :
16009 : 258 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
16010 : 258 : (*True) = static_cast<unsigned int> (f->TrueExit);
16011 : 258 : (*False) = static_cast<unsigned int> (f->FalseExit);
16012 : 258 : (*Dim) = static_cast<unsigned int> (f->Dimension);
16013 : 258 : (*Tok) = f->tokenno;
16014 : 258 : M2Debug_Assert (! f->BooleanOp);
16015 : 258 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
16016 : 258 : }
16017 : :
16018 : :
16019 : : /*
16020 : : PushTFDrwtok - Push True, False, Dim, numbers onto the
16021 : : True/False stack. True and False are assumed to
16022 : : contain Symbols or Ident etc.
16023 : : */
16024 : :
16025 : 47726 : static void PushTFDrwtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int rw, unsigned int Tok)
16026 : : {
16027 : 47726 : M2Quads_BoolFrame f;
16028 : :
16029 : 47726 : f = newBoolFrame ();
16030 : 47726 : f->TrueExit = static_cast<unsigned int> (True);
16031 : 47726 : f->FalseExit = static_cast<unsigned int> (False);
16032 : 47726 : f->Dimension = static_cast<unsigned int> (Dim);
16033 : 47726 : f->ReadWrite = static_cast<unsigned int> (rw);
16034 : 47726 : f->tokenno = Tok;
16035 : 47726 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
16036 : 47726 : }
16037 : :
16038 : :
16039 : : /*
16040 : : PushTFrw - Push a True and False numbers onto the True/False stack.
16041 : : True and False are assumed to contain Symbols or Ident etc.
16042 : : It also pushes the higher level symbol which is associated
16043 : : with the True symbol. Eg record variable or array variable.
16044 : : */
16045 : :
16046 : 2358 : static void PushTFrw (unsigned int True, unsigned int False, unsigned int rw)
16047 : : {
16048 : 2358 : M2Quads_BoolFrame f;
16049 : :
16050 : 2358 : f = newBoolFrame ();
16051 : 2358 : f->TrueExit = static_cast<unsigned int> (True);
16052 : 2358 : f->FalseExit = static_cast<unsigned int> (False);
16053 : 2358 : f->ReadWrite = rw;
16054 : 2358 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
16055 : 2358 : }
16056 : :
16057 : :
16058 : : /*
16059 : : PopTFrw - Pop a True and False number from the True/False stack.
16060 : : True and False are assumed to contain Symbols or Ident etc.
16061 : : */
16062 : :
16063 : 30984 : static void PopTFrw (unsigned int *True, unsigned int *False, unsigned int *rw)
16064 : : {
16065 : 30984 : M2Quads_BoolFrame f;
16066 : :
16067 : 30984 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
16068 : 30984 : (*True) = static_cast<unsigned int> (f->TrueExit);
16069 : 30984 : (*False) = static_cast<unsigned int> (f->FalseExit);
16070 : 30984 : M2Debug_Assert (! f->BooleanOp);
16071 : 30984 : (*rw) = static_cast<unsigned int> (f->ReadWrite);
16072 : 30984 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
16073 : 30984 : }
16074 : :
16075 : :
16076 : : /*
16077 : : newBoolFrame - creates a new BoolFrame with all fields initialised to their defaults.
16078 : : */
16079 : :
16080 : 345681193 : static M2Quads_BoolFrame newBoolFrame (void)
16081 : : {
16082 : 345681193 : M2Quads_BoolFrame f;
16083 : :
16084 : 345681193 : Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T2));
16085 : 345681193 : f->TrueExit = 0;
16086 : 345681193 : f->FalseExit = 0;
16087 : 345681193 : f->Unbounded = SymbolTable_NulSym;
16088 : 345681193 : f->BooleanOp = false;
16089 : 345681193 : f->Dimension = 0;
16090 : 345681193 : f->ReadWrite = SymbolTable_NulSym;
16091 : 345681193 : f->name = SymbolTable_NulSym;
16092 : 345681193 : f->Annotation = static_cast<DynamicStrings_String> (NULL);
16093 : 345681193 : f->tokenno = M2LexBuf_UnknownTokenNo;
16094 : 345681193 : return f;
16095 : : /* static analysis guarentees a RETURN statement will be used before here. */
16096 : : __builtin_unreachable ();
16097 : : }
16098 : :
16099 : :
16100 : : /*
16101 : : PushTrwtok - Push an item onto the True/False stack. The False value will be zero.
16102 : : */
16103 : :
16104 : 144 : static void PushTrwtok (unsigned int True, unsigned int rw, unsigned int tok)
16105 : : {
16106 : 144 : M2Quads_BoolFrame f;
16107 : :
16108 : 144 : f = newBoolFrame ();
16109 : 144 : f->TrueExit = static_cast<unsigned int> (True);
16110 : 144 : f->ReadWrite = static_cast<unsigned int> (rw);
16111 : 144 : f->tokenno = tok;
16112 : 144 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
16113 : 144 : }
16114 : :
16115 : :
16116 : : /*
16117 : : PopTrw - Pop a True field and rw symbol from the stack.
16118 : : */
16119 : :
16120 : 2358 : static void PopTrw (unsigned int *True, unsigned int *rw)
16121 : : {
16122 : 2358 : M2Quads_BoolFrame f;
16123 : :
16124 : 2358 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
16125 : 2358 : (*True) = static_cast<unsigned int> (f->TrueExit);
16126 : 2358 : M2Debug_Assert (! f->BooleanOp);
16127 : 2358 : (*rw) = static_cast<unsigned int> (f->ReadWrite);
16128 : 2358 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
16129 : 2358 : }
16130 : :
16131 : :
16132 : : /*
16133 : : PopTrwtok - Pop a True field and rw symbol from the stack.
16134 : : */
16135 : :
16136 : 1078254 : static void PopTrwtok (unsigned int *True, unsigned int *rw, unsigned int *tok)
16137 : : {
16138 : 1078254 : M2Quads_BoolFrame f;
16139 : :
16140 : 1078254 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
16141 : 1078254 : (*True) = static_cast<unsigned int> (f->TrueExit);
16142 : 1078254 : M2Debug_Assert (! f->BooleanOp);
16143 : 1078254 : (*rw) = static_cast<unsigned int> (f->ReadWrite);
16144 : 1078254 : (*tok) = f->tokenno;
16145 : 1078254 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
16146 : 1078254 : }
16147 : :
16148 : :
16149 : : /*
16150 : : gdbhook - a debugger convenience hook.
16151 : : */
16152 : :
16153 : 0 : static void gdbhook (void)
16154 : : {
16155 : 0 : }
16156 : :
16157 : :
16158 : : /*
16159 : : BreakWhenQuadCreated - to be called interactively by gdb.
16160 : : */
16161 : :
16162 : 15506 : static void BreakWhenQuadCreated (unsigned int quad)
16163 : : {
16164 : 15506 : BreakQuad = quad;
16165 : 0 : }
16166 : :
16167 : :
16168 : : /*
16169 : : CheckBreak - if quad = BreakQuad then call gdbhook.
16170 : : */
16171 : :
16172 : 0 : static void CheckBreak (unsigned int quad)
16173 : : {
16174 : 0 : if (quad == BreakQuad)
16175 : : {
16176 : 0 : gdbhook ();
16177 : : }
16178 : 0 : }
16179 : :
16180 : :
16181 : : /*
16182 : : Init - initialize the M2Quads module, all the stacks, all the lists
16183 : : and the quads list.
16184 : : */
16185 : :
16186 : 15506 : static void Init (void)
16187 : : {
16188 : 15506 : BreakWhenQuadCreated (0); /* Disable the intereactive quad watch. */
16189 : : /* To examine the quad table when a quad is created run cc1gm2 from gdb
16190 : : and set a break point on gdbhook.
16191 : : (gdb) break gdbhook
16192 : : (gdb) run
16193 : : Now below interactively call BreakWhenQuadCreated with the quad
16194 : : under investigation. */
16195 : 15506 : gdbhook ();
16196 : : /* Now is the time to interactively call gdb, for example:
16197 : : (gdb) print BreakWhenQuadCreated (1234)
16198 : : (gdb) cont
16199 : : and you will arrive at gdbhook when this quad is created. */
16200 : 15506 : LogicalOrTok = NameKey_MakeKey ((const char *) "_LOR", 4);
16201 : 15506 : LogicalAndTok = NameKey_MakeKey ((const char *) "_LAND", 5);
16202 : 15506 : LogicalXorTok = NameKey_MakeKey ((const char *) "_LXOR", 5);
16203 : 15506 : LogicalDifferenceTok = NameKey_MakeKey ((const char *) "_LDIFF", 6);
16204 : 15506 : ArithPlusTok = NameKey_MakeKey ((const char *) "_ARITH_+", 8);
16205 : 15506 : QuadArray = Indexing_InitIndexTuned (1, (1024*1024) / 16, 16);
16206 : 15506 : FreeList = 1;
16207 : 15506 : NewQuad (&NextQuad);
16208 : 15506 : M2Debug_Assert (NextQuad == 1);
16209 : 15506 : BoolStack = M2StackAddress_InitStackAddress ();
16210 : 15506 : ExitStack = M2StackWord_InitStackWord ();
16211 : 15506 : RepeatStack = M2StackWord_InitStackWord ();
16212 : 15506 : WhileStack = M2StackWord_InitStackWord ();
16213 : 15506 : ForStack = M2StackWord_InitStackWord ();
16214 : 15506 : WithStack = M2StackAddress_InitStackAddress ();
16215 : 15506 : ReturnStack = M2StackWord_InitStackWord ();
16216 : 15506 : LineStack = M2StackAddress_InitStackAddress ();
16217 : 15506 : PriorityStack = M2StackWord_InitStackWord ();
16218 : 15506 : TryStack = M2StackWord_InitStackWord ();
16219 : 15506 : CatchStack = M2StackWord_InitStackWord ();
16220 : 15506 : ExceptStack = M2StackWord_InitStackWord ();
16221 : 15506 : ConstructorStack = M2StackAddress_InitStackAddress ();
16222 : 15506 : ConstParamStack = M2StackWord_InitStackWord ();
16223 : 15506 : ConstExprStack = M2StackWord_InitStackWord ();
16224 : : /* StressStack ; */
16225 : 15506 : SuppressWith = false;
16226 : 15506 : Head = 1;
16227 : 15506 : LastQuadNo = 0;
16228 : 15506 : MustNotCheckBounds = false;
16229 : 15506 : InitQuad = 0;
16230 : 15506 : GrowInitialization = 0;
16231 : 15506 : ForInfo = Indexing_InitIndex (1);
16232 : 15506 : QuadrupleGeneration = true;
16233 : 15506 : BuildingHigh = false;
16234 : 15506 : BuildingSize = false;
16235 : 15506 : AutoStack = M2StackWord_InitStackWord ();
16236 : 15506 : IsAutoOn = true;
16237 : 15506 : InConstExpression = false;
16238 : 15506 : InConstParameters = false;
16239 : 15506 : FreeLineList = NULL;
16240 : 15506 : Lists_InitList (&VarientFields);
16241 : 15506 : VarientFieldNo = 0;
16242 : 15506 : NoOfQuads = 0;
16243 : 15506 : QuadMemDiag = M2Diagnostic_InitMemDiagnostic ((const char *) "M2Quad:Quadruples", 17, (const char *) "{0N} total quadruples {1d} consuming {2M} ram {0M} ({2P})", 57);
16244 : 15506 : }
16245 : :
16246 : :
16247 : : /*
16248 : : SetOptionCoding - builds a code quadruple if the profiling
16249 : : option was given to the compiler.
16250 : : */
16251 : :
16252 : 0 : extern "C" void M2Quads_SetOptionCoding (bool b)
16253 : : {
16254 : 0 : if (b != M2Options_Coding)
16255 : : {
16256 : 0 : if (b)
16257 : : {
16258 : 0 : M2Quads_BuildCodeOn ();
16259 : : }
16260 : : else
16261 : : {
16262 : 0 : M2Quads_BuildCodeOff ();
16263 : : }
16264 : 0 : M2Options_Coding = b;
16265 : : }
16266 : 0 : }
16267 : :
16268 : :
16269 : : /*
16270 : : SetOptionProfiling - builds a profile quadruple if the profiling
16271 : : option was given to the compiler.
16272 : : */
16273 : :
16274 : 0 : extern "C" void M2Quads_SetOptionProfiling (bool b)
16275 : : {
16276 : 0 : if (b != M2Options_Profiling)
16277 : : {
16278 : 0 : if (b)
16279 : : {
16280 : 0 : M2Quads_BuildProfileOn ();
16281 : : }
16282 : : else
16283 : : {
16284 : 0 : M2Quads_BuildProfileOff ();
16285 : : }
16286 : 0 : M2Options_Profiling = b;
16287 : : }
16288 : 0 : }
16289 : :
16290 : :
16291 : : /*
16292 : : SetOptionOptimizing - builds a quadruple to say that the optimization option
16293 : : has been found in a comment.
16294 : : */
16295 : :
16296 : 0 : extern "C" void M2Quads_SetOptionOptimizing (bool b)
16297 : : {
16298 : 0 : if (b)
16299 : : {
16300 : 0 : M2Quads_BuildOptimizeOn ();
16301 : : }
16302 : : else
16303 : : {
16304 : 0 : M2Quads_BuildOptimizeOff ();
16305 : : }
16306 : 0 : }
16307 : :
16308 : :
16309 : : /*
16310 : : Opposite - returns the opposite comparison operator.
16311 : : */
16312 : :
16313 : 81904 : extern "C" M2Quads_QuadOperator M2Quads_Opposite (M2Quads_QuadOperator Operator)
16314 : : {
16315 : 81904 : M2Quads_QuadOperator Op;
16316 : :
16317 : 81904 : switch (Operator)
16318 : : {
16319 : : case M2Quads_IfNotEquOp:
16320 : : Op = M2Quads_IfEquOp;
16321 : : break;
16322 : :
16323 : : case M2Quads_IfEquOp:
16324 : : Op = M2Quads_IfNotEquOp;
16325 : : break;
16326 : :
16327 : : case M2Quads_IfLessEquOp:
16328 : : Op = M2Quads_IfGreOp;
16329 : : break;
16330 : :
16331 : : case M2Quads_IfGreOp:
16332 : : Op = M2Quads_IfLessEquOp;
16333 : : break;
16334 : :
16335 : : case M2Quads_IfGreEquOp:
16336 : : Op = M2Quads_IfLessOp;
16337 : : break;
16338 : :
16339 : : case M2Quads_IfLessOp:
16340 : : Op = M2Quads_IfGreEquOp;
16341 : : break;
16342 : :
16343 : : case M2Quads_IfInOp:
16344 : : Op = M2Quads_IfNotInOp;
16345 : : break;
16346 : :
16347 : : case M2Quads_IfNotInOp:
16348 : : Op = M2Quads_IfInOp;
16349 : : break;
16350 : :
16351 : :
16352 : 0 : default:
16353 : 0 : M2Error_InternalError ((const char *) "unexpected operator", 19);
16354 : 81904 : break;
16355 : : }
16356 : 81904 : return Op;
16357 : : /* static analysis guarentees a RETURN statement will be used before here. */
16358 : : __builtin_unreachable ();
16359 : : }
16360 : :
16361 : :
16362 : : /*
16363 : : IsReferenced - returns true if QuadNo is referenced by another quadruple.
16364 : : */
16365 : :
16366 : 257307909 : extern "C" bool M2Quads_IsReferenced (unsigned int QuadNo)
16367 : : {
16368 : 257307909 : M2Quads_QuadFrame f;
16369 : :
16370 : 257307909 : f = GetQF (QuadNo);
16371 : 257307909 : return ((f->Operator == M2Quads_ProcedureScopeOp) || (f->Operator == M2Quads_NewLocalVarOp)) || (f->NoOfTimesReferenced > 0);
16372 : : /* static analysis guarentees a RETURN statement will be used before here. */
16373 : : __builtin_unreachable ();
16374 : : }
16375 : :
16376 : :
16377 : : /*
16378 : : IsBackReference - returns TRUE if quadruple, q, is referenced from a quad further on.
16379 : : */
16380 : :
16381 : 96533 : extern "C" bool M2Quads_IsBackReference (unsigned int q)
16382 : : {
16383 : 96533 : unsigned int i;
16384 : 96533 : M2Quads_QuadOperator op;
16385 : 96533 : unsigned int op1;
16386 : 96533 : unsigned int op2;
16387 : 96533 : unsigned int op3;
16388 : :
16389 : 96533 : i = q;
16390 : 3792454 : while (i != 0)
16391 : : {
16392 : 3792454 : M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
16393 : 3792454 : switch (op)
16394 : : {
16395 : : case M2Quads_NewLocalVarOp:
16396 : : case M2Quads_KillLocalVarOp:
16397 : : case M2Quads_FinallyStartOp:
16398 : : case M2Quads_FinallyEndOp:
16399 : : case M2Quads_InitEndOp:
16400 : : case M2Quads_InitStartOp:
16401 : : case M2Quads_EndFileOp:
16402 : : case M2Quads_StartDefFileOp:
16403 : : case M2Quads_StartModFileOp:
16404 : : return false; /* run into end of procedure or module */
16405 : 167652 : break;
16406 : :
16407 : 167652 : case M2Quads_GotoOp:
16408 : 167652 : case M2Quads_IfEquOp:
16409 : 167652 : case M2Quads_IfLessEquOp:
16410 : 167652 : case M2Quads_IfGreEquOp:
16411 : 167652 : case M2Quads_IfGreOp:
16412 : 167652 : case M2Quads_IfLessOp:
16413 : 167652 : case M2Quads_IfNotEquOp:
16414 : 167652 : case M2Quads_IfInOp:
16415 : 167652 : case M2Quads_IfNotInOp:
16416 : 167652 : if (op3 == q) /* run into end of procedure or module */
16417 : : {
16418 : : return true;
16419 : : }
16420 : : break;
16421 : :
16422 : :
16423 : : default:
16424 : : break;
16425 : : }
16426 : 3695921 : i = M2Quads_GetNextQuad (i);
16427 : : }
16428 : 0 : M2Error_InternalError ((const char *) "fix this for the sake of efficiency..", 37);
16429 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
16430 : : __builtin_unreachable ();
16431 : : }
16432 : :
16433 : :
16434 : : /*
16435 : : IsUnConditional - returns true if QuadNo is an unconditional jump.
16436 : : */
16437 : :
16438 : 520528458 : extern "C" bool M2Quads_IsUnConditional (unsigned int QuadNo)
16439 : : {
16440 : 520528458 : M2Quads_QuadFrame f;
16441 : :
16442 : 520528458 : f = GetQF (QuadNo);
16443 : 520528458 : switch (f->Operator)
16444 : : {
16445 : : case M2Quads_ThrowOp:
16446 : : case M2Quads_RetryOp:
16447 : : case M2Quads_CallOp:
16448 : : case M2Quads_ReturnOp:
16449 : : case M2Quads_GotoOp:
16450 : : return true;
16451 : 500027474 : break;
16452 : :
16453 : :
16454 : 500027474 : default:
16455 : 500027474 : return false;
16456 : : break;
16457 : : }
16458 : : /* static analysis guarentees a RETURN statement will be used before here. */
16459 : : __builtin_unreachable ();
16460 : : }
16461 : :
16462 : :
16463 : : /*
16464 : : IsConditional - returns true if QuadNo is a conditional jump.
16465 : : */
16466 : :
16467 : 520635353 : extern "C" bool M2Quads_IsConditional (unsigned int QuadNo)
16468 : : {
16469 : 520635353 : M2Quads_QuadFrame f;
16470 : :
16471 : 520635353 : f = GetQF (QuadNo);
16472 : 520635353 : switch (f->Operator)
16473 : : {
16474 : : case M2Quads_IfInOp:
16475 : : case M2Quads_IfNotInOp:
16476 : : case M2Quads_IfEquOp:
16477 : : case M2Quads_IfNotEquOp:
16478 : : case M2Quads_IfLessOp:
16479 : : case M2Quads_IfLessEquOp:
16480 : : case M2Quads_IfGreOp:
16481 : : case M2Quads_IfGreEquOp:
16482 : : return true;
16483 : 516662370 : break;
16484 : :
16485 : :
16486 : 516662370 : default:
16487 : 516662370 : return false;
16488 : : break;
16489 : : }
16490 : : /* static analysis guarentees a RETURN statement will be used before here. */
16491 : : __builtin_unreachable ();
16492 : : }
16493 : :
16494 : :
16495 : : /*
16496 : : IsBackReferenceConditional - returns TRUE if quadruple, q, is referenced from
16497 : : a conditional quad further on.
16498 : : */
16499 : :
16500 : 0 : extern "C" bool M2Quads_IsBackReferenceConditional (unsigned int q)
16501 : : {
16502 : 0 : unsigned int i;
16503 : 0 : M2Quads_QuadOperator op;
16504 : 0 : unsigned int op1;
16505 : 0 : unsigned int op2;
16506 : 0 : unsigned int op3;
16507 : :
16508 : 0 : i = q;
16509 : 0 : while (i != 0)
16510 : : {
16511 : 0 : M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
16512 : 0 : switch (op)
16513 : : {
16514 : : case M2Quads_NewLocalVarOp:
16515 : : case M2Quads_KillLocalVarOp:
16516 : : case M2Quads_FinallyStartOp:
16517 : : case M2Quads_FinallyEndOp:
16518 : : case M2Quads_InitEndOp:
16519 : : case M2Quads_InitStartOp:
16520 : : case M2Quads_EndFileOp:
16521 : : case M2Quads_StartDefFileOp:
16522 : : case M2Quads_StartModFileOp:
16523 : : return false; /* run into end of procedure or module */
16524 : 0 : break;
16525 : :
16526 : 0 : case M2Quads_TryOp:
16527 : 0 : case M2Quads_RetryOp:
16528 : 0 : case M2Quads_GotoOp:
16529 : 0 : case M2Quads_IfEquOp:
16530 : 0 : case M2Quads_IfLessEquOp:
16531 : 0 : case M2Quads_IfGreEquOp:
16532 : 0 : case M2Quads_IfGreOp:
16533 : 0 : case M2Quads_IfLessOp:
16534 : 0 : case M2Quads_IfNotEquOp:
16535 : 0 : case M2Quads_IfInOp:
16536 : 0 : case M2Quads_IfNotInOp:
16537 : 0 : if ((op3 == q) && (M2Quads_IsConditional (q))) /* run into end of procedure or module */
16538 : : {
16539 : : return true;
16540 : : }
16541 : 0 : break;
16542 : :
16543 : :
16544 : : default:
16545 : : return false;
16546 : 0 : break;
16547 : : }
16548 : 0 : i = M2Quads_GetNextQuad (i);
16549 : : }
16550 : 0 : M2Error_InternalError ((const char *) "fix this for the sake of efficiency..", 37);
16551 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
16552 : : __builtin_unreachable ();
16553 : : }
16554 : :
16555 : :
16556 : : /*
16557 : : IsGoto - returns true if QuadNo is a goto operation.
16558 : : */
16559 : :
16560 : 96533 : extern "C" bool M2Quads_IsGoto (unsigned int QuadNo)
16561 : : {
16562 : 96533 : return IsQuadA (QuadNo, M2Quads_GotoOp);
16563 : : /* static analysis guarentees a RETURN statement will be used before here. */
16564 : : __builtin_unreachable ();
16565 : : }
16566 : :
16567 : :
16568 : : /*
16569 : : IsCall - returns true if QuadNo is a call operation.
16570 : : */
16571 : :
16572 : 520624991 : extern "C" bool M2Quads_IsCall (unsigned int QuadNo)
16573 : : {
16574 : 520624991 : return IsQuadA (QuadNo, M2Quads_CallOp);
16575 : : /* static analysis guarentees a RETURN statement will be used before here. */
16576 : : __builtin_unreachable ();
16577 : : }
16578 : :
16579 : :
16580 : : /*
16581 : : IsReturn - returns true if QuadNo is a return operation.
16582 : : */
16583 : :
16584 : 520786447 : extern "C" bool M2Quads_IsReturn (unsigned int QuadNo)
16585 : : {
16586 : 520786447 : return IsQuadA (QuadNo, M2Quads_ReturnOp);
16587 : : /* static analysis guarentees a RETURN statement will be used before here. */
16588 : : __builtin_unreachable ();
16589 : : }
16590 : :
16591 : :
16592 : : /*
16593 : : IsProcedureScope - returns true if QuadNo is a ProcedureScope operation.
16594 : : */
16595 : :
16596 : 0 : extern "C" bool M2Quads_IsProcedureScope (unsigned int QuadNo)
16597 : : {
16598 : 0 : return IsQuadA (QuadNo, M2Quads_ProcedureScopeOp);
16599 : : /* static analysis guarentees a RETURN statement will be used before here. */
16600 : : __builtin_unreachable ();
16601 : : }
16602 : :
16603 : :
16604 : : /*
16605 : : IsNewLocalVar - returns true if QuadNo is a NewLocalVar operation.
16606 : : */
16607 : :
16608 : 0 : extern "C" bool M2Quads_IsNewLocalVar (unsigned int QuadNo)
16609 : : {
16610 : 0 : return IsQuadA (QuadNo, M2Quads_NewLocalVarOp);
16611 : : /* static analysis guarentees a RETURN statement will be used before here. */
16612 : : __builtin_unreachable ();
16613 : : }
16614 : :
16615 : :
16616 : : /*
16617 : : IsKillLocalVar - returns true if QuadNo is a KillLocalVar operation.
16618 : : */
16619 : :
16620 : 253833 : extern "C" bool M2Quads_IsKillLocalVar (unsigned int QuadNo)
16621 : : {
16622 : 253833 : return IsQuadA (QuadNo, M2Quads_KillLocalVarOp);
16623 : : /* static analysis guarentees a RETURN statement will be used before here. */
16624 : : __builtin_unreachable ();
16625 : : }
16626 : :
16627 : :
16628 : : /*
16629 : : IsCatchBegin - returns true if QuadNo is a catch begin quad.
16630 : : */
16631 : :
16632 : 136536 : extern "C" bool M2Quads_IsCatchBegin (unsigned int QuadNo)
16633 : : {
16634 : 136536 : return IsQuadA (QuadNo, M2Quads_CatchBeginOp);
16635 : : /* static analysis guarentees a RETURN statement will be used before here. */
16636 : : __builtin_unreachable ();
16637 : : }
16638 : :
16639 : :
16640 : : /*
16641 : : IsCatchEnd - returns true if QuadNo is a catch end quad.
16642 : : */
16643 : :
16644 : 153144 : extern "C" bool M2Quads_IsCatchEnd (unsigned int QuadNo)
16645 : : {
16646 : 153144 : return IsQuadA (QuadNo, M2Quads_CatchEndOp);
16647 : : /* static analysis guarentees a RETURN statement will be used before here. */
16648 : : __builtin_unreachable ();
16649 : : }
16650 : :
16651 : :
16652 : : /*
16653 : : IsInitStart - returns true if QuadNo is a init start quad.
16654 : : */
16655 : :
16656 : 136536 : extern "C" bool M2Quads_IsInitStart (unsigned int QuadNo)
16657 : : {
16658 : 136536 : return IsQuadA (QuadNo, M2Quads_InitStartOp);
16659 : : /* static analysis guarentees a RETURN statement will be used before here. */
16660 : : __builtin_unreachable ();
16661 : : }
16662 : :
16663 : :
16664 : : /*
16665 : : IsInitEnd - returns true if QuadNo is a init end quad.
16666 : : */
16667 : :
16668 : 136536 : extern "C" bool M2Quads_IsInitEnd (unsigned int QuadNo)
16669 : : {
16670 : 136536 : return IsQuadA (QuadNo, M2Quads_InitEndOp);
16671 : : /* static analysis guarentees a RETURN statement will be used before here. */
16672 : : __builtin_unreachable ();
16673 : : }
16674 : :
16675 : :
16676 : : /*
16677 : : IsFinallyStart - returns true if QuadNo is a finally start quad.
16678 : : */
16679 : :
16680 : 131082 : extern "C" bool M2Quads_IsFinallyStart (unsigned int QuadNo)
16681 : : {
16682 : 131082 : return IsQuadA (QuadNo, M2Quads_FinallyStartOp);
16683 : : /* static analysis guarentees a RETURN statement will be used before here. */
16684 : : __builtin_unreachable ();
16685 : : }
16686 : :
16687 : :
16688 : : /*
16689 : : IsFinallyEnd - returns true if QuadNo is a finally end quad.
16690 : : */
16691 : :
16692 : 125628 : extern "C" bool M2Quads_IsFinallyEnd (unsigned int QuadNo)
16693 : : {
16694 : 125628 : return IsQuadA (QuadNo, M2Quads_FinallyEndOp);
16695 : : /* static analysis guarentees a RETURN statement will be used before here. */
16696 : : __builtin_unreachable ();
16697 : : }
16698 : :
16699 : :
16700 : : /*
16701 : : IsBecomes - return TRUE if QuadNo is a BecomesOp.
16702 : : */
16703 : :
16704 : 0 : extern "C" bool M2Quads_IsBecomes (unsigned int QuadNo)
16705 : : {
16706 : 0 : return IsQuadA (QuadNo, M2Quads_BecomesOp);
16707 : : /* static analysis guarentees a RETURN statement will be used before here. */
16708 : : __builtin_unreachable ();
16709 : : }
16710 : :
16711 : :
16712 : : /*
16713 : : IsDummy - return TRUE if QuadNo is a DummyOp.
16714 : : */
16715 : :
16716 : 0 : extern "C" bool M2Quads_IsDummy (unsigned int QuadNo)
16717 : : {
16718 : 0 : return IsQuadA (QuadNo, M2Quads_DummyOp);
16719 : : /* static analysis guarentees a RETURN statement will be used before here. */
16720 : : __builtin_unreachable ();
16721 : : }
16722 : :
16723 : :
16724 : : /*
16725 : : IsQuadConstExpr - returns TRUE if QuadNo is part of a constant expression.
16726 : : */
16727 : :
16728 : 0 : extern "C" bool M2Quads_IsQuadConstExpr (unsigned int QuadNo)
16729 : : {
16730 : 0 : M2Quads_QuadFrame f;
16731 : :
16732 : 0 : f = GetQF (QuadNo);
16733 : 0 : return f->ConstExpr;
16734 : : /* static analysis guarentees a RETURN statement will be used before here. */
16735 : : __builtin_unreachable ();
16736 : : }
16737 : :
16738 : :
16739 : : /*
16740 : : SetQuadConstExpr - sets the constexpr field to value.
16741 : : */
16742 : :
16743 : 0 : extern "C" void M2Quads_SetQuadConstExpr (unsigned int QuadNo, bool value)
16744 : : {
16745 : 0 : M2Quads_QuadFrame f;
16746 : :
16747 : 0 : f = GetQF (QuadNo);
16748 : 0 : f->ConstExpr = value;
16749 : 0 : }
16750 : :
16751 : :
16752 : : /*
16753 : : GetQuadDest - returns the jump destination associated with quad.
16754 : : */
16755 : :
16756 : 0 : extern "C" unsigned int M2Quads_GetQuadDest (unsigned int QuadNo)
16757 : : {
16758 : 0 : return M2Quads_GetQuadOp3 (QuadNo);
16759 : : /* static analysis guarentees a RETURN statement will be used before here. */
16760 : : __builtin_unreachable ();
16761 : : }
16762 : :
16763 : :
16764 : : /*
16765 : : GetQuadOp1 - returns the 1st operand associated with quad.
16766 : : */
16767 : :
16768 : 0 : extern "C" unsigned int M2Quads_GetQuadOp1 (unsigned int QuadNo)
16769 : : {
16770 : 0 : M2Quads_QuadFrame f;
16771 : :
16772 : 0 : f = GetQF (QuadNo);
16773 : 0 : return f->Operand1;
16774 : : /* static analysis guarentees a RETURN statement will be used before here. */
16775 : : __builtin_unreachable ();
16776 : : }
16777 : :
16778 : :
16779 : : /*
16780 : : GetQuadOp2 - returns the 2nd operand associated with quad.
16781 : : */
16782 : :
16783 : 0 : extern "C" unsigned int M2Quads_GetQuadOp2 (unsigned int QuadNo)
16784 : : {
16785 : 0 : M2Quads_QuadFrame f;
16786 : :
16787 : 0 : f = GetQF (QuadNo);
16788 : 0 : return f->Operand2;
16789 : : /* static analysis guarentees a RETURN statement will be used before here. */
16790 : : __builtin_unreachable ();
16791 : : }
16792 : :
16793 : :
16794 : : /*
16795 : : GetQuadOp3 - returns the 3rd operand associated with quad.
16796 : : */
16797 : :
16798 : 0 : extern "C" unsigned int M2Quads_GetQuadOp3 (unsigned int QuadNo)
16799 : : {
16800 : 0 : M2Quads_QuadFrame f;
16801 : :
16802 : 0 : f = GetQF (QuadNo);
16803 : 0 : return f->Operand3;
16804 : : /* static analysis guarentees a RETURN statement will be used before here. */
16805 : : __builtin_unreachable ();
16806 : : }
16807 : :
16808 : :
16809 : : /*
16810 : : IsInitialisingConst - returns TRUE if the quadruple is setting
16811 : : a const (op1) with a value.
16812 : : */
16813 : :
16814 : 0 : extern "C" bool M2Quads_IsInitialisingConst (unsigned int QuadNo)
16815 : : {
16816 : 0 : M2Quads_QuadOperator op;
16817 : 0 : unsigned int op1;
16818 : 0 : unsigned int op2;
16819 : 0 : unsigned int op3;
16820 : :
16821 : 0 : M2Quads_GetQuad (QuadNo, &op, &op1, &op2, &op3);
16822 : 0 : return (OpUsesOp1 (op)) && (SymbolTable_IsConst (op1));
16823 : : /* static analysis guarentees a RETURN statement will be used before here. */
16824 : : __builtin_unreachable ();
16825 : : }
16826 : :
16827 : :
16828 : : /*
16829 : : IsConstQuad - return TRUE if the quadruple is marked as a constexpr.
16830 : : */
16831 : :
16832 : 0 : extern "C" bool M2Quads_IsConstQuad (unsigned int quad)
16833 : : {
16834 : 0 : M2Quads_QuadFrame f;
16835 : :
16836 : 0 : f = GetQF (quad);
16837 : 0 : return f->ConstExpr;
16838 : : /* static analysis guarentees a RETURN statement will be used before here. */
16839 : : __builtin_unreachable ();
16840 : : }
16841 : :
16842 : :
16843 : : /*
16844 : : IsConditionalBooleanQuad - return TRUE if operand 1 is a boolean result.
16845 : : */
16846 : :
16847 : 419698 : extern "C" bool M2Quads_IsConditionalBooleanQuad (unsigned int quad)
16848 : : {
16849 : 419698 : M2Quads_QuadFrame f;
16850 : :
16851 : 419698 : f = GetQF (quad);
16852 : 419698 : return ((OpUsesOp1 (f->Operator)) && ((SymbolTable_IsVar (f->Operand1)) || (SymbolTable_IsConst (f->Operand1)))) && (SymbolTable_IsVarConditional (f->Operand1));
16853 : : /* static analysis guarentees a RETURN statement will be used before here. */
16854 : : __builtin_unreachable ();
16855 : : }
16856 : :
16857 : :
16858 : : /*
16859 : : IsOptimizeOn - returns true if the Optimize flag was true at QuadNo.
16860 : : */
16861 : :
16862 : 0 : extern "C" bool M2Quads_IsOptimizeOn (unsigned int QuadNo)
16863 : : {
16864 : 0 : M2Quads_QuadFrame f;
16865 : 0 : unsigned int n;
16866 : 0 : unsigned int q;
16867 : 0 : bool On;
16868 : :
16869 : 0 : On = M2Options_Optimizing;
16870 : 0 : q = Head;
16871 : 0 : while ((q != 0) && (q != QuadNo))
16872 : : {
16873 : 0 : f = GetQF (q);
16874 : 0 : if (f->Operator == M2Quads_OptimizeOnOp)
16875 : : {
16876 : : On = true;
16877 : : }
16878 : 0 : else if (f->Operator == M2Quads_OptimizeOffOp)
16879 : : {
16880 : : /* avoid dangling else. */
16881 : 0 : On = false;
16882 : : }
16883 : 0 : n = f->Next;
16884 : 0 : q = n;
16885 : : }
16886 : 0 : return On;
16887 : : /* static analysis guarentees a RETURN statement will be used before here. */
16888 : : __builtin_unreachable ();
16889 : : }
16890 : :
16891 : :
16892 : : /*
16893 : : IsProfileOn - returns true if the Profile flag was true at QuadNo.
16894 : : */
16895 : :
16896 : 0 : extern "C" bool M2Quads_IsProfileOn (unsigned int QuadNo)
16897 : : {
16898 : 0 : M2Quads_QuadFrame f;
16899 : 0 : unsigned int n;
16900 : 0 : unsigned int q;
16901 : 0 : bool On;
16902 : :
16903 : 0 : On = M2Options_Profiling;
16904 : 0 : q = Head;
16905 : 0 : while ((q != 0) && (q != QuadNo))
16906 : : {
16907 : 0 : f = GetQF (q);
16908 : 0 : if (f->Operator == M2Quads_ProfileOnOp)
16909 : : {
16910 : : On = true;
16911 : : }
16912 : 0 : else if (f->Operator == M2Quads_ProfileOffOp)
16913 : : {
16914 : : /* avoid dangling else. */
16915 : 0 : On = false;
16916 : : }
16917 : 0 : n = f->Next;
16918 : 0 : q = n;
16919 : : }
16920 : 0 : return On;
16921 : : /* static analysis guarentees a RETURN statement will be used before here. */
16922 : : __builtin_unreachable ();
16923 : : }
16924 : :
16925 : :
16926 : : /*
16927 : : IsCodeOn - returns true if the Code flag was true at QuadNo.
16928 : : */
16929 : :
16930 : 0 : extern "C" bool M2Quads_IsCodeOn (unsigned int QuadNo)
16931 : : {
16932 : 0 : M2Quads_QuadFrame f;
16933 : 0 : unsigned int n;
16934 : 0 : unsigned int q;
16935 : 0 : bool On;
16936 : :
16937 : 0 : On = M2Options_Coding;
16938 : 0 : q = Head;
16939 : 0 : while ((q != 0) && (q != QuadNo))
16940 : : {
16941 : 0 : f = GetQF (q);
16942 : 0 : if (f->Operator == M2Quads_CodeOnOp)
16943 : : {
16944 : : On = true;
16945 : : }
16946 : 0 : else if (f->Operator == M2Quads_CodeOffOp)
16947 : : {
16948 : : /* avoid dangling else. */
16949 : 0 : On = false;
16950 : : }
16951 : 0 : n = f->Next;
16952 : 0 : q = n;
16953 : : }
16954 : 0 : return On;
16955 : : /* static analysis guarentees a RETURN statement will be used before here. */
16956 : : __builtin_unreachable ();
16957 : : }
16958 : :
16959 : :
16960 : : /*
16961 : : IsPseudoQuad - returns true if QuadNo is a compiler directive.
16962 : : ie code, profile and optimize.
16963 : : StartFile, EndFile,
16964 : : */
16965 : :
16966 : 23264095 : extern "C" bool M2Quads_IsPseudoQuad (unsigned int QuadNo)
16967 : : {
16968 : 23264095 : M2Quads_QuadFrame f;
16969 : :
16970 : 23264095 : f = GetQF (QuadNo);
16971 : 23264095 : 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);
16972 : : /* static analysis guarentees a RETURN statement will be used before here. */
16973 : : __builtin_unreachable ();
16974 : : }
16975 : :
16976 : :
16977 : : /*
16978 : : IsDefOrModFile - returns TRUE if QuadNo is a start of Module or Def file
16979 : : directive.
16980 : : */
16981 : :
16982 : 520528458 : extern "C" bool M2Quads_IsDefOrModFile (unsigned int QuadNo)
16983 : : {
16984 : 520528458 : M2Quads_QuadFrame f;
16985 : :
16986 : 520528458 : f = GetQF (QuadNo);
16987 : 520528458 : return (f->Operator == M2Quads_StartDefFileOp) || (f->Operator == M2Quads_StartModFileOp);
16988 : : /* static analysis guarentees a RETURN statement will be used before here. */
16989 : : __builtin_unreachable ();
16990 : : }
16991 : :
16992 : :
16993 : : /*
16994 : : DumpQuadruples - dump all quadruples providing the -fq, -fdump-lang-quad,
16995 : : -fdump-lang-quad= or -fdump-lang-all were issued to the
16996 : : command line.
16997 : : */
16998 : :
16999 : 72287 : extern "C" void M2Quads_DumpQuadruples (const char *title_, unsigned int _title_high)
17000 : : {
17001 : 72287 : char title[_title_high+1];
17002 : :
17003 : : /* make a local copy of each unbounded array. */
17004 : 72287 : memcpy (title, title_, _title_high+1);
17005 : :
17006 : 72287 : if (M2Options_GetDumpQuad ())
17007 : : {
17008 : 0 : M2LangDump_CreateDumpQuad ((const char *) title, _title_high);
17009 : 0 : if ((M2Options_GetM2DumpFilter ()) == NULL)
17010 : : {
17011 : 0 : DumpQuadrupleAll ();
17012 : : }
17013 : : else
17014 : : {
17015 : 0 : DumpQuadrupleFilter ();
17016 : : }
17017 : 0 : M2LangDump_CloseDumpQuad ();
17018 : : }
17019 : 72287 : }
17020 : :
17021 : :
17022 : : /*
17023 : : DisplayQuadRange - displays all quads in list range, start..end.
17024 : : */
17025 : :
17026 : 0 : extern "C" void M2Quads_DisplayQuadRange (unsigned int scope, unsigned int start, unsigned int end)
17027 : : {
17028 : 0 : M2Quads_QuadFrame f;
17029 : :
17030 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "Quadruples for scope: %d\\n", 26, (const unsigned char *) &scope, (sizeof (scope)-1));
17031 : 0 : while ((start <= end) && (start != 0))
17032 : : {
17033 : 0 : M2Quads_DisplayQuad (start);
17034 : 0 : f = GetQF (start);
17035 : 0 : start = f->Next;
17036 : : }
17037 : 0 : }
17038 : :
17039 : :
17040 : : /*
17041 : : DisplayQuad - displays a quadruple, QuadNo.
17042 : : */
17043 : :
17044 : 0 : extern "C" void M2Quads_DisplayQuad (unsigned int QuadNo)
17045 : : {
17046 : 0 : if (QuadNo != 0)
17047 : : {
17048 : 0 : DSdbEnter ();
17049 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d ", 5, (const unsigned char *) &QuadNo, (sizeof (QuadNo)-1));
17050 : 0 : WriteQuad (QuadNo);
17051 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "\\n", 2);
17052 : 0 : DSdbExit ();
17053 : : }
17054 : 0 : }
17055 : :
17056 : :
17057 : : /*
17058 : : GetLastFileQuad - returns the Quadruple number of the last StartDefFile or
17059 : : StartModFile quadruple.
17060 : : */
17061 : :
17062 : 0 : extern "C" unsigned int M2Quads_GetLastFileQuad (unsigned int QuadNo)
17063 : : {
17064 : 0 : M2Quads_QuadFrame f;
17065 : 0 : unsigned int q;
17066 : 0 : unsigned int i;
17067 : 0 : unsigned int FileQuad;
17068 : :
17069 : 0 : q = Head;
17070 : 0 : FileQuad = 0;
17071 : 0 : do {
17072 : 0 : f = GetQF (q);
17073 : 0 : if ((f->Operator == M2Quads_StartModFileOp) || (f->Operator == M2Quads_StartDefFileOp))
17074 : : {
17075 : 0 : FileQuad = q;
17076 : : }
17077 : 0 : i = f->Next;
17078 : 0 : q = i;
17079 : 0 : } while (! ((i == QuadNo) || (i == 0)));
17080 : 0 : M2Debug_Assert (i != 0);
17081 : 0 : M2Debug_Assert (FileQuad != 0);
17082 : 0 : return FileQuad;
17083 : : /* static analysis guarentees a RETURN statement will be used before here. */
17084 : : __builtin_unreachable ();
17085 : : }
17086 : :
17087 : :
17088 : : /*
17089 : : GetLastQuadNo - returns the last quadruple number referenced
17090 : : by a GetQuad.
17091 : : */
17092 : :
17093 : 0 : extern "C" unsigned int M2Quads_GetLastQuadNo (void)
17094 : : {
17095 : 0 : return LastQuadNo;
17096 : : /* static analysis guarentees a RETURN statement will be used before here. */
17097 : : __builtin_unreachable ();
17098 : : }
17099 : :
17100 : :
17101 : : /*
17102 : : QuadToTokenNo - Converts a QuadNo into the approprate token number of the
17103 : : source file, the line number is returned.
17104 : :
17105 : : This may be used to yield an idea where abouts in the
17106 : : source file the code generetion is
17107 : : processing.
17108 : : */
17109 : :
17110 : 7410641 : extern "C" unsigned int M2Quads_QuadToTokenNo (unsigned int QuadNo)
17111 : : {
17112 : 7410641 : M2Quads_QuadFrame f;
17113 : :
17114 : 7410641 : if ((((LastQuadNo == 0) && (! (M2Pass_IsNoPass ()))) && (! (M2Pass_IsPassCodeGeneration ()))) || (! (Indexing_InBounds (QuadArray, QuadNo))))
17115 : : {
17116 : 0 : return 0;
17117 : : }
17118 : : else
17119 : : {
17120 : 7410641 : f = GetQF (QuadNo);
17121 : 7410641 : return f->TokenNo;
17122 : : }
17123 : : /* static analysis guarentees a RETURN statement will be used before here. */
17124 : : __builtin_unreachable ();
17125 : : }
17126 : :
17127 : :
17128 : : /*
17129 : : QuadToLineNo - Converts a QuadNo into the approprate line number of the
17130 : : source file, the line number is returned.
17131 : :
17132 : : This may be used to yield an idea where abouts in the
17133 : : source file the code generetion is
17134 : : processing.
17135 : : */
17136 : :
17137 : 0 : extern "C" unsigned int M2Quads_QuadToLineNo (unsigned int QuadNo)
17138 : : {
17139 : 0 : M2Quads_QuadFrame f;
17140 : :
17141 : 0 : if ((((LastQuadNo == 0) && (! (M2Pass_IsNoPass ()))) && (! (M2Pass_IsPassCodeGeneration ()))) || (! (Indexing_InBounds (QuadArray, QuadNo))))
17142 : : {
17143 : 0 : return 0;
17144 : : }
17145 : : else
17146 : : {
17147 : 0 : f = GetQF (QuadNo);
17148 : 0 : return f->LineNo;
17149 : : }
17150 : : /* static analysis guarentees a RETURN statement will be used before here. */
17151 : : __builtin_unreachable ();
17152 : : }
17153 : :
17154 : :
17155 : : /*
17156 : : GetQuad - returns the Quadruple QuadNo.
17157 : : */
17158 : :
17159 : 2673626884 : extern "C" void M2Quads_GetQuad (unsigned int QuadNo, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3)
17160 : : {
17161 : 2673626884 : M2Quads_QuadFrame f;
17162 : :
17163 : 2673626884 : f = GetQF (QuadNo);
17164 : 2673626884 : LastQuadNo = QuadNo;
17165 : 2673626884 : (*Op) = f->Operator;
17166 : 2673626884 : (*Oper1) = f->Operand1;
17167 : 2673626884 : (*Oper2) = f->Operand2;
17168 : 2673626884 : (*Oper3) = f->Operand3;
17169 : 2673626884 : }
17170 : :
17171 : :
17172 : : /*
17173 : : GetQuadOp - returns the operator for quad.
17174 : : */
17175 : :
17176 : 24 : extern "C" M2Quads_QuadOperator M2Quads_GetQuadOp (unsigned int quad)
17177 : : {
17178 : 24 : M2Quads_QuadFrame f;
17179 : :
17180 : 24 : f = GetQF (quad);
17181 : 24 : return f->Operator;
17182 : : /* static analysis guarentees a RETURN statement will be used before here. */
17183 : : __builtin_unreachable ();
17184 : : }
17185 : :
17186 : :
17187 : : /*
17188 : : GetM2OperatorDesc - returns the Modula-2 string associated with the quad operator
17189 : : (if possible). It returns NIL if no there is not an obvious match
17190 : : in Modula-2. It is assummed that the string will be used during
17191 : : construction of error messages and therefore keywords are
17192 : : wrapped with a format specifier.
17193 : : */
17194 : :
17195 : 31 : extern "C" DynamicStrings_String M2Quads_GetM2OperatorDesc (M2Quads_QuadOperator op)
17196 : : {
17197 : 31 : switch (op)
17198 : : {
17199 : 6 : case M2Quads_NegateOp:
17200 : 6 : return DynamicStrings_InitString ((const char *) "-", 1);
17201 : 18 : break;
17202 : :
17203 : 18 : case M2Quads_AddOp:
17204 : 18 : return DynamicStrings_InitString ((const char *) "+", 1);
17205 : 0 : break;
17206 : :
17207 : 0 : case M2Quads_SubOp:
17208 : 0 : return DynamicStrings_InitString ((const char *) "-", 1);
17209 : 0 : break;
17210 : :
17211 : 0 : case M2Quads_MultOp:
17212 : 0 : return DynamicStrings_InitString ((const char *) "*", 1);
17213 : 0 : break;
17214 : :
17215 : 0 : case M2Quads_DivM2Op:
17216 : 0 : case M2Quads_DivCeilOp:
17217 : 0 : case M2Quads_DivFloorOp:
17218 : 0 : case M2Quads_DivTruncOp:
17219 : 0 : return DynamicStrings_InitString ((const char *) "{%kDIV}", 7);
17220 : 0 : break;
17221 : :
17222 : 0 : case M2Quads_ModM2Op:
17223 : 0 : case M2Quads_ModCeilOp:
17224 : 0 : case M2Quads_ModFloorOp:
17225 : 0 : return DynamicStrings_InitString ((const char *) "{%kMOD}", 7);
17226 : 0 : break;
17227 : :
17228 : 0 : case M2Quads_ModTruncOp:
17229 : 0 : return DynamicStrings_InitString ((const char *) "{%kREM}", 7);
17230 : 0 : break;
17231 : :
17232 : 0 : case M2Quads_LogicalOrOp:
17233 : 0 : return DynamicStrings_InitString ((const char *) "{%kOR}", 6);
17234 : 0 : break;
17235 : :
17236 : 0 : case M2Quads_LogicalAndOp:
17237 : 0 : return DynamicStrings_InitString ((const char *) "{%kAND}", 7);
17238 : 0 : break;
17239 : :
17240 : 0 : case M2Quads_InclOp:
17241 : 0 : return DynamicStrings_InitString ((const char *) "{%kINCL}", 8);
17242 : 0 : break;
17243 : :
17244 : 0 : case M2Quads_ExclOp:
17245 : 0 : return DynamicStrings_InitString ((const char *) "{%kEXCL}", 8);
17246 : 7 : break;
17247 : :
17248 : 7 : case M2Quads_IfEquOp:
17249 : 7 : return DynamicStrings_InitString ((const char *) "=", 1);
17250 : 0 : break;
17251 : :
17252 : 0 : case M2Quads_IfLessEquOp:
17253 : 0 : return DynamicStrings_InitString ((const char *) "<=", 2);
17254 : 0 : break;
17255 : :
17256 : 0 : case M2Quads_IfGreEquOp:
17257 : 0 : return DynamicStrings_InitString ((const char *) ">=", 2);
17258 : 0 : break;
17259 : :
17260 : 0 : case M2Quads_IfGreOp:
17261 : 0 : return DynamicStrings_InitString ((const char *) ">", 1);
17262 : 0 : break;
17263 : :
17264 : 0 : case M2Quads_IfLessOp:
17265 : 0 : return DynamicStrings_InitString ((const char *) "<", 1);
17266 : 0 : break;
17267 : :
17268 : 0 : case M2Quads_IfNotEquOp:
17269 : 0 : return DynamicStrings_InitString ((const char *) "#", 1);
17270 : 0 : break;
17271 : :
17272 : 0 : case M2Quads_IfInOp:
17273 : 0 : return DynamicStrings_InitString ((const char *) "IN", 2);
17274 : 0 : break;
17275 : :
17276 : 0 : case M2Quads_IfNotInOp:
17277 : 0 : return DynamicStrings_InitString ((const char *) "NOT IN", 6);
17278 : : break;
17279 : :
17280 : :
17281 : : default:
17282 : : return static_cast<DynamicStrings_String> (NULL);
17283 : : break;
17284 : : }
17285 : : /* static analysis guarentees a RETURN statement will be used before here. */
17286 : : __builtin_unreachable ();
17287 : : }
17288 : :
17289 : :
17290 : : /*
17291 : : GetQuadtok - returns the Quadruple QuadNo.
17292 : : */
17293 : :
17294 : 170793414 : 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)
17295 : : {
17296 : 170793414 : M2Quads_QuadFrame f;
17297 : :
17298 : 170793414 : f = GetQF (QuadNo);
17299 : 170793414 : LastQuadNo = QuadNo;
17300 : 170793414 : (*Op) = f->Operator;
17301 : 170793414 : (*Oper1) = f->Operand1;
17302 : 170793414 : (*Oper2) = f->Operand2;
17303 : 170793414 : (*Oper3) = f->Operand3;
17304 : 170793414 : (*Op1Pos) = f->op1pos;
17305 : 170793414 : (*Op2Pos) = f->op2pos;
17306 : 170793414 : (*Op3Pos) = f->op3pos;
17307 : 170793414 : }
17308 : :
17309 : :
17310 : : /*
17311 : : GetQuadOtok - returns the Quadruple QuadNo.
17312 : : */
17313 : :
17314 : 6946071 : 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)
17315 : : {
17316 : 6946071 : M2Quads_QuadFrame f;
17317 : :
17318 : 6946071 : f = GetQF (QuadNo);
17319 : 6946071 : LastQuadNo = QuadNo;
17320 : 6946071 : (*Op) = f->Operator;
17321 : 6946071 : (*Oper1) = f->Operand1;
17322 : 6946071 : (*Oper2) = f->Operand2;
17323 : 6946071 : (*Oper3) = f->Operand3;
17324 : 6946071 : (*Op1Pos) = f->op1pos;
17325 : 6946071 : (*Op2Pos) = f->op2pos;
17326 : 6946071 : (*Op3Pos) = f->op3pos;
17327 : 6946071 : (*tok) = f->TokenNo;
17328 : 6946071 : (*overflowChecking) = f->CheckOverflow;
17329 : 6946071 : (*constExpr) = f->ConstExpr;
17330 : 6946071 : }
17331 : :
17332 : :
17333 : : /*
17334 : : GetQuadOTypetok - returns the fields associated with quadruple QuadNo.
17335 : : */
17336 : :
17337 : 6668 : extern "C" void M2Quads_GetQuadOTypetok (unsigned int QuadNo, unsigned int *tok, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3, bool *overflowChecking, bool *typeChecking, bool *constExpr, unsigned int *Op1Pos, unsigned int *Op2Pos, unsigned int *Op3Pos)
17338 : : {
17339 : 6668 : M2Quads_QuadFrame f;
17340 : :
17341 : 6668 : f = GetQF (QuadNo);
17342 : 6668 : LastQuadNo = QuadNo;
17343 : 6668 : (*Op) = f->Operator;
17344 : 6668 : (*Oper1) = f->Operand1;
17345 : 6668 : (*Oper2) = f->Operand2;
17346 : 6668 : (*Oper3) = f->Operand3;
17347 : 6668 : (*Op1Pos) = f->op1pos;
17348 : 6668 : (*Op2Pos) = f->op2pos;
17349 : 6668 : (*Op3Pos) = f->op3pos;
17350 : 6668 : (*tok) = f->TokenNo;
17351 : 6668 : (*overflowChecking) = f->CheckOverflow;
17352 : 6668 : (*typeChecking) = f->CheckType;
17353 : 6668 : (*constExpr) = f->ConstExpr;
17354 : 6668 : }
17355 : :
17356 : :
17357 : : /*
17358 : : PutQuadOtok - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
17359 : : sets a boolean to determinine whether overflow should be checked.
17360 : : */
17361 : :
17362 : 81897 : 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)
17363 : : {
17364 : 81897 : M2Quads_QuadFrame f;
17365 : :
17366 : 81897 : if (QuadrupleGeneration)
17367 : : {
17368 : 81897 : M2Quads_EraseQuad (QuadNo);
17369 : 81897 : AddQuadInformation (QuadNo, Op, Oper1, Oper2, Oper3);
17370 : 81897 : f = GetQF (QuadNo);
17371 : 81897 : f->Operator = Op;
17372 : 81897 : f->Operand1 = Oper1;
17373 : 81897 : f->Operand2 = Oper2;
17374 : 81897 : f->Operand3 = Oper3;
17375 : 81897 : f->CheckOverflow = overflowChecking;
17376 : 81897 : f->op1pos = Op1Pos;
17377 : 81897 : f->op2pos = Op2Pos;
17378 : 81897 : f->op3pos = Op3Pos;
17379 : 81897 : f->TokenNo = tok;
17380 : 81897 : f->ConstExpr = constExpr;
17381 : : }
17382 : 81897 : }
17383 : :
17384 : :
17385 : : /*
17386 : : PutQuad - overwrites a quadruple QuadNo with Op, Oper1, Oper2, Oper3
17387 : : */
17388 : :
17389 : 14709 : extern "C" void M2Quads_PutQuad (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
17390 : : {
17391 : 14709 : PutQuadO (QuadNo, Op, Oper1, Oper2, Oper3, true);
17392 : 14709 : }
17393 : :
17394 : :
17395 : : /*
17396 : : GetFirstQuad - returns the first quadruple.
17397 : : */
17398 : :
17399 : 788583 : extern "C" unsigned int M2Quads_GetFirstQuad (void)
17400 : : {
17401 : 788583 : return Head;
17402 : : /* static analysis guarentees a RETURN statement will be used before here. */
17403 : : __builtin_unreachable ();
17404 : : }
17405 : :
17406 : :
17407 : : /*
17408 : : GetNextQuad - returns the Quadruple number following QuadNo.
17409 : : */
17410 : :
17411 : 3365483363 : extern "C" unsigned int M2Quads_GetNextQuad (unsigned int QuadNo)
17412 : : {
17413 : 3365483363 : M2Quads_QuadFrame f;
17414 : :
17415 : 3365483363 : f = GetQF (QuadNo);
17416 : 3365483363 : return f->Next;
17417 : : /* static analysis guarentees a RETURN statement will be used before here. */
17418 : : __builtin_unreachable ();
17419 : : }
17420 : :
17421 : :
17422 : : /*
17423 : : GetRealQuad - returns the Quadruple number of the real quadruple
17424 : : at QuadNo or beyond.
17425 : : */
17426 : :
17427 : 15239860 : extern "C" unsigned int M2Quads_GetRealQuad (unsigned int QuadNo)
17428 : : {
17429 : 15239860 : M2Quads_QuadFrame f;
17430 : :
17431 : 23180908 : while (QuadNo != 0)
17432 : : {
17433 : 23180908 : if (Indexing_InBounds (QuadArray, QuadNo))
17434 : : {
17435 : 23097185 : f = GetQF (QuadNo);
17436 : 23097185 : if ((((! (M2Quads_IsPseudoQuad (QuadNo))) && (f->Operator != M2Quads_DummyOp)) && (f->Operator != M2Quads_LineNumberOp)) && (f->Operator != M2Quads_StatementNoteOp))
17437 : : {
17438 : : return QuadNo;
17439 : : }
17440 : 7941048 : QuadNo += 1;
17441 : : }
17442 : : else
17443 : : {
17444 : : return 0;
17445 : : }
17446 : : }
17447 : : return 0;
17448 : : /* static analysis guarentees a RETURN statement will be used before here. */
17449 : : __builtin_unreachable ();
17450 : : }
17451 : :
17452 : :
17453 : : /*
17454 : : SubQuad - subtracts a quadruple QuadNo from a list Head.
17455 : : */
17456 : :
17457 : 1904194 : extern "C" void M2Quads_SubQuad (unsigned int QuadNo)
17458 : : {
17459 : 1904194 : unsigned int i;
17460 : 1904194 : M2Quads_QuadFrame f;
17461 : 1904194 : M2Quads_QuadFrame g;
17462 : :
17463 : 1904194 : CheckBreak (QuadNo);
17464 : 1904194 : f = GetQF (QuadNo);
17465 : 1904194 : AlterReference (Head, QuadNo, f->Next);
17466 : 1904194 : UndoReadWriteInfo (QuadNo, f->Operator, f->Operand1, f->Operand2, f->Operand3);
17467 : 1904194 : if (Head == QuadNo)
17468 : : {
17469 : 0 : Head = f->Next;
17470 : : }
17471 : : else
17472 : : {
17473 : 1904194 : i = Head;
17474 : 1904194 : g = GetQF (i);
17475 : 5018010305 : while (g->Next != QuadNo)
17476 : : {
17477 : 5014201917 : i = g->Next;
17478 : 5014201917 : g = GetQF (i);
17479 : : }
17480 : 1904194 : g->Next = f->Next;
17481 : : }
17482 : 1904194 : f->Operator = M2Quads_DummyOp;
17483 : 1904194 : NoOfQuads -= 1;
17484 : 1904194 : }
17485 : :
17486 : :
17487 : : /*
17488 : : EraseQuad - erases a quadruple QuadNo, the quadruple is still in the list
17489 : : but wiped clean.
17490 : : */
17491 : :
17492 : 6349408 : extern "C" void M2Quads_EraseQuad (unsigned int QuadNo)
17493 : : {
17494 : 6349408 : M2Quads_QuadFrame f;
17495 : :
17496 : 6349408 : CheckBreak (QuadNo);
17497 : 6349408 : f = GetQF (QuadNo);
17498 : 6349408 : UndoReadWriteInfo (QuadNo, f->Operator, f->Operand1, f->Operand2, f->Operand3);
17499 : 6349408 : f->Operator = M2Quads_DummyOp; /* finally blank it out */
17500 : 6349408 : f->Operand1 = 0; /* finally blank it out */
17501 : 6349408 : f->Operand2 = 0;
17502 : 6349408 : f->Operand3 = 0;
17503 : 6349408 : f->Trash = 0;
17504 : 6349408 : f->op1pos = M2LexBuf_UnknownTokenNo;
17505 : 6349408 : f->op2pos = M2LexBuf_UnknownTokenNo;
17506 : 6349408 : f->op3pos = M2LexBuf_UnknownTokenNo;
17507 : 6349408 : f->ConstExpr = false;
17508 : 6349408 : }
17509 : :
17510 : :
17511 : : /*
17512 : : CountQuads - returns the number of quadruples.
17513 : : */
17514 : :
17515 : 9089501 : extern "C" unsigned int M2Quads_CountQuads (void)
17516 : : {
17517 : 9089501 : return NoOfQuads;
17518 : : /* static analysis guarentees a RETURN statement will be used before here. */
17519 : : __builtin_unreachable ();
17520 : : }
17521 : :
17522 : :
17523 : : /*
17524 : : BuildScaffold - generate the main, init, finish functions if
17525 : : no -c and this is the application module.
17526 : : */
17527 : :
17528 : 15663 : extern "C" void M2Quads_BuildScaffold (unsigned int tok, unsigned int moduleSym)
17529 : : {
17530 : 15663 : if ((SymbolTable_GetMainModule ()) == moduleSym)
17531 : : {
17532 : 15135 : M2Scaffold_DeclareScaffold (tok);
17533 : 15135 : if (M2Options_ScaffoldMain || ! M2Options_cflag)
17534 : : {
17535 : : /* There are module init/fini functions and
17536 : : application init/fini functions.
17537 : : Here we create the application pair. */
17538 : 2706 : BuildM2LinkFunction (tok);
17539 : 2706 : BuildM2MainFunction (tok);
17540 : 2706 : BuildM2InitFunction (tok, moduleSym); /* Application init. */
17541 : 2706 : BuildM2FiniFunction (tok, moduleSym); /* Application fini. */
17542 : : }
17543 : : /* Application fini. */
17544 : 15135 : BuildM2DepFunction (tok, moduleSym); /* Per module dependency. */
17545 : : /* Each module needs a ctor to register the module
17546 : : init/finish/dep with M2RTS. */
17547 : 15135 : BuildM2CtorFunction (tok, moduleSym);
17548 : : }
17549 : 528 : else if (M2Options_WholeProgram)
17550 : : {
17551 : : /* avoid dangling else. */
17552 : 528 : M2Scaffold_DeclareScaffold (tok);
17553 : 528 : BuildM2DepFunction (tok, moduleSym); /* Per module dependency. */
17554 : : /* Each module needs a ctor to register the module
17555 : : init/finish/dep with M2RTS. */
17556 : 528 : BuildM2CtorFunction (tok, moduleSym);
17557 : : }
17558 : 15663 : }
17559 : :
17560 : :
17561 : : /*
17562 : : StartBuildDefFile - generates a StartFileDefOp quadruple indicating the file
17563 : : that has produced the subsequent quadruples.
17564 : : The code generator uses the StartDefFileOp quadruples
17565 : : to relate any error to the appropriate file.
17566 : :
17567 : :
17568 : : Entry Exit
17569 : : ===== ====
17570 : :
17571 : :
17572 : : Ptr -> <- Ptr
17573 : : +------------+ +------------+
17574 : : | ModuleName | | ModuleName |
17575 : : |------------| |------------|
17576 : :
17577 : :
17578 : : Quadruples Produced
17579 : :
17580 : : q StartDefFileOp _ _ ModuleSym
17581 : : */
17582 : :
17583 : 163205 : extern "C" void M2Quads_StartBuildDefFile (unsigned int tok)
17584 : : {
17585 : 163205 : NameKey_Name ModuleName;
17586 : :
17587 : 163205 : M2Quads_PopT (&ModuleName);
17588 : 163205 : M2Quads_PushT (ModuleName);
17589 : 163205 : GenQuadO (tok, M2Quads_StartDefFileOp, tok, SymbolTable_NulSym, SymbolTable_GetModule (ModuleName), false);
17590 : 163205 : }
17591 : :
17592 : :
17593 : : /*
17594 : : StartBuildModFile - generates a StartModFileOp quadruple indicating the file
17595 : : that has produced the subsequent quadruples.
17596 : : The code generator uses the StartModFileOp quadruples
17597 : : to relate any error to the appropriate file.
17598 : :
17599 : :
17600 : : Entry Exit
17601 : : ===== ====
17602 : :
17603 : :
17604 : : Ptr -> <- Ptr
17605 : : +------------+ +------------+
17606 : : | ModuleName | | ModuleName |
17607 : : |------------| |------------|
17608 : :
17609 : :
17610 : : Quadruples Produced
17611 : :
17612 : : q StartModFileOp lineno filename ModuleSym
17613 : : */
17614 : :
17615 : 82737 : extern "C" void M2Quads_StartBuildModFile (unsigned int tok)
17616 : : {
17617 : 82737 : GenQuadO (tok, M2Quads_StartModFileOp, tok, (unsigned int ) (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()))), SymbolTable_GetFileModule (), false);
17618 : 82737 : }
17619 : :
17620 : :
17621 : : /*
17622 : : EndBuildFile - generates an EndFileOp quadruple indicating the file
17623 : : that has produced the previous quadruples has ended.
17624 : :
17625 : : Entry Exit
17626 : : ===== ====
17627 : :
17628 : :
17629 : : Ptr -> <- Ptr
17630 : : +------------+ +------------+
17631 : : | ModuleName | | ModuleName |
17632 : : |------------| |------------|
17633 : :
17634 : :
17635 : : Quadruples Produced
17636 : :
17637 : : q EndFileOp _ _ ModuleSym
17638 : : */
17639 : :
17640 : 245731 : extern "C" void M2Quads_EndBuildFile (unsigned int tok)
17641 : : {
17642 : 245731 : NameKey_Name ModuleName;
17643 : :
17644 : 245731 : ModuleName = static_cast<NameKey_Name> (M2Quads_OperandT (1));
17645 : 245731 : GenQuadO (tok, M2Quads_EndFileOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_GetModule (ModuleName), false);
17646 : 245731 : }
17647 : :
17648 : :
17649 : : /*
17650 : : StartBuildInit - Sets the start of initialization code of the
17651 : : current module to the next quadruple.
17652 : : */
17653 : :
17654 : 83103 : extern "C" void M2Quads_StartBuildInit (unsigned int tok)
17655 : : {
17656 : 83103 : NameKey_Name name;
17657 : 83103 : unsigned int ModuleSym;
17658 : :
17659 : 83103 : M2Quads_PopT (&name);
17660 : 83103 : ModuleSym = SymbolTable_GetCurrentModule ();
17661 : 166206 : M2Debug_Assert ((SymbolTable_IsModule (ModuleSym)) || (SymbolTable_IsDefImp (ModuleSym)));
17662 : 83103 : M2Debug_Assert ((SymbolTable_GetSymName (ModuleSym)) == name);
17663 : 83097 : SymbolTable_PutModuleStartQuad (ModuleSym, NextQuad);
17664 : 83097 : GenQuad (M2Quads_InitStartOp, tok, SymbolTable_GetFileModule (), ModuleSym);
17665 : 83097 : M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
17666 : 83097 : M2Quads_PushT (name);
17667 : 83097 : CheckVariablesAt (ModuleSym);
17668 : 83097 : CheckNeedPriorityBegin (tok, ModuleSym, ModuleSym);
17669 : 83097 : M2StackWord_PushWord (TryStack, NextQuad);
17670 : 83097 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
17671 : 83097 : if (SymbolTable_HasExceptionBlock (ModuleSym))
17672 : : {
17673 : 54 : GenQuad (M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
17674 : : }
17675 : 83097 : }
17676 : :
17677 : :
17678 : : /*
17679 : : EndBuildInit - Sets the end initialization code of a module.
17680 : : */
17681 : :
17682 : 82952 : extern "C" void M2Quads_EndBuildInit (unsigned int tok)
17683 : : {
17684 : 82952 : if (SymbolTable_HasExceptionBlock (SymbolTable_GetCurrentModule ()))
17685 : : {
17686 : 54 : BuildRTExceptLeave (tok, true);
17687 : 54 : GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17688 : : }
17689 : 82952 : BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
17690 : 82952 : CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
17691 : 82952 : SymbolTable_PutModuleEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
17692 : 82952 : CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
17693 : 82952 : GenQuadO (tok, M2Quads_InitEndOp, tok, SymbolTable_GetFileModule (), SymbolTable_GetCurrentModule (), false);
17694 : 82952 : }
17695 : :
17696 : :
17697 : : /*
17698 : : StartBuildFinally - Sets the start of finalization code of the
17699 : : current module to the next quadruple.
17700 : : */
17701 : :
17702 : 15878 : extern "C" void M2Quads_StartBuildFinally (unsigned int tok)
17703 : : {
17704 : 15878 : NameKey_Name name;
17705 : 15878 : unsigned int ModuleSym;
17706 : :
17707 : 15878 : M2Quads_PopT (&name);
17708 : 15872 : ModuleSym = SymbolTable_GetCurrentModule ();
17709 : 31744 : M2Debug_Assert ((SymbolTable_IsModule (ModuleSym)) || (SymbolTable_IsDefImp (ModuleSym)));
17710 : 15872 : M2Debug_Assert ((SymbolTable_GetSymName (ModuleSym)) == name);
17711 : 15872 : SymbolTable_PutModuleFinallyStartQuad (ModuleSym, NextQuad);
17712 : 15872 : GenQuadO (tok, M2Quads_FinallyStartOp, tok, SymbolTable_GetFileModule (), ModuleSym, false);
17713 : 15872 : M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
17714 : 15872 : M2Quads_PushT (name);
17715 : : /* CheckVariablesAt(ModuleSym) ; */
17716 : 15872 : CheckNeedPriorityBegin (tok, ModuleSym, ModuleSym);
17717 : 15872 : M2StackWord_PushWord (TryStack, NextQuad);
17718 : 15872 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
17719 : 15872 : if (SymbolTable_HasExceptionFinally (ModuleSym))
17720 : : {
17721 : 0 : GenQuadO (tok, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
17722 : : }
17723 : 15872 : }
17724 : :
17725 : :
17726 : : /*
17727 : : EndBuildFinally - Sets the end finalization code of a module.
17728 : : */
17729 : :
17730 : 15872 : extern "C" void M2Quads_EndBuildFinally (unsigned int tok)
17731 : : {
17732 : 15872 : if (SymbolTable_HasExceptionFinally (SymbolTable_GetCurrentModule ()))
17733 : : {
17734 : 0 : BuildRTExceptLeave (tok, true);
17735 : 0 : GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17736 : : }
17737 : 15872 : BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
17738 : 15872 : CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
17739 : 15872 : SymbolTable_PutModuleFinallyEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
17740 : 15872 : CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
17741 : 15872 : GenQuadO (tok, M2Quads_FinallyEndOp, tok, SymbolTable_GetFileModule (), SymbolTable_GetCurrentModule (), false);
17742 : 15872 : }
17743 : :
17744 : :
17745 : : /*
17746 : : BuildExceptInitial - adds an CatchBeginOp, CatchEndOp quadruple
17747 : : in the current block.
17748 : : */
17749 : :
17750 : 2892 : extern "C" void M2Quads_BuildExceptInitial (unsigned int tok)
17751 : : {
17752 : 2892 : unsigned int previous;
17753 : :
17754 : : /* we have finished the 'try' block, so now goto the return
17755 : : section which will tidy up (any) priorities before returning.
17756 : : */
17757 : 2892 : GenQuadO (tok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PopWord (ReturnStack), false);
17758 : 2892 : M2StackWord_PushWord (ReturnStack, NextQuad-1);
17759 : : /*
17760 : : this is the 'catch' block.
17761 : : */
17762 : 2892 : BackPatch (M2StackWord_PeepWord (TryStack, 1), NextQuad);
17763 : 2892 : GenQuadO (tok, M2Quads_CatchBeginOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17764 : 2892 : previous = static_cast<unsigned int> (M2StackWord_PopWord (CatchStack));
17765 : 2892 : if (previous != 0)
17766 : : {
17767 : 0 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}only allowed one EXCEPT statement in a procedure or module", 62);
17768 : : }
17769 : 2892 : M2StackWord_PushWord (CatchStack, NextQuad-1);
17770 : 2892 : BuildRTExceptEnter (tok);
17771 : 2892 : }
17772 : :
17773 : :
17774 : : /*
17775 : : BuildExceptFinally - adds an ExceptOp quadruple in a modules
17776 : : finally block.
17777 : : */
17778 : :
17779 : 0 : extern "C" void M2Quads_BuildExceptFinally (unsigned int tok)
17780 : : {
17781 : 0 : M2Quads_BuildExceptInitial (tok);
17782 : 0 : }
17783 : :
17784 : :
17785 : : /*
17786 : : BuildExceptProcedure - adds an ExceptOp quadruple in a procedure
17787 : : block.
17788 : : */
17789 : :
17790 : 168 : extern "C" void M2Quads_BuildExceptProcedure (unsigned int tok)
17791 : : {
17792 : 168 : M2Quads_BuildExceptInitial (tok);
17793 : 168 : }
17794 : :
17795 : :
17796 : : /*
17797 : : BuildRetry - adds an RetryOp quadruple.
17798 : : */
17799 : :
17800 : 168 : extern "C" void M2Quads_BuildRetry (unsigned int tok)
17801 : : {
17802 : 168 : if ((M2StackWord_PeepWord (CatchStack, 1)) == 0)
17803 : : {
17804 : 6 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}the {%kRETRY} statement must occur after an {%kEXCEPT} statement in the same module or procedure block", 106);
17805 : : }
17806 : : else
17807 : : {
17808 : 162 : BuildRTExceptLeave (tok, false);
17809 : 162 : GenQuadO (tok, M2Quads_RetryOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PeepWord (TryStack, 1), false);
17810 : : }
17811 : 168 : }
17812 : :
17813 : :
17814 : : /*
17815 : : BuildReThrow - creates a ThrowOp _ _ NulSym, indicating that
17816 : : the exception needs to be rethrown. The stack
17817 : : is unaltered.
17818 : : */
17819 : :
17820 : 222 : extern "C" void M2Quads_BuildReThrow (unsigned int tokenno)
17821 : : {
17822 : 222 : GenQuadO (tokenno, M2Quads_ThrowOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17823 : 222 : }
17824 : :
17825 : :
17826 : : /*
17827 : : StartBuildInnerInit - Sets the start of initialization code of the
17828 : : inner module to the next quadruple.
17829 : : */
17830 : :
17831 : 0 : extern "C" void M2Quads_StartBuildInnerInit (unsigned int tok)
17832 : : {
17833 : 0 : SymbolTable_PutModuleStartQuad (SymbolTable_GetCurrentModule (), NextQuad);
17834 : 0 : GenQuadO (tok, M2Quads_InitStartOp, tok, SymbolTable_NulSym, SymbolTable_GetCurrentModule (), false);
17835 : 0 : M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
17836 : 0 : CheckNeedPriorityBegin (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
17837 : 0 : M2StackWord_PushWord (TryStack, NextQuad);
17838 : 0 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
17839 : 0 : if (SymbolTable_HasExceptionFinally (SymbolTable_GetCurrentModule ()))
17840 : : {
17841 : 0 : GenQuadO (tok, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
17842 : : }
17843 : 0 : }
17844 : :
17845 : :
17846 : : /*
17847 : : EndBuildInnerInit - Sets the end initialization code of a module.
17848 : : */
17849 : :
17850 : 0 : extern "C" void M2Quads_EndBuildInnerInit (unsigned int tok)
17851 : : {
17852 : 0 : if (SymbolTable_HasExceptionBlock (SymbolTable_GetCurrentModule ()))
17853 : : {
17854 : 0 : BuildRTExceptLeave (tok, true);
17855 : 0 : GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17856 : : }
17857 : 0 : SymbolTable_PutModuleEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
17858 : 0 : CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
17859 : 0 : BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
17860 : 0 : CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
17861 : 0 : GenQuadO (tok, M2Quads_InitEndOp, tok, SymbolTable_NulSym, SymbolTable_GetCurrentModule (), false);
17862 : 0 : }
17863 : :
17864 : :
17865 : : /*
17866 : : BuildBuiltinConst - makes reference to a builtin constant within gm2.
17867 : :
17868 : : Entry Exit
17869 : :
17870 : : Ptr ->
17871 : : +------------+ +------------+
17872 : : | Ident | | Sym |
17873 : : |------------| |------------|
17874 : :
17875 : : Quadruple produced:
17876 : :
17877 : : q Sym BuiltinConstOp Ident
17878 : : */
17879 : :
17880 : 29846 : extern "C" void M2Quads_BuildBuiltinConst (void)
17881 : : {
17882 : 29846 : unsigned int idtok;
17883 : 29846 : unsigned int Id;
17884 : 29846 : unsigned int Sym;
17885 : :
17886 : 29846 : M2Quads_PopTtok (&Id, &idtok);
17887 : 29846 : Sym = SymbolTable_MakeTemporary (idtok, SymbolTable_ImmediateValue);
17888 : 29846 : SymbolTable_PutVar (Sym, M2Base_Integer);
17889 : : /*
17890 : : CASE GetBuiltinConstType(KeyToCharStar(Name(Id))) OF
17891 : :
17892 : : 0: ErrorFormat1(NewError(GetTokenNo()),
17893 : : '%a unrecognised builtin constant', Id) |
17894 : : 1: PutVar(Sym, Integer) |
17895 : : 2: PutVar(Sym, Real)
17896 : :
17897 : : ELSE
17898 : : InternalError ('unrecognised value')
17899 : : END ;
17900 : : */
17901 : 29846 : GenQuadO (idtok, M2Quads_BuiltinConstOp, Sym, SymbolTable_NulSym, Id, false);
17902 : 29846 : M2Quads_PushTtok (Sym, idtok);
17903 : 29846 : }
17904 : :
17905 : :
17906 : : /*
17907 : : BuildBuiltinTypeInfo - make reference to a builtin typeinfo function
17908 : : within gm2.
17909 : :
17910 : : Entry Exit
17911 : :
17912 : : Ptr ->
17913 : : +-------------+
17914 : : | Type |
17915 : : |-------------| +------------+
17916 : : | Ident | | Sym |
17917 : : |-------------| |------------|
17918 : :
17919 : : Quadruple produced:
17920 : :
17921 : : q Sym BuiltinTypeInfoOp Type Ident
17922 : : */
17923 : :
17924 : 360 : extern "C" void M2Quads_BuildBuiltinTypeInfo (void)
17925 : : {
17926 : 360 : unsigned int idtok;
17927 : 360 : unsigned int Ident;
17928 : 360 : unsigned int Type;
17929 : 360 : unsigned int Sym;
17930 : :
17931 : 360 : M2Quads_PopTtok (&Ident, &idtok);
17932 : 360 : M2Quads_PopT (&Type);
17933 : 360 : Sym = SymbolTable_MakeTemporary (M2LexBuf_BuiltinTokenNo, SymbolTable_ImmediateValue);
17934 : 360 : switch (m2builtins_GetBuiltinTypeInfoType (const_cast <const char * > (static_cast <char * > (NameKey_KeyToCharStar ((NameKey_Name) (Ident))))))
17935 : : {
17936 : 0 : case 0:
17937 : 0 : M2Error_ErrorFormat1 (M2Error_NewError (idtok), (const char *) "%a unrecognised builtin constant", 32, (const unsigned char *) &Ident, (sizeof (Ident)-1));
17938 : 0 : break;
17939 : :
17940 : 192 : case 1:
17941 : 192 : SymbolTable_PutVar (Sym, M2Base_Boolean);
17942 : 192 : break;
17943 : :
17944 : 120 : case 2:
17945 : 120 : SymbolTable_PutVar (Sym, M2Base_ZType);
17946 : 120 : break;
17947 : :
17948 : 48 : case 3:
17949 : 48 : SymbolTable_PutVar (Sym, M2Base_RType);
17950 : 48 : break;
17951 : :
17952 : :
17953 : 0 : default:
17954 : 0 : M2Error_InternalError ((const char *) "unrecognised value", 18);
17955 : 360 : break;
17956 : : }
17957 : 360 : GenQuadO (idtok, M2Quads_BuiltinTypeInfoOp, Sym, Type, Ident, false);
17958 : 360 : M2Quads_PushTtok (Sym, idtok);
17959 : 360 : }
17960 : :
17961 : :
17962 : : /*
17963 : : BuildAssignment - Builds an assignment from the values given on the
17964 : : quad stack. Either an assignment to an
17965 : : arithmetic expression or an assignment to a
17966 : : boolean expression. This procedure should not
17967 : : be called in CONST declarations.
17968 : : The Stack is expected to contain:
17969 : :
17970 : :
17971 : : Either
17972 : :
17973 : : Entry Exit
17974 : : ===== ====
17975 : :
17976 : : Ptr ->
17977 : : +------------+
17978 : : | Expression |
17979 : : |------------|
17980 : : | Designator |
17981 : : |------------| +------------+
17982 : : | | | | <- Ptr
17983 : : |------------| |------------|
17984 : :
17985 : :
17986 : : Quadruples Produced
17987 : :
17988 : : q BecomesOp Designator _ Expression
17989 : :
17990 : : OR
17991 : :
17992 : : Entry Exit
17993 : : ===== ====
17994 : :
17995 : : Ptr ->
17996 : : +------------+
17997 : : | True |False|
17998 : : |------------|
17999 : : | Designator |
18000 : : |------------| +------------+
18001 : : | | | | <- Ptr
18002 : : |------------| |------------|
18003 : :
18004 : :
18005 : : Quadruples Produced
18006 : :
18007 : : q BecomesOp Designator _ TRUE
18008 : : q+1 GotoOp q+3
18009 : : q+2 BecomesOp Designator _ FALSE
18010 : :
18011 : : */
18012 : :
18013 : 127623 : extern "C" void M2Quads_BuildAssignment (unsigned int becomesTokNo)
18014 : : {
18015 : 127623 : unsigned int des;
18016 : 127623 : unsigned int exp;
18017 : 127623 : unsigned int destok;
18018 : 127623 : unsigned int exptok;
18019 : 127623 : unsigned int combinedtok;
18020 : :
18021 : 127623 : des = static_cast<unsigned int> (M2Quads_OperandT (2));
18022 : 127623 : if (IsReadOnly (des))
18023 : : {
18024 : 36 : destok = static_cast<unsigned int> (M2Quads_OperandTok (2));
18025 : 36 : exptok = static_cast<unsigned int> (M2Quads_OperandTok (1));
18026 : 36 : exp = static_cast<unsigned int> (M2Quads_OperandT (1));
18027 : 36 : if (DebugTokPos)
18028 : : {
18029 : : M2MetaError_MetaErrorT1 (destok, (const char *) "destok {%1Ead}", 14, des);
18030 : : M2MetaError_MetaErrorT1 (exptok, (const char *) "exptok {%1Ead}", 14, exp);
18031 : : }
18032 : 36 : combinedtok = M2LexBuf_MakeVirtualTok (becomesTokNo, destok, exptok);
18033 : 36 : if (DebugTokPos)
18034 : : {
18035 : : M2MetaError_MetaErrorT1 (combinedtok, (const char *) "combined {%1Ead}", 16, des);
18036 : : }
18037 : 36 : if (IsBoolean (1))
18038 : : {
18039 : 0 : M2MetaError_MetaErrorT1 (combinedtok, (const char *) "cannot assign expression to a constant designator {%1Ead}", 57, des);
18040 : : }
18041 : : else
18042 : : {
18043 : 36 : exp = static_cast<unsigned int> (M2Quads_OperandT (1));
18044 : 36 : M2MetaError_MetaErrorT2 (combinedtok, (const char *) "cannot assign a constant designator {%1Ead} with an expression {%2Ead}", 70, des, exp);
18045 : : }
18046 : 36 : M2Quads_PopN (2); /* Remove both parameters. */
18047 : : }
18048 : 127587 : else if (SymbolTable_IsError (des))
18049 : : {
18050 : : /* avoid dangling else. */
18051 : 25 : M2Quads_PopN (2); /* Remove both parameters. */
18052 : : }
18053 : : else
18054 : : {
18055 : : /* avoid dangling else. */
18056 : 127562 : doBuildAssignment (becomesTokNo, true, true);
18057 : : }
18058 : 127617 : }
18059 : :
18060 : :
18061 : : /*
18062 : : BuildAssignConstant - used to create constant in the CONST declaration.
18063 : : The stack is expected to contain:
18064 : :
18065 : : Either
18066 : :
18067 : : Entry Exit
18068 : : ===== ====
18069 : :
18070 : : Ptr ->
18071 : : +------------+
18072 : : | Expression |
18073 : : |------------|
18074 : : | Designator |
18075 : : |------------| +------------+
18076 : : | | | | <- Ptr
18077 : : |------------| |------------|
18078 : :
18079 : :
18080 : : Quadruples Produced
18081 : :
18082 : : q BecomesOp Designator _ Expression
18083 : :
18084 : : OR
18085 : :
18086 : : Entry Exit
18087 : : ===== ====
18088 : :
18089 : : Ptr ->
18090 : : +------------+
18091 : : | True |False|
18092 : : |------------|
18093 : : | Designator |
18094 : : |------------| +------------+
18095 : : | | | | <- Ptr
18096 : : |------------| |------------|
18097 : :
18098 : :
18099 : : Quadruples Produced
18100 : :
18101 : : q BecomesOp Designator _ TRUE
18102 : : q+1 GotoOp q+3
18103 : : q+2 BecomesOp Designator _ FALSE
18104 : : */
18105 : :
18106 : 294808 : extern "C" void M2Quads_BuildAssignConstant (unsigned int equalsTokNo)
18107 : : {
18108 : 294808 : doBuildAssignment (equalsTokNo, true, true);
18109 : 294808 : }
18110 : :
18111 : :
18112 : : /*
18113 : : BuildAlignment - builds an assignment to an alignment constant.
18114 : :
18115 : : The Stack is expected to contain:
18116 : :
18117 : :
18118 : : Entry Exit
18119 : : ===== ====
18120 : :
18121 : : Ptr ->
18122 : : +---------------+
18123 : : | Expression |
18124 : : |---------------|
18125 : : | bytealignment |
18126 : : |---------------| empty
18127 : : */
18128 : :
18129 : 72 : extern "C" void M2Quads_BuildAlignment (unsigned int tokno)
18130 : : {
18131 : 72 : NameKey_Name name;
18132 : 72 : unsigned int expr;
18133 : 72 : unsigned int align;
18134 : :
18135 : 72 : M2Quads_PopT (&expr);
18136 : 72 : M2Quads_PopT (&name);
18137 : 72 : if (name != (NameKey_MakeKey ((const char *) "bytealignment", 13)))
18138 : : {
18139 : 0 : M2MetaError_MetaError1 ((const char *) "expecting bytealignment identifier, rather than {%1Ea}", 54, SymbolTable_MakeError (tokno, name));
18140 : : }
18141 : 72 : FifoQueue_GetConstFromFifoQueue (&align);
18142 : 72 : M2Quads_PushT (align);
18143 : 72 : M2Quads_PushT (expr);
18144 : 72 : M2Quads_BuildAssignConstant (tokno);
18145 : 72 : }
18146 : :
18147 : :
18148 : : /*
18149 : : BuildBitLength - builds an assignment to a bit length constant.
18150 : :
18151 : : The Stack is expected to contain:
18152 : :
18153 : :
18154 : : Entry Exit
18155 : : ===== ====
18156 : :
18157 : : Ptr ->
18158 : : +------------+
18159 : : | Expression |
18160 : : |------------| empty
18161 : : */
18162 : :
18163 : 0 : extern "C" void M2Quads_BuildBitLength (unsigned int tokno)
18164 : : {
18165 : 0 : unsigned int expr;
18166 : 0 : unsigned int length;
18167 : :
18168 : 0 : M2Quads_PopT (&expr);
18169 : 0 : FifoQueue_GetConstFromFifoQueue (&length);
18170 : 0 : M2Quads_PushT (length);
18171 : 0 : M2Quads_PushT (expr);
18172 : 0 : M2Quads_BuildAssignConstant (tokno);
18173 : 0 : }
18174 : :
18175 : :
18176 : : /*
18177 : : BuildPragmaField - builds an assignment to an alignment constant.
18178 : :
18179 : : The Stack is expected to contain:
18180 : :
18181 : :
18182 : : Entry Exit
18183 : : ===== ====
18184 : :
18185 : : Ptr ->
18186 : : +------------+
18187 : : | Expression |
18188 : : |------------| empty
18189 : : */
18190 : :
18191 : 12 : extern "C" void M2Quads_BuildPragmaField (void)
18192 : : {
18193 : 12 : unsigned int expr;
18194 : 12 : unsigned int const_;
18195 : 12 : NameKey_Name name;
18196 : :
18197 : 12 : M2Quads_PopT (&expr);
18198 : 12 : M2Quads_PopT (&name);
18199 : 12 : if ((name != (NameKey_MakeKey ((const char *) "unused", 6))) && (name != (NameKey_MakeKey ((const char *) "bytealignment", 13))))
18200 : : {
18201 : 0 : M2MetaError_MetaError0 ((const char *) "only allowed to use the attribute {%Ekbytealignment} in the default record field alignment pragma", 97);
18202 : : }
18203 : 12 : if (expr != SymbolTable_NulSym)
18204 : : {
18205 : 12 : FifoQueue_GetConstFromFifoQueue (&const_);
18206 : 12 : M2Quads_PushT (const_);
18207 : 12 : M2Quads_PushT (expr);
18208 : 12 : M2Quads_BuildAssignConstant (M2LexBuf_GetTokenNo ());
18209 : : }
18210 : 12 : }
18211 : :
18212 : :
18213 : : /*
18214 : : BuildDefaultFieldAlignment - builds an assignment to an alignment constant.
18215 : :
18216 : : The Stack is expected to contain:
18217 : :
18218 : :
18219 : : Entry Exit
18220 : : ===== ====
18221 : :
18222 : : Ptr ->
18223 : : +------------+
18224 : : | Expression |
18225 : : |------------| empty
18226 : : */
18227 : :
18228 : 36 : extern "C" void M2Quads_BuildDefaultFieldAlignment (void)
18229 : : {
18230 : 36 : unsigned int expr;
18231 : 36 : unsigned int align;
18232 : 36 : NameKey_Name name;
18233 : :
18234 : 36 : M2Quads_PopT (&expr);
18235 : 36 : M2Quads_PopT (&name);
18236 : 36 : if (name != (NameKey_MakeKey ((const char *) "bytealignment", 13)))
18237 : : {
18238 : 0 : M2MetaError_MetaError0 ((const char *) "{%E}only allowed to use the attribute {%kbytealignment} in the default record field alignment pragma", 100);
18239 : : }
18240 : 36 : FifoQueue_GetConstFromFifoQueue (&align);
18241 : 36 : M2Quads_PushT (align);
18242 : 36 : M2Quads_PushT (expr);
18243 : 36 : M2Quads_BuildAssignConstant (M2LexBuf_GetTokenNo ());
18244 : 36 : }
18245 : :
18246 : :
18247 : : /*
18248 : : BuildRepeat - Builds the repeat statement from the quad stack.
18249 : : The Stack is expected to contain:
18250 : :
18251 : :
18252 : : Entry Exit
18253 : : ===== ====
18254 : :
18255 : :
18256 : : Empty
18257 : : <- Ptr
18258 : : +------------+
18259 : : | RepeatQuad |
18260 : : |------------|
18261 : :
18262 : : */
18263 : :
18264 : 1422 : extern "C" void M2Quads_BuildRepeat (void)
18265 : : {
18266 : 1422 : M2Quads_PushT (NextQuad);
18267 : 1422 : }
18268 : :
18269 : :
18270 : : /*
18271 : : BuildUntil - Builds the until part of the repeat statement
18272 : : from the quad stack.
18273 : : The Stack is expected to contain:
18274 : :
18275 : :
18276 : : Entry Exit
18277 : : ===== ====
18278 : :
18279 : : Ptr ->
18280 : : +------------+
18281 : : | t | f |
18282 : : |------------|
18283 : : | RepeatQuad | Empty
18284 : : |------------|
18285 : : */
18286 : :
18287 : 1422 : extern "C" void M2Quads_BuildUntil (void)
18288 : : {
18289 : 1422 : unsigned int t;
18290 : 1422 : unsigned int f;
18291 : 1422 : unsigned int Repeat;
18292 : :
18293 : 1422 : CheckBooleanId ();
18294 : 1422 : PopBool (&t, &f);
18295 : 1422 : M2Quads_PopT (&Repeat);
18296 : 1422 : BackPatch (f, Repeat); /* If False then keep on repeating */
18297 : 1422 : BackPatch (t, NextQuad); /* If True then exit repeat */
18298 : 1422 : }
18299 : :
18300 : :
18301 : : /*
18302 : : BuildWhile - Builds the While part of the While statement
18303 : : from the quad stack.
18304 : : The Stack is expected to contain:
18305 : :
18306 : :
18307 : : Entry Exit
18308 : : ===== ====
18309 : :
18310 : : <- Ptr
18311 : : |------------|
18312 : : Empty | WhileQuad |
18313 : : |------------|
18314 : : */
18315 : :
18316 : 7870 : extern "C" void M2Quads_BuildWhile (void)
18317 : : {
18318 : 7870 : M2Quads_PushT (NextQuad);
18319 : 7870 : }
18320 : :
18321 : :
18322 : : /*
18323 : : BuildDoWhile - Builds the Do part of the while statement
18324 : : from the quad stack.
18325 : : The Stack is expected to contain:
18326 : :
18327 : :
18328 : : Entry Exit
18329 : : ===== ====
18330 : :
18331 : : Ptr ->
18332 : : +------------+ +------------+
18333 : : | t | f | | 0 | f |
18334 : : |------------| |------------|
18335 : : | WhileQuad | | WhileQuad |
18336 : : |------------| |------------|
18337 : :
18338 : : Quadruples
18339 : :
18340 : : BackPatch t exit to the NextQuad
18341 : : */
18342 : :
18343 : 7870 : extern "C" void M2Quads_BuildDoWhile (void)
18344 : : {
18345 : 7870 : unsigned int t;
18346 : 7870 : unsigned int f;
18347 : :
18348 : 7870 : CheckBooleanId ();
18349 : 7870 : PopBool (&t, &f);
18350 : 7870 : BackPatch (t, NextQuad);
18351 : 7870 : PushBool (0, f);
18352 : 7870 : }
18353 : :
18354 : :
18355 : : /*
18356 : : BuildEndWhile - Builds the end part of the while statement
18357 : : from the quad stack.
18358 : : The Stack is expected to contain:
18359 : :
18360 : :
18361 : : Entry Exit
18362 : : ===== ====
18363 : :
18364 : : Ptr ->
18365 : : +------------+
18366 : : | t | f |
18367 : : |------------|
18368 : : | WhileQuad | Empty
18369 : : |------------|
18370 : :
18371 : : Quadruples
18372 : :
18373 : : q GotoOp WhileQuad
18374 : : False exit is backpatched with q+1
18375 : : */
18376 : :
18377 : 7870 : extern "C" void M2Quads_BuildEndWhile (int reltokpos)
18378 : : {
18379 : 7870 : unsigned int tok;
18380 : 7870 : unsigned int While;
18381 : 7870 : unsigned int t;
18382 : 7870 : unsigned int f;
18383 : :
18384 : 7870 : tok = M2LexBuf_GetTokenNo ();
18385 : 7870 : tok = ((int ) (tok))+reltokpos;
18386 : 7870 : PopBool (&t, &f);
18387 : 7870 : M2Debug_Assert (t == 0);
18388 : 7870 : M2Quads_PopT (&While);
18389 : 7870 : GenQuadO (tok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, While, false);
18390 : 7870 : BackPatch (f, NextQuad);
18391 : 7870 : }
18392 : :
18393 : :
18394 : : /*
18395 : : BuildLoop - Builds the Loop part of the Loop statement
18396 : : from the quad stack.
18397 : : The Stack is expected to contain:
18398 : :
18399 : :
18400 : : Entry Exit
18401 : : ===== ====
18402 : :
18403 : : <- Ptr
18404 : : Empty +------------+
18405 : : | LoopQuad |
18406 : : |------------|
18407 : : */
18408 : :
18409 : 516 : extern "C" void M2Quads_BuildLoop (void)
18410 : : {
18411 : 516 : M2Quads_PushT (NextQuad);
18412 : 516 : PushExit (0); /* Seperate Exit Stack for loop end */
18413 : 516 : }
18414 : :
18415 : :
18416 : : /*
18417 : : BuildExit - Builds the Exit part of the Loop statement.
18418 : : */
18419 : :
18420 : 94 : extern "C" void M2Quads_BuildExit (void)
18421 : : {
18422 : 94 : if (M2StackWord_IsEmptyWord (ExitStack))
18423 : : {
18424 : 0 : M2MetaError_MetaError0 ((const char *) "{%EkEXIT} is only allowed in a {%kLOOP} statement", 49);
18425 : : }
18426 : : else
18427 : : {
18428 : 94 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18429 : 94 : PushExit (Merge (PopExit (), NextQuad-1));
18430 : : }
18431 : 94 : }
18432 : :
18433 : :
18434 : : /*
18435 : : BuildEndLoop - Builds the End part of the Loop statement
18436 : : from the quad stack.
18437 : : The Stack is expected to contain:
18438 : :
18439 : :
18440 : : Entry Exit
18441 : : ===== ====
18442 : :
18443 : : Ptr ->
18444 : : +------------+
18445 : : | LoopQuad | Empty
18446 : : |------------|
18447 : :
18448 : : Quadruples
18449 : :
18450 : : Goto _ _ LoopQuad
18451 : : */
18452 : :
18453 : 516 : extern "C" void M2Quads_BuildEndLoop (void)
18454 : : {
18455 : 516 : unsigned int Loop;
18456 : :
18457 : 516 : M2Quads_PopT (&Loop);
18458 : 516 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, Loop);
18459 : 516 : BackPatch (PopExit (), NextQuad);
18460 : 516 : }
18461 : :
18462 : :
18463 : : /*
18464 : : BuildThenIf - Builds the Then part of the If statement
18465 : : from the quad stack.
18466 : : The Stack is expected to contain:
18467 : :
18468 : :
18469 : : Entry Exit
18470 : : ===== ====
18471 : :
18472 : : Ptr -> <- Ptr
18473 : : +------------+ +------------+
18474 : : | t | f | | 0 | f |
18475 : : |------------| |------------|
18476 : :
18477 : : Quadruples
18478 : :
18479 : : The true exit is BackPatched to point to
18480 : : the NextQuad.
18481 : : */
18482 : :
18483 : 45049 : extern "C" void M2Quads_BuildThenIf (void)
18484 : : {
18485 : 45049 : unsigned int t;
18486 : 45049 : unsigned int f;
18487 : :
18488 : 45049 : CheckBooleanId ();
18489 : 45049 : PopBool (&t, &f);
18490 : 45049 : BackPatch (t, NextQuad);
18491 : 45049 : PushBool (0, f);
18492 : 45049 : }
18493 : :
18494 : :
18495 : : /*
18496 : : BuildElse - Builds the Else part of the If statement
18497 : : from the quad stack.
18498 : : The Stack is expected to contain:
18499 : :
18500 : :
18501 : : Entry Exit
18502 : : ===== ====
18503 : :
18504 : : Ptr ->
18505 : : +------------+ +------------+
18506 : : | t | f | | t+q | 0 |
18507 : : |------------| |------------|
18508 : :
18509 : : Quadruples
18510 : :
18511 : : q GotoOp _ _ 0
18512 : : q+1 <- BackPatched from f
18513 : : */
18514 : :
18515 : 15152 : extern "C" void M2Quads_BuildElse (void)
18516 : : {
18517 : 15152 : unsigned int t;
18518 : 15152 : unsigned int f;
18519 : :
18520 : 15152 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18521 : 15152 : PopBool (&t, &f);
18522 : 15152 : BackPatch (f, NextQuad);
18523 : 15152 : PushBool (Merge (t, NextQuad-1), 0); /* NextQuad-1 = Goto Quad */
18524 : 15152 : }
18525 : :
18526 : :
18527 : : /*
18528 : : BuildEndIf - Builds the End part of the If statement
18529 : : from the quad stack.
18530 : : The Stack is expected to contain:
18531 : :
18532 : :
18533 : : Entry Exit
18534 : : ===== ====
18535 : :
18536 : : Ptr ->
18537 : : +------------+
18538 : : | t | f | Empty
18539 : : |------------|
18540 : :
18541 : : Quadruples
18542 : :
18543 : : Both t and f are backpatched to point to the NextQuad
18544 : : */
18545 : :
18546 : 41769 : extern "C" void M2Quads_BuildEndIf (void)
18547 : : {
18548 : 41769 : unsigned int t;
18549 : 41769 : unsigned int f;
18550 : :
18551 : 41769 : PopBool (&t, &f);
18552 : 41769 : BackPatch (t, NextQuad);
18553 : 41769 : BackPatch (f, NextQuad);
18554 : 41769 : }
18555 : :
18556 : :
18557 : : /*
18558 : : BuildElsif1 - Builds the Elsif part of the If statement
18559 : : from the quad stack.
18560 : : The Stack is expected to contain:
18561 : :
18562 : :
18563 : : Entry Exit
18564 : : ===== ====
18565 : :
18566 : : Ptr ->
18567 : : +------------+ +------------+
18568 : : | t | f | | t+q | 0 |
18569 : : |------------| |------------|
18570 : :
18571 : : Quadruples
18572 : :
18573 : : q GotoOp _ _ 0
18574 : : q+1 <- BackPatched from f
18575 : : */
18576 : :
18577 : 3280 : extern "C" void M2Quads_BuildElsif1 (void)
18578 : : {
18579 : 3280 : unsigned int t;
18580 : 3280 : unsigned int f;
18581 : :
18582 : 3280 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18583 : 3280 : PopBool (&t, &f);
18584 : 3280 : BackPatch (f, NextQuad);
18585 : 3280 : PushBool (Merge (t, NextQuad-1), 0); /* NextQuad-1 = Goto Quad */
18586 : 3280 : }
18587 : :
18588 : :
18589 : : /*
18590 : : BuildElsif2 - Builds the Elsif until part of the If statement
18591 : : from the quad stack.
18592 : : The Stack is expected to contain:
18593 : :
18594 : :
18595 : : Entry Exit
18596 : : ===== ====
18597 : :
18598 : : Ptr ->
18599 : : +--------------+
18600 : : | 0 | f1 | <- Ptr
18601 : : |--------------| +---------------+
18602 : : | t2 | f2 | | t2 | f1+f2 |
18603 : : |--------------| |---------------|
18604 : : */
18605 : :
18606 : 3280 : extern "C" void M2Quads_BuildElsif2 (void)
18607 : : {
18608 : 3280 : unsigned int t1;
18609 : 3280 : unsigned int f1;
18610 : 3280 : unsigned int t2;
18611 : 3280 : unsigned int f2;
18612 : :
18613 : 3280 : PopBool (&t1, &f1);
18614 : 3280 : M2Debug_Assert (t1 == 0);
18615 : 3280 : PopBool (&t2, &f2);
18616 : 3280 : PushBool (t2, Merge (f1, f2));
18617 : 3280 : }
18618 : :
18619 : :
18620 : : /*
18621 : : BuildForToByDo - Builds the For To By Do part of the For statement
18622 : : from the quad stack.
18623 : : The Stack is expected to contain:
18624 : :
18625 : :
18626 : : Entry Exit
18627 : : ===== ====
18628 : :
18629 : : <- Ptr
18630 : : +----------------+
18631 : : Ptr -> | RangeId |
18632 : : +----------------+ |----------------|
18633 : : | BySym | ByType | | ForQuad |
18634 : : |----------------| |----------------|
18635 : : | e2 | | LastValue |
18636 : : |----------------| |----------------|
18637 : : | e1 | | BySym | ByType |
18638 : : |----------------| |----------------|
18639 : : | Ident | | IdentSym |
18640 : : |----------------| |----------------|
18641 : :
18642 : :
18643 : : x := e1 ;
18644 : : Note that LASTVALUE is calculated during M2GenGCC
18645 : : after all the types have been resolved.
18646 : : LASTVALUE := ((e2-e1) DIV BySym) * BySym + e1
18647 : : IF BySym<0
18648 : : THEN
18649 : : IF e1<e2
18650 : : THEN
18651 : : goto exit
18652 : : END
18653 : : ELSE
18654 : : IF e1>e2
18655 : : THEN
18656 : : goto exit
18657 : : END
18658 : : END ;
18659 : : LOOP
18660 : : body
18661 : : IF x=LASTVALUE
18662 : : THEN
18663 : : goto exit
18664 : : END ;
18665 : : INC(x, BySym)
18666 : : END
18667 : :
18668 : : Quadruples:
18669 : :
18670 : : q BecomesOp IdentSym _ e1
18671 : : q+ LastForIteratorOp LastValue := ((e1-e2) DIV by) * by + e1
18672 : : q+1 if >= by 0 q+..2
18673 : : q+2 GotoOp q+3
18674 : : q+3 If >= e1 e2 q+5
18675 : : q+4 GotoOp exit
18676 : : q+5 ..
18677 : : q+..1 Goto q+..5
18678 : : q+..2 If >= e2 e1 q+..4
18679 : : q+..3 GotoOp exit
18680 : : q+..4 ..
18681 : :
18682 : : The For Loop is regarded:
18683 : :
18684 : : For ident := e1 To e2 By by Do
18685 : :
18686 : : End
18687 : : */
18688 : :
18689 : 2610 : extern "C" void M2Quads_BuildForToByDo (void)
18690 : : {
18691 : 2610 : M2Quads_LineNote l1;
18692 : 2610 : M2Quads_LineNote l2;
18693 : 2610 : NameKey_Name e1;
18694 : 2610 : NameKey_Name e2;
18695 : 2610 : NameKey_Name Id;
18696 : 2610 : unsigned int e1tok;
18697 : 2610 : unsigned int e2tok;
18698 : 2610 : unsigned int idtok;
18699 : 2610 : unsigned int bytok;
18700 : 2610 : unsigned int LastIterator;
18701 : 2610 : unsigned int exit1;
18702 : 2610 : unsigned int IdSym;
18703 : 2610 : unsigned int BySym;
18704 : 2610 : unsigned int ByType;
18705 : 2610 : unsigned int ForLoop;
18706 : 2610 : unsigned int RangeId;
18707 : 2610 : unsigned int t;
18708 : 2610 : unsigned int f;
18709 : 2610 : unsigned int etype;
18710 : 2610 : unsigned int t1;
18711 : :
18712 : 2610 : l2 = PopLineNo ();
18713 : 2610 : l1 = PopLineNo ();
18714 : 2610 : UseLineNote (l1);
18715 : 2610 : PushFor (0);
18716 : 2610 : M2Quads_PopTFtok (&BySym, &ByType, &bytok);
18717 : 2610 : M2Quads_PopTtok (&e2, &e2tok);
18718 : 2610 : M2Quads_PopTtok (&e1, &e1tok);
18719 : 2610 : M2Quads_PopTtok (&Id, &idtok);
18720 : 2610 : IdSym = SymbolTable_RequestSym (idtok, Id);
18721 : 2610 : RangeId = M2Range_InitForLoopBeginRangeCheck (IdSym, idtok, e1, e1tok, e2, e2tok, BySym, bytok);
18722 : 2610 : BuildRange (RangeId);
18723 : 2610 : M2Quads_PushTtok (IdSym, idtok);
18724 : 2610 : M2Quads_PushTtok (e1, e1tok);
18725 : 2610 : BuildAssignmentWithoutBounds (idtok, true, true);
18726 : 2610 : UseLineNote (l2);
18727 : 3492 : LastIterator = SymbolTable_MakeTemporary (e2tok, AreConstant (((SymbolTable_IsConst (e1)) && (SymbolTable_IsConst (e2))) && (SymbolTable_IsConst (BySym))));
18728 : 2610 : SymbolTable_PutVar (LastIterator, SymbolTable_GetSType (IdSym));
18729 : 2610 : etype = M2Base_MixTypes (SymbolTable_GetSType (e1), SymbolTable_GetSType (e2), e2tok);
18730 : 2610 : e1 = doConvert (etype, e1);
18731 : 2610 : e2 = doConvert (etype, e2);
18732 : 2604 : ForLoopLastIterator (LastIterator, e1, e2, BySym, e1tok, e2tok, bytok);
18733 : : /* q+2 GotoOp q+3 */
18734 : 2604 : M2Quads_PushTFtok (BySym, ByType, bytok); /* BuildRelOp 1st parameter. */
18735 : 2604 : M2Quads_PushT (M2Reserved_GreaterEqualTok); /* 2nd parameter. */
18736 : : /* 3rd parameter. */
18737 : 2604 : PushZero (bytok, ByType);
18738 : 2604 : M2Quads_BuildRelOp (e2tok); /* Choose final expression position. */
18739 : 2604 : PopBool (&t, &f); /* Choose final expression position. */
18740 : 2604 : BackPatch (f, NextQuad);
18741 : : /* q+4 GotoOp Exit */
18742 : 2604 : M2Quads_PushTFtok (e1, SymbolTable_GetSType (e1), e1tok); /* BuildRelOp 1st parameter */
18743 : 2604 : M2Quads_PushT (M2Reserved_GreaterEqualTok); /* 2nd parameter */
18744 : 2604 : M2Quads_PushTFtok (e2, SymbolTable_GetSType (e2), e2tok); /* 3rd parameter */
18745 : 2604 : M2Quads_BuildRelOp (e2tok); /* Choose final expression position. */
18746 : 2604 : PopBool (&t1, &exit1); /* Choose final expression position. */
18747 : 2604 : BackPatch (t1, NextQuad);
18748 : 2604 : PushFor (Merge (PopFor (), exit1)); /* Merge exit1. */
18749 : 2604 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0); /* Merge exit1. */
18750 : 2604 : ForLoop = NextQuad-1;
18751 : : /* ELSE. */
18752 : 2604 : BackPatch (t, NextQuad);
18753 : 2604 : M2Quads_PushTFtok (e2, SymbolTable_GetSType (e2), e2tok); /* BuildRelOp 1st parameter */
18754 : 2604 : M2Quads_PushT (M2Reserved_GreaterEqualTok); /* 2nd parameter */
18755 : 2604 : M2Quads_PushTFtok (e1, SymbolTable_GetSType (e1), e1tok); /* 3rd parameter */
18756 : 2604 : M2Quads_BuildRelOp (e2tok); /* 3rd parameter */
18757 : 2604 : PopBool (&t1, &exit1);
18758 : 2604 : BackPatch (t1, NextQuad);
18759 : 2604 : PushFor (Merge (PopFor (), exit1)); /* Merge exit1. */
18760 : 2604 : BackPatch (ForLoop, NextQuad); /* Fixes the start of the for loop. */
18761 : 2604 : ForLoop = NextQuad;
18762 : : /* And set up the stack. */
18763 : 2604 : M2Quads_PushTFtok (IdSym, SymbolTable_GetSym (IdSym), idtok);
18764 : 2604 : M2Quads_PushTFtok (BySym, ByType, bytok);
18765 : 2604 : M2Quads_PushTFtok (LastIterator, SymbolTable_GetSType (LastIterator), e2tok);
18766 : 2604 : M2Quads_PushT (ForLoop);
18767 : 2604 : M2Quads_PushT (RangeId);
18768 : 2604 : }
18769 : :
18770 : :
18771 : : /*
18772 : : BuildPseudoBy - Builds the Non existant part of the By
18773 : : clause of the For statement
18774 : : from the quad stack.
18775 : : The Stack is expected to contain:
18776 : :
18777 : :
18778 : : Entry Exit
18779 : : ===== ====
18780 : :
18781 : : <- Ptr
18782 : : +------------+
18783 : : Ptr -> | BySym | t |
18784 : : +------------+ |------------|
18785 : : | e | t | | e | t |
18786 : : |------------| |------------|
18787 : : */
18788 : :
18789 : 2244 : extern "C" void M2Quads_BuildPseudoBy (void)
18790 : : {
18791 : 2244 : unsigned int expr;
18792 : 2244 : unsigned int type;
18793 : 2244 : unsigned int dotok;
18794 : :
18795 : : /* As there is no BY token this position is the DO at the end of the last expression. */
18796 : 2244 : M2Quads_PopTFtok (&expr, &type, &dotok);
18797 : 2244 : M2Quads_PushTFtok (expr, type, dotok);
18798 : 2244 : if (type == SymbolTable_NulSym)
18799 : : {} /* empty. */
18800 : : /* Use type. */
18801 : 2024 : else if ((SymbolTable_IsEnumeration (SymbolTable_SkipType (type))) || ((SymbolTable_SkipType (type)) == M2Base_Char))
18802 : : {
18803 : : /* avoid dangling else. */
18804 : : }
18805 : 1804 : else if (M2Base_IsOrdinalType (SymbolTable_SkipType (type)))
18806 : : {
18807 : : /* avoid dangling else. */
18808 : 1804 : type = M2Base_ZType;
18809 : : }
18810 : 2244 : PushOne (dotok, type, (const char *) "the implied {%kFOR} loop increment will cause an overflow {%1ad}", 64);
18811 : 2244 : }
18812 : :
18813 : :
18814 : : /*
18815 : : BuildEndFor - Builds the End part of the For statement
18816 : : from the quad stack.
18817 : : The Stack is expected to contain:
18818 : :
18819 : :
18820 : : Entry Exit
18821 : : ===== ====
18822 : :
18823 : : Ptr ->
18824 : : +----------------+
18825 : : | RangeId |
18826 : : |----------------|
18827 : : | ForQuad |
18828 : : |----------------|
18829 : : | LastValue |
18830 : : |----------------|
18831 : : | BySym | ByType |
18832 : : |----------------|
18833 : : | IdSym | Empty
18834 : : |----------------|
18835 : : */
18836 : :
18837 : 2604 : extern "C" void M2Quads_BuildEndFor (unsigned int endpostok)
18838 : : {
18839 : 2604 : unsigned int t;
18840 : 2604 : unsigned int f;
18841 : 2604 : unsigned int tsym;
18842 : 2604 : unsigned int RangeId;
18843 : 2604 : unsigned int IncQuad;
18844 : 2604 : unsigned int ForQuad;
18845 : 2604 : unsigned int LastSym;
18846 : 2604 : unsigned int ByType;
18847 : 2604 : unsigned int BySym;
18848 : 2604 : unsigned int bytok;
18849 : 2604 : unsigned int IdSym;
18850 : 2604 : unsigned int idtok;
18851 : :
18852 : 2604 : M2Quads_PopT (&RangeId);
18853 : 2604 : M2Quads_PopT (&ForQuad);
18854 : 2604 : M2Quads_PopT (&LastSym);
18855 : 2604 : M2Quads_PopTFtok (&BySym, &ByType, &bytok);
18856 : 2604 : M2Quads_PopTtok (&IdSym, &idtok);
18857 : : /* IF IdSym=LastSym THEN exit END */
18858 : 2604 : M2Quads_PushTF (IdSym, SymbolTable_GetSType (IdSym));
18859 : 2604 : M2Quads_PushT (M2Reserved_EqualTok);
18860 : 2604 : M2Quads_PushTF (LastSym, SymbolTable_GetSType (LastSym));
18861 : 2604 : M2Quads_BuildRelOp (endpostok);
18862 : 2604 : PopBool (&t, &f);
18863 : 2604 : BackPatch (t, NextQuad);
18864 : 2604 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18865 : 2604 : PushFor (Merge (PopFor (), NextQuad-1));
18866 : 2604 : BackPatch (f, NextQuad);
18867 : 2604 : if ((SymbolTable_GetMode (IdSym)) == SymbolTable_LeftValue)
18868 : : {
18869 : : /* index variable is a LeftValue, therefore we must dereference it */
18870 : 0 : tsym = SymbolTable_MakeTemporary (idtok, SymbolTable_RightValue);
18871 : 0 : SymbolTable_PutVar (tsym, SymbolTable_GetSType (IdSym));
18872 : 0 : CheckPointerThroughNil (idtok, IdSym);
18873 : 0 : doIndrX (endpostok, tsym, IdSym);
18874 : 0 : BuildRange (M2Range_InitForLoopEndRangeCheck (tsym, BySym)); /* --fixme-- pass endpostok. */
18875 : 0 : IncQuad = NextQuad;
18876 : : /* we have explicitly checked using the above and also
18877 : : this addition can legitimately overflow if a cardinal type
18878 : : is counting down. The above test will generate a more
18879 : : precise error message, so we suppress overflow detection
18880 : : here. */
18881 : 0 : GenQuadOTypetok (bytok, M2Quads_AddOp, tsym, tsym, BySym, false, false, idtok, idtok, bytok);
18882 : 0 : CheckPointerThroughNil (idtok, IdSym);
18883 : 0 : GenQuadOtok (idtok, M2Quads_XIndrOp, IdSym, SymbolTable_GetSType (IdSym), tsym, false, idtok, idtok, idtok);
18884 : : }
18885 : : else
18886 : : {
18887 : 2604 : BuildRange (M2Range_InitForLoopEndRangeCheck (IdSym, BySym));
18888 : 2604 : IncQuad = NextQuad;
18889 : : /* we have explicitly checked using the above and also
18890 : : this addition can legitimately overflow if a cardinal type
18891 : : is counting down. The above test will generate a more
18892 : : precise error message, so we suppress overflow detection
18893 : : here.
18894 : :
18895 : : This quadruple suppresses the generic binary op type
18896 : : check (performed in M2GenGCC.mod) as there
18897 : : will be a more informative/exhaustive check performed by the
18898 : : InitForLoopBeginRangeCheck setup in BuildForToByDo and
18899 : : performed by M2Range.mod. */
18900 : 2604 : GenQuadOTypetok (idtok, M2Quads_AddOp, IdSym, IdSym, BySym, false, false, idtok, idtok, bytok);
18901 : : }
18902 : 2604 : GenQuadO (endpostok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, ForQuad, false);
18903 : 2604 : BackPatch (PopFor (), NextQuad);
18904 : 2604 : AddForInfo (ForQuad, NextQuad-1, IncQuad, IdSym, idtok);
18905 : 2604 : M2Range_PutRangeForIncrement (RangeId, IncQuad);
18906 : 2604 : }
18907 : :
18908 : :
18909 : : /*
18910 : : BuildCaseStart - starts the case statement.
18911 : : It initializes a backpatch list on the compile
18912 : : time stack, the list is used to contain all
18913 : : case break points. The list is later backpatched
18914 : : and contains all positions of the case statement
18915 : : which jump to the end of the case statement.
18916 : : The stack also contains room for a boolean
18917 : : expression, this is needed to allow , operator
18918 : : in the CaseField alternatives.
18919 : :
18920 : : The Stack is expected to contain:
18921 : :
18922 : :
18923 : : Entry Exit
18924 : : ===== ====
18925 : :
18926 : : <- Ptr
18927 : : +------------+
18928 : : | 0 | 0 |
18929 : : |------------|
18930 : : | 0 | 0 |
18931 : : +-------------+ |------------|
18932 : : | Expr | | | Expr | |
18933 : : |-------------| |------------|
18934 : : */
18935 : :
18936 : 990 : extern "C" void M2Quads_BuildCaseStart (void)
18937 : : {
18938 : 990 : BuildRange (M2Range_InitCaseBounds (M2CaseList_PushCase (SymbolTable_NulSym, SymbolTable_NulSym, M2Quads_OperandT (1))));
18939 : 990 : PushBool (0, 0); /* BackPatch list initialized */
18940 : 990 : PushBool (0, 0); /* Room for a boolean expression */
18941 : 990 : }
18942 : :
18943 : :
18944 : : /*
18945 : : BuildCaseStartStatementSequence - starts the statement sequence
18946 : : inside a case clause.
18947 : : BackPatches the true exit to the
18948 : : NextQuad.
18949 : : The Stack:
18950 : :
18951 : : Entry Exit
18952 : :
18953 : : Ptr -> <- Ptr
18954 : : +-----------+ +------------+
18955 : : | t | f | | 0 | f |
18956 : : |-----------| |------------|
18957 : : */
18958 : :
18959 : 3856 : extern "C" void M2Quads_BuildCaseStartStatementSequence (void)
18960 : : {
18961 : 3856 : unsigned int t;
18962 : 3856 : unsigned int f;
18963 : :
18964 : 3856 : PopBool (&t, &f);
18965 : 3856 : BackPatch (t, NextQuad);
18966 : 3856 : PushBool (0, f);
18967 : 3856 : }
18968 : :
18969 : :
18970 : : /*
18971 : : BuildCaseEndStatementSequence - ends the statement sequence
18972 : : inside a case clause.
18973 : : BackPatches the false exit f1 to the
18974 : : NextQuad.
18975 : : Asserts that t1 and f2 is 0
18976 : : Pushes t2+q and 0
18977 : :
18978 : : Quadruples:
18979 : :
18980 : : q GotoOp _ _ 0
18981 : :
18982 : : The Stack:
18983 : :
18984 : : Entry Exit
18985 : :
18986 : : Ptr -> <- Ptr
18987 : : +-----------+ +------------+
18988 : : | t1 | f1 | | 0 | 0 |
18989 : : |-----------| |------------|
18990 : : | t2 | f2 | | t2+q | 0 |
18991 : : |-----------| |------------|
18992 : : */
18993 : :
18994 : 3856 : extern "C" void M2Quads_BuildCaseEndStatementSequence (void)
18995 : : {
18996 : 3856 : unsigned int t1;
18997 : 3856 : unsigned int f1;
18998 : 3856 : unsigned int t2;
18999 : 3856 : unsigned int f2;
19000 : :
19001 : 3856 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
19002 : 3856 : PopBool (&t1, &f1);
19003 : 3856 : PopBool (&t2, &f2); /* t2 contains the break list for the case */
19004 : 3856 : BackPatch (f1, NextQuad); /* f1 no longer needed */
19005 : 3856 : M2Debug_Assert (t1 == 0); /* f1 no longer needed */
19006 : 3856 : M2Debug_Assert (f2 == 0);
19007 : 3856 : PushBool (Merge (t2, NextQuad-1), 0); /* NextQuad-1 = Goto Quad */
19008 : 3856 : PushBool (0, 0); /* Room for boolean expression */
19009 : 3856 : }
19010 : :
19011 : :
19012 : : /*
19013 : : BuildCaseRange - builds the range testing quaruples for
19014 : : a case clause.
19015 : :
19016 : : IF (e1>=ce1) AND (e1<=ce2)
19017 : : THEN
19018 : :
19019 : : ELS..
19020 : :
19021 : : The Stack:
19022 : :
19023 : : Entry Exit
19024 : :
19025 : : Ptr ->
19026 : : +-----------+
19027 : : | ce2 | <- Ptr
19028 : : |-----------| +-----------+
19029 : : | ce1 | | t | f |
19030 : : |-----------| |-----------|
19031 : : | t1 | f1 | | t1 | f1 |
19032 : : |-----------| |-----------|
19033 : : | t2 | f2 | | t2 | f2 |
19034 : : |-----------| |-----------|
19035 : : | e1 | | e1 |
19036 : : |-----------| |-----------|
19037 : : */
19038 : :
19039 : 172 : extern "C" void M2Quads_BuildCaseRange (void)
19040 : : {
19041 : 172 : unsigned int ce1;
19042 : 172 : unsigned int ce2;
19043 : 172 : unsigned int combinedtok;
19044 : 172 : unsigned int ce1tok;
19045 : 172 : unsigned int ce2tok;
19046 : 172 : unsigned int e1tok;
19047 : 172 : unsigned int e1;
19048 : 172 : unsigned int t2;
19049 : 172 : unsigned int f2;
19050 : 172 : unsigned int t1;
19051 : 172 : unsigned int f1;
19052 : :
19053 : 172 : M2Quads_PopTtok (&ce2, &ce2tok);
19054 : 172 : M2Quads_PopTtok (&ce1, &ce1tok);
19055 : 172 : combinedtok = M2LexBuf_MakeVirtualTok (ce2tok, ce2tok, ce1tok);
19056 : 172 : M2CaseList_AddRange (ce1, ce2, combinedtok);
19057 : 172 : PopBool (&t1, &f1);
19058 : 172 : PopBool (&t2, &f2);
19059 : 172 : M2Quads_PopTtok (&e1, &e1tok);
19060 : 172 : M2Quads_PushTtok (e1, e1tok); /* leave e1 on bottom of stack when exit procedure */
19061 : 172 : PushBool (t2, f2); /* leave e1 on bottom of stack when exit procedure */
19062 : 172 : PushBool (t1, f1); /* also leave t1 and f1 on the bottom of the stack */
19063 : 172 : M2Quads_PushTtok (e1, e1tok); /* also leave t1 and f1 on the bottom of the stack */
19064 : 172 : M2Quads_PushT (M2Reserved_GreaterEqualTok);
19065 : 172 : M2Quads_PushTtok (ce1, ce1tok);
19066 : 172 : M2Quads_BuildRelOp (combinedtok);
19067 : 172 : M2Quads_PushT (M2Reserved_AndTok);
19068 : 172 : M2Quads_RecordOp ();
19069 : 172 : M2Quads_PushTtok (e1, e1tok);
19070 : 172 : M2Quads_PushT (M2Reserved_LessEqualTok);
19071 : 172 : M2Quads_PushTtok (ce2, ce2tok);
19072 : 172 : M2Quads_BuildRelOp (combinedtok);
19073 : 172 : M2Quads_BuildBinaryOp ();
19074 : 172 : }
19075 : :
19076 : :
19077 : : /*
19078 : : BuildCaseEquality - builds the range testing quadruples for
19079 : : a case clause.
19080 : :
19081 : : IF e1=ce1
19082 : : THEN
19083 : :
19084 : : ELS..
19085 : :
19086 : : The Stack:
19087 : :
19088 : : Entry Exit
19089 : :
19090 : : Ptr ->
19091 : : +-----------+ +-----------+
19092 : : | ce1 | | t | f |
19093 : : |-----------| |-----------|
19094 : : | t1 | f1 | | t1 | f1 |
19095 : : |-----------| |-----------|
19096 : : | t2 | f2 | | t2 | f2 |
19097 : : |-----------| |-----------|
19098 : : | e1 | | e1 |
19099 : : |-----------| |-----------|
19100 : : */
19101 : :
19102 : 3734 : extern "C" void M2Quads_BuildCaseEquality (void)
19103 : : {
19104 : 3734 : unsigned int ce1tok;
19105 : 3734 : unsigned int e1tok;
19106 : 3734 : unsigned int ce1;
19107 : 3734 : unsigned int e1;
19108 : 3734 : unsigned int t2;
19109 : 3734 : unsigned int f2;
19110 : 3734 : unsigned int t1;
19111 : 3734 : unsigned int f1;
19112 : :
19113 : 3734 : M2Quads_PopTtok (&ce1, &ce1tok);
19114 : 3734 : M2CaseList_AddRange (ce1, SymbolTable_NulSym, ce1tok);
19115 : 3734 : PopBool (&t1, &f1);
19116 : 3734 : PopBool (&t2, &f2);
19117 : 3734 : M2Quads_PopTtok (&e1, &e1tok);
19118 : 3734 : M2Quads_PushTtok (e1, e1tok); /* leave e1 on bottom of stack when exit procedure */
19119 : 3734 : PushBool (t2, f2); /* also leave t2 and f2 on the bottom of the stack */
19120 : 3734 : PushBool (t1, f1); /* also leave t2 and f2 on the bottom of the stack */
19121 : 3734 : M2Quads_PushTtok (e1, e1tok);
19122 : 3734 : M2Quads_PushT (M2Reserved_EqualTok);
19123 : 3734 : M2Quads_PushTtok (ce1, ce1tok);
19124 : 3734 : M2Quads_BuildRelOp (ce1tok);
19125 : 3734 : }
19126 : :
19127 : :
19128 : : /*
19129 : : BuildCaseList - merges two case tests into one
19130 : :
19131 : : The Stack:
19132 : :
19133 : : Entry Exit
19134 : :
19135 : : Ptr ->
19136 : : +-----------+
19137 : : | t2 | f2 |
19138 : : |-----------| +-------------+
19139 : : | t1 | f1 | | t1+t2| f1+f2|
19140 : : |-----------| |-------------|
19141 : : */
19142 : :
19143 : 3906 : extern "C" void M2Quads_BuildCaseList (void)
19144 : : {
19145 : 3906 : unsigned int t2;
19146 : 3906 : unsigned int f2;
19147 : 3906 : unsigned int t1;
19148 : 3906 : unsigned int f1;
19149 : :
19150 : 3906 : PopBool (&t2, &f2);
19151 : 3906 : PopBool (&t1, &f1);
19152 : 3906 : PushBool (Merge (t1, t2), Merge (f1, f2));
19153 : 3906 : }
19154 : :
19155 : :
19156 : : /*
19157 : : BuildCaseOr - builds the , in the case clause.
19158 : :
19159 : : The Stack:
19160 : :
19161 : : Entry Exit
19162 : :
19163 : : Ptr -> <- Ptr
19164 : : +-----------+ +------------+
19165 : : | t | f | | t | 0 |
19166 : : |-----------| |------------|
19167 : : */
19168 : :
19169 : 50 : extern "C" void M2Quads_BuildCaseOr (void)
19170 : : {
19171 : 50 : unsigned int t;
19172 : 50 : unsigned int f;
19173 : :
19174 : 50 : PopBool (&t, &f);
19175 : 50 : BackPatch (f, NextQuad);
19176 : 50 : PushBool (t, 0);
19177 : 50 : }
19178 : :
19179 : :
19180 : : /*
19181 : : BuildCaseElse - builds the else of case clause.
19182 : :
19183 : : The Stack:
19184 : :
19185 : : Entry Exit
19186 : :
19187 : : Ptr -> <- Ptr
19188 : : +-----------+ +------------+
19189 : : | t | f | | t | 0 |
19190 : : |-----------| |------------|
19191 : : */
19192 : :
19193 : 990 : extern "C" void M2Quads_BuildCaseElse (void)
19194 : : {
19195 : 990 : unsigned int t;
19196 : 990 : unsigned int f;
19197 : :
19198 : 990 : PopBool (&t, &f);
19199 : 990 : BackPatch (f, NextQuad);
19200 : 990 : PushBool (t, 0);
19201 : 990 : }
19202 : :
19203 : :
19204 : : /*
19205 : : BuildCaseEnd - builds the end of case clause.
19206 : :
19207 : : The Stack:
19208 : :
19209 : : Entry Exit
19210 : :
19211 : : Ptr ->
19212 : : +-----------+
19213 : : | t1 | f1 |
19214 : : |-----------|
19215 : : | t2 | f2 |
19216 : : |-----------|
19217 : : | e1 |
19218 : : |-----------| Empty
19219 : : */
19220 : :
19221 : 990 : extern "C" void M2Quads_BuildCaseEnd (void)
19222 : : {
19223 : 990 : unsigned int e1;
19224 : 990 : unsigned int t;
19225 : 990 : unsigned int f;
19226 : :
19227 : 990 : PopBool (&t, &f);
19228 : 990 : BackPatch (f, NextQuad);
19229 : 990 : BackPatch (t, NextQuad);
19230 : 990 : PopBool (&t, &f);
19231 : 990 : BackPatch (f, NextQuad);
19232 : 990 : BackPatch (t, NextQuad);
19233 : 990 : M2Quads_PopT (&e1);
19234 : 990 : M2CaseList_PopCase ();
19235 : 990 : }
19236 : :
19237 : :
19238 : : /*
19239 : : BuildCaseCheck - builds the case checking code to ensure that
19240 : : the program does not need an else clause at runtime.
19241 : : The stack is unaltered.
19242 : : */
19243 : :
19244 : 482 : extern "C" void M2Quads_BuildCaseCheck (void)
19245 : : {
19246 : 482 : BuildError (M2Range_InitNoElseRangeCheck ());
19247 : 482 : }
19248 : :
19249 : :
19250 : : /*
19251 : : BuildNulParam - Builds a nul parameter on the stack.
19252 : : The Stack:
19253 : :
19254 : : Entry Exit
19255 : :
19256 : : <- Ptr
19257 : : Empty +------------+
19258 : : | 0 |
19259 : : |------------|
19260 : : */
19261 : :
19262 : 18493 : extern "C" void M2Quads_BuildNulParam (void)
19263 : : {
19264 : 18493 : M2Quads_PushT (static_cast<unsigned int> (0));
19265 : 18493 : }
19266 : :
19267 : :
19268 : : /*
19269 : : BuildProcedureCall - builds a procedure call.
19270 : : Although this procedure does not directly
19271 : : destroy the procedure parameters, it calls
19272 : : routine which will manipulate the stack and
19273 : : so the entry and exit states of the stack are shown.
19274 : :
19275 : : The Stack:
19276 : :
19277 : :
19278 : : Entry Exit
19279 : :
19280 : : Ptr ->
19281 : : +----------------+
19282 : : | NoOfParam |
19283 : : |----------------|
19284 : : | Param 1 |
19285 : : |----------------|
19286 : : | Param 2 |
19287 : : |----------------|
19288 : : . .
19289 : : . .
19290 : : . .
19291 : : |----------------|
19292 : : | Param # |
19293 : : |----------------|
19294 : : | ProcSym | Type | Empty
19295 : : |----------------|
19296 : : */
19297 : :
19298 : 178930 : extern "C" void M2Quads_BuildProcedureCall (unsigned int tokno)
19299 : : {
19300 : 178930 : unsigned int NoOfParam;
19301 : 178930 : unsigned int ProcSym;
19302 : :
19303 : 178930 : M2Quads_PopT (&NoOfParam);
19304 : 178930 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
19305 : 178930 : M2Quads_PushT (NoOfParam); /* Compile time stack restored to entry state */
19306 : 178930 : if ((M2Base_IsPseudoBaseProcedure (ProcSym)) || (M2System_IsPseudoSystemProcedure (ProcSym))) /* Compile time stack restored to entry state */
19307 : : {
19308 : 21502 : M2Quads_DisplayStack ();
19309 : 21502 : ManipulatePseudoCallParameters ();
19310 : 21502 : M2Quads_DisplayStack ();
19311 : 21502 : BuildPseudoProcedureCall (tokno);
19312 : 21502 : M2Quads_DisplayStack ();
19313 : : }
19314 : 157428 : else if (SymbolTable_IsUnknown (ProcSym))
19315 : : {
19316 : : /* avoid dangling else. */
19317 : : /* Spellcheck. */
19318 : 24 : M2MetaError_MetaError1 ((const char *) "{%1Ua} is not recognised as a procedure {%1&s}", 46, ProcSym);
19319 : 24 : M2Quads_PopN (NoOfParam+2);
19320 : 24 : SymbolTable_UnknownReported (ProcSym);
19321 : : }
19322 : : else
19323 : : {
19324 : : /* avoid dangling else. */
19325 : 157404 : M2Quads_DisplayStack ();
19326 : 157404 : BuildRealProcedureCall (tokno);
19327 : 157398 : M2Quads_DisplayStack ();
19328 : : }
19329 : 178924 : }
19330 : :
19331 : :
19332 : : /*
19333 : : CheckBuildFunction - checks to see whether ProcSym is a function
19334 : : and if so it adds a TempSym value which will
19335 : : hold the return value once the function finishes.
19336 : : This procedure also generates an error message
19337 : : if the user is calling a function and ignoring
19338 : : the return result. The additional TempSym
19339 : : is not created if ProcSym is a procedure
19340 : : and the stack is unaltered.
19341 : :
19342 : : The Stack:
19343 : :
19344 : :
19345 : : Entry Exit
19346 : :
19347 : : Ptr ->
19348 : :
19349 : : +----------------+
19350 : : | ProcSym | Type |
19351 : : +----------------+ |----------------|
19352 : : | ProcSym | Type | | TempSym | Type |
19353 : : |----------------| |----------------|
19354 : : */
19355 : :
19356 : 107339 : extern "C" bool M2Quads_CheckBuildFunction (void)
19357 : : {
19358 : 107339 : unsigned int tokpos;
19359 : 107339 : unsigned int TempSym;
19360 : 107339 : unsigned int ProcSym;
19361 : 107339 : unsigned int Type;
19362 : :
19363 : 107339 : M2Quads_PopTFtok (&ProcSym, &Type, &tokpos);
19364 : 107339 : if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (Type)))
19365 : : {
19366 : : /* avoid dangling else. */
19367 : 672 : if ((SymbolTable_GetSType (Type)) != SymbolTable_NulSym)
19368 : : {
19369 : 0 : TempSym = SymbolTable_MakeTemporary (tokpos, SymbolTable_RightValue);
19370 : 0 : SymbolTable_PutVar (TempSym, SymbolTable_GetSType (Type));
19371 : 0 : M2Quads_PushTFtok (TempSym, SymbolTable_GetSType (Type), tokpos);
19372 : 0 : M2Quads_PushTFtok (ProcSym, Type, tokpos);
19373 : 0 : if (! (SymbolTable_IsReturnOptionalAny (Type)))
19374 : : {
19375 : 0 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "function {%1Ea} is called but its return value is ignored", 57, ProcSym);
19376 : : }
19377 : 0 : return true;
19378 : : }
19379 : : }
19380 : 106667 : else if ((SymbolTable_IsProcedure (ProcSym)) && (Type != SymbolTable_NulSym))
19381 : : {
19382 : : /* avoid dangling else. */
19383 : 0 : TempSym = SymbolTable_MakeTemporary (tokpos, SymbolTable_RightValue);
19384 : 0 : SymbolTable_PutVar (TempSym, Type);
19385 : 0 : M2Quads_PushTFtok (TempSym, Type, tokpos);
19386 : 0 : M2Quads_PushTFtok (ProcSym, Type, tokpos);
19387 : 0 : if (! (SymbolTable_IsReturnOptionalAny (ProcSym)))
19388 : : {
19389 : 0 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "function {%1Ea} is called but its return value is ignored", 57, ProcSym);
19390 : : }
19391 : 0 : return true;
19392 : : }
19393 : 107339 : M2Quads_PushTFtok (ProcSym, Type, tokpos);
19394 : 107339 : return false;
19395 : : /* static analysis guarentees a RETURN statement will be used before here. */
19396 : : __builtin_unreachable ();
19397 : : }
19398 : :
19399 : :
19400 : : /*
19401 : : BuildFunctionCall - builds a function call.
19402 : : The Stack:
19403 : :
19404 : :
19405 : : Entry Exit
19406 : :
19407 : : Ptr ->
19408 : : +----------------+
19409 : : | NoOfParam |
19410 : : |----------------|
19411 : : | Param 1 |
19412 : : |----------------|
19413 : : | Param 2 |
19414 : : |----------------|
19415 : : . .
19416 : : . .
19417 : : . .
19418 : : |----------------|
19419 : : | Param # | <- Ptr
19420 : : |----------------| +------------+
19421 : : | ProcSym | Type | | ReturnVar |
19422 : : |----------------| |------------|
19423 : : */
19424 : :
19425 : 106502 : extern "C" void M2Quads_BuildFunctionCall (bool ConstExpr)
19426 : : {
19427 : 106502 : unsigned int paramtok;
19428 : 106502 : unsigned int combinedtok;
19429 : 106502 : unsigned int functok;
19430 : 106502 : unsigned int NoOfParam;
19431 : 106502 : unsigned int ProcSym;
19432 : :
19433 : 106502 : M2Quads_PopT (&NoOfParam);
19434 : 106502 : functok = OperandTtok (NoOfParam+1);
19435 : 106502 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
19436 : 106502 : ProcSym = PCSymBuild_SkipConst (ProcSym);
19437 : 106502 : M2Quads_PushT (NoOfParam);
19438 : : /* Compile time stack restored to entry state. */
19439 : 106502 : if (SymbolTable_IsUnknown (ProcSym))
19440 : : {
19441 : : /* Spellcheck. */
19442 : 6 : paramtok = OperandTtok (1);
19443 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, paramtok);
19444 : 6 : M2MetaError_MetaErrorT1 (functok, (const char *) "procedure function {%1Ea} is undefined {%1&s}", 45, ProcSym);
19445 : 6 : SymbolTable_UnknownReported (ProcSym);
19446 : 6 : M2Quads_PopN (NoOfParam+2);
19447 : : /* Fake return value to continue compiling. */
19448 : 6 : M2Quads_PushT (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym));
19449 : : }
19450 : 106496 : else if (SymbolTable_IsAModula2Type (ProcSym))
19451 : : {
19452 : : /* avoid dangling else. */
19453 : 2508 : ManipulatePseudoCallParameters ();
19454 : 2508 : BuildTypeCoercion (ConstExpr);
19455 : : }
19456 : 103988 : else if ((M2System_IsPseudoSystemFunction (ProcSym)) || (M2Base_IsPseudoBaseFunction (ProcSym)))
19457 : : {
19458 : : /* avoid dangling else. */
19459 : 42534 : ManipulatePseudoCallParameters ();
19460 : 42534 : BuildPseudoFunctionCall (ConstExpr);
19461 : : }
19462 : : else
19463 : : {
19464 : : /* avoid dangling else. */
19465 : 61454 : BuildRealFunctionCall (functok, ConstExpr);
19466 : : }
19467 : 106478 : }
19468 : :
19469 : :
19470 : : /*
19471 : : BuildConstFunctionCall - builds a function call and checks that this function can be
19472 : : called inside a ConstExpression.
19473 : :
19474 : : The Stack:
19475 : :
19476 : :
19477 : : Entry Exit
19478 : :
19479 : : Ptr ->
19480 : : +----------------+
19481 : : | NoOfParam |
19482 : : |----------------|
19483 : : | Param 1 |
19484 : : |----------------|
19485 : : | Param 2 |
19486 : : |----------------|
19487 : : . .
19488 : : . .
19489 : : . .
19490 : : |----------------|
19491 : : | Param # | <- Ptr
19492 : : |----------------| +------------+
19493 : : | ProcSym | Type | | ReturnVar |
19494 : : |----------------| |------------|
19495 : :
19496 : : */
19497 : :
19498 : 7262 : extern "C" void M2Quads_BuildConstFunctionCall (void)
19499 : : {
19500 : 7262 : unsigned int functok;
19501 : 7262 : unsigned int combinedtok;
19502 : 7262 : unsigned int paramtok;
19503 : 7262 : unsigned int ConstExpression;
19504 : 7262 : unsigned int NoOfParam;
19505 : 7262 : unsigned int ProcSym;
19506 : :
19507 : 7262 : M2Quads_DisplayStack ();
19508 : 7262 : M2Quads_PopT (&NoOfParam);
19509 : 7262 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
19510 : 7262 : functok = OperandTtok (NoOfParam+1);
19511 : 7262 : if (M2Options_CompilerDebugging)
19512 : : {
19513 : 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));
19514 : : }
19515 : : /* ErrorStringAt (InitString ('constant function'), functok). */
19516 : 7262 : M2Quads_PushT (NoOfParam);
19517 : 7262 : if ((ProcSym != M2Base_Convert) && (((M2Base_IsPseudoBaseFunction (ProcSym)) || (M2System_IsPseudoSystemFunctionConstExpression (ProcSym))) || ((SymbolTable_IsProcedure (ProcSym)) && (SymbolTable_IsProcedureBuiltin (ProcSym)))))
19518 : : {
19519 : 7130 : M2Quads_BuildFunctionCall (true);
19520 : : }
19521 : : else
19522 : : {
19523 : 132 : if (SymbolTable_IsAModula2Type (ProcSym))
19524 : : {
19525 : : /* Type conversion. */
19526 : 132 : if (NoOfParam == 1)
19527 : : {
19528 : 132 : ConstExpression = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
19529 : 132 : paramtok = OperandTtok (NoOfParam+1);
19530 : 132 : M2Quads_PopN (NoOfParam+2);
19531 : : /* Build macro: CONVERT( ProcSym, ConstExpression ). */
19532 : 132 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
19533 : 132 : M2Quads_PushTtok (ProcSym, functok);
19534 : 132 : M2Quads_PushTtok (ConstExpression, paramtok);
19535 : 132 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters. */
19536 : 132 : BuildConvertFunction (M2Base_Convert, true); /* Two parameters. */
19537 : : }
19538 : : else
19539 : : {
19540 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}a constant type conversion can only have one argument", 57);
19541 : : }
19542 : : }
19543 : : else
19544 : : {
19545 : : /* Error issue message and fake return stack. */
19546 : 0 : if (M2Options_Iso)
19547 : : {
19548 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the only functions permissible in a constant expression are: {%kCAP}, {%kCHR}, {%kCMPLX}, {%kFLOAT}, {%kHIGH}, {%kIM}, {%kLENGTH}, {%kMAX}, {%kMIN}, {%kODD}, {%kORD}, {%kRE}, {%kSIZE}, {%kTSIZE}, {%kTBITSIZE}, {%kTRUNC}, {%kVAL} and gcc builtins", 245);
19549 : : }
19550 : : else
19551 : : {
19552 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the only functions permissible in a constant expression are: {%kCAP}, {%kCHR}, {%kFLOAT}, {%kHIGH}, {%kMAX}, {%kMIN}, {%kODD}, {%kORD}, {%kSIZE}, {%kTSIZE}, {%kTRUNC}, {%kTBITSIZE}, {%kVAL} and gcc builtins", 206);
19553 : : }
19554 : 0 : if (NoOfParam > 0)
19555 : : {
19556 : 0 : paramtok = OperandTtok (NoOfParam+1);
19557 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
19558 : : }
19559 : : else
19560 : : {
19561 : 0 : combinedtok = functok;
19562 : : }
19563 : 0 : M2Quads_PopN (NoOfParam+2);
19564 : 0 : M2Quads_PushT (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym)); /* Fake return value to continue compiling. */
19565 : : }
19566 : : }
19567 : 7262 : }
19568 : :
19569 : :
19570 : : /*
19571 : : BuildBooleanVariable - tests to see whether top of stack is a boolean
19572 : : conditional and if so it converts it into a boolean
19573 : : variable.
19574 : : */
19575 : :
19576 : 359975 : extern "C" void M2Quads_BuildBooleanVariable (void)
19577 : : {
19578 : 359975 : if (IsBoolean (1))
19579 : : {
19580 : 7238 : ConvertBooleanToVariable (OperandTtok (1), 1);
19581 : : }
19582 : 359975 : }
19583 : :
19584 : :
19585 : : /*
19586 : : BuildModuleStart - starts current module scope.
19587 : : */
19588 : :
19589 : 83157 : extern "C" void M2Quads_BuildModuleStart (unsigned int tok)
19590 : : {
19591 : 83157 : GenQuadO (tok, M2Quads_ModuleScopeOp, tok, (unsigned int ) (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()))), SymbolTable_GetCurrentModule (), false);
19592 : 83157 : }
19593 : :
19594 : :
19595 : : /*
19596 : : BuildProcedureStart - Builds start of the procedure. Generates a
19597 : : quadruple which indicated the start of
19598 : : this procedure declarations scope.
19599 : : The Stack is expected to contain:
19600 : :
19601 : :
19602 : : Entry Exit
19603 : : ===== ====
19604 : :
19605 : : Ptr -> <- Ptr
19606 : : +------------+ +-----------+
19607 : : | ProcSym | | ProcSym |
19608 : : |------------| |-----------|
19609 : : | Name | | Name |
19610 : : |------------| |-----------|
19611 : :
19612 : :
19613 : : Quadruples:
19614 : :
19615 : : q ProcedureScopeOp Line# Scope ProcSym
19616 : : */
19617 : :
19618 : 80970 : extern "C" void M2Quads_BuildProcedureStart (void)
19619 : : {
19620 : 80970 : unsigned int ProcSym;
19621 : :
19622 : 80970 : M2Quads_PopT (&ProcSym);
19623 : 80970 : M2Debug_Assert (SymbolTable_IsProcedure (ProcSym));
19624 : 80970 : SymbolTable_PutProcedureScopeQuad (ProcSym, NextQuad);
19625 : 80970 : GenQuad (M2Quads_ProcedureScopeOp, M2LexBuf_GetPreviousTokenLineNo (), SymbolTable_GetScope (ProcSym), ProcSym);
19626 : 80970 : M2Quads_PushT (ProcSym);
19627 : 80970 : }
19628 : :
19629 : :
19630 : : /*
19631 : : BuildProcedureBegin - determines the start of the BEGIN END block of
19632 : : the procedure.
19633 : : The Stack is expected to contain:
19634 : :
19635 : :
19636 : : Entry Exit
19637 : : ===== ====
19638 : :
19639 : : Ptr -> <- Ptr
19640 : : +------------+ +-----------+
19641 : : | ProcSym | | ProcSym |
19642 : : |------------| |-----------|
19643 : : | Name | | Name |
19644 : : |------------| |-----------|
19645 : :
19646 : :
19647 : : Quadruples:
19648 : :
19649 : : q NewLocalVarOp TokenNo(BEGIN) _ ProcSym
19650 : : */
19651 : :
19652 : 80958 : extern "C" void M2Quads_BuildProcedureBegin (void)
19653 : : {
19654 : 80958 : unsigned int ProcSym;
19655 : :
19656 : 80958 : M2Quads_PopT (&ProcSym);
19657 : 80958 : M2Debug_Assert (SymbolTable_IsProcedure (ProcSym));
19658 : 80958 : SymbolTable_PutProcedureStartQuad (ProcSym, NextQuad);
19659 : 80958 : SymbolTable_PutProcedureBegin (ProcSym, M2LexBuf_GetTokenNo ());
19660 : 80958 : GenQuad (M2Quads_NewLocalVarOp, M2LexBuf_GetTokenNo (), SymbolTable_GetScope (ProcSym), ProcSym);
19661 : 80958 : CurrentProc = ProcSym;
19662 : 80958 : M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
19663 : 80958 : M2Quads_PushT (ProcSym);
19664 : 80958 : CheckVariablesAt (ProcSym);
19665 : 80958 : CheckNeedPriorityBegin (M2LexBuf_GetTokenNo (), ProcSym, SymbolTable_GetCurrentModule ());
19666 : 80958 : M2StackWord_PushWord (TryStack, NextQuad);
19667 : 80958 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
19668 : 80958 : if (SymbolTable_HasExceptionBlock (ProcSym))
19669 : : {
19670 : 168 : GenQuad (M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
19671 : : }
19672 : 80958 : }
19673 : :
19674 : :
19675 : : /*
19676 : : BuildProcedureEnd - Builds end of the procedure. Destroys space for
19677 : : the local variables.
19678 : : The Stack is expected to contain:
19679 : :
19680 : :
19681 : : Entry Exit
19682 : : ===== ====
19683 : :
19684 : : Ptr -> <- Ptr
19685 : : +------------+ +-----------+
19686 : : | ProcSym | | ProcSym |
19687 : : |------------| |-----------|
19688 : : | Name | | Name |
19689 : : |------------| |-----------|
19690 : :
19691 : :
19692 : : Quadruples:
19693 : :
19694 : : q KillLocalVarOp TokenNo(END) _ ProcSym
19695 : : */
19696 : :
19697 : 80928 : extern "C" void M2Quads_BuildProcedureEnd (void)
19698 : : {
19699 : 80928 : unsigned int tok;
19700 : 80928 : unsigned int ProcSym;
19701 : :
19702 : 80928 : M2Quads_PopTtok (&ProcSym, &tok);
19703 : 80928 : if (SymbolTable_HasExceptionBlock (ProcSym))
19704 : : {
19705 : 168 : BuildRTExceptLeave (tok, true);
19706 : 168 : GenQuad (M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
19707 : : }
19708 : 80928 : if ((SymbolTable_GetSType (ProcSym)) != SymbolTable_NulSym)
19709 : : {
19710 : 18963 : BuildError (M2Range_InitNoReturnRangeCheck ());
19711 : : }
19712 : 80928 : BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
19713 : 80928 : CheckNeedPriorityEnd (tok, ProcSym, SymbolTable_GetCurrentModule ());
19714 : 80928 : CurrentProc = SymbolTable_NulSym;
19715 : 80928 : SymbolTable_PutProcedureEnd (ProcSym, (M2LexBuf_GetTokenNo ())-1); /* --fixme-- */
19716 : 80928 : GenQuad (M2Quads_KillLocalVarOp, (M2LexBuf_GetTokenNo ())-1, SymbolTable_NulSym, ProcSym); /* --fixme-- */
19717 : 80928 : SymbolTable_PutProcedureEndQuad (ProcSym, NextQuad);
19718 : 80928 : GenQuad (M2Quads_ReturnOp, SymbolTable_NulSym, SymbolTable_NulSym, ProcSym);
19719 : 80928 : CheckFunctionReturn (ProcSym);
19720 : 80928 : CheckVariablesInBlock (ProcSym);
19721 : : /* Call PutProcedureEndQuad so that any runtime procedure will be
19722 : : seen as defined even if it not seen during pass 2 (which will also
19723 : : call PutProcedureEndQuad). */
19724 : 80928 : SymbolTable_PutProcedureParametersDefined (ProcSym, SymbolTable_ProperProcedure);
19725 : 80928 : SymbolTable_PutProcedureDefined (ProcSym, SymbolTable_ProperProcedure);
19726 : 80928 : M2StackWord_RemoveTop (CatchStack);
19727 : 80928 : M2StackWord_RemoveTop (TryStack);
19728 : 80928 : M2Quads_PushT (ProcSym);
19729 : 80928 : }
19730 : :
19731 : :
19732 : : /*
19733 : : BuildReturn - Builds the Return part of the procedure.
19734 : : tokreturn is the location of the RETURN keyword.
19735 : : The Stack is expected to contain:
19736 : :
19737 : :
19738 : : Entry Exit
19739 : : ===== ====
19740 : :
19741 : : Ptr ->
19742 : : +------------+
19743 : : | e1 | Empty
19744 : : |------------|
19745 : : */
19746 : :
19747 : 28543 : extern "C" void M2Quads_BuildReturn (unsigned int tokreturn)
19748 : : {
19749 : 28543 : unsigned int tokcombined;
19750 : 28543 : unsigned int tokexpr;
19751 : 28543 : unsigned int e1;
19752 : 28543 : unsigned int t1;
19753 : 28543 : unsigned int t;
19754 : 28543 : unsigned int f;
19755 : 28543 : unsigned int Des;
19756 : :
19757 : 28543 : if (IsBoolean (1))
19758 : : {
19759 : 1776 : PopBooltok (&t, &f, &tokexpr);
19760 : : /* Des will be a boolean type */
19761 : 1776 : Des = SymbolTable_MakeTemporary (tokexpr, SymbolTable_RightValue);
19762 : 1776 : SymbolTable_PutVar (Des, M2Base_Boolean);
19763 : 1776 : M2Quads_PushTFtok (Des, M2Base_Boolean, tokexpr);
19764 : 1776 : PushBooltok (t, f, tokexpr);
19765 : 1776 : BuildAssignmentWithoutBounds (tokreturn, false, true);
19766 : 1776 : M2Quads_PushTFtok (Des, M2Base_Boolean, tokexpr);
19767 : : }
19768 : 28543 : M2Quads_PopTFtok (&e1, &t1, &tokexpr);
19769 : 28543 : tokcombined = M2LexBuf_MakeVirtualTok (tokreturn, tokreturn, tokexpr);
19770 : 28543 : if (e1 != SymbolTable_NulSym)
19771 : : {
19772 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
19773 : : /* Check we are in a procedure scope and that the procedure has a return type. */
19774 : 27691 : if (CurrentProc == SymbolTable_NulSym)
19775 : : {
19776 : 6 : M2MetaError_MetaErrorT0 (tokcombined, (const char *) "{%1E} attempting to return a value when not in a procedure scope", 64);
19777 : : }
19778 : 27685 : else if ((SymbolTable_GetSType (CurrentProc)) == SymbolTable_NulSym)
19779 : : {
19780 : : /* avoid dangling else. */
19781 : 6 : M2MetaError_MetaErrorT1 (tokcombined, (const char *) "attempting to return a value from procedure {%1Ea} which does not have a return type", 84, CurrentProc);
19782 : : }
19783 : : else
19784 : : {
19785 : : /* avoid dangling else. */
19786 : 27679 : BuildReturnLower (tokcombined, tokexpr, e1, t1);
19787 : : }
19788 : : }
19789 : 28543 : GenQuadO (tokcombined, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PopWord (ReturnStack), false);
19790 : 28543 : M2StackWord_PushWord (ReturnStack, NextQuad-1);
19791 : 28543 : }
19792 : :
19793 : :
19794 : : /*
19795 : : BuildModulePriority - assigns the current module with a priority
19796 : : from the top of stack.
19797 : :
19798 : : Entry Exit
19799 : : ===== ====
19800 : :
19801 : :
19802 : : Ptr -> Empty
19803 : : +------------+
19804 : : | Priority |
19805 : : |------------|
19806 : : */
19807 : :
19808 : 38 : extern "C" void M2Quads_BuildModulePriority (void)
19809 : : {
19810 : 38 : unsigned int Priority;
19811 : :
19812 : 38 : M2Quads_PopT (&Priority);
19813 : 38 : SymbolTable_PutPriority (SymbolTable_GetCurrentModule (), Priority);
19814 : 38 : }
19815 : :
19816 : :
19817 : : /*
19818 : : StartBuildWith - performs the with statement.
19819 : : The Stack:
19820 : :
19821 : : Entry Exit
19822 : :
19823 : : +------------+
19824 : : | Sym | Type | Empty
19825 : : |------------|
19826 : : */
19827 : :
19828 : 6164 : extern "C" void M2Quads_StartBuildWith (unsigned int withTok)
19829 : : {
19830 : 6164 : unsigned int tok;
19831 : 6164 : unsigned int Sym;
19832 : 6164 : unsigned int Type;
19833 : 6164 : unsigned int Ref;
19834 : :
19835 : 6164 : DebugLocation (static_cast<unsigned int> (M2Reserved_withtok), (const char *) "with", 4);
19836 : 6164 : BuildStmtNoteTok (withTok);
19837 : 6164 : M2Quads_DisplayStack ();
19838 : 6164 : M2Quads_PopTFtok (&Sym, &Type, &tok);
19839 : 6164 : DebugLocation (tok, (const char *) "expression", 10);
19840 : 6164 : Type = SymbolTable_SkipType (Type);
19841 : 6164 : if (Type == SymbolTable_NulSym)
19842 : : {
19843 : 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);
19844 : : }
19845 : : else
19846 : : {
19847 : 6158 : Ref = SymbolTable_MakeTemporary (tok, SymbolTable_LeftValue);
19848 : 6158 : SymbolTable_PutVar (Ref, Type);
19849 : 6158 : if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
19850 : : {
19851 : : /* Copy LeftValue. */
19852 : 5870 : GenQuadO (tok, M2Quads_BecomesOp, Ref, SymbolTable_NulSym, Sym, true);
19853 : : }
19854 : : else
19855 : : {
19856 : : /* Calculate the address of Sym. */
19857 : 288 : GenQuadO (tok, M2Quads_AddrOp, Ref, SymbolTable_NulSym, Sym, true);
19858 : : }
19859 : 6158 : PushWith (Sym, Type, Ref, tok);
19860 : 6158 : DebugLocation (tok, (const char *) "with ref", 8);
19861 : 6158 : if (! (SymbolTable_IsRecord (Type)))
19862 : : {
19863 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "the {%kWITH} statement requires that {%1Ea} {%1d} be of a {%kRECORD} {%1tsa:type rather than {%1tsa}}", 101, Sym);
19864 : : }
19865 : 6158 : SymbolTable_StartScope (Type);
19866 : : }
19867 : 6158 : M2StackSpell_Push (Type);
19868 : 6158 : M2Quads_DisplayStack ();
19869 : 6158 : }
19870 : :
19871 : :
19872 : : /*
19873 : : EndBuildWith - terminates the innermost with scope.
19874 : : */
19875 : :
19876 : 6158 : extern "C" void M2Quads_EndBuildWith (void)
19877 : : {
19878 : 6158 : M2Quads_DisplayStack ();
19879 : 6158 : SymbolTable_EndScope ();
19880 : 6158 : PopWith ();
19881 : 6158 : M2StackSpell_Pop ();
19882 : 6158 : M2Quads_DisplayStack ();
19883 : 6158 : }
19884 : :
19885 : :
19886 : : /*
19887 : : CheckWithReference - performs the with statement.
19888 : : The Stack:
19889 : :
19890 : : Entry Exit
19891 : :
19892 : : +------------+ +------------+
19893 : : | Sym | Type | | Sym | Type |
19894 : : |------------| |------------|
19895 : : */
19896 : :
19897 : 694703 : extern "C" void M2Quads_CheckWithReference (void)
19898 : : {
19899 : 694703 : M2Quads_WithFrame f;
19900 : 694703 : unsigned int tokpos;
19901 : 694703 : unsigned int i;
19902 : 694703 : unsigned int n;
19903 : 694703 : unsigned int rw;
19904 : 694703 : unsigned int Sym;
19905 : 694703 : unsigned int Type;
19906 : :
19907 : 694703 : n = M2StackAddress_NoOfItemsInStackAddress (WithStack);
19908 : 694703 : if ((n > 0) && ! SuppressWith)
19909 : : {
19910 : 106974 : PopTFrwtok (&Sym, &Type, &rw, &tokpos);
19911 : 106974 : M2Debug_Assert (tokpos != M2LexBuf_UnknownTokenNo);
19912 : 106974 : if (SymbolTable_IsUnknown (Sym))
19913 : : {
19914 : 6 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1ad} is unknown {%1&s}", 24, Sym);
19915 : 6 : SymbolTable_UnknownReported (Sym);
19916 : : }
19917 : : else
19918 : : {
19919 : : /* Inner WITH always has precedence. */
19920 : : i = 1; /* top of stack */
19921 : : /* WriteString('Checking for a with') ; */
19922 : 227136 : while (i <= n)
19923 : : {
19924 : 120168 : f = static_cast<M2Quads_WithFrame> (M2StackAddress_PeepAddress (WithStack, i));
19925 : 120168 : if ((SymbolTable_IsRecordField (Sym)) && ((SymbolTable_GetRecord (SymbolTable_GetParent (Sym))) == f->RecordType))
19926 : : {
19927 : 30984 : if (SymbolTable_IsUnused (Sym))
19928 : : {
19929 : 0 : M2MetaError_MetaError1 ((const char *) "record field {%1Dad} was declared as unused by a pragma", 55, Sym);
19930 : : }
19931 : : /* Fake a RecordSym.op */
19932 : 30984 : PushTFrwtok (f->RecordRef, f->RecordType, f->rw, f->RecordTokPos);
19933 : 30984 : M2Quads_PushTFtok (Sym, Type, tokpos);
19934 : 30984 : BuildAccessWithField ();
19935 : 30984 : PopTFrw (&Sym, &Type, &f->rw);
19936 : 30984 : i = n+1; /* Finish loop. */
19937 : : }
19938 : : else
19939 : : {
19940 : 89184 : i += 1;
19941 : : }
19942 : : }
19943 : : }
19944 : 106974 : PushTFrwtok (Sym, Type, rw, tokpos);
19945 : : }
19946 : 694703 : }
19947 : :
19948 : :
19949 : : /*
19950 : : BuildDesignatorRecord - Builds the record referencing.
19951 : : The Stack is expected to contain:
19952 : :
19953 : :
19954 : : Entry Exit
19955 : : ===== ====
19956 : :
19957 : : Ptr ->
19958 : : +--------------+
19959 : : | n |
19960 : : |--------------|
19961 : : | fld1 | type1 |
19962 : : |--------------|
19963 : : . .
19964 : : . .
19965 : : . .
19966 : : |--------------|
19967 : : | fldn | typen | <- Ptr
19968 : : |--------------| +-------------+
19969 : : | Sym | Type | | S | type1|
19970 : : |--------------| |-------------|
19971 : : */
19972 : :
19973 : 116882 : extern "C" void M2Quads_BuildDesignatorRecord (unsigned int dottok)
19974 : : {
19975 : 116882 : unsigned int RecordTok;
19976 : 116882 : unsigned int FieldTok;
19977 : 116882 : unsigned int combinedtok;
19978 : 116882 : unsigned int n;
19979 : 116882 : unsigned int rw;
19980 : 116882 : unsigned int Field;
19981 : 116882 : unsigned int FieldType;
19982 : 116882 : unsigned int RecordSym;
19983 : 116882 : unsigned int Res;
19984 : :
19985 : 116882 : M2Quads_PopT (&n);
19986 : 116882 : RecordSym = static_cast<unsigned int> (M2Quads_OperandT (n+1));
19987 : : /* RecordType could be found by: SkipType (OperandF (n+1)). */
19988 : 116882 : RecordTok = static_cast<unsigned int> (M2Quads_OperandTok (n+1));
19989 : 116882 : rw = static_cast<unsigned int> (OperandMergeRW (n+1));
19990 : 116882 : M2Debug_Assert (SymbolTable_IsLegal (rw));
19991 : 116882 : Field = static_cast<unsigned int> (M2Quads_OperandT (n));
19992 : 116882 : FieldType = SymbolTable_SkipType (M2Quads_OperandF (n));
19993 : 116882 : FieldTok = static_cast<unsigned int> (M2Quads_OperandTok (n));
19994 : 116882 : combinedtok = M2LexBuf_MakeVirtualTok (dottok, RecordTok, FieldTok);
19995 : 116882 : if (n > 1)
19996 : : {
19997 : 0 : M2Error_InternalError ((const char *) "not expecting to see n>1", 24);
19998 : : }
19999 : 116882 : if (SymbolTable_IsUnused (Field))
20000 : : {
20001 : 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);
20002 : : }
20003 : 116882 : Res = SymbolTable_MakeComponentRef (SymbolTable_MakeComponentRecord (combinedtok, SymbolTable_RightValue, RecordSym), Field);
20004 : 116882 : SymbolTable_PutVarConst (Res, IsReadOnly (RecordSym));
20005 : 116882 : GenQuadO (combinedtok, M2Quads_RecordFieldOp, Res, RecordSym, Field, false);
20006 : 116882 : M2Quads_PopN (n+1);
20007 : 116882 : PushTFrwtok (Res, FieldType, rw, combinedtok);
20008 : 116882 : }
20009 : :
20010 : :
20011 : : /*
20012 : : BuildDesignatorArray - Builds the array referencing.
20013 : : The purpose of this procedure is to work out
20014 : : whether the DesignatorArray is a constant string or
20015 : : dynamic array/static array and to call the appropriate
20016 : : BuildRoutine.
20017 : :
20018 : : The Stack is expected to contain:
20019 : :
20020 : : Entry Exit
20021 : : ===== ====
20022 : :
20023 : : Ptr ->
20024 : : +--------------+
20025 : : | e | <- Ptr
20026 : : |--------------| +------------+
20027 : : | Sym | Type | | S | T |
20028 : : |--------------| |------------|
20029 : : */
20030 : :
20031 : 56762 : extern "C" void M2Quads_BuildDesignatorArray (void)
20032 : : {
20033 : 56762 : if ((SymbolTable_IsConst (M2Quads_OperandT (2))) && (SymbolTable_IsConstString (M2Quads_OperandT (2))))
20034 : : {
20035 : 6 : M2MetaError_MetaErrorT1 (OperandTtok (2), (const char *) "{%1Ead} is not an array, but a constant string. Hint use a string constant created with an array constructor", 109, M2Quads_OperandT (2));
20036 : 6 : BuildDesignatorError ((const char *) "bad array access", 16);
20037 : : }
20038 : : else
20039 : : {
20040 : 56756 : BuildDesignatorArrayStaticDynamic ();
20041 : : }
20042 : 56756 : }
20043 : :
20044 : :
20045 : : /*
20046 : : BuildDesignatorPointer - Builds a pointer reference.
20047 : : The Stack is expected to contain:
20048 : :
20049 : :
20050 : : Entry Exit
20051 : : ===== ====
20052 : :
20053 : : Ptr -> <- Ptr
20054 : : +--------------+ +--------------+
20055 : : | Sym1 | Type1| | Sym2 | Type2|
20056 : : |--------------| |--------------|
20057 : : */
20058 : :
20059 : 19830 : extern "C" void M2Quads_BuildDesignatorPointer (unsigned int ptrtok)
20060 : : {
20061 : 19830 : unsigned int combinedtok;
20062 : 19830 : unsigned int destok;
20063 : 19830 : unsigned int rw;
20064 : 19830 : unsigned int Sym1;
20065 : 19830 : unsigned int Type1;
20066 : 19830 : unsigned int Sym2;
20067 : 19830 : unsigned int Type2;
20068 : :
20069 : 19830 : PopTFrwtok (&Sym1, &Type1, &rw, &destok);
20070 : 19830 : DebugLocation (destok, (const char *) "des ptr expression", 18);
20071 : 19830 : Type1 = SymbolTable_SkipType (Type1);
20072 : 19830 : if (Type1 == SymbolTable_NulSym)
20073 : : {
20074 : 0 : M2MetaError_MetaErrorT1 (ptrtok, (const char *) "{%1ad} has no type and therefore cannot be dereferenced by ^", 60, Sym1);
20075 : : }
20076 : 19830 : else if (SymbolTable_IsUnknown (Sym1))
20077 : : {
20078 : : /* avoid dangling else. */
20079 : : /* Spellcheck. */
20080 : 0 : M2MetaError_MetaError1 ((const char *) "{%1EMad} is undefined and therefore {%1ad}^ cannot be resolved {%1&s}", 69, Sym1);
20081 : 0 : SymbolTable_UnknownReported (Sym1);
20082 : : }
20083 : : else
20084 : : {
20085 : : /* avoid dangling else. */
20086 : 19830 : combinedtok = M2LexBuf_MakeVirtual2Tok (destok, ptrtok);
20087 : 19830 : if (SymbolTable_IsPointer (Type1))
20088 : : {
20089 : 19828 : Type2 = SymbolTable_GetSType (Type1);
20090 : 19828 : Sym2 = SymbolTable_MakeTemporary (ptrtok, SymbolTable_LeftValue);
20091 : : /*
20092 : : Ok must reference by address
20093 : : - but we contain the type of the referenced entity
20094 : : */
20095 : 19828 : MarkAsRead (rw);
20096 : 19828 : SymbolTable_PutVarPointerCheck (Sym1, true);
20097 : 19828 : CheckPointerThroughNil (ptrtok, Sym1);
20098 : 19828 : if ((SymbolTable_GetMode (Sym1)) == SymbolTable_LeftValue)
20099 : : {
20100 : 510 : rw = SymbolTable_NulSym;
20101 : 510 : SymbolTable_PutLeftValueFrontBackType (Sym2, Type2, Type1);
20102 : 510 : GenQuadO (ptrtok, M2Quads_IndrXOp, Sym2, Type1, Sym1, false); /* Sym2 := *Sym1. */
20103 : : }
20104 : : else
20105 : : {
20106 : 19318 : SymbolTable_PutLeftValueFrontBackType (Sym2, Type2, SymbolTable_NulSym);
20107 : 19318 : GenQuadO (ptrtok, M2Quads_BecomesOp, Sym2, SymbolTable_NulSym, Sym1, false); /* Sym2 := Sym1. */
20108 : : }
20109 : : /* We should check this for Sym2 later on (pointer via NIL). */
20110 : 19828 : SymbolTable_PutVarPointerCheck (Sym2, true);
20111 : 19828 : PushTFrwtok (Sym2, Type2, rw, combinedtok);
20112 : 19828 : DebugLocation (combinedtok, (const char *) "pointer expression", 18);
20113 : : }
20114 : 2 : else if ((SymbolTable_IsHiddenType (Type1)) && ((SymbolTable_GetModuleScope (Type1)) != (SymbolTable_GetCurrentModuleScope ())))
20115 : : {
20116 : : /* avoid dangling else. */
20117 : 2 : M2MetaError_MetaErrorT1 (ptrtok, (const char *) "{%1Ead} is declared with an opaque type from a different module and cannot be dereferenced", 90, Sym1);
20118 : 2 : MarkAsRead (rw);
20119 : 2 : BuildDesignatorPointerError (Type1, rw, combinedtok, (const char *) "bad opaque pointer dereference", 30);
20120 : : }
20121 : : else
20122 : : {
20123 : : /* avoid dangling else. */
20124 : 0 : M2MetaError_MetaError2 ((const char *) "{%1Ead} is not a pointer type but a {%2dv}", 42, Sym1, Type1);
20125 : 0 : MarkAsRead (rw);
20126 : 0 : BuildDesignatorPointerError (Type1, rw, combinedtok, (const char *) "bad pointer dereference", 23);
20127 : : }
20128 : : }
20129 : 19830 : }
20130 : :
20131 : :
20132 : : /*
20133 : : BuildNulExpression - Builds a nul expression on the stack.
20134 : : The Stack:
20135 : :
20136 : : Entry Exit
20137 : :
20138 : : <- Ptr
20139 : : Empty +------------+
20140 : : | NulSym |
20141 : : |------------|
20142 : : tokpos is the position of the RETURN token.
20143 : : */
20144 : :
20145 : 852 : extern "C" void M2Quads_BuildNulExpression (unsigned int tokpos)
20146 : : {
20147 : 852 : M2Quads_PushTtok (static_cast<unsigned int> (SymbolTable_NulSym), tokpos);
20148 : 852 : }
20149 : :
20150 : :
20151 : : /*
20152 : : BuildSetStart - Pushes a Bitset type on the stack.
20153 : :
20154 : : The Stack:
20155 : :
20156 : : Entry Exit
20157 : :
20158 : : Ptr -> <- Ptr
20159 : :
20160 : : Empty +--------------+
20161 : : | Bitset |
20162 : : |--------------|
20163 : : */
20164 : :
20165 : 0 : extern "C" void M2Quads_BuildSetStart (unsigned int tokpos)
20166 : : {
20167 : 0 : M2Quads_PushTtok (M2Bitset_Bitset, tokpos);
20168 : 0 : }
20169 : :
20170 : :
20171 : : /*
20172 : : BuildSetEnd - pops the set value and type from the stack
20173 : : and pushes the value,type pair.
20174 : :
20175 : : Entry Exit
20176 : :
20177 : : Ptr ->
20178 : : +--------------+
20179 : : | Set Value | <- Ptr
20180 : : |--------------| +--------------+
20181 : : | Set Type | | Value | Type |
20182 : : |--------------| |--------------|
20183 : : */
20184 : :
20185 : 0 : extern "C" void M2Quads_BuildSetEnd (void)
20186 : : {
20187 : 0 : unsigned int valuepos;
20188 : 0 : unsigned int typepos;
20189 : 0 : unsigned int combined;
20190 : 0 : unsigned int value;
20191 : 0 : unsigned int type;
20192 : :
20193 : 0 : M2Quads_PopTtok (&value, &valuepos);
20194 : 0 : M2Quads_PopTtok (&type, &typepos);
20195 : 0 : combined = M2LexBuf_MakeVirtual2Tok (typepos, valuepos);
20196 : 0 : M2Quads_PushTFtok (value, type, combined);
20197 : 0 : M2Debug_Assert (SymbolTable_IsSet (type));
20198 : 0 : }
20199 : :
20200 : :
20201 : : /*
20202 : : BuildEmptySet - Builds an empty set on the stack.
20203 : : The Stack:
20204 : :
20205 : : Entry Exit
20206 : :
20207 : : <- Ptr
20208 : : +-------------+
20209 : : Ptr -> | Value |
20210 : : +-----------+ |-------------|
20211 : : | SetType | | SetType |
20212 : : |-----------| |-------------|
20213 : :
20214 : : tokpos points to the opening '{'.
20215 : : */
20216 : :
20217 : 0 : extern "C" void M2Quads_BuildEmptySet (unsigned int tokpos)
20218 : : {
20219 : 0 : NameKey_Name n;
20220 : 0 : unsigned int typepos;
20221 : 0 : unsigned int Type;
20222 : 0 : unsigned int NulSet;
20223 : :
20224 : 0 : M2Quads_PopTtok (&Type, &typepos); /* type of set we are building */
20225 : 0 : if ((Type == SymbolTable_NulSym) && M2Options_Pim)
20226 : : {
20227 : : /* allowed generic {} in PIM Modula-2 */
20228 : 0 : typepos = tokpos;
20229 : : }
20230 : 0 : else if (SymbolTable_IsUnknown (Type))
20231 : : {
20232 : : /* avoid dangling else. */
20233 : : /* Spellcheck. */
20234 : 0 : M2MetaError_MetaError1 ((const char *) "set type {%1a} is undefined {%1&s}", 34, Type);
20235 : 0 : SymbolTable_UnknownReported (Type);
20236 : 0 : Type = M2Bitset_Bitset;
20237 : : }
20238 : 0 : else if (! (SymbolTable_IsSet (SymbolTable_SkipType (Type))))
20239 : : {
20240 : : /* avoid dangling else. */
20241 : 0 : M2MetaError_MetaError1 ((const char *) "expecting a set type {%1a} and not a {%1d}", 42, Type);
20242 : 0 : Type = M2Bitset_Bitset;
20243 : : }
20244 : : else
20245 : : {
20246 : : /* avoid dangling else. */
20247 : 0 : Type = SymbolTable_SkipType (Type);
20248 : 0 : M2Debug_Assert (Type != SymbolTable_NulSym);
20249 : : }
20250 : 0 : NulSet = SymbolTable_MakeTemporary (typepos, SymbolTable_ImmediateValue);
20251 : 0 : SymbolTable_PutVar (NulSet, Type);
20252 : 0 : SymbolTable_PutConstSet (NulSet);
20253 : 0 : if (M2Options_CompilerDebugging)
20254 : : {
20255 : 0 : n = SymbolTable_GetSymName (Type);
20256 : 0 : M2Printf_printf1 ((const char *) "set type = %a\\n", 15, (const unsigned char *) &n, (sizeof (n)-1));
20257 : : }
20258 : 0 : M2ALU_PushNulSet (Type); /* onto the ALU stack */
20259 : 0 : SymbolTable_PopValue (NulSet); /* ALU -> symbol table */
20260 : : /* and now construct the M2Quads stack as defined by the comments above */
20261 : 0 : M2Quads_PushTtok (Type, typepos);
20262 : 0 : M2Quads_PushTtok (NulSet, typepos);
20263 : 0 : if (M2Options_CompilerDebugging)
20264 : : {
20265 : 0 : n = SymbolTable_GetSymName (Type);
20266 : 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));
20267 : 0 : M2Quads_DisplayStack (); /* Debugging info */
20268 : : }
20269 : 0 : }
20270 : :
20271 : :
20272 : : /*
20273 : : BuildInclRange - includes a set range with a set.
20274 : :
20275 : :
20276 : : Entry Exit
20277 : : ===== ====
20278 : :
20279 : :
20280 : : Ptr ->
20281 : : +------------+
20282 : : | El2 |
20283 : : |------------|
20284 : : | El1 | <- Ptr
20285 : : |------------| +-------------------+
20286 : : | Set Value | | Value + {El1..El2}|
20287 : : |------------| |-------------------|
20288 : :
20289 : : No quadruples produced as the range info is contained within
20290 : : the set value.
20291 : : */
20292 : :
20293 : 0 : extern "C" void M2Quads_BuildInclRange (void)
20294 : : {
20295 : 0 : NameKey_Name n;
20296 : 0 : unsigned int el1;
20297 : 0 : unsigned int el2;
20298 : 0 : unsigned int value;
20299 : :
20300 : 0 : M2Quads_PopT (&el2);
20301 : 0 : M2Quads_PopT (&el1);
20302 : 0 : M2Quads_PopT (&value);
20303 : 0 : if (! (SymbolTable_IsConstSet (value)))
20304 : : {
20305 : 0 : n = SymbolTable_GetSymName (el1);
20306 : 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));
20307 : : }
20308 : 0 : if ((SymbolTable_IsConst (el1)) && (SymbolTable_IsConst (el2)))
20309 : : {
20310 : 0 : SymbolTable_PushValue (value); /* onto ALU stack */
20311 : 0 : M2ALU_AddBitRange (M2LexBuf_GetTokenNo (), el1, el2); /* onto ALU stack */
20312 : 0 : SymbolTable_PopValue (value); /* ALU -> symboltable */
20313 : : }
20314 : : else
20315 : : {
20316 : 0 : if (! (SymbolTable_IsConst (el1)))
20317 : : {
20318 : 0 : n = SymbolTable_GetSymName (el1);
20319 : 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));
20320 : : }
20321 : 0 : if (! (SymbolTable_IsConst (el2)))
20322 : : {
20323 : 0 : n = SymbolTable_GetSymName (el2);
20324 : 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));
20325 : : }
20326 : : }
20327 : 0 : M2Quads_PushT (value);
20328 : 0 : }
20329 : :
20330 : :
20331 : : /*
20332 : : BuildInclBit - includes a bit into the set.
20333 : :
20334 : : Entry Exit
20335 : : ===== ====
20336 : :
20337 : :
20338 : : Ptr ->
20339 : : +------------+
20340 : : | Element | <- Ptr
20341 : : |------------| +------------+
20342 : : | Value | | Value |
20343 : : |------------| |------------|
20344 : :
20345 : : */
20346 : :
20347 : 12028 : extern "C" void M2Quads_BuildInclBit (void)
20348 : : {
20349 : 12028 : unsigned int tok;
20350 : 12028 : unsigned int el;
20351 : 12028 : unsigned int value;
20352 : 12028 : unsigned int t;
20353 : :
20354 : 12028 : M2Quads_PopT (&el);
20355 : 12028 : M2Quads_PopT (&value);
20356 : 12028 : tok = M2LexBuf_GetTokenNo ();
20357 : 12028 : if (SymbolTable_IsConst (el))
20358 : : {
20359 : 11954 : SymbolTable_PushValue (value); /* onto ALU stack */
20360 : 11954 : M2ALU_AddBit (tok, el); /* onto ALU stack */
20361 : 11954 : SymbolTable_PopValue (value); /* ALU -> symboltable */
20362 : : }
20363 : : else
20364 : : {
20365 : 74 : if ((SymbolTable_GetMode (el)) == SymbolTable_LeftValue)
20366 : : {
20367 : 0 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
20368 : 0 : SymbolTable_PutVar (t, SymbolTable_GetSType (el));
20369 : 0 : CheckPointerThroughNil (tok, el);
20370 : 0 : doIndrX (tok, t, el);
20371 : 0 : el = t;
20372 : : }
20373 : 74 : if (SymbolTable_IsConst (value))
20374 : : {
20375 : : /* move constant into a variable to achieve the include */
20376 : 74 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
20377 : 74 : SymbolTable_PutVar (t, SymbolTable_GetSType (value));
20378 : 74 : GenQuad (M2Quads_BecomesOp, t, SymbolTable_NulSym, value);
20379 : 74 : value = t;
20380 : : }
20381 : 74 : GenQuad (M2Quads_InclOp, value, SymbolTable_NulSym, el);
20382 : : }
20383 : 12028 : M2Quads_PushT (value);
20384 : 12028 : }
20385 : :
20386 : :
20387 : : /*
20388 : : SilentBuildConstructor - places NulSym into the constructor fifo queue.
20389 : : */
20390 : :
20391 : 0 : extern "C" void M2Quads_SilentBuildConstructor (void)
20392 : : {
20393 : 0 : FifoQueue_PutConstructorIntoFifoQueue (SymbolTable_NulSym);
20394 : 0 : }
20395 : :
20396 : :
20397 : : /*
20398 : : SilentBuildConstructorStart - removes an entry from the constructor fifo queue.
20399 : : */
20400 : :
20401 : 25390 : extern "C" void M2Quads_SilentBuildConstructorStart (void)
20402 : : {
20403 : 25390 : unsigned int constValue;
20404 : :
20405 : 25390 : FifoQueue_GetConstructorFromFifoQueue (&constValue);
20406 : 25390 : }
20407 : :
20408 : :
20409 : : /*
20410 : : BuildConstructor - builds a constructor.
20411 : : Stack
20412 : :
20413 : : Entry Exit
20414 : :
20415 : : Ptr ->
20416 : : +------------+
20417 : : | Type | <- Ptr
20418 : : |------------+
20419 : : */
20420 : :
20421 : 36512 : extern "C" void M2Quads_BuildConstructor (unsigned int tokcbrpos)
20422 : : {
20423 : 36512 : unsigned int tok;
20424 : 36512 : unsigned int constValue;
20425 : 36512 : unsigned int type;
20426 : :
20427 : 36512 : M2Quads_PopTtok (&type, &tok);
20428 : 36512 : constValue = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
20429 : 36512 : SymbolTable_PutVar (constValue, type);
20430 : 36512 : SymbolTable_PutConstructor (constValue);
20431 : 36512 : SymbolTable_PushValue (constValue);
20432 : 36512 : if (type == SymbolTable_NulSym)
20433 : : {
20434 : 6 : M2MetaError_MetaErrorT0 (tokcbrpos, (const char *) "{%E}constructor requires a type before the opening %{", 53);
20435 : : }
20436 : : else
20437 : : {
20438 : 36506 : M2ALU_ChangeToConstructor (tok, type);
20439 : 36506 : SymbolTable_PutConstructorFrom (constValue, type);
20440 : 36506 : SymbolTable_PopValue (constValue);
20441 : 36506 : FifoQueue_PutConstructorIntoFifoQueue (constValue);
20442 : : }
20443 : 36512 : PushConstructor (type);
20444 : 36512 : }
20445 : :
20446 : :
20447 : : /*
20448 : : BuildConstructorStart - builds a constructor.
20449 : : Stack
20450 : :
20451 : : Entry Exit
20452 : :
20453 : : Ptr -> <- Ptr
20454 : : +------------+ +----------------+
20455 : : | Type | | ConstructorSym |
20456 : : |------------+ |----------------|
20457 : : */
20458 : :
20459 : 11110 : extern "C" void M2Quads_BuildConstructorStart (unsigned int cbratokpos)
20460 : : {
20461 : 11110 : unsigned int typepos;
20462 : 11110 : unsigned int constValue;
20463 : 11110 : unsigned int type;
20464 : :
20465 : 11110 : M2Quads_PopTtok (&type, &typepos); /* we ignore the type as we already have the constructor symbol from pass C */
20466 : 11110 : FifoQueue_GetConstructorFromFifoQueue (&constValue); /* we ignore the type as we already have the constructor symbol from pass C */
20467 : 11110 : if (type != (SymbolTable_GetSType (constValue)))
20468 : : {
20469 : 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);
20470 : : }
20471 : 11110 : M2Quads_PushTtok (constValue, cbratokpos);
20472 : 11110 : PushConstructor (type);
20473 : 11110 : }
20474 : :
20475 : :
20476 : : /*
20477 : : BuildConstructorEnd - removes the current constructor frame from the
20478 : : constructor stack (it does not effect the quad
20479 : : stack)
20480 : :
20481 : : Entry Exit
20482 : :
20483 : : Ptr -> <- Ptr
20484 : : +------------+ +------------+
20485 : : | const | | const |
20486 : : |------------| |------------|
20487 : :
20488 : : startpos is the start of the constructor, either the typename or '{'
20489 : : cbratokpos is the '}'.
20490 : : */
20491 : :
20492 : 11110 : extern "C" void M2Quads_BuildConstructorEnd (unsigned int startpos, unsigned int cbratokpos)
20493 : : {
20494 : 11110 : unsigned int value;
20495 : 11110 : unsigned int valtok;
20496 : :
20497 : 11110 : if (DebugTokPos)
20498 : : {
20499 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "startpos", 8), startpos);
20500 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "cbratokpos", 10), cbratokpos);
20501 : : }
20502 : 11110 : M2Quads_PopTtok (&value, &valtok);
20503 : 11110 : if (DebugTokPos)
20504 : : {
20505 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "value valtok", 12), valtok);
20506 : : }
20507 : 11110 : valtok = M2LexBuf_MakeVirtual2Tok (startpos, cbratokpos);
20508 : 11110 : SymbolTable_PutDeclared (valtok, value);
20509 : 11110 : M2Quads_PushTtok (value, valtok); /* Use valtok as we now know it was a constructor. */
20510 : 11110 : M2Quads_PopConstructor (); /* Use valtok as we now know it was a constructor. */
20511 : 11110 : if (DebugTokPos)
20512 : : {
20513 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "aggregate constant", 18), valtok);
20514 : : }
20515 : 11110 : }
20516 : :
20517 : :
20518 : : /*
20519 : : NextConstructorField - increments the top of constructor stacks index by one.
20520 : : */
20521 : :
20522 : 35164 : extern "C" void M2Quads_NextConstructorField (void)
20523 : : {
20524 : 35164 : M2Quads_ConstructorFrame c;
20525 : :
20526 : 35164 : c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PeepAddress (ConstructorStack, 1));
20527 : 35164 : c->index += 1;
20528 : 35164 : }
20529 : :
20530 : :
20531 : : /*
20532 : : BuildTypeForConstructor - pushes the type implied by the current constructor.
20533 : : If no constructor is currently being built then
20534 : : it Pushes a Bitset type.
20535 : : */
20536 : :
20537 : 1728 : extern "C" void M2Quads_BuildTypeForConstructor (unsigned int tokpos)
20538 : : {
20539 : 1728 : M2Quads_ConstructorFrame c;
20540 : :
20541 : 1728 : if ((M2StackAddress_NoOfItemsInStackAddress (ConstructorStack)) == 0)
20542 : : {
20543 : 660 : M2Quads_PushTtok (M2Bitset_Bitset, tokpos);
20544 : : }
20545 : : else
20546 : : {
20547 : 1068 : c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PeepAddress (ConstructorStack, 1));
20548 : 1068 : if ((SymbolTable_IsArray (c->type)) || (SymbolTable_IsSet (c->type)))
20549 : : {
20550 : 972 : M2Quads_PushTtok (SymbolTable_GetSType (c->type), tokpos);
20551 : : }
20552 : 96 : else if (SymbolTable_IsRecord (c->type))
20553 : : {
20554 : : /* avoid dangling else. */
20555 : 96 : M2Quads_PushTtok (SymbolTable_GetSType (SymbolTable_GetNth (c->type, c->index)), tokpos);
20556 : : }
20557 : : else
20558 : : {
20559 : : /* avoid dangling else. */
20560 : 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);
20561 : : }
20562 : : }
20563 : 1728 : }
20564 : :
20565 : :
20566 : : /*
20567 : : BuildComponentValue - builds a component value.
20568 : :
20569 : : Entry Exit
20570 : :
20571 : : Ptr -> <- Ptr
20572 : :
20573 : :
20574 : : +------------+ +------------+
20575 : : | const | | const |
20576 : : |------------| |------------|
20577 : : */
20578 : :
20579 : 26042 : extern "C" void M2Quads_BuildComponentValue (void)
20580 : : {
20581 : 26042 : unsigned int const_;
20582 : 26042 : unsigned int e1;
20583 : 26042 : unsigned int e2;
20584 : 26042 : NameKey_Name nuldotdot;
20585 : 26042 : NameKey_Name nulby;
20586 : :
20587 : 26042 : M2Quads_PopT (&nulby);
20588 : 26042 : if (nulby == M2Reserved_NulTok)
20589 : : {
20590 : 26012 : M2Quads_PopT (&nuldotdot);
20591 : 26012 : if (nuldotdot == M2Reserved_NulTok)
20592 : : {
20593 : 25770 : M2Quads_PopT (&e1);
20594 : 25770 : M2Quads_PopT (&const_);
20595 : 25770 : M2Quads_PushT (AddFieldTo (const_, e1));
20596 : : }
20597 : : else
20598 : : {
20599 : 242 : M2Quads_PopT (&e2);
20600 : 242 : M2Quads_PopT (&e1);
20601 : 242 : M2Quads_PopT (&const_);
20602 : 242 : SymbolTable_PushValue (const_);
20603 : 242 : M2ALU_AddBitRange (M2LexBuf_GetTokenNo (), e1, e2);
20604 : 242 : SymbolTable_PopValue (const_);
20605 : 242 : M2Quads_PushT (const_);
20606 : : }
20607 : : }
20608 : : else
20609 : : {
20610 : 30 : M2Quads_PopT (&e1);
20611 : 30 : M2Quads_PopT (&nuldotdot);
20612 : 30 : if (nuldotdot == M2Reserved_NulTok)
20613 : : {
20614 : 30 : M2Quads_PopT (&e2);
20615 : 30 : M2Quads_PopT (&const_);
20616 : 30 : SymbolTable_PushValue (const_);
20617 : 30 : M2ALU_AddElements (M2LexBuf_GetTokenNo (), e2, e1);
20618 : 30 : SymbolTable_PopValue (const_);
20619 : 30 : M2Quads_PushT (const_);
20620 : : }
20621 : : else
20622 : : {
20623 : 0 : M2Quads_PopT (&e2);
20624 : 0 : M2Quads_PopT (&e1);
20625 : 0 : M2Quads_PopT (&const_);
20626 : 0 : M2Error_WriteFormat0 ((const char *) "the constant must be either an array constructor or a set constructor", 69);
20627 : 0 : M2Quads_PushT (const_);
20628 : : }
20629 : : }
20630 : 26042 : }
20631 : :
20632 : :
20633 : : /*
20634 : : PopConstructor - removes the top constructor from the top of stack.
20635 : : */
20636 : :
20637 : 47622 : extern "C" void M2Quads_PopConstructor (void)
20638 : : {
20639 : 47622 : M2Quads_ConstructorFrame c;
20640 : :
20641 : 47622 : c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PopAddress (ConstructorStack));
20642 : 47622 : Storage_DEALLOCATE ((void **) &c, sizeof (M2Quads__T1));
20643 : 47622 : }
20644 : :
20645 : :
20646 : : /*
20647 : : BuildNot - Builds a NOT operation from the quad stack.
20648 : : The Stack is expected to contain:
20649 : :
20650 : :
20651 : : Entry Exit
20652 : : ===== ====
20653 : :
20654 : : Ptr -> <- Ptr
20655 : : +------------+ +------------+
20656 : : | t | f | | f | t |
20657 : : |------------| |------------|
20658 : : */
20659 : :
20660 : 4944 : extern "C" void M2Quads_BuildNot (unsigned int notTokPos)
20661 : : {
20662 : 4944 : unsigned int combinedTok;
20663 : 4944 : unsigned int exprTokPos;
20664 : 4944 : unsigned int t;
20665 : 4944 : unsigned int f;
20666 : :
20667 : 4944 : CheckBooleanId ();
20668 : 4944 : PopBooltok (&t, &f, &exprTokPos);
20669 : 4944 : combinedTok = M2LexBuf_MakeVirtualTok (notTokPos, notTokPos, exprTokPos);
20670 : 4944 : PushBooltok (f, t, combinedTok);
20671 : 4944 : }
20672 : :
20673 : :
20674 : : /*
20675 : : RecordOp - Records the operator passed on the stack.
20676 : : This is called when a boolean operator is found in an
20677 : : expression. It is called just after the lhs has been built
20678 : : and pushed to the quad stack and prior to the rhs build.
20679 : : It checks to see if AND OR or equality tests are required.
20680 : : It will short circuit AND and OR expressions. It also
20681 : : converts a lhs to a boolean variable if an xor comparison
20682 : : is about to be performed.
20683 : :
20684 : : Checks for AND operator or OR operator
20685 : : if either of these operators are found then BackPatching
20686 : : takes place.
20687 : : The Expected Stack:
20688 : :
20689 : : Entry Exit
20690 : :
20691 : : Ptr -> <- Ptr
20692 : : +-------------+ +-------------+
20693 : : | OperatorTok | | OperatorTok |
20694 : : |-------------| |-------------|
20695 : : | t | f | | t | f |
20696 : : |-------------| |-------------|
20697 : :
20698 : :
20699 : : If OperatorTok=AndTok
20700 : : Then
20701 : : BackPatch(f, NextQuad)
20702 : : Elsif OperatorTok=OrTok
20703 : : Then
20704 : : BackPatch(t, NextQuad)
20705 : : End
20706 : : */
20707 : :
20708 : 105042 : extern "C" void M2Quads_RecordOp (void)
20709 : : {
20710 : 105042 : NameKey_Name Op;
20711 : 105042 : unsigned int tokno;
20712 : 105042 : unsigned int t;
20713 : 105042 : unsigned int f;
20714 : :
20715 : 105042 : M2Quads_PopTtok (&Op, &tokno);
20716 : 105042 : if ((Op == M2Reserved_AndTok) || (Op == M2Reserved_AmbersandTok))
20717 : : {
20718 : 9688 : CheckBooleanId ();
20719 : 9688 : PopBool (&t, &f);
20720 : 9688 : BackPatch (t, NextQuad);
20721 : 9688 : PushBool (0, f);
20722 : : }
20723 : 95354 : else if (Op == M2Reserved_OrTok)
20724 : : {
20725 : : /* avoid dangling else. */
20726 : 3630 : CheckBooleanId ();
20727 : 3630 : PopBool (&t, &f);
20728 : 3630 : BackPatch (f, NextQuad);
20729 : 3630 : PushBool (t, 0);
20730 : : }
20731 : 91724 : else if ((IsBoolean (1)) && ((((Op == M2Reserved_EqualTok) || (Op == M2Reserved_LessGreaterTok)) || (Op == M2Reserved_HashTok)) || (Op == M2Reserved_InTok)))
20732 : : {
20733 : : /* avoid dangling else. */
20734 : 52 : ConvertBooleanToVariable (tokno, 1);
20735 : : }
20736 : 105042 : M2Quads_PushTtok (Op, tokno);
20737 : 105042 : }
20738 : :
20739 : :
20740 : : /*
20741 : : BuildRelOp - Builds a relative operation from the quad stack.
20742 : : The Stack is expected to contain:
20743 : :
20744 : :
20745 : : Entry Exit
20746 : : ===== ====
20747 : :
20748 : : Ptr ->
20749 : : +------------+
20750 : : | e1 |
20751 : : |------------| <- Ptr
20752 : : | Operator |
20753 : : |------------| +------------+
20754 : : | e2 | | t | f |
20755 : : |------------| |------------|
20756 : :
20757 : :
20758 : : Quadruples Produced
20759 : :
20760 : : q IFOperator e2 e1 TrueExit ; e2 e1 since
20761 : : q+1 GotoOp FalseExit ; relation > etc
20762 : : ; requires order.
20763 : : */
20764 : :
20765 : 91961 : extern "C" void M2Quads_BuildRelOp (unsigned int optokpos)
20766 : : {
20767 : 91961 : unsigned int combinedTok;
20768 : 91961 : unsigned int rightpos;
20769 : 91961 : unsigned int leftpos;
20770 : 91961 : NameKey_Name Op;
20771 : 91961 : unsigned int t;
20772 : 91961 : unsigned int rightType;
20773 : 91961 : unsigned int leftType;
20774 : 91961 : unsigned int right;
20775 : 91961 : unsigned int left;
20776 : 91961 : DynamicStrings_String s;
20777 : :
20778 : 91961 : if (M2Options_CompilerDebugging)
20779 : : {
20780 : 0 : M2Quads_DisplayStack (); /* Debugging info */
20781 : : }
20782 : 91961 : if (((M2Quads_IsInConstExpression ()) && (IsBoolean (1))) && (IsBoolean (3)))
20783 : : {
20784 : : /*
20785 : : we allow # and = to be used with Boolean expressions.
20786 : : we do not allow > < >= <= though. We only examine
20787 : : this case if we are in a const expression as there will be
20788 : : no dereferencing of operands.
20789 : : */
20790 : 0 : BuildRelOpFromBoolean (optokpos);
20791 : : }
20792 : : else
20793 : : {
20794 : 91961 : if (IsBoolean (1))
20795 : : {
20796 : 64 : ConvertBooleanToVariable (OperandTtok (1), 1);
20797 : : }
20798 : 91961 : if (IsBoolean (3))
20799 : : {
20800 : 0 : ConvertBooleanToVariable (OperandTtok (3), 3);
20801 : : }
20802 : 91961 : M2Quads_PopTFtok (&right, &rightType, &rightpos);
20803 : 91961 : M2Quads_PopT (&Op);
20804 : 91961 : M2Quads_PopTFtok (&left, &leftType, &leftpos);
20805 : 91961 : CheckVariableOrConstantOrProcedure (rightpos, right);
20806 : 91961 : CheckVariableOrConstantOrProcedure (leftpos, left);
20807 : 91961 : combinedTok = M2LexBuf_MakeVirtualTok (optokpos, leftpos, rightpos);
20808 : 91961 : if ((left != SymbolTable_NulSym) && (right != SymbolTable_NulSym))
20809 : : {
20810 : : /* BuildRange will check the expression later on once gcc knows about all data types. */
20811 : 91961 : BuildRange (M2Range_InitTypesExpressionCheck (combinedTok, left, right, true, Op == M2Reserved_InTok));
20812 : : }
20813 : : /* Must dereference LeftValue operands. */
20814 : 91961 : if ((SymbolTable_GetMode (right)) == SymbolTable_LeftValue)
20815 : : {
20816 : 1936 : t = SymbolTable_MakeTemporary (rightpos, SymbolTable_RightValue);
20817 : 1936 : SymbolTable_PutVar (t, SymbolTable_GetSType (right));
20818 : 1936 : CheckPointerThroughNil (rightpos, right);
20819 : 1936 : doIndrX (rightpos, t, right);
20820 : 1936 : right = t;
20821 : : }
20822 : 91961 : if ((SymbolTable_GetMode (left)) == SymbolTable_LeftValue)
20823 : : {
20824 : 6401 : t = SymbolTable_MakeTemporary (leftpos, SymbolTable_RightValue);
20825 : 6401 : SymbolTable_PutVar (t, SymbolTable_GetSType (left));
20826 : 6401 : CheckPointerThroughNil (leftpos, left);
20827 : 6401 : doIndrX (leftpos, t, left);
20828 : 6401 : left = t;
20829 : : }
20830 : 91961 : if (DebugTokPos)
20831 : : {
20832 : : s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (M2LexBuf_GetTokenName (Op)));
20833 : : M2Error_WarnStringAt (s, optokpos);
20834 : : s = DynamicStrings_InitString ((const char *) "left", 4);
20835 : : M2Error_WarnStringAt (s, leftpos);
20836 : : s = DynamicStrings_InitString ((const char *) "right", 5);
20837 : : M2Error_WarnStringAt (s, rightpos);
20838 : : s = DynamicStrings_InitString ((const char *) "caret", 5);
20839 : : M2Error_WarnStringAt (s, optokpos);
20840 : : s = DynamicStrings_InitString ((const char *) "combined", 8);
20841 : : M2Error_WarnStringAt (s, combinedTok);
20842 : : }
20843 : 91961 : GenQuadOtok (combinedTok, MakeOp (Op), left, right, 0, false, leftpos, rightpos, M2LexBuf_UnknownTokenNo); /* True Exit */
20844 : 91961 : GenQuadO (combinedTok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false); /* False Exit */
20845 : 91961 : PushBooltok (NextQuad-2, NextQuad-1, combinedTok); /* False Exit */
20846 : : }
20847 : 91961 : }
20848 : :
20849 : :
20850 : : /*
20851 : : BuildBinaryOp - Builds a binary operation from the quad stack.
20852 : : Be aware that this procedure will check for
20853 : : the overloading of the bitset operators + - \ *.
20854 : : So do NOT call this procedure if you are building
20855 : : a reference to an array which has a bitset type or
20856 : : the address arithmetic will be wrongly coersed into
20857 : : logical ORs.
20858 : :
20859 : : The Stack is expected to contain:
20860 : :
20861 : :
20862 : : Entry Exit
20863 : : ===== ====
20864 : :
20865 : : Ptr ->
20866 : : +------------+
20867 : : | Sym1 |
20868 : : |------------|
20869 : : | Operator | <- Ptr
20870 : : |------------| +------------+
20871 : : | Sym2 | | Temporary |
20872 : : |------------| |------------|
20873 : :
20874 : :
20875 : : Quadruples Produced
20876 : :
20877 : : q Operator Temporary Sym1 Sym2
20878 : :
20879 : :
20880 : : OR
20881 : :
20882 : :
20883 : : Entry Exit
20884 : : ===== ====
20885 : :
20886 : : Ptr ->
20887 : : +------------+
20888 : : | T1 | F1 |
20889 : : |------------|
20890 : : | OrTok | <- Ptr
20891 : : |------------| +------------+
20892 : : | T2 | F2 | | T1+T2| F1 |
20893 : : |------------| |------------|
20894 : :
20895 : :
20896 : : Quadruples Produced
20897 : :
20898 : : */
20899 : :
20900 : 73304 : extern "C" void M2Quads_BuildBinaryOp (void)
20901 : : {
20902 : 73304 : doBuildBinaryOp (true, true);
20903 : 73196 : }
20904 : :
20905 : :
20906 : : /*
20907 : : BuildUnaryOp - Builds a unary operation from the quad stack.
20908 : : The Stack is expected to contain:
20909 : :
20910 : :
20911 : : Entry Exit
20912 : : ===== ====
20913 : :
20914 : : Ptr ->
20915 : : +------------+
20916 : : | Sym |
20917 : : |------------| +------------+
20918 : : | Operator | | Temporary | <- Ptr
20919 : : |------------| |------------|
20920 : :
20921 : :
20922 : : Quadruples Produced
20923 : :
20924 : : q Operator Temporary _ Sym
20925 : :
20926 : : */
20927 : :
20928 : 21220 : extern "C" void M2Quads_BuildUnaryOp (void)
20929 : : {
20930 : 21220 : unsigned int sympos;
20931 : 21220 : unsigned int tokpos;
20932 : 21220 : NameKey_Name Tok;
20933 : 21220 : unsigned int type;
20934 : 21220 : unsigned int Sym;
20935 : 21220 : unsigned int SymT;
20936 : 21220 : unsigned int r;
20937 : 21220 : unsigned int t;
20938 : :
20939 : 21220 : PopTrwtok (&Sym, &r, &sympos);
20940 : 21220 : M2Quads_PopTtok (&Tok, &tokpos);
20941 : 21220 : if (Tok == M2Reserved_MinusTok)
20942 : : {
20943 : 21076 : MarkAsRead (r);
20944 : 21076 : type = M2Base_NegateType (SymbolTable_GetSType (Sym)); /* , sympos */
20945 : 21076 : tokpos = M2LexBuf_MakeVirtualTok (tokpos, tokpos, sympos);
20946 : 42152 : t = SymbolTable_MakeTemporary (tokpos, AreConstant (SymbolTable_IsConst (Sym)));
20947 : 21076 : SymbolTable_PutVar (t, type);
20948 : : /*
20949 : : variables must have a type and REAL/LONGREAL constants must
20950 : : be typed
20951 : : */
20952 : 21076 : if (! (SymbolTable_IsConst (Sym)))
20953 : : {
20954 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
20955 : 1002 : if ((type != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_SkipType (type))))
20956 : : {} /* empty. */
20957 : : /* do not dereference set variables */
20958 : 924 : else if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
20959 : : {
20960 : : /* avoid dangling else. */
20961 : : /* dereference symbols which are not sets and which are variables */
20962 : 0 : SymT = SymbolTable_MakeTemporary (sympos, SymbolTable_RightValue);
20963 : 0 : SymbolTable_PutVar (SymT, SymbolTable_GetSType (Sym));
20964 : 0 : CheckPointerThroughNil (sympos, Sym);
20965 : 0 : doIndrX (sympos, SymT, Sym);
20966 : 0 : Sym = SymT;
20967 : : }
20968 : : }
20969 : 21076 : GenQuadO (tokpos, M2Quads_NegateOp, t, SymbolTable_NulSym, Sym, true);
20970 : 21076 : M2Quads_PushTtok (t, tokpos);
20971 : : }
20972 : 144 : else if (Tok == M2Reserved_PlusTok)
20973 : : {
20974 : : /* avoid dangling else. */
20975 : 144 : tokpos = M2LexBuf_MakeVirtualTok (tokpos, tokpos, sympos);
20976 : 144 : PushTrwtok (Sym, r, tokpos);
20977 : : }
20978 : : else
20979 : : {
20980 : : /* avoid dangling else. */
20981 : 0 : M2MetaError_MetaErrorNT1 (tokpos, (const char *) "expecting an unary operator, seen {%Ek%a}", 41, Tok);
20982 : : }
20983 : 21220 : }
20984 : :
20985 : :
20986 : : /*
20987 : : OperandT - returns the ident operand stored in the true position on the boolean stack.
20988 : : */
20989 : :
20990 : 210625034 : extern "C" unsigned int M2Quads_OperandT (unsigned int pos)
20991 : : {
20992 : 210625034 : M2Debug_Assert (! (IsBoolean (pos)));
20993 : 210625034 : return OperandTno (pos);
20994 : : /* static analysis guarentees a RETURN statement will be used before here. */
20995 : : __builtin_unreachable ();
20996 : : }
20997 : :
20998 : :
20999 : : /*
21000 : : OperandF - returns the ident operand stored in the false position on the boolean stack.
21001 : : */
21002 : :
21003 : 177492 : extern "C" unsigned int M2Quads_OperandF (unsigned int pos)
21004 : : {
21005 : 177492 : M2Debug_Assert (! (IsBoolean (pos)));
21006 : 177492 : return OperandFno (pos);
21007 : : /* static analysis guarentees a RETURN statement will be used before here. */
21008 : : __builtin_unreachable ();
21009 : : }
21010 : :
21011 : :
21012 : : /*
21013 : : PushTF - Push a True and False numbers onto the True/False stack.
21014 : : True and False are assumed to contain Symbols or Ident etc.
21015 : : */
21016 : :
21017 : 15660707 : extern "C" void M2Quads_PushTF (unsigned int True, unsigned int False)
21018 : : {
21019 : 15660707 : M2Quads_BoolFrame f;
21020 : :
21021 : 15660707 : f = newBoolFrame ();
21022 : 15660707 : f->TrueExit = static_cast<unsigned int> (True);
21023 : 15660707 : f->FalseExit = static_cast<unsigned int> (False);
21024 : 15660707 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
21025 : 15660707 : }
21026 : :
21027 : :
21028 : : /*
21029 : : PopTF - Pop a True and False number from the True/False stack.
21030 : : True and False are assumed to contain Symbols or Ident etc.
21031 : : */
21032 : :
21033 : 10552525 : extern "C" void M2Quads_PopTF (unsigned int *True, unsigned int *False)
21034 : : {
21035 : 10552525 : M2Quads_BoolFrame f;
21036 : :
21037 : 10552525 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
21038 : 10552525 : (*True) = static_cast<unsigned int> (f->TrueExit);
21039 : 10552525 : (*False) = static_cast<unsigned int> (f->FalseExit);
21040 : 10552525 : M2Debug_Assert (! f->BooleanOp);
21041 : 10552525 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
21042 : 10552525 : }
21043 : :
21044 : :
21045 : : /*
21046 : : PushT - Push an item onto the stack in the T (true) position.
21047 : : */
21048 : :
21049 : 97364561 : extern "C" void M2Quads_PushT (unsigned int True)
21050 : : {
21051 : 97364561 : M2Quads_BoolFrame f;
21052 : :
21053 : 97364561 : f = newBoolFrame ();
21054 : 97364561 : f->TrueExit = static_cast<unsigned int> (True);
21055 : 97364561 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
21056 : 97364561 : }
21057 : :
21058 : :
21059 : : /*
21060 : : PopT - Pops the T value from the stack.
21061 : : */
21062 : :
21063 : 143576755 : extern "C" void M2Quads_PopT (unsigned int *True)
21064 : : {
21065 : 143576755 : M2Quads_BoolFrame f;
21066 : :
21067 : 143576755 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
21068 : 143576749 : (*True) = static_cast<unsigned int> (f->TrueExit);
21069 : 143576749 : M2Debug_Assert (! f->BooleanOp);
21070 : 143576749 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
21071 : 143576749 : }
21072 : :
21073 : :
21074 : : /*
21075 : : PushTtok - Push an item onto the stack in the T (true) position,
21076 : : it is assummed to be a token and its token location is recorded.
21077 : : */
21078 : :
21079 : 77209559 : extern "C" void M2Quads_PushTtok (unsigned int True, unsigned int tokno)
21080 : : {
21081 : 77209559 : M2Quads_BoolFrame f;
21082 : :
21083 : : /* PrintTokenNo (tokno) ; */
21084 : 77209559 : f = newBoolFrame ();
21085 : 77209559 : f->TrueExit = static_cast<unsigned int> (True);
21086 : 77209559 : f->tokenno = tokno;
21087 : 77209559 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
21088 : 77209559 : }
21089 : :
21090 : :
21091 : : /*
21092 : : PushTFtok - Push an item onto the stack in the T (true) position,
21093 : : it is assummed to be a token and its token location is recorded.
21094 : : */
21095 : :
21096 : 154176162 : extern "C" void M2Quads_PushTFtok (unsigned int True, unsigned int False, unsigned int tokno)
21097 : : {
21098 : 154176162 : M2Quads_BoolFrame f;
21099 : :
21100 : 154176162 : f = newBoolFrame ();
21101 : 154176162 : f->TrueExit = static_cast<unsigned int> (True);
21102 : 154176162 : f->FalseExit = static_cast<unsigned int> (False);
21103 : 154176162 : f->tokenno = tokno;
21104 : 154176162 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
21105 : 154176162 : }
21106 : :
21107 : :
21108 : : /*
21109 : : PopTFtok - Pop T/F/tok from the stack.
21110 : : */
21111 : :
21112 : 9338186 : extern "C" void M2Quads_PopTFtok (unsigned int *True, unsigned int *False, unsigned int *tokno)
21113 : : {
21114 : 9338186 : M2Quads_BoolFrame f;
21115 : :
21116 : 9338186 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
21117 : 9338186 : (*True) = static_cast<unsigned int> (f->TrueExit);
21118 : 9338186 : (*False) = static_cast<unsigned int> (f->FalseExit);
21119 : 9338186 : (*tokno) = f->tokenno;
21120 : 9338186 : }
21121 : :
21122 : :
21123 : : /*
21124 : : PushTFAtok - Push T/F/A/tok to the stack.
21125 : : */
21126 : :
21127 : 54 : extern "C" void M2Quads_PushTFAtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int tokno)
21128 : : {
21129 : 54 : M2Quads_BoolFrame f;
21130 : :
21131 : 54 : f = newBoolFrame ();
21132 : 54 : f->TrueExit = static_cast<unsigned int> (True);
21133 : 54 : f->FalseExit = static_cast<unsigned int> (False);
21134 : 54 : f->Unbounded = static_cast<unsigned int> (Array);
21135 : 54 : f->tokenno = tokno;
21136 : 54 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
21137 : 54 : }
21138 : :
21139 : :
21140 : : /*
21141 : : PopTtok - Pops the T value from the stack and token position.
21142 : : */
21143 : :
21144 : 115300090 : extern "C" void M2Quads_PopTtok (unsigned int *True, unsigned int *tok)
21145 : : {
21146 : 115300090 : M2Quads_BoolFrame f;
21147 : :
21148 : 115300090 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
21149 : 115300090 : (*True) = static_cast<unsigned int> (f->TrueExit);
21150 : 115300090 : (*tok) = f->tokenno;
21151 : 115300090 : M2Debug_Assert (! f->BooleanOp);
21152 : 115300090 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
21153 : 115300090 : }
21154 : :
21155 : :
21156 : : /*
21157 : : PushTFn - Push a True and False numbers onto the True/False stack.
21158 : : True and False are assumed to contain Symbols or Ident etc.
21159 : : */
21160 : :
21161 : 0 : extern "C" void M2Quads_PushTFn (unsigned int True, unsigned int False, unsigned int n)
21162 : : {
21163 : 0 : M2Quads_BoolFrame f;
21164 : :
21165 : 0 : f = newBoolFrame ();
21166 : 0 : f->TrueExit = static_cast<unsigned int> (True);
21167 : 0 : f->FalseExit = static_cast<unsigned int> (False);
21168 : 0 : f->name = static_cast<unsigned int> (n);
21169 : 0 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
21170 : 0 : }
21171 : :
21172 : :
21173 : : /*
21174 : : PushTFntok - Push a True and False numbers onto the True/False stack.
21175 : : True and False are assumed to contain Symbols or Ident etc.
21176 : : */
21177 : :
21178 : 651370 : extern "C" void M2Quads_PushTFntok (unsigned int True, unsigned int False, unsigned int n, unsigned int tokno)
21179 : : {
21180 : 651370 : M2Quads_BoolFrame f;
21181 : :
21182 : 651370 : f = newBoolFrame ();
21183 : 651370 : f->TrueExit = static_cast<unsigned int> (True);
21184 : 651370 : f->FalseExit = static_cast<unsigned int> (False);
21185 : 651370 : f->name = static_cast<unsigned int> (n);
21186 : 651370 : f->tokenno = tokno;
21187 : 651370 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
21188 : 651370 : }
21189 : :
21190 : :
21191 : : /*
21192 : : PopTFn - Pop a True and False number from the True/False stack.
21193 : : True and False are assumed to contain Symbols or Ident etc.
21194 : : */
21195 : :
21196 : 0 : extern "C" void M2Quads_PopTFn (unsigned int *True, unsigned int *False, unsigned int *n)
21197 : : {
21198 : 0 : M2Quads_BoolFrame f;
21199 : :
21200 : 0 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
21201 : 0 : (*True) = static_cast<unsigned int> (f->TrueExit);
21202 : 0 : (*False) = static_cast<unsigned int> (f->FalseExit);
21203 : 0 : (*n) = static_cast<unsigned int> (f->name);
21204 : 0 : M2Debug_Assert (! f->BooleanOp);
21205 : 0 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
21206 : 0 : }
21207 : :
21208 : :
21209 : : /*
21210 : : PopNothing - pops the top element on the boolean stack.
21211 : : */
21212 : :
21213 : 65221181 : extern "C" void M2Quads_PopNothing (void)
21214 : : {
21215 : 65221181 : M2Quads_BoolFrame f;
21216 : :
21217 : 65221181 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
21218 : 65221181 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
21219 : 65221181 : }
21220 : :
21221 : :
21222 : : /*
21223 : : PopN - pops multiple elements from the BoolStack.
21224 : : */
21225 : :
21226 : 12542241 : extern "C" void M2Quads_PopN (unsigned int n)
21227 : : {
21228 : 47545533 : while (n > 0)
21229 : : {
21230 : 35003292 : M2Quads_PopNothing ();
21231 : 35003292 : n -= 1;
21232 : : }
21233 : 12542241 : }
21234 : :
21235 : :
21236 : : /*
21237 : : PushTFA - Push True, False, Array, numbers onto the
21238 : : True/False stack. True and False are assumed to
21239 : : contain Symbols or Ident etc.
21240 : : */
21241 : :
21242 : 0 : extern "C" void M2Quads_PushTFA (unsigned int True, unsigned int False, unsigned int Array)
21243 : : {
21244 : 0 : M2Quads_BoolFrame f;
21245 : :
21246 : 0 : f = newBoolFrame ();
21247 : 0 : f->TrueExit = static_cast<unsigned int> (True);
21248 : 0 : f->FalseExit = static_cast<unsigned int> (False);
21249 : 0 : f->Unbounded = static_cast<unsigned int> (Array);
21250 : 0 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
21251 : 0 : }
21252 : :
21253 : :
21254 : : /*
21255 : : OperandTok - returns the token associated with pos, on the stack.
21256 : : */
21257 : :
21258 : 55977164 : extern "C" unsigned int M2Quads_OperandTok (unsigned int pos)
21259 : : {
21260 : 55977164 : M2Debug_Assert (! (IsBoolean (pos)));
21261 : 55977164 : return static_cast<unsigned int> (OperandTtok (pos));
21262 : : /* static analysis guarentees a RETURN statement will be used before here. */
21263 : : __builtin_unreachable ();
21264 : : }
21265 : :
21266 : :
21267 : : /*
21268 : : OperandA - returns possible array symbol associated with the ident
21269 : : operand stored on the boolean stack.
21270 : : */
21271 : :
21272 : 2217509 : extern "C" unsigned int M2Quads_OperandA (unsigned int pos)
21273 : : {
21274 : 2217509 : M2Quads_BoolFrame f;
21275 : :
21276 : 2217509 : M2Debug_Assert (pos > 0);
21277 : 2217509 : M2Debug_Assert (! (IsBoolean (pos)));
21278 : 2217509 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
21279 : 2217509 : return static_cast<unsigned int> (f->Unbounded);
21280 : : /* static analysis guarentees a RETURN statement will be used before here. */
21281 : : __builtin_unreachable ();
21282 : : }
21283 : :
21284 : :
21285 : : /*
21286 : : OperandAnno - returns the annotation string associated with the
21287 : : position, n, on the stack.
21288 : : */
21289 : :
21290 : 0 : extern "C" DynamicStrings_String M2Quads_OperandAnno (unsigned int n)
21291 : : {
21292 : 0 : M2Quads_BoolFrame f;
21293 : :
21294 : 0 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, n));
21295 : 0 : return f->Annotation;
21296 : : /* static analysis guarentees a RETURN statement will be used before here. */
21297 : : __builtin_unreachable ();
21298 : : }
21299 : :
21300 : :
21301 : : /*
21302 : : Annotate - annotate the top of stack.
21303 : : */
21304 : :
21305 : 123672833 : extern "C" void M2Quads_Annotate (const char *a_, unsigned int _a_high)
21306 : : {
21307 : 123672833 : M2Quads_BoolFrame f;
21308 : 123672833 : char a[_a_high+1];
21309 : :
21310 : : /* make a local copy of each unbounded array. */
21311 : 123672833 : memcpy (a, a_, _a_high+1);
21312 : :
21313 : 0 : if ((DebugStackOn && M2Options_CompilerDebugging) && ((M2StackAddress_NoOfItemsInStackAddress (BoolStack)) > 0))
21314 : : {
21315 : 0 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, 1)); /* top of stack */
21316 : 0 : if (f->Annotation != NULL) /* top of stack */
21317 : : {
21318 : 0 : f->Annotation = DynamicStrings_KillString (f->Annotation);
21319 : : }
21320 : 0 : f->Annotation = DynamicStrings_InitString ((const char *) a, _a_high);
21321 : : }
21322 : 123672833 : }
21323 : :
21324 : :
21325 : : /*
21326 : : DisplayStack - displays the compile time symbol stack.
21327 : : */
21328 : :
21329 : 20176506 : extern "C" void M2Quads_DisplayStack (void)
21330 : : {
21331 : 20176506 : if (DebugStackOn && M2Options_CompilerDebugging)
21332 : : {
21333 : 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});
21334 : : }
21335 : 20176506 : }
21336 : :
21337 : :
21338 : : /*
21339 : : Top - returns the no of items held in the stack.
21340 : : */
21341 : :
21342 : 89466350 : extern "C" unsigned int M2Quads_Top (void)
21343 : : {
21344 : 89466350 : return M2StackAddress_NoOfItemsInStackAddress (BoolStack);
21345 : : /* static analysis guarentees a RETURN statement will be used before here. */
21346 : : __builtin_unreachable ();
21347 : : }
21348 : :
21349 : :
21350 : : /*
21351 : : DupFrame - duplicate the top of stack and push the new frame.
21352 : : */
21353 : :
21354 : 0 : extern "C" void M2Quads_DupFrame (void)
21355 : : {
21356 : 0 : M2Quads_BoolFrame f;
21357 : 0 : M2Quads_BoolFrame newf;
21358 : :
21359 : 0 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
21360 : 0 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
21361 : 0 : newf = newBoolFrame ();
21362 : 0 : (*newf) = (*f);
21363 : 0 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (newf));
21364 : 0 : }
21365 : :
21366 : :
21367 : : /*
21368 : : WriteOperand - displays the operands name, symbol id and mode of addressing.
21369 : : */
21370 : :
21371 : 0 : extern "C" void M2Quads_WriteOperand (unsigned int Sym)
21372 : : {
21373 : 0 : NameKey_Name n;
21374 : :
21375 : 0 : if (Sym == SymbolTable_NulSym)
21376 : : {
21377 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "<nulsym>", 8);
21378 : : }
21379 : : else
21380 : : {
21381 : 0 : n = SymbolTable_GetSymName (Sym);
21382 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%a", 2, (const unsigned char *) &n, (sizeof (n)-1));
21383 : 0 : if ((SymbolTable_IsVar (Sym)) || (SymbolTable_IsConst (Sym)))
21384 : : {
21385 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "[", 1);
21386 : 0 : WriteMode (SymbolTable_GetMode (Sym));
21387 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "]", 1);
21388 : : }
21389 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "(%d)", 4, (const unsigned char *) &Sym, (sizeof (Sym)-1));
21390 : 0 : if (SymbolConversion_GccKnowsAbout (Sym))
21391 : : {
21392 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "[gcc]", 5);
21393 : : }
21394 : : }
21395 : 0 : }
21396 : :
21397 : :
21398 : : /*
21399 : : BeginVarient - begin a varient record.
21400 : : */
21401 : :
21402 : 2982 : extern "C" void M2Quads_BeginVarient (void)
21403 : : {
21404 : 2982 : unsigned int r;
21405 : 2982 : unsigned int v;
21406 : :
21407 : 2982 : r = GetRecordOrField ();
21408 : 5964 : M2Debug_Assert ((SymbolTable_IsRecord (r)) || (SymbolTable_IsFieldVarient (r)));
21409 : 2982 : v = GetRecordOrField ();
21410 : 2982 : M2Debug_Assert (SymbolTable_IsVarient (v));
21411 : 2982 : BuildRange (M2Range_InitCaseBounds (M2CaseList_PushCase (r, v, SymbolTable_NulSym)));
21412 : 2982 : }
21413 : :
21414 : :
21415 : : /*
21416 : : EndVarient - end a varient record.
21417 : : */
21418 : :
21419 : 2982 : extern "C" void M2Quads_EndVarient (void)
21420 : : {
21421 : 2982 : M2CaseList_PopCase ();
21422 : 2982 : }
21423 : :
21424 : :
21425 : : /*
21426 : : ElseVarient - associate an ELSE clause with a varient record.
21427 : : */
21428 : :
21429 : 114 : extern "C" void M2Quads_ElseVarient (void)
21430 : : {
21431 : 114 : unsigned int f;
21432 : :
21433 : 114 : f = GetRecordOrField ();
21434 : 114 : M2Debug_Assert (SymbolTable_IsFieldVarient (f));
21435 : 114 : M2CaseList_ElseCase (f);
21436 : 114 : }
21437 : :
21438 : :
21439 : : /*
21440 : : BeginVarientList - begin an ident list containing ranges belonging to a
21441 : : varient list.
21442 : : */
21443 : :
21444 : 5964 : extern "C" void M2Quads_BeginVarientList (void)
21445 : : {
21446 : 5964 : unsigned int f;
21447 : :
21448 : 5964 : f = GetRecordOrField ();
21449 : 5964 : M2Debug_Assert (SymbolTable_IsFieldVarient (f));
21450 : 5964 : M2CaseList_BeginCaseList (f);
21451 : 5964 : }
21452 : :
21453 : :
21454 : : /*
21455 : : EndVarientList - end a range list for a varient field.
21456 : : */
21457 : :
21458 : 5964 : extern "C" void M2Quads_EndVarientList (void)
21459 : : {
21460 : 5964 : M2CaseList_EndCaseList ();
21461 : 5964 : }
21462 : :
21463 : :
21464 : : /*
21465 : : AddRecordToList - adds the record held on the top of stack to the
21466 : : list of records and varient fields.
21467 : : */
21468 : :
21469 : 2982 : extern "C" void M2Quads_AddRecordToList (void)
21470 : : {
21471 : 2982 : unsigned int r;
21472 : 2982 : unsigned int n;
21473 : :
21474 : 2982 : r = static_cast<unsigned int> (M2Quads_OperandT (1));
21475 : 5964 : M2Debug_Assert ((SymbolTable_IsRecord (r)) || (SymbolTable_IsFieldVarient (r)));
21476 : : /*
21477 : : r might be a field varient if the declaration consists of nested
21478 : : varients. However ISO TSIZE can only utilise record types, we store
21479 : : a varient field anyway as the next pass would not know whether to
21480 : : ignore a varient field.
21481 : : */
21482 : 2982 : Lists_PutItemIntoList (VarientFields, r);
21483 : 2982 : if (DebugVarients)
21484 : : {
21485 : : n = Lists_NoOfItemsInList (VarientFields);
21486 : : if (SymbolTable_IsRecord (r))
21487 : : {
21488 : : 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));
21489 : : }
21490 : : else
21491 : : {
21492 : : 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));
21493 : : }
21494 : : }
21495 : 2982 : }
21496 : :
21497 : :
21498 : : /*
21499 : : AddVarientToList - adds varient held on the top of stack to the list.
21500 : : */
21501 : :
21502 : 2982 : extern "C" void M2Quads_AddVarientToList (void)
21503 : : {
21504 : 2982 : unsigned int v;
21505 : 2982 : unsigned int n;
21506 : :
21507 : 2982 : v = static_cast<unsigned int> (M2Quads_OperandT (1));
21508 : 2982 : M2Debug_Assert (SymbolTable_IsVarient (v));
21509 : 2982 : Lists_PutItemIntoList (VarientFields, v);
21510 : 2982 : if (DebugVarients)
21511 : : {
21512 : : n = Lists_NoOfItemsInList (VarientFields);
21513 : : 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));
21514 : : }
21515 : 2982 : }
21516 : :
21517 : :
21518 : : /*
21519 : : AddVarientFieldToList - adds varient field, f, to the list of all varient
21520 : : fields created.
21521 : : */
21522 : :
21523 : 6078 : extern "C" void M2Quads_AddVarientFieldToList (unsigned int f)
21524 : : {
21525 : 6078 : unsigned int n;
21526 : :
21527 : 6078 : M2Debug_Assert (SymbolTable_IsFieldVarient (f));
21528 : 6078 : Lists_PutItemIntoList (VarientFields, f);
21529 : 6078 : if (DebugVarients)
21530 : : {
21531 : : n = Lists_NoOfItemsInList (VarientFields);
21532 : : 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));
21533 : : }
21534 : 6078 : }
21535 : :
21536 : :
21537 : : /*
21538 : : AddVarientRange - creates a range from the top two contant expressions
21539 : : on the stack which are recorded with the current
21540 : : varient field. The stack is unaltered.
21541 : : */
21542 : :
21543 : 0 : extern "C" void M2Quads_AddVarientRange (void)
21544 : : {
21545 : 0 : unsigned int r1;
21546 : 0 : unsigned int r2;
21547 : :
21548 : 0 : M2Quads_PopT (&r2);
21549 : 0 : M2Quads_PopT (&r1);
21550 : 0 : M2CaseList_AddRange (r1, r2, M2LexBuf_GetTokenNo ());
21551 : 0 : }
21552 : :
21553 : :
21554 : : /*
21555 : : AddVarientEquality - adds the contant expression on the top of the stack
21556 : : to the current varient field being recorded.
21557 : : The stack is unaltered.
21558 : : */
21559 : :
21560 : 6006 : extern "C" void M2Quads_AddVarientEquality (void)
21561 : : {
21562 : 6006 : unsigned int r1;
21563 : :
21564 : 6006 : M2Quads_PopT (&r1);
21565 : 6006 : M2CaseList_AddRange (r1, SymbolTable_NulSym, M2LexBuf_GetTokenNo ());
21566 : 6006 : }
21567 : :
21568 : :
21569 : : /*
21570 : : BuildCodeOn - generates a quadruple declaring that code should be
21571 : : emmitted from henceforth.
21572 : :
21573 : : The Stack is unnaffected.
21574 : : */
21575 : :
21576 : 0 : extern "C" void M2Quads_BuildCodeOn (void)
21577 : : {
21578 : 0 : GenQuad (M2Quads_CodeOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21579 : 0 : }
21580 : :
21581 : :
21582 : : /*
21583 : : BuildCodeOff - generates a quadruple declaring that code should not be
21584 : : emmitted from henceforth.
21585 : :
21586 : : The Stack is unnaffected.
21587 : : */
21588 : :
21589 : 0 : extern "C" void M2Quads_BuildCodeOff (void)
21590 : : {
21591 : 0 : GenQuad (M2Quads_CodeOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21592 : 0 : }
21593 : :
21594 : :
21595 : : /*
21596 : : BuildProfileOn - generates a quadruple declaring that profile timings
21597 : : should be emmitted from henceforth.
21598 : :
21599 : : The Stack is unnaffected.
21600 : : */
21601 : :
21602 : 0 : extern "C" void M2Quads_BuildProfileOn (void)
21603 : : {
21604 : 0 : GenQuad (M2Quads_ProfileOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21605 : 0 : }
21606 : :
21607 : 0 : extern "C" void M2Quads_BuildProfileOff (void)
21608 : : {
21609 : : /*
21610 : : BuildProfileOn - generates a quadruple declaring that profile timings
21611 : : should be emmitted from henceforth.
21612 : :
21613 : : The Stack is unnaffected.
21614 : : */
21615 : 0 : GenQuad (M2Quads_ProfileOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21616 : 0 : }
21617 : :
21618 : :
21619 : : /*
21620 : : BuildOptimizeOn - generates a quadruple declaring that optimization
21621 : : should occur from henceforth.
21622 : :
21623 : : The Stack is unnaffected.
21624 : : */
21625 : :
21626 : 0 : extern "C" void M2Quads_BuildOptimizeOn (void)
21627 : : {
21628 : 0 : GenQuad (M2Quads_OptimizeOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21629 : 0 : }
21630 : :
21631 : :
21632 : : /*
21633 : : BuildOptimizeOff - generates a quadruple declaring that optimization
21634 : : should not occur from henceforth.
21635 : :
21636 : : The Stack is unnaffected.
21637 : : */
21638 : :
21639 : 0 : extern "C" void M2Quads_BuildOptimizeOff (void)
21640 : : {
21641 : 0 : GenQuad (M2Quads_OptimizeOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21642 : 0 : }
21643 : :
21644 : :
21645 : : /*
21646 : : BuildAsm - builds an Inline pseudo quadruple operator.
21647 : : The inline interface, Sym, is stored as the operand
21648 : : to the operator InlineOp.
21649 : :
21650 : : The stack is expected to contain:
21651 : :
21652 : :
21653 : : Entry Exit
21654 : : ===== ====
21655 : :
21656 : : Ptr ->
21657 : : +--------------+
21658 : : | Sym | Empty
21659 : : |--------------|
21660 : : */
21661 : :
21662 : 27 : extern "C" void M2Quads_BuildAsm (unsigned int tok)
21663 : : {
21664 : 27 : unsigned int Sym;
21665 : :
21666 : 27 : M2Quads_PopT (&Sym);
21667 : 27 : GenQuadO (tok, M2Quads_InlineOp, SymbolTable_NulSym, SymbolTable_NulSym, Sym, false);
21668 : 27 : }
21669 : :
21670 : :
21671 : : /*
21672 : : BuildLineNo - builds a LineNumberOp pseudo quadruple operator.
21673 : : This quadruple indicates which source line has been
21674 : : processed, these quadruples are only generated if we
21675 : : are producing runtime debugging information.
21676 : :
21677 : : The stack is not affected, read or altered in any way.
21678 : :
21679 : :
21680 : : Entry Exit
21681 : : ===== ====
21682 : :
21683 : : Ptr -> <- Ptr
21684 : : */
21685 : :
21686 : 0 : extern "C" void M2Quads_BuildLineNo (void)
21687 : : {
21688 : 0 : NameKey_Name filename;
21689 : 0 : M2Quads_QuadFrame f;
21690 : :
21691 : 0 : if (((NextQuad != Head) && (M2Options_GenerateLineDebug || M2Options_GenerateDebugging)) && false)
21692 : : {
21693 : : filename = NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()));
21694 : : f = GetQF (NextQuad-1);
21695 : : if (! ((f->Operator == M2Quads_LineNumberOp) && (f->Operand1 == ((unsigned int ) (filename)))))
21696 : : {
21697 : : GenQuad (M2Quads_LineNumberOp, (unsigned int ) (filename), SymbolTable_NulSym, (unsigned int ) (M2LexBuf_GetLineNo ()));
21698 : : }
21699 : : }
21700 : 0 : }
21701 : :
21702 : :
21703 : : /*
21704 : : PushLineNo - pushes the current file and line number to the stack.
21705 : : */
21706 : :
21707 : 5220 : extern "C" void M2Quads_PushLineNo (void)
21708 : : {
21709 : 5220 : PushLineNote (InitLineNote (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ())), M2LexBuf_GetLineNo ()));
21710 : 5220 : }
21711 : :
21712 : :
21713 : : /*
21714 : : BuildStmtNote - builds a StatementNoteOp pseudo quadruple operator.
21715 : : This quadruple indicates which source line has been
21716 : : processed and it represents the start of a statement
21717 : : sequence.
21718 : : It differs from LineNumberOp in that multiple successive
21719 : : LineNumberOps will be removed and the final one is attached to
21720 : : the next real GCC tree. Whereas a StatementNoteOp is always left
21721 : : alone. Depending upon the debugging level it will issue a nop
21722 : : instruction to ensure that the gdb single step will step into
21723 : : this line. Practically it allows pedalogical debugging to
21724 : : occur when there is syntax sugar such as:
21725 : :
21726 : :
21727 : : END step
21728 : : END step
21729 : : END ; step
21730 : : a := 1 ; step
21731 : :
21732 : : REPEAT step
21733 : : i := 1 step
21734 : :
21735 : : The stack is not affected, read or altered in any way.
21736 : :
21737 : :
21738 : : Entry Exit
21739 : : ===== ====
21740 : :
21741 : : Ptr -> <- Ptr
21742 : : */
21743 : :
21744 : 543012 : extern "C" void M2Quads_BuildStmtNote (int offset)
21745 : : {
21746 : 543012 : int tokenno;
21747 : :
21748 : 543012 : if (NextQuad != Head)
21749 : : {
21750 : 543012 : tokenno = offset;
21751 : 543012 : tokenno += M2LexBuf_GetTokenNo ();
21752 : 543012 : BuildStmtNoteTok ((unsigned int ) (tokenno));
21753 : : }
21754 : 543012 : }
21755 : :
21756 : :
21757 : : /*
21758 : : LoopAnalysis - checks whether an infinite loop exists.
21759 : : */
21760 : :
21761 : 403718 : extern "C" void M2Quads_LoopAnalysis (unsigned int Scope, unsigned int Current, unsigned int End)
21762 : : {
21763 : 403718 : M2Quads_QuadOperator op;
21764 : 403718 : unsigned int op1;
21765 : 403718 : unsigned int op2;
21766 : 403718 : unsigned int op3;
21767 : :
21768 : 403718 : if (M2Options_Pedantic)
21769 : : {
21770 : 11430 : while ((Current <= End) && (Current != 0))
21771 : : {
21772 : 9978 : M2Quads_GetQuad (Current, &op, &op1, &op2, &op3);
21773 : 9978 : if ((op == M2Quads_GotoOp) || (M2Quads_IsConditional (Current)))
21774 : : {
21775 : 114 : if (op3 <= Current)
21776 : : {
21777 : : /* found a loop - ie a branch which goes back in quadruple numbers */
21778 : 24 : if (IsInfiniteLoop (Current))
21779 : : {
21780 : 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);
21781 : 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);
21782 : : }
21783 : : /*
21784 : : WarnStringAt(InitString('it is very likely (although not absolutely certain) that the top of an infinite loop is here'),
21785 : : QuadToTokenNo(op3)) ;
21786 : : WarnStringAt(InitString('and the bottom of the infinite loop is ends here or alternatively a component of this loop is never executed'),
21787 : : QuadToTokenNo(Current))
21788 : : */
21789 : : }
21790 : : }
21791 : 9978 : Current = M2Quads_GetNextQuad (Current);
21792 : : }
21793 : : }
21794 : 403718 : }
21795 : :
21796 : :
21797 : : /*
21798 : : ForLoopAnalysis - checks all the FOR loops for index variable manipulation
21799 : : and dangerous usage outside the loop.
21800 : : */
21801 : :
21802 : 14515 : extern "C" void M2Quads_ForLoopAnalysis (void)
21803 : : {
21804 : 14515 : unsigned int i;
21805 : 14515 : unsigned int n;
21806 : 14515 : M2Quads_ForLoopInfo forDesc;
21807 : :
21808 : 14515 : if (M2Options_Pedantic)
21809 : : {
21810 : 108 : n = Indexing_HighIndice (ForInfo);
21811 : 108 : i = 1;
21812 : 216 : while (i <= n)
21813 : : {
21814 : 0 : forDesc = static_cast<M2Quads_ForLoopInfo> (Indexing_GetIndice (ForInfo, i));
21815 : 0 : CheckForIndex (forDesc);
21816 : 0 : i += 1;
21817 : : }
21818 : : }
21819 : 14515 : }
21820 : :
21821 : :
21822 : : /*
21823 : : BuildSizeCheckStart - switches off all quadruple generation if the function SIZE or HIGH
21824 : : is being "called". This should be done as SIZE only requires the
21825 : : actual type of the expression, not its value. Consider the problem of
21826 : : SIZE(UninitializedPointer^) which is quite legal and it must
21827 : : also be safe!
21828 : : ISO Modula-2 also allows HIGH(a[0]) for a two dimensional array
21829 : : and there is no need to compute a[0], we just need to follow the
21830 : : type and count dimensions. However if SIZE(a) or HIGH(a) occurs
21831 : : and, a, is an unbounded array then we turn on quadruple generation.
21832 : :
21833 : : The Stack is expected to contain:
21834 : :
21835 : :
21836 : : Entry Exit
21837 : : ===== ====
21838 : :
21839 : : Ptr -> <- Ptr
21840 : : +----------------------+ +----------------------+
21841 : : | ProcSym | Type | tok | | ProcSym | Type | tok |
21842 : : |----------------------| |----------------------|
21843 : : */
21844 : :
21845 : 191923 : extern "C" void M2Quads_BuildSizeCheckStart (void)
21846 : : {
21847 : 191923 : unsigned int ProcSym;
21848 : 191923 : unsigned int Type;
21849 : 191923 : unsigned int tok;
21850 : :
21851 : 191923 : M2Quads_PopTFtok (&ProcSym, &Type, &tok);
21852 : 191923 : if (((ProcSym == M2Size_Size) || (ProcSym == M2System_TSize)) || (ProcSym == M2System_TBitSize))
21853 : : {
21854 : 9054 : QuadrupleGeneration = false;
21855 : 9054 : BuildingSize = true;
21856 : : }
21857 : 182869 : else if (ProcSym == M2Base_High)
21858 : : {
21859 : : /* avoid dangling else. */
21860 : 2978 : QuadrupleGeneration = false;
21861 : 2978 : BuildingHigh = true;
21862 : : }
21863 : 191923 : M2Quads_PushTFtok (ProcSym, Type, tok);
21864 : 191923 : }
21865 : :
21866 : :
21867 : : /*
21868 : : BackPatchSubrangesAndOptParam - runs through all the quadruples and finds SubrangeLow or SubrangeHigh
21869 : : quadruples and replaces it by an assignment to the Low or High component
21870 : : of the subrange type.
21871 : :
21872 : : Input:
21873 : : SubrangeLow op1 op3 op3 is a subrange
21874 : :
21875 : : Output:
21876 : : Becomes op1 low
21877 : :
21878 : : Input:
21879 : : SubrangeHigh op1 op3 op3 is a subrange
21880 : :
21881 : : Output:
21882 : : Becomes op1 high
21883 : :
21884 : : Input:
21885 : : OptParam op1 op2 op3
21886 : :
21887 : : Output:
21888 : : Param op1 op2 GetOptArgInit(op3)
21889 : : */
21890 : :
21891 : 14515 : extern "C" void M2Quads_BackPatchSubrangesAndOptParam (void)
21892 : : {
21893 : 14515 : M2Quads_QuadFrame f;
21894 : 14515 : unsigned int q;
21895 : :
21896 : 14515 : q = M2Quads_GetFirstQuad ();
21897 : 14515 : if (q != 0)
21898 : : {
21899 : 6199926 : do {
21900 : 6199926 : f = GetQF (q);
21901 : 6199926 : switch (f->Operator)
21902 : : {
21903 : 282 : case M2Quads_SubrangeLowOp:
21904 : 282 : f->Operand3 = CollectLow (f->Operand3);
21905 : 282 : f->Operator = M2Quads_BecomesOp;
21906 : 282 : f->ConstExpr = false;
21907 : 282 : break;
21908 : :
21909 : 562 : case M2Quads_SubrangeHighOp:
21910 : 562 : f->Operand3 = CollectHigh (f->Operand3);
21911 : 562 : f->Operator = M2Quads_BecomesOp;
21912 : 562 : f->ConstExpr = false;
21913 : 562 : break;
21914 : :
21915 : 3622 : case M2Quads_OptParamOp:
21916 : 3622 : f->Operand3 = SymbolTable_GetOptArgInit (f->Operand3);
21917 : 3622 : f->Operator = M2Quads_ParamOp;
21918 : 3622 : break;
21919 : :
21920 : :
21921 : : default:
21922 : : break;
21923 : : }
21924 : 6199926 : q = f->Next;
21925 : 6199926 : } while (! (q == 0));
21926 : : }
21927 : 14515 : }
21928 : :
21929 : :
21930 : : /*
21931 : : WriteOperator - writes the name of the quadruple operator.
21932 : : */
21933 : :
21934 : 0 : extern "C" void M2Quads_WriteOperator (M2Quads_QuadOperator Operator)
21935 : : {
21936 : 0 : switch (Operator)
21937 : : {
21938 : 0 : case M2Quads_ArithAddOp:
21939 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Arith + ", 18);
21940 : 0 : break;
21941 : :
21942 : 0 : case M2Quads_InitAddressOp:
21943 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitAddress ", 18);
21944 : 0 : break;
21945 : :
21946 : 0 : case M2Quads_LastForIteratorOp:
21947 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "LastForIterator ", 18);
21948 : 0 : break;
21949 : :
21950 : 0 : case M2Quads_LogicalOrOp:
21951 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Or ", 18);
21952 : 0 : break;
21953 : :
21954 : 0 : case M2Quads_LogicalAndOp:
21955 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "And ", 18);
21956 : 0 : break;
21957 : :
21958 : 0 : case M2Quads_LogicalXorOp:
21959 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Xor ", 18);
21960 : 0 : break;
21961 : :
21962 : 0 : case M2Quads_LogicalDiffOp:
21963 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Ldiff ", 18);
21964 : 0 : break;
21965 : :
21966 : 0 : case M2Quads_LogicalShiftOp:
21967 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Shift ", 18);
21968 : 0 : break;
21969 : :
21970 : 0 : case M2Quads_LogicalRotateOp:
21971 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Rotate ", 18);
21972 : 0 : break;
21973 : :
21974 : 0 : case M2Quads_BecomesOp:
21975 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Becomes ", 18);
21976 : 0 : break;
21977 : :
21978 : 0 : case M2Quads_IndrXOp:
21979 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "IndrX ", 18);
21980 : 0 : break;
21981 : :
21982 : 0 : case M2Quads_XIndrOp:
21983 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "XIndr ", 18);
21984 : 0 : break;
21985 : :
21986 : 0 : case M2Quads_ArrayOp:
21987 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Array ", 18);
21988 : 0 : break;
21989 : :
21990 : 0 : case M2Quads_ElementSizeOp:
21991 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ElementSize ", 18);
21992 : 0 : break;
21993 : :
21994 : 0 : case M2Quads_RecordFieldOp:
21995 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RecordField ", 18);
21996 : 0 : break;
21997 : :
21998 : 0 : case M2Quads_AddrOp:
21999 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Addr ", 18);
22000 : 0 : break;
22001 : :
22002 : 0 : case M2Quads_SizeOp:
22003 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Size ", 18);
22004 : 0 : break;
22005 : :
22006 : 0 : case M2Quads_IfInOp:
22007 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If IN ", 18);
22008 : 0 : break;
22009 : :
22010 : 0 : case M2Quads_IfNotInOp:
22011 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If NOT IN ", 18);
22012 : 0 : break;
22013 : :
22014 : 0 : case M2Quads_IfNotEquOp:
22015 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If <> ", 18);
22016 : 0 : break;
22017 : :
22018 : 0 : case M2Quads_IfEquOp:
22019 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If = ", 18);
22020 : 0 : break;
22021 : :
22022 : 0 : case M2Quads_IfLessEquOp:
22023 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If <= ", 18);
22024 : 0 : break;
22025 : :
22026 : 0 : case M2Quads_IfGreEquOp:
22027 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If >= ", 18);
22028 : 0 : break;
22029 : :
22030 : 0 : case M2Quads_IfGreOp:
22031 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If > ", 18);
22032 : 0 : break;
22033 : :
22034 : 0 : case M2Quads_IfLessOp:
22035 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If < ", 18);
22036 : 0 : break;
22037 : :
22038 : 0 : case M2Quads_GotoOp:
22039 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Goto ", 18);
22040 : 0 : break;
22041 : :
22042 : 0 : case M2Quads_DummyOp:
22043 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Dummy ", 18);
22044 : 0 : break;
22045 : :
22046 : 0 : case M2Quads_ModuleScopeOp:
22047 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ModuleScopeOp ", 18);
22048 : 0 : break;
22049 : :
22050 : 0 : case M2Quads_StartDefFileOp:
22051 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StartDefFile ", 18);
22052 : 0 : break;
22053 : :
22054 : 0 : case M2Quads_StartModFileOp:
22055 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StartModFile ", 18);
22056 : 0 : break;
22057 : :
22058 : 0 : case M2Quads_EndFileOp:
22059 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "EndFileOp ", 18);
22060 : 0 : break;
22061 : :
22062 : 0 : case M2Quads_InitStartOp:
22063 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitStart ", 18);
22064 : 0 : break;
22065 : :
22066 : 0 : case M2Quads_InitEndOp:
22067 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitEnd ", 18);
22068 : 0 : break;
22069 : :
22070 : 0 : case M2Quads_FinallyStartOp:
22071 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FinallyStart ", 18);
22072 : 0 : break;
22073 : :
22074 : 0 : case M2Quads_FinallyEndOp:
22075 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FinallyEnd ", 18);
22076 : 0 : break;
22077 : :
22078 : 0 : case M2Quads_RetryOp:
22079 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Retry ", 18);
22080 : 0 : break;
22081 : :
22082 : 0 : case M2Quads_TryOp:
22083 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Try ", 18);
22084 : 0 : break;
22085 : :
22086 : 0 : case M2Quads_ThrowOp:
22087 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Throw ", 18);
22088 : 0 : break;
22089 : :
22090 : 0 : case M2Quads_CatchBeginOp:
22091 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CatchBegin ", 18);
22092 : 0 : break;
22093 : :
22094 : 0 : case M2Quads_CatchEndOp:
22095 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CatchEnd ", 18);
22096 : 0 : break;
22097 : :
22098 : 0 : case M2Quads_AddOp:
22099 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "+ ", 18);
22100 : 0 : break;
22101 : :
22102 : 0 : case M2Quads_SubOp:
22103 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "- ", 18);
22104 : 0 : break;
22105 : :
22106 : 0 : case M2Quads_DivM2Op:
22107 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV M2 ", 18);
22108 : 0 : break;
22109 : :
22110 : 0 : case M2Quads_ModM2Op:
22111 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD M2 ", 18);
22112 : 0 : break;
22113 : :
22114 : 0 : case M2Quads_DivCeilOp:
22115 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV ceil ", 18);
22116 : 0 : break;
22117 : :
22118 : 0 : case M2Quads_ModCeilOp:
22119 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD ceil ", 18);
22120 : 0 : break;
22121 : :
22122 : 0 : case M2Quads_DivFloorOp:
22123 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV floor ", 18);
22124 : 0 : break;
22125 : :
22126 : 0 : case M2Quads_ModFloorOp:
22127 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD floor ", 18);
22128 : 0 : break;
22129 : :
22130 : 0 : case M2Quads_DivTruncOp:
22131 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV trunc ", 18);
22132 : 0 : break;
22133 : :
22134 : 0 : case M2Quads_ModTruncOp:
22135 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD trunc ", 18);
22136 : 0 : break;
22137 : :
22138 : 0 : case M2Quads_MultOp:
22139 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "* ", 18);
22140 : 0 : break;
22141 : :
22142 : 0 : case M2Quads_NegateOp:
22143 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Negate ", 18);
22144 : 0 : break;
22145 : :
22146 : 0 : case M2Quads_InclOp:
22147 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Incl ", 18);
22148 : 0 : break;
22149 : :
22150 : 0 : case M2Quads_ExclOp:
22151 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Excl ", 18);
22152 : 0 : break;
22153 : :
22154 : 0 : case M2Quads_ReturnOp:
22155 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Return ", 18);
22156 : 0 : break;
22157 : :
22158 : 0 : case M2Quads_ReturnValueOp:
22159 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ReturnValue ", 18);
22160 : 0 : break;
22161 : :
22162 : 0 : case M2Quads_FunctValueOp:
22163 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FunctValue ", 18);
22164 : 0 : break;
22165 : :
22166 : 0 : case M2Quads_CallOp:
22167 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Call ", 18);
22168 : 0 : break;
22169 : :
22170 : 0 : case M2Quads_ParamOp:
22171 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Param ", 18);
22172 : 0 : break;
22173 : :
22174 : 0 : case M2Quads_OptParamOp:
22175 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptParam ", 18);
22176 : 0 : break;
22177 : :
22178 : 0 : case M2Quads_NewLocalVarOp:
22179 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "NewLocalVar ", 18);
22180 : 0 : break;
22181 : :
22182 : 0 : case M2Quads_KillLocalVarOp:
22183 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "KillLocalVar ", 18);
22184 : 0 : break;
22185 : :
22186 : 0 : case M2Quads_ProcedureScopeOp:
22187 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProcedureScope ", 18);
22188 : 0 : break;
22189 : :
22190 : 0 : case M2Quads_UnboundedOp:
22191 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Unbounded ", 18);
22192 : 0 : break;
22193 : :
22194 : 0 : case M2Quads_CoerceOp:
22195 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Coerce ", 18);
22196 : 0 : break;
22197 : :
22198 : 0 : case M2Quads_ConvertOp:
22199 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Convert ", 18);
22200 : 0 : break;
22201 : :
22202 : 0 : case M2Quads_CastOp:
22203 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Cast ", 18);
22204 : 0 : break;
22205 : :
22206 : 0 : case M2Quads_HighOp:
22207 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "High ", 18);
22208 : 0 : break;
22209 : :
22210 : 0 : case M2Quads_CodeOnOp:
22211 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CodeOn ", 18);
22212 : 0 : break;
22213 : :
22214 : 0 : case M2Quads_CodeOffOp:
22215 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CodeOff ", 18);
22216 : 0 : break;
22217 : :
22218 : 0 : case M2Quads_ProfileOnOp:
22219 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProfileOn ", 18);
22220 : 0 : break;
22221 : :
22222 : 0 : case M2Quads_ProfileOffOp:
22223 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProfileOff ", 18);
22224 : 0 : break;
22225 : :
22226 : 0 : case M2Quads_OptimizeOnOp:
22227 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptimizeOn ", 18);
22228 : 0 : break;
22229 : :
22230 : 0 : case M2Quads_OptimizeOffOp:
22231 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptimizeOff ", 18);
22232 : 0 : break;
22233 : :
22234 : 0 : case M2Quads_InlineOp:
22235 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Inline ", 18);
22236 : 0 : break;
22237 : :
22238 : 0 : case M2Quads_StatementNoteOp:
22239 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StatementNote ", 18);
22240 : 0 : break;
22241 : :
22242 : 0 : case M2Quads_LineNumberOp:
22243 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "LineNumber ", 18);
22244 : 0 : break;
22245 : :
22246 : 0 : case M2Quads_BuiltinConstOp:
22247 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "BuiltinConst ", 18);
22248 : 0 : break;
22249 : :
22250 : 0 : case M2Quads_BuiltinTypeInfoOp:
22251 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "BuiltinTypeInfo ", 18);
22252 : 0 : break;
22253 : :
22254 : 0 : case M2Quads_StandardFunctionOp:
22255 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StandardFunction ", 18);
22256 : 0 : break;
22257 : :
22258 : 0 : case M2Quads_SavePriorityOp:
22259 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SavePriority ", 18);
22260 : 0 : break;
22261 : :
22262 : 0 : case M2Quads_RestorePriorityOp:
22263 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RestorePriority ", 18);
22264 : 0 : break;
22265 : :
22266 : 0 : case M2Quads_RangeCheckOp:
22267 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RangeCheck ", 18);
22268 : 0 : break;
22269 : :
22270 : 0 : case M2Quads_ErrorOp:
22271 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Error ", 18);
22272 : 0 : break;
22273 : :
22274 : 0 : case M2Quads_SaveExceptionOp:
22275 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SaveException ", 18);
22276 : 0 : break;
22277 : :
22278 : 0 : case M2Quads_RestoreExceptionOp:
22279 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RestoreException ", 18);
22280 : 0 : break;
22281 : :
22282 : 0 : case M2Quads_StringConvertCnulOp:
22283 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringConvertCnul ", 18);
22284 : 0 : break;
22285 : :
22286 : 0 : case M2Quads_StringConvertM2nulOp:
22287 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringConvertM2nul", 18);
22288 : 0 : break;
22289 : :
22290 : 0 : case M2Quads_StringLengthOp:
22291 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringLength ", 18);
22292 : 0 : break;
22293 : :
22294 : 0 : case M2Quads_SubrangeHighOp:
22295 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SubrangeHigh ", 18);
22296 : 0 : break;
22297 : :
22298 : 0 : case M2Quads_SubrangeLowOp:
22299 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SubrangeLow ", 18);
22300 : 0 : break;
22301 : :
22302 : :
22303 : 0 : default:
22304 : 0 : M2Error_InternalError ((const char *) "operator not expected", 21);
22305 : 0 : break;
22306 : : }
22307 : 0 : }
22308 : :
22309 : :
22310 : : /*
22311 : : PushAutoOn - push the auto flag and then set it to TRUE.
22312 : : Any call to ident in the parser will result in the token being pushed.
22313 : : */
22314 : :
22315 : 62754177 : extern "C" void M2Quads_PushAutoOn (void)
22316 : : {
22317 : 62754177 : M2StackWord_PushWord (AutoStack, static_cast<unsigned int> (IsAutoOn));
22318 : 62754177 : IsAutoOn = true;
22319 : 62754177 : }
22320 : :
22321 : :
22322 : : /*
22323 : : PushAutoOff - push the auto flag and then set it to FALSE.
22324 : : */
22325 : :
22326 : 117169628 : extern "C" void M2Quads_PushAutoOff (void)
22327 : : {
22328 : 117169628 : M2StackWord_PushWord (AutoStack, static_cast<unsigned int> (IsAutoOn));
22329 : 117169628 : IsAutoOn = false;
22330 : 117169628 : }
22331 : :
22332 : :
22333 : : /*
22334 : : IsAutoPushOn - returns the value of the current Auto ident push flag.
22335 : : */
22336 : :
22337 : 561566103 : extern "C" bool M2Quads_IsAutoPushOn (void)
22338 : : {
22339 : 561566103 : return IsAutoOn;
22340 : : /* static analysis guarentees a RETURN statement will be used before here. */
22341 : : __builtin_unreachable ();
22342 : : }
22343 : :
22344 : :
22345 : : /*
22346 : : PopAuto - restores the previous value of the Auto flag.
22347 : : */
22348 : :
22349 : 179899345 : extern "C" void M2Quads_PopAuto (void)
22350 : : {
22351 : 179899345 : IsAutoOn = static_cast<bool> (M2StackWord_PopWord (AutoStack));
22352 : 179899345 : }
22353 : :
22354 : :
22355 : : /*
22356 : : MustCheckOverflow - returns TRUE if the quadruple should test for overflow.
22357 : : */
22358 : :
22359 : 537452 : extern "C" bool M2Quads_MustCheckOverflow (unsigned int q)
22360 : : {
22361 : 537452 : M2Quads_QuadFrame f;
22362 : :
22363 : 537452 : f = GetQF (q);
22364 : 537452 : return f->CheckOverflow;
22365 : : /* static analysis guarentees a RETURN statement will be used before here. */
22366 : : __builtin_unreachable ();
22367 : : }
22368 : :
22369 : :
22370 : : /*
22371 : : PushInConstExpression - push the InConstExpression flag and then set it to TRUE.
22372 : : */
22373 : :
22374 : 1229468 : extern "C" void M2Quads_PushInConstExpression (void)
22375 : : {
22376 : 1229468 : M2StackWord_PushWord (ConstExprStack, static_cast<unsigned int> (InConstExpression));
22377 : 1229468 : InConstExpression = true;
22378 : 1229468 : }
22379 : :
22380 : :
22381 : : /*
22382 : : PopInConstExpression - restores the previous value of the InConstExpression.
22383 : : */
22384 : :
22385 : 1229444 : extern "C" void M2Quads_PopInConstExpression (void)
22386 : : {
22387 : 1229444 : InConstExpression = static_cast<bool> (M2StackWord_PopWord (ConstExprStack));
22388 : 1229444 : }
22389 : :
22390 : :
22391 : : /*
22392 : : IsInConstExpression - returns the value of the InConstExpression.
22393 : : */
22394 : :
22395 : 99315 : extern "C" bool M2Quads_IsInConstExpression (void)
22396 : : {
22397 : 99315 : return InConstExpression;
22398 : : /* static analysis guarentees a RETURN statement will be used before here. */
22399 : : __builtin_unreachable ();
22400 : : }
22401 : :
22402 : :
22403 : : /*
22404 : : PushInConstParameters - push the InConstParameters flag and then set it to TRUE.
22405 : : */
22406 : :
22407 : 1726 : extern "C" void M2Quads_PushInConstParameters (void)
22408 : : {
22409 : 1726 : M2StackWord_PushWord (ConstParamStack, static_cast<unsigned int> (InConstParameters));
22410 : 1726 : InConstParameters = true;
22411 : 1726 : }
22412 : :
22413 : :
22414 : : /*
22415 : : PopInConstParameters - restores the previous value of the InConstParameters.
22416 : : */
22417 : :
22418 : 1726 : extern "C" void M2Quads_PopInConstParameters (void)
22419 : : {
22420 : 1726 : InConstParameters = static_cast<bool> (M2StackWord_PopWord (ConstParamStack));
22421 : 1726 : }
22422 : :
22423 : :
22424 : : /*
22425 : : IsInConstParameters - returns the value of the InConstParameters.
22426 : : */
22427 : :
22428 : 92278 : extern "C" bool M2Quads_IsInConstParameters (void)
22429 : : {
22430 : 92278 : return InConstParameters;
22431 : : /* static analysis guarentees a RETURN statement will be used before here. */
22432 : : __builtin_unreachable ();
22433 : : }
22434 : :
22435 : :
22436 : : /*
22437 : : BuildAsmElement - the stack is expected to contain:
22438 : :
22439 : :
22440 : : Entry Exit
22441 : : ===== ====
22442 : :
22443 : : Ptr ->
22444 : : +------------------+
22445 : : | expr | tokpos |
22446 : : |------------------|
22447 : : | str |
22448 : : |------------------|
22449 : : | name |
22450 : : |------------------| +------------------+
22451 : : | CurrentInterface | | CurrentInterface |
22452 : : |------------------| |------------------|
22453 : : | CurrentAsm | | CurrentAsm |
22454 : : |------------------| |------------------|
22455 : : | n | | n |
22456 : : |------------------| |------------------|
22457 : : */
22458 : :
22459 : 33 : extern "C" void M2Quads_BuildAsmElement (bool input, bool output)
22460 : : {
22461 : 33 : DynamicStrings_String s;
22462 : 33 : unsigned int n;
22463 : 33 : unsigned int str;
22464 : 33 : unsigned int expr;
22465 : 33 : unsigned int tokpos;
22466 : 33 : unsigned int CurrentInterface;
22467 : 33 : unsigned int CurrentAsm;
22468 : 33 : unsigned int name;
22469 : :
22470 : 33 : M2Quads_PopTtok (&expr, &tokpos);
22471 : 33 : M2Quads_PopT (&str);
22472 : 33 : M2Quads_PopT (&name);
22473 : 33 : M2Quads_PopT (&CurrentInterface);
22474 : 33 : M2Quads_PopT (&CurrentAsm);
22475 : 66 : M2Debug_Assert ((SymbolTable_IsGnuAsm (CurrentAsm)) || (SymbolTable_IsGnuAsmVolatile (CurrentAsm)));
22476 : 33 : M2Quads_PopT (&n);
22477 : 33 : n += 1;
22478 : 33 : if (CurrentInterface == SymbolTable_NulSym)
22479 : : {
22480 : 30 : CurrentInterface = SymbolTable_MakeRegInterface ();
22481 : : }
22482 : 33 : if (input)
22483 : : {
22484 : 18 : SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, name, str, expr, NextQuad, 0);
22485 : 18 : if (DebugAsmTokPos)
22486 : : {
22487 : : s = DynamicStrings_InitString ((const char *) "input expression", 16);
22488 : : M2Error_WarnStringAt (s, tokpos);
22489 : : }
22490 : : }
22491 : 33 : if (output)
22492 : : {
22493 : 15 : SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, name, str, expr, 0, NextQuad);
22494 : 15 : if (DebugAsmTokPos)
22495 : : {
22496 : : s = DynamicStrings_InitString ((const char *) "output expression", 17);
22497 : : M2Error_WarnStringAt (s, tokpos);
22498 : : }
22499 : : }
22500 : 33 : M2Quads_PushT (n);
22501 : 33 : M2Quads_PushT (CurrentAsm);
22502 : 33 : M2Quads_PushT (CurrentInterface);
22503 : 33 : }
22504 : :
22505 : :
22506 : : /*
22507 : : BuildAsmTrash - the stack is expected to contain:
22508 : :
22509 : :
22510 : : Entry Exit
22511 : : ===== ====
22512 : :
22513 : : Ptr ->
22514 : : +------------------+
22515 : : | expr | tokpos |
22516 : : |------------------| +------------------+
22517 : : | CurrentInterface | | CurrentInterface |
22518 : : |------------------| |------------------|
22519 : : | CurrentAsm | | CurrentAsm |
22520 : : |------------------| |------------------|
22521 : : | n | | n |
22522 : : |------------------| |------------------|
22523 : : */
22524 : :
22525 : 3 : extern "C" void M2Quads_BuildAsmTrash (void)
22526 : : {
22527 : 3 : unsigned int n;
22528 : 3 : unsigned int expr;
22529 : 3 : unsigned int tokpos;
22530 : 3 : unsigned int CurrentInterface;
22531 : 3 : unsigned int CurrentAsm;
22532 : :
22533 : 3 : M2Quads_PopTtok (&expr, &tokpos);
22534 : 3 : M2Quads_PopT (&CurrentInterface);
22535 : 3 : M2Quads_PopT (&CurrentAsm);
22536 : 6 : M2Debug_Assert ((SymbolTable_IsGnuAsm (CurrentAsm)) || (SymbolTable_IsGnuAsmVolatile (CurrentAsm)));
22537 : 3 : M2Quads_PopT (&n);
22538 : 3 : n += 1;
22539 : 3 : if (CurrentInterface == SymbolTable_NulSym)
22540 : : {
22541 : 3 : CurrentInterface = SymbolTable_MakeRegInterface ();
22542 : : }
22543 : 3 : SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, NameKey_NulName, SymbolTable_NulSym, expr, 0, NextQuad);
22544 : 3 : M2Quads_PushT (n);
22545 : 3 : M2Quads_PushT (CurrentAsm);
22546 : 3 : M2Quads_PushT (CurrentInterface);
22547 : 3 : }
22548 : :
22549 : :
22550 : : /*
22551 : : GetQuadTrash - return the symbol associated with the trashed operand.
22552 : : */
22553 : :
22554 : 252 : extern "C" unsigned int M2Quads_GetQuadTrash (unsigned int quad)
22555 : : {
22556 : 252 : M2Quads_QuadFrame f;
22557 : :
22558 : 252 : f = GetQF (quad);
22559 : 252 : LastQuadNo = quad;
22560 : 252 : return f->Trash;
22561 : : /* static analysis guarentees a RETURN statement will be used before here. */
22562 : : __builtin_unreachable ();
22563 : : }
22564 : :
22565 : 15506 : extern "C" void _M2_M2Quads_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
22566 : : {
22567 : 15506 : Init ();
22568 : 15506 : }
22569 : :
22570 : 0 : extern "C" void _M2_M2Quads_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
22571 : : {
22572 : 0 : }
|